Hello community,
here is the log from the commit of package librsvg for openSUSE:Factory checked in at 2016-01-12 16:11:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/librsvg (Old)
and /work/SRC/openSUSE:Factory/.librsvg.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "librsvg"
Changes:
--------
--- /work/SRC/openSUSE:Factory/librsvg/librsvg.changes 2015-12-09 19:32:35.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.librsvg.new/librsvg.changes 2016-01-12 16:11:31.000000000 +0100
@@ -1,0 +2,10 @@
+Fri Jan 8 19:20:06 UTC 2016 - zaitor@opensuse.org
+
+- Update to version 2.40.13:
+ + Fixed the Windows build.
+ + Added basic support for the "baseline-shift" attribute in text
+ objects (bgo#340047).
+ + Fixed some duplicate logic when rendering paths (bgo#749415).
+ + Rewrote the markers engine (bgo#685906, bgo#760180).
+
+-------------------------------------------------------------------
Old:
----
librsvg-2.40.12.tar.xz
New:
----
librsvg-2.40.13.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ librsvg.spec ++++++
--- /var/tmp/diff_new_pack.eXeshj/_old 2016-01-12 16:11:32.000000000 +0100
+++ /var/tmp/diff_new_pack.eXeshj/_new 2016-01-12 16:11:32.000000000 +0100
@@ -1,7 +1,7 @@
#
# spec file for package librsvg
#
-# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: librsvg
-Version: 2.40.12
+Version: 2.40.13
Release: 0
Summary: A Library for Rendering SVG Data
License: LGPL-2.0+ and GPL-2.0+
++++++ librsvg-2.40.12.tar.xz -> librsvg-2.40.13.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/ChangeLog new/librsvg-2.40.13/ChangeLog
--- old/librsvg-2.40.12/ChangeLog 2015-12-02 02:13:44.000000000 +0100
+++ new/librsvg-2.40.13/ChangeLog 2016-01-08 02:44:51.000000000 +0100
@@ -1,3 +1,245 @@
+commit a12e7b90e7b9fa6a6a325f39fb409722b06a6735
+Author: Federico Mena Quintero
+Date: Thu Jan 7 19:37:34 2016 -0600
+
+ Update NEWS
+
+ NEWS | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 954e40e52363fe5bcfbb7e9c28dfcc05aa1affa3
+Author: Federico Mena Quintero
+Date: Thu Jan 7 19:27:22 2016 -0600
+
+ Regenerate reference images which were failing; they are OK now
+
+ tests/fixtures/reftests/bugs/340047-ref.png | Bin 4855 -> 4706 bytes
+ tests/fixtures/reftests/bugs/749415-ref.png | Bin 22441 -> 19572 bytes
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 63371906c63d74bfb1f1ca6b10237d3b563bb55a
+Author: Federico Mena Quintero
+Date: Thu Jan 7 19:15:38 2016 -0600
+
+ bgo#760180: handle the viewBox of markers correctly
+
+ One of the SVG test suite's images has a marker with a viewBox that doesn't actually start at (0, 0).
+ This was rendered incorrectly.
+
+ I'm not sure why this specific use of rsvg_preserve_aspect_ratio() is not the same as the others
+ in librsvg, but it certainly produced incorrect results.
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=760180
+
+ rsvg-marker.c | 13 +--
+ tests/fixtures/reftests/bugs/760180-ref.png | Bin 0 -> 8120 bytes
+ tests/fixtures/reftests/bugs/760180.svg | 159 ++++++++++++++++++++++++++++
+ 3 files changed, 161 insertions(+), 11 deletions(-)
+
+commit 0e2c78cb95a72e7378638a6bb6b647e5c7a7c8c1
+Author: Federico Mena Quintero
+Date: Thu Jan 7 17:24:42 2016 -0600
+
+ rsvg-marker: Use the correct default marker size as specified in the spec
+
+ The spec uses 3 as the default markerWidth and markerHeight:
+ http://www.w3.org/TR/SVG/painting.html#MarkerWidthAttribute
+
+ rsvg-marker.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 92b16618981031f4599d429192ad0b99337a680d
+Author: Paolo Borelli
+Date: Thu Jan 7 23:56:56 2016 +0100
+
+ MSVC builds: Fix install with CopyDir != GlibEtcInstallRoot
+
+ We should create CopyDir since that is where we copy the files
+
+ build/win32/vs10/rsvg-install.propsin | 4 ++--
+ build/win32/vs9/rsvg-install.vspropsin | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit bb0a86f9daa7a8504d6c52a08e9b604b9af80f25
+Author: Federico Mena Quintero
+Date: Wed Jan 6 14:34:32 2016 -0600
+
+ Update NEWS
+
+ NEWS | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit cb7fd6b635a519e968ea67ec529651fe774abe26
+Author: Menner
+Date: Sat Jan 2 09:35:52 2016 +0100
+
+ bgo#749415: Don't duplicate logic for deciding when to push discrete layers
+
+ rsvg_cairo_render_path() tried to avoid calling
+ rsvg_cairo_push/pop_discrete_layer(), but the logic to decide whether
+ to actually create an intermediate surface is best left in those
+ functions. With the duplicate/incorrect logic, text had incorrect
+ spacing as a result.
+
+ Also, remove an extra-old comment from when those functions were first
+ implemented.
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=749415
+
+ rsvg-cairo-draw.c | 23 +++--------------
+ tests/fixtures/reftests/bugs/749415-ref.png | Bin 0 -> 22441 bytes
+ tests/fixtures/reftests/bugs/749415.svg | 38 ++++++++++++++++++++++++++++
+ 3 files changed, 42 insertions(+), 19 deletions(-)
+
+commit 41345523c756297b0b88dbcfeedc38e5f5c86c18
+Author: Federico Mena Quintero
+Date: Tue Jan 5 19:40:39 2016 -0600
+
+ Update NEWS
+
+ NEWS | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 5dc9e603227296766ee05b9fab6812b5e6b4d535
+Author: Federico Mena Quintero
+Date: Tue Jan 5 19:40:32 2016 -0600
+
+ Remove leftover from the unsupported a:adobe-blending-mode
+
+ rsvg-styles.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit e804fb1adcf564ce4bae661cc595a8d4df55efd3
+Author: Menner
+Date: Sat Jan 2 09:42:53 2016 +0100
+
+ bgo#340047 - Add support for the "baseline-shift" text attribute
+
+ This commit adds support for the baseline-shift attribute for tags
+ "sub/super/baseline". We don't support percentages of the font size
+ or explicit lengths yet.
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=340047
+
+ rsvg-css.c | 24 +++++++++++++++-
+ rsvg-private.h | 2 ++
+ rsvg-styles.c | 21 ++++++++++++++
+ rsvg-styles.h | 2 ++
+ rsvg-text.c | 16 +++++++----
+ tests/fixtures/reftests/bugs/340047-ref.png | Bin 0 -> 4855 bytes
+ tests/fixtures/reftests/bugs/340047.svg | 43 ++++++++++++++++++++++++++++
+ 7 files changed, 101 insertions(+), 7 deletions(-)
+
+commit 1fc06fe6def169920f4032e348040c38be320fb1
+Author: Menner
+Date: Tue Jan 5 13:50:17 2016 -0600
+
+ rsvg-marker: Don't try to render NULL markers
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=685906#c7
+
+ rsvg-marker.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit b945b6f5dbee693ac82d1b94f8f5a0ec37d00ee5
+Author: Chun-wei Fan
+Date: Tue Dec 15 14:00:44 2015 +0800
+
+ MSVC 2008 builds: include gio-win32-2.0 in the include paths
+
+ This is a follow-up commit for commit 7ebe28c for Visual Studio 2008
+ builds, for the same reason as that commit.
+
+ build/win32/vs9/rsvg-build-defines.vsprops | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 00744676387ce7914bff33f43ce5f04960219925
+Author: Chun-wei Fan
+Date: Tue Dec 15 13:55:49 2015 +0800
+
+ MSVC builds: Fix pixbuf loaders cache generation
+
+ Use $(GlibEtcInstallRoot)\bin\gdk-pixbuf-query-loaders instead of
+ $(CopyDir)\bin\gdk-pixbuf-query-loaders to fix the "installation" when
+ CopyDir != GlibEtcInstallRoot.
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=759438
+
+ build/win32/vs10/rsvg-install.propsin | 2 +-
+ build/win32/vs9/rsvg-install.vspropsin | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 7ebe28c3be9ba8227cebd407511dcec92d34c39e
+Author: Paolo Borelli
+Date: Sat Dec 12 17:33:46 2015 +0100
+
+ win32: add gio-win32-2.0 to the include paths
+
+ rsvg-convert uses the win32 gio streams
+
+ build/win32/vs10/rsvg-build-defines.props | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3ef996ce17903642187326e20fc5dea48a3c6206
+Author: Federico Mena Quintero
+Date: Mon Dec 7 20:15:30 2015 -0600
+
+ test/bugs: add reference image for #685906
+
+ tests/bugs/685906-ref.png | Bin 0 -> 2955 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 0cfdd27ecb5023b65865d6458d9a810f48f08eb2
+Author: Federico Mena Quintero
+Date: Mon Dec 7 20:11:43 2015 -0600
+
+ bgo#685906 - Marker angles are wrong when control points of a curve are coincident
+
+ This is a rewrite of the code to draw markers at path vertices. The previous code did a single pass
+ over the cairo_path_t data, and it tried to figure out the appropriate marker type for each vertex
+ (start marker, middle, or end). However, it had trouble with coincident points in curveto
+ commands, and with zero-length path segments. The SVG spec is verbose but clear on the behavior
+ for those cases.
+
+ The code now does two passes:
+
+ 1. Take the cairo_path_t data, which is an array of moveto/lineto/curveto/closepath commands, and
+ turn it into a sequence of segments. Each segment either has four control points, *or* it has
+ a single point and the segment is degenerate.
+
+ 2. Walk that list of segments, and draw the appropriate markers for them.
+
+ Having the list of segments makes it easy to implement the algorithm from the SVG spec,
+ in which the directionality of special vertices (like those at the ends of zero-length segments)
+ needs to be determined.
+
+ This code is careful to not do division by zero or to get NaNs in the middle of the computation,
+ which would get Cairo into an error state, preventing further drawing of markers within
+ the path.
+
+ Fixes https://bugzilla.gnome.org/show_bug.cgi?id=685906
+
+ rsvg-marker.c | 524 ++++++++++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 414 insertions(+), 110 deletions(-)
+
+commit 7621ae4f61901c349af7cfe5ae3790b417227bf6
+Author: Federico Mena Quintero
+Date: Tue Dec 1 18:58:15 2015 -0600
+
+ Tests: add bug test for #685906
+
+ tests/bugs/685906.svg | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 313 insertions(+)
+
+commit 3c58d0816d1ebacdd840ba5c60c3cbdfe2eb87c0
+Author: Federico Mena Quintero
+Date: Tue Dec 1 19:18:19 2015 -0600
+
+ Post release version bump
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
commit 513c51f88ed66e7d76718039998658e8b68ba92c
Author: Federico Mena Quintero
Date: Tue Dec 1 19:13:09 2015 -0600
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/NEWS new/librsvg-2.40.13/NEWS
--- old/librsvg-2.40.12/NEWS 2015-12-02 02:12:51.000000000 +0100
+++ new/librsvg-2.40.13/NEWS 2016-01-08 02:43:51.000000000 +0100
@@ -1,3 +1,23 @@
+Version 2.40.13
+- Chun-wei Fan and Paolo Borelli fixed the Windows build.
+- Menner added basic support for the "baseline-shift" attribute in
+ text objects. We support "sub", "super", and plain "baseline", so
+ you can at least have subscripts and superscripts for formulas and
+ such. There is no support for percentages or explicit lengths yet.
+ bgo#340047.
+- Menner fixed some duplicate logic when rendering paths, which would
+ try to decide whether to create intermediate surfaces. Now we have
+ a single place where this is done. This fixes inconsistent text
+ spacing in some situations. bgo#749415.
+- Rewrote the markers engine, for bgo#685906 and bgo#760180 - Our
+ machinery for rendering SVG markers (like arrowheads and such)
+ didn't handle several cases correctly. Curves with coincident
+ control points produced incorrect orientations for the markers, as
+ did multiple contiguous zero-length segments. We follow the spec
+ for this now and handle things correctly. Also, markers didn't
+ render in the correct position if they had the viewBox attribute
+ set.
+
Version 2.40.12
- Benjamin Otte did *great* work in refactoring the test harness to
use Glib's gtest infrastructure, instead of using home-grown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/build/win32/vs10/rsvg-build-defines.props new/librsvg-2.40.13/build/win32/vs10/rsvg-build-defines.props
--- old/librsvg-2.40.12/build/win32/vs10/rsvg-build-defines.props 2015-10-08 00:25:45.000000000 +0200
+++ new/librsvg-2.40.13/build/win32/vs10/rsvg-build-defines.props 2016-01-05 20:44:05.000000000 +0100
@@ -19,7 +19,7 @@
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
- <AdditionalIncludeDirectories>..\..\..;$(GlibEtcInstallRoot)\include\gdk-pixbuf-2.0;$(GlibEtcInstallRoot)\include\glib-2.0;$(GlibEtcInstallRoot)\lib\glib-2.0\include;$(GlibEtcInstallRoot)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..\..;$(GlibEtcInstallRoot)\include\gdk-pixbuf-2.0;$(GlibEtcInstallRoot)\include\glib-2.0;$(GlibEtcInstallRoot)\lib\glib-2.0\include;$(GlibEtcInstallRoot)\include\gio-win32-2.0;$(GlibEtcInstallRoot)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>msvc_recommended_pragmas.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/build/win32/vs10/rsvg-install.props new/librsvg-2.40.13/build/win32/vs10/rsvg-install.props
--- old/librsvg-2.40.12/build/win32/vs10/rsvg-install.props 2015-12-02 02:13:48.000000000 +0100
+++ new/librsvg-2.40.13/build/win32/vs10/rsvg-install.props 2016-01-08 02:44:53.000000000 +0100
@@ -5,8 +5,8 @@
</ImportGroup>
<PropertyGroup Label="UserMacros">
<RsvgDoInstall>
-mkdir $(GlibEtcInstallRoot)
-mkdir $(GlibEtcInstallRoot)\bin
+mkdir $(CopyDir)
+mkdir $(CopyDir)\bin
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\$(RsvgDllPrefix)rsvg$(RsvgDllSuffix).dll $(CopyDir)\bin
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\$(RsvgDllPrefix)rsvg$(RsvgDllSuffix).pdb $(CopyDir)\bin
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\rsvg-convert.exe $(CopyDir)\bin
@@ -22,7 +22,7 @@
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\rsvg-$(ApiVersion).lib $(CopyDir)\lib
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\libpixbufloader-svg.dll $(CopyDir)\lib\gdk-pixbuf-2.0\2.10.0\loaders
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\libpixbufloader-svg.pdb $(CopyDir)\lib\gdk-pixbuf-2.0\2.10.0\loaders
-$(CopyDir)\bin\gdk-pixbuf-query-loaders.exe > $(CopyDir)\lib\gdk-pixbuf-2.0\2.10.0\loaders.cache
+$(GlibEtcInstallRoot)\bin\gdk-pixbuf-query-loaders.exe > $(CopyDir)\lib\gdk-pixbuf-2.0\2.10.0\loaders.cache
</RsvgDoInstall>
</PropertyGroup>
<PropertyGroup>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/build/win32/vs10/rsvg-install.propsin new/librsvg-2.40.13/build/win32/vs10/rsvg-install.propsin
--- old/librsvg-2.40.12/build/win32/vs10/rsvg-install.propsin 2015-10-08 00:25:45.000000000 +0200
+++ new/librsvg-2.40.13/build/win32/vs10/rsvg-install.propsin 2016-01-08 02:43:40.000000000 +0100
@@ -5,8 +5,8 @@
</ImportGroup>
<PropertyGroup Label="UserMacros">
<RsvgDoInstall>
-mkdir $(GlibEtcInstallRoot)
-mkdir $(GlibEtcInstallRoot)\bin
+mkdir $(CopyDir)
+mkdir $(CopyDir)\bin
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\$(RsvgDllPrefix)rsvg$(RsvgDllSuffix).dll $(CopyDir)\bin
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\$(RsvgDllPrefix)rsvg$(RsvgDllSuffix).pdb $(CopyDir)\bin
@@ -23,7 +23,7 @@
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\libpixbufloader-svg.dll $(CopyDir)\lib\gdk-pixbuf-2.0\2.10.0\loaders
copy $(SolutionDir)$(Configuration)\$(Platform)\bin\libpixbufloader-svg.pdb $(CopyDir)\lib\gdk-pixbuf-2.0\2.10.0\loaders
-$(CopyDir)\bin\gdk-pixbuf-query-loaders.exe > $(CopyDir)\lib\gdk-pixbuf-2.0\2.10.0\loaders.cache
+$(GlibEtcInstallRoot)\bin\gdk-pixbuf-query-loaders.exe > $(CopyDir)\lib\gdk-pixbuf-2.0\2.10.0\loaders.cache
</RsvgDoInstall>
</PropertyGroup>
<PropertyGroup>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/build/win32/vs9/rsvg-build-defines.vsprops new/librsvg-2.40.13/build/win32/vs9/rsvg-build-defines.vsprops
--- old/librsvg-2.40.12/build/win32/vs9/rsvg-build-defines.vsprops 2015-10-08 00:25:45.000000000 +0200
+++ new/librsvg-2.40.13/build/win32/vs9/rsvg-build-defines.vsprops 2016-01-05 20:44:05.000000000 +0100
@@ -9,7 +9,7 @@
>
https://bugzilla.gnome.org/enter_bug.cgi?product=librsvg.
#
@@ -591,8 +591,8 @@
# Identity of this package.
PACKAGE_NAME='RSVG'
PACKAGE_TARNAME='librsvg'
-PACKAGE_VERSION='2.40.12'
-PACKAGE_STRING='RSVG 2.40.12'
+PACKAGE_VERSION='2.40.13'
+PACKAGE_STRING='RSVG 2.40.13'
PACKAGE_BUGREPORT='https://bugzilla.gnome.org/enter_bug.cgi?product=librsvg'
PACKAGE_URL=''
@@ -1433,7 +1433,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 RSVG 2.40.12 to adapt to many kinds of systems.
+\`configure' configures RSVG 2.40.13 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1503,7 +1503,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of RSVG 2.40.12:";;
+ short | recursive ) echo "Configuration of RSVG 2.40.13:";;
esac
cat <<\_ACEOF
@@ -1657,7 +1657,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-RSVG configure 2.40.12
+RSVG configure 2.40.13
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2026,7 +2026,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by RSVG $as_me 2.40.12, which was
+It was created by RSVG $as_me 2.40.13, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2895,7 +2895,7 @@
# Define the identity of the package.
PACKAGE='librsvg'
- VERSION='2.40.12'
+ VERSION='2.40.13'
cat >>confdefs.h <<_ACEOF
@@ -3033,13 +3033,13 @@
# ===========================================================================
-RSVG_LT_VERSION_INFO=42:12:40
+RSVG_LT_VERSION_INFO=42:13:40
LIBRSVG_MAJOR_VERSION=2
LIBRSVG_MINOR_VERSION=40
-LIBRSVG_MICRO_VERSION=12
+LIBRSVG_MICRO_VERSION=13
@@ -15688,7 +15688,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by RSVG $as_me 2.40.12, which was
+This file was extended by RSVG $as_me 2.40.13, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -15754,7 +15754,7 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-RSVG config.status 2.40.12
+RSVG config.status 2.40.13
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/librsvg-2.40.12/configure.ac new/librsvg-2.40.13/configure.ac
--- old/librsvg-2.40.12/configure.ac 2015-10-22 16:45:11.000000000 +0200
+++ new/librsvg-2.40.13/configure.ac 2015-12-02 02:18:33.000000000 +0100
@@ -1,6 +1,6 @@
m4_define([rsvg_major_version],[2])
m4_define([rsvg_minor_version],[40])
-m4_define([rsvg_micro_version],[12])
+m4_define([rsvg_micro_version],[13])
m4_define([rsvg_extra_version],[])
m4_define([rsvg_version],[rsvg_major_version.rsvg_minor_version.rsvg_micro_version()rsvg_extra_version])
m4_define([rsvg_lt_version_info],m4_eval(rsvg_major_version + rsvg_minor_version):rsvg_micro_version:rsvg_minor_version)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/doc/html/index.html new/librsvg-2.40.13/doc/html/index.html
--- old/librsvg-2.40.12/doc/html/index.html 2015-12-02 02:13:48.000000000 +0100
+++ new/librsvg-2.40.13/doc/html/index.html 2016-01-08 02:44:53.000000000 +0100
@@ -15,7 +15,7 @@
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">RSVG Libary Reference Manual</p></th></tr></table></div>
<div><p class="releaseinfo">
- For RSVG version 2.40.12
+ For RSVG version 2.40.13
.
The latest version of this documentation can be found on-line at the
<a class="ulink" href="http://library.gnome.org/devel/rsvg/index.html" target="_top">GNOME Library</a>.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/doc/version.xml new/librsvg-2.40.13/doc/version.xml
--- old/librsvg-2.40.12/doc/version.xml 2015-12-02 02:00:13.000000000 +0100
+++ new/librsvg-2.40.13/doc/version.xml 2015-12-02 21:27:37.000000000 +0100
@@ -1 +1 @@
-2.40.12
+2.40.13
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/librsvg-features.h new/librsvg-2.40.13/librsvg-features.h
--- old/librsvg-2.40.12/librsvg-features.h 2015-12-02 02:00:13.000000000 +0100
+++ new/librsvg-2.40.13/librsvg-features.h 2015-12-02 21:27:36.000000000 +0100
@@ -7,8 +7,8 @@
#define LIBRSVG_MAJOR_VERSION (2)
#define LIBRSVG_MINOR_VERSION (40)
-#define LIBRSVG_MICRO_VERSION (12)
-#define LIBRSVG_VERSION "2.40.12"
+#define LIBRSVG_MICRO_VERSION (13)
+#define LIBRSVG_VERSION "2.40.13"
#define LIBRSVG_CHECK_VERSION(major,minor,micro) \
(LIBRSVG_MAJOR_VERSION > (major) || \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/rsvg-cairo-draw.c new/librsvg-2.40.13/rsvg-cairo-draw.c
--- old/librsvg-2.40.12/rsvg-cairo-draw.c 2015-11-03 21:56:53.000000000 +0100
+++ new/librsvg-2.40.13/rsvg-cairo-draw.c 2016-01-07 23:12:03.000000000 +0100
@@ -458,16 +458,10 @@
RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
RsvgState *state = rsvg_current_state (ctx);
cairo_t *cr;
- int need_tmpbuf = 0;
RsvgBbox bbox;
double backup_tolerance;
- need_tmpbuf = ((state->fill != NULL) && (state->stroke != NULL) && state->opacity != 0xff)
- || state->clip_path || state->mask || state->filter
- || (state->comp_op != CAIRO_OPERATOR_OVER);
-
- if (need_tmpbuf)
- rsvg_cairo_push_discrete_layer (ctx);
+ rsvg_cairo_push_discrete_layer (ctx);
cr = render->cr;
@@ -530,10 +524,7 @@
cairo_set_fill_rule (cr, state->fill_rule);
- if (!need_tmpbuf)
- opacity = (state->fill_opacity * state->opacity) / 255;
- else
- opacity = state->fill_opacity;
+ opacity = state->fill_opacity;
_set_source_rsvg_paint_server (ctx,
state->current_color,
@@ -548,10 +539,7 @@
if (state->stroke != NULL) {
int opacity;
- if (!need_tmpbuf)
- opacity = (state->stroke_opacity * state->opacity) / 255;
- else
- opacity = state->stroke_opacity;
+ opacity = state->stroke_opacity;
_set_source_rsvg_paint_server (ctx,
state->current_color,
@@ -563,8 +551,7 @@
cairo_new_path (cr); /* clear the path in case stroke == fill == NULL; otherwise we leave it around from computing the bounding box */
- if (need_tmpbuf)
- rsvg_cairo_pop_discrete_layer (ctx);
+ rsvg_cairo_pop_discrete_layer (ctx);
}
void
@@ -724,8 +711,6 @@
static void
rsvg_cairo_push_render_stack (RsvgDrawingCtx * ctx)
{
- /* XXX: Untested, probably needs help wrt filters */
-
RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
cairo_surface_t *surface;
cairo_t *child_cr;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/rsvg-css.c new/librsvg-2.40.13/rsvg-css.c
--- old/librsvg-2.40.12/rsvg-css.c 2015-08-18 22:07:56.000000000 +0200
+++ new/librsvg-2.40.13/rsvg-css.c 2016-01-06 01:55:44.000000000 +0100
@@ -204,6 +204,7 @@
return out;
}
+/* Recursive evaluation of all parent elements regarding absolute font size */
double
_rsvg_css_normalize_font_size (RsvgState * state, RsvgDrawingCtx * ctx)
{
@@ -213,7 +214,7 @@
case 'p':
case 'm':
case 'x':
- parent= rsvg_state_parent (state);
+ parent = rsvg_state_parent (state);
if (parent) {
double parent_size;
parent_size = _rsvg_css_normalize_font_size (parent, ctx);
@@ -263,6 +264,27 @@
return 0;
}
+/* Recursive evaluation of all parent elements regarding basline-shift */
+double
+_rsvg_css_accumulate_baseline_shift (RsvgState * state, RsvgDrawingCtx * ctx)
+{
+ RsvgState *parent;
+ double shift = 0.;
+
+ parent = rsvg_state_parent (state);
+ if (parent) {
+ if (state->has_baseline_shift) {
+ double parent_font_size;
+ parent_font_size = _rsvg_css_normalize_font_size (parent, ctx); /* font size from here */
+ shift = parent_font_size * state->baseline_shift;
+ }
+ shift += _rsvg_css_accumulate_baseline_shift (parent, ctx); /* baseline-shift for parent element */
+ }
+
+ return shift;
+}
+
+
double
_rsvg_css_hand_normalize_length (const RsvgLength * in, gdouble pixels_per_inch,
gdouble width_or_height, gdouble font_size)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/rsvg-marker.c new/librsvg-2.40.13/rsvg-marker.c
--- old/librsvg-2.40.12/rsvg-marker.c 2015-10-22 16:45:11.000000000 +0200
+++ new/librsvg-2.40.13/rsvg-marker.c 2016-01-08 02:43:41.000000000 +0100
@@ -92,7 +92,7 @@
marker->orientAuto = FALSE;
marker->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
marker->refX = marker->refY = _rsvg_css_parse_length ("0");
- marker->width = marker->height = _rsvg_css_parse_length ("1");
+ marker->width = marker->height = _rsvg_css_parse_length ("3");
marker->bbox = TRUE;
marker->vbox.active = FALSE;
marker->super.set_atts = rsvg_node_marker_set_atts;
@@ -109,6 +109,9 @@
gdouble rotation;
RsvgState *state = rsvg_current_state (ctx);
+ if (marker_name == NULL)
+ return; /* to avoid the caller having to check for nonexistent markers on every call */
+
self = (RsvgMarker *) rsvg_acquire_node (ctx, marker_name);
if (self == NULL || RSVG_NODE_TYPE (&self->super) != RSVG_NODE_TYPE_MARKER)
{
@@ -133,7 +136,6 @@
}
if (self->vbox.active) {
-
double w, h, x, y;
w = _rsvg_css_normalize_length (&self->width, ctx, 'h');
h = _rsvg_css_normalize_length (&self->height, ctx, 'v');
@@ -145,17 +147,9 @@
self->vbox.rect.height,
&w, &h, &x, &y);
- x = -self->vbox.rect.x * w / self->vbox.rect.width;
- y = -self->vbox.rect.y * h / self->vbox.rect.height;
-
- cairo_matrix_init (&taffine,
- w / self->vbox.rect.width,
- 0,
- 0,
- h / self->vbox.rect.height,
- x,
- y);
+ cairo_matrix_init_scale (&taffine, w / self->vbox.rect.width, h / self->vbox.rect.height);
cairo_matrix_multiply (&affine, &taffine, &affine);
+
_rsvg_push_view_box (ctx, self->vbox.rect.width, self->vbox.rect.height);
}
@@ -203,21 +197,361 @@
rsvg_release_node (ctx, (RsvgNode *) self);
}
+typedef struct {
+ gboolean is_degenerate; /* If true, only (p1x, p1y) are valid. If false, all are valid */
+ double p1x, p1y;
+ double p2x, p2y;
+ double p3x, p3y;
+ double p4x, p4y;
+} Segment;
+
+typedef enum {
+ SEGMENT_START,
+ SEGMENT_END,
+} SegmentState;
+
+/* This converts a cairo_path_t into a list of curveto-like segments. Each segment can be:
+ *
+ * 1. segment->is_degenerate = TRUE => the segment is actually a single point (segment->p1x, segment->p1y)
+ *
+ * 2. segment->is_degenerate = FALSE => either a lineto or a curveto (or the effective lineto that results from a closepath).
+ * We have the following points:
+ * P1 = (p1x, p1y)
+ * P2 = (p2x, p2y)
+ * P3 = (p3x, p3y)
+ * P4 = (p4x, p4y)
+ *
+ * The start and end points are P1 and P4, respectively.
+ * The tangent at the start point is given by the vector (P2 - P1).
+ * The tangent at the end point is given by the vector (P4 - P3).
+ * The tangents also work if the segment refers to a lineto (they will both just point in the same direction).
+ */
+
+#define EPSILON 1e-10
+#define DOUBLE_EQUALS(a, b) (fabs ((a) - (b)) < EPSILON)
+
+static void
+path_to_segments (const cairo_path_t *path,
+ Segment **out_segments,
+ int *num_segments)
+{
+ int i;
+ double last_x, last_y;
+ double cur_x, cur_y;
+ double subpath_start_x, subpath_start_y;
+ int max_segments;
+ int segment_num;
+ Segment *segments;
+ SegmentState state;
+
+ max_segments = path->num_data; /* We'll generate maximum this many segments */
+ segments = g_new (Segment, max_segments);
+ *out_segments = segments;
+
+ last_x = last_y = cur_x = cur_y = subpath_start_x = subpath_start_y = 0.0;
+
+ segment_num = -1;
+ state = SEGMENT_END;
+
+ for (i = 0; i < path->num_data; i += path->data[i].header.length) {
+ last_x = cur_x;
+ last_y = cur_y;
+
+ switch (path->data[i].header.type) {
+ case CAIRO_PATH_MOVE_TO:
+ segment_num++;
+ g_assert (segment_num < max_segments);
+
+ g_assert (i + 1 < path->num_data);
+ cur_x = path->data[i + 1].point.x;
+ cur_y = path->data[i + 1].point.y;
+
+ subpath_start_x = cur_x;
+ subpath_start_y = cur_y;
+
+ segments[segment_num].is_degenerate = TRUE;
+
+ segments[segment_num].p1x = cur_x;
+ segments[segment_num].p1y = cur_y;
+
+ state = SEGMENT_START;
+
+ break;
+
+ case CAIRO_PATH_LINE_TO:
+ g_assert (i + 1 < path->num_data);
+ cur_x = path->data[i + 1].point.x;
+ cur_y = path->data[i + 1].point.y;
+
+ if (state == SEGMENT_START) {
+ segments[segment_num].is_degenerate = FALSE;
+ state = SEGMENT_END;
+ } else {
+ segment_num++;
+ g_assert (segment_num < max_segments);
+
+ segments[segment_num].is_degenerate = FALSE;
+
+ segments[segment_num].p1x = last_x;
+ segments[segment_num].p1y = last_y;
+ }
+
+ segments[segment_num].p2x = cur_x;
+ segments[segment_num].p2y = cur_y;
+
+ segments[segment_num].p3x = last_x;
+ segments[segment_num].p3y = last_y;
+
+ segments[segment_num].p4x = cur_x;
+ segments[segment_num].p4y = cur_y;
+
+ break;
+
+ case CAIRO_PATH_CURVE_TO:
+ g_assert (i + 3 < path->num_data);
+ cur_x = path->data[i + 3].point.x;
+ cur_y = path->data[i + 3].point.y;
+
+ if (state == SEGMENT_START) {
+ segments[segment_num].is_degenerate = FALSE;
+ state = SEGMENT_END;
+ } else {
+ segment_num++;
+ g_assert (segment_num < max_segments);
+
+ segments[segment_num].is_degenerate = FALSE;
+
+ segments[segment_num].p1x = last_x;
+ segments[segment_num].p1y = last_y;
+ }
+
+ segments[segment_num].p2x = path->data[i + 1].point.x;
+ segments[segment_num].p2y = path->data[i + 1].point.y;
+
+ segments[segment_num].p3x = path->data[i + 2].point.x;
+ segments[segment_num].p3y = path->data[i + 2].point.y;
+
+ segments[segment_num].p4x = cur_x;
+ segments[segment_num].p4y = cur_y;
+
+ /* Fix the tangents for when the middle control points coincide with their respective endpoints */
+
+ if (DOUBLE_EQUALS (segments[segment_num].p2x, segments[segment_num].p1x)
+ && DOUBLE_EQUALS (segments[segment_num].p2y, segments[segment_num].p1y)) {
+ segments[segment_num].p2x = segments[segment_num].p3x;
+ segments[segment_num].p2y = segments[segment_num].p3y;
+ }
+
+ if (DOUBLE_EQUALS (segments[segment_num].p3x, segments[segment_num].p4x)
+ && DOUBLE_EQUALS (segments[segment_num].p3y, segments[segment_num].p4y)) {
+ segments[segment_num].p3x = segments[segment_num].p2x;
+ segments[segment_num].p3y = segments[segment_num].p2y;
+ }
+
+ break;
+
+ case CAIRO_PATH_CLOSE_PATH:
+ cur_x = subpath_start_x;
+ cur_y = subpath_start_y;
+
+ if (state == SEGMENT_START) {
+ segments[segment_num].is_degenerate = FALSE;
+
+ segments[segment_num].p2x = cur_x;
+ segments[segment_num].p2y = cur_y;
+
+ segments[segment_num].p3x = last_x;
+ segments[segment_num].p3y = last_y;
+
+ segments[segment_num].p4x = cur_x;
+ segments[segment_num].p4y = cur_y;
+
+ state = SEGMENT_END;
+ } else {
+ /* nothing; closepath after moveto (or a single lone closepath) does nothing */
+ }
+
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ *num_segments = segment_num + 1;
+ g_assert (*num_segments <= max_segments);
+}
+
+static gboolean
+points_equal (double x1, double y1, double x2, double y2)
+{
+ return DOUBLE_EQUALS (x1, x2) && DOUBLE_EQUALS (y1, y2);
+}
+
+/* A segment is zero length if it is degenerate, or if all four control points
+ * coincide (the first and last control points may coincide, but the others may
+ * define a loop - thus nonzero length)
+ */
+static gboolean
+is_zero_length_segment (Segment *segment)
+{
+ double p1x, p1y;
+ double p2x, p2y;
+ double p3x, p3y;
+ double p4x, p4y;
+
+ if (segment->is_degenerate)
+ return TRUE;
+
+ p1x = segment->p1x;
+ p1y = segment->p1y;
+
+ p2x = segment->p2x;
+ p2y = segment->p2y;
+
+ p3x = segment->p3x;
+ p3y = segment->p3y;
+
+ p4x = segment->p4x;
+ p4y = segment->p4y;
+
+ return (points_equal (p1x, p1y, p2x, p2y)
+ && points_equal (p1x, p1y, p3x, p3y)
+ && points_equal (p1x, p1y, p4x, p4y));
+}
+
+/* The SVG spec 1.1 says http://www.w3.org/TR/SVG/implnote.html#PathElementImplementationNotes
+ *
+ * Certain line-capping and line-joining situations and markers
+ * require that a path segment have directionality at its start and
+ * end points. Zero-length path segments have no directionality. In
+ * these cases, the following algorithm is used to establish
+ * directionality: to determine the directionality of the start
+ * point of a zero-length path segment, go backwards in the path
+ * data specification within the current subpath until you find a
+ * segment which has directionality at its end point (e.g., a path
+ * segment with non-zero length) and use its ending direction;
+ * otherwise, temporarily consider the start point to lack
+ * directionality. Similarly, to determine the directionality of the
+ * end point of a zero-length path segment, go forwards in the path
+ * data specification within the current subpath until you find a
+ * segment which has directionality at its start point (e.g., a path
+ * segment with non-zero length) and use its starting direction;
+ * otherwise, temporarily consider the end point to lack
+ * directionality. If the start point has directionality but the end
+ * point doesn't, then the end point uses the start point's
+ * directionality. If the end point has directionality but the start
+ * point doesn't, then the start point uses the end point's
+ * directionality. Otherwise, set the directionality for the path
+ * segment's start and end points to align with the positive x-axis
+ * in user space.
+ */
+static gboolean
+find_incoming_directionality_backwards (Segment *segments, int num_segments, int start_index, double *vx, double *vy)
+{
+ int j;
+ gboolean found;
+
+ /* "go backwards ... within the current subpath until ... segment which has directionality at its end point" */
+
+ found = FALSE;
+
+ for (j = start_index; j >= 0; j--) {
+ if (segments[j].is_degenerate)
+ break; /* reached the beginning of the subpath as we ran into a standalone point */
+ else {
+ if (is_zero_length_segment (&segments[j]))
+ continue;
+ else {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ g_assert (j >= 0);
+ *vx = segments[j].p4x - segments[j].p3x;
+ *vy = segments[j].p4y - segments[j].p3y;
+ return TRUE;
+ } else {
+ *vx = 0.0;
+ *vy = 0.0;
+ return FALSE;
+ }
+}
+
+static gboolean
+find_outgoing_directionality_forwards (Segment *segments, int num_segments, int start_index, double *vx, double *vy)
+{
+ int j;
+ gboolean found;
+
+ /* "go forwards ... within the current subpath until ... segment which has directionality at its start point" */
+
+ found = FALSE;
+
+ for (j = start_index; j < num_segments; j++) {
+ if (segments[j].is_degenerate)
+ break; /* reached the end of a subpath as we ran into a standalone point */
+ else {
+ if (is_zero_length_segment (&segments[j]))
+ continue;
+ else {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ g_assert (j < num_segments);
+ *vx = segments[j].p2x - segments[j].p1x;
+ *vy = segments[j].p2y - segments[j].p1y;
+ return TRUE;
+ } else {
+ *vx = 0.0;
+ *vy = 0.0;
+ return FALSE;
+ }
+}
+
+static double
+angle_from_vector (double vx, double vy)
+{
+ double angle;
+
+ angle = atan2 (vy, vx);
+
+ if (isnan (angle))
+ return 0.0;
+ else
+ return angle;
+}
+
+typedef enum {
+ NO_SUBPATH,
+ IN_SUBPATH,
+} SubpathState;
+
void
rsvg_render_markers (RsvgDrawingCtx * ctx,
const cairo_path_t *path)
{
- double x, y;
- double lastx, lasty;
- double linewidth;
- cairo_path_data_type_t code, nextcode;
-
RsvgState *state;
+ double linewidth;
const char *startmarker;
const char *middlemarker;
const char *endmarker;
- cairo_path_data_t *data, *nextdata, *end;
- cairo_path_data_t nextp;
+
+ int i;
+ double incoming_vx, incoming_vy;
+ double outgoing_vx, outgoing_vy;
+
+ Segment *segments;
+ int num_segments;
+
+ SubpathState subpath_state;
state = rsvg_current_state (ctx);
@@ -232,116 +566,80 @@
if (!startmarker && !middlemarker && !endmarker)
return;
- x = 0;
- y = 0;
-
if (path->num_data <= 0)
return;
- end = &path->data[path->num_data];
- data = &path->data[0];
- nextcode = data[0].header.type;
- if (data[0].header.length > 1)
- nextp = data[data[0].header.length - 1];
- else
- nextp.point.x = nextp.point.y = 0.;
+ /* Convert the path to a list of segments and bare points (i.e. degenerate segments) */
+ path_to_segments (path, &segments, &num_segments);
- for ( ; data < end; data = nextdata) {
- lastx = x;
- lasty = y;
- x = nextp.point.x;
- y = nextp.point.y;
- code = nextcode;
-
- nextdata = data + data->header.length;
- if (nextdata < end) {
- nextcode = nextdata->header.type;
- if (nextdata->header.length > 1) {
- nextp = nextdata[nextdata->header.length - 1];
- } else {
- /* keep nextp unchanged */
- }
- } else {
- nextcode = CAIRO_PATH_MOVE_TO;
- }
+ subpath_state = NO_SUBPATH;
- if (nextcode == CAIRO_PATH_MOVE_TO ||
- code == CAIRO_PATH_CLOSE_PATH) {
- if (endmarker) {
- if (code == CAIRO_PATH_CURVE_TO) {
- if (data[2].point.x == x && data[2].point.y == y) {
- /* Can't calculate angle as points are coincident; use the previous point */
- rsvg_marker_render (endmarker, x, y,
- atan2 (y - data[1].point.y,
- x - data[1].point.x),
- linewidth, ctx);
- } else {
- rsvg_marker_render (endmarker, x, y,
- atan2 (y - data[2].point.y,
- x - data[2].point.x),
- linewidth, ctx);
- }
- } else {
- rsvg_marker_render (endmarker, x, y,
- atan2 (y - lasty, x - lastx),
- linewidth, ctx);
- }
- }
- } else if (code == CAIRO_PATH_MOVE_TO ||
- code == CAIRO_PATH_CLOSE_PATH) {
- if (startmarker) {
- if (nextcode == CAIRO_PATH_CURVE_TO) {
- if (nextdata[1].point.x == x && nextdata[1].point.y == y) {
- /* Can't calculate angle as points are coincident; use the next point */
- rsvg_marker_render (startmarker, x, y,
- atan2 (nextdata[2].point.y - y,
- nextdata[2].point.x - x),
- linewidth,
- ctx);
- } else {
- rsvg_marker_render (startmarker, x, y,
- atan2 (nextdata[1].point.y - y,
- nextdata[1].point.x - x),
- linewidth,
- ctx);
- }
- } else {
- rsvg_marker_render (startmarker, x, y,
- atan2 (nextp.point.y - y, nextp.point.x - x),
- linewidth,
- ctx);
- }
+ for (i = 0; i < num_segments; i++) {
+ incoming_vx = incoming_vy = outgoing_vx = outgoing_vy = 0.0;
+
+ if (segments[i].is_degenerate) {
+ if (subpath_state == IN_SUBPATH) {
+ g_assert (i > 0);
+
+ /* Got a lone point after a subpath; render the subpath's end marker first */
+
+ find_incoming_directionality_backwards (segments, num_segments, i - 1, &incoming_vx, &incoming_vy);
+ rsvg_marker_render (endmarker, segments[i - 1].p4x, segments[i - 1].p4y, angle_from_vector (incoming_vx, incoming_vy), linewidth, ctx);
}
+
+ /* Render marker for the lone point; no directionality */
+ rsvg_marker_render (middlemarker, segments[i].p1x, segments[i].p1y, 0.0, linewidth, ctx);
+
+ subpath_state = NO_SUBPATH;
} else {
- if (middlemarker) {
- double xdifin, ydifin, xdifout, ydifout, intot, outtot, angle;
+ /* Not a degenerate segment */
+
+ if (subpath_state == NO_SUBPATH) {
+ find_outgoing_directionality_forwards (segments, num_segments, i, &outgoing_vx, &outgoing_vy);
+ rsvg_marker_render (startmarker, segments[i].p1x, segments[i].p1y, angle_from_vector (outgoing_vx, outgoing_vy), linewidth, ctx);
+
+ subpath_state = IN_SUBPATH;
+ } else {
+ /* subpath_state == IN_SUBPATH */
+
+ gboolean has_incoming, has_outgoing;
+ double incoming, outgoing;
+ double angle;
+
+ g_assert (i > 0);
+
+ has_incoming = find_incoming_directionality_backwards (segments, num_segments, i - 1, &incoming_vx, &incoming_vy);
+ has_outgoing = find_outgoing_directionality_forwards (segments, num_segments, i, &outgoing_vx, &outgoing_vy);
- if (code == CAIRO_PATH_CURVE_TO) {
- xdifin = x - data[2].point.x;
- ydifin = y - data[2].point.y;
- } else {
- xdifin = x - lastx;
- ydifin = y - lasty;
- }
- if (nextcode == CAIRO_PATH_CURVE_TO) {
- xdifout = nextdata[1].point.x - x;
- ydifout = nextdata[1].point.y - y;
- } else {
- xdifout = nextp.point.x - x;
- ydifout = nextp.point.y - y;
- }
-
- intot = sqrt (xdifin * xdifin + ydifin * ydifin);
- outtot = sqrt (xdifout * xdifout + ydifout * ydifout);
-
- xdifin /= intot;
- ydifin /= intot;
- xdifout /= outtot;
- ydifout /= outtot;
+ if (has_incoming)
+ incoming = angle_from_vector (incoming_vx, incoming_vy);
- angle = atan2 ((ydifin + ydifout) / 2, (xdifin + xdifout) / 2);
- rsvg_marker_render (middlemarker, x, y, angle, linewidth, ctx);
+ if (has_outgoing)
+ outgoing = angle_from_vector (outgoing_vx, outgoing_vy);
+
+ if (has_incoming && has_outgoing)
+ angle = (incoming + outgoing) / 2;
+ else if (has_incoming)
+ angle = incoming;
+ else if (has_outgoing)
+ angle = outgoing;
+ else
+ angle = 0.0;
+
+ rsvg_marker_render (middlemarker, segments[i].p1x, segments[i].p1y, angle, linewidth, ctx);
}
}
}
+
+ /* Finally, render the last point */
+
+ if (num_segments > 0) {
+ if (!segments[num_segments - 1].is_degenerate) {
+ find_incoming_directionality_backwards (segments, num_segments, num_segments - 1, &incoming_vx, &incoming_vy);
+
+ rsvg_marker_render (endmarker, segments[num_segments - 1].p4x, segments[num_segments - 1].p4y, angle_from_vector (incoming_vx, incoming_vy), linewidth, ctx);
+ }
+ }
+
+ g_free (segments);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/rsvg-private.h new/librsvg-2.40.13/rsvg-private.h
--- old/librsvg-2.40.12/rsvg-private.h 2015-10-22 16:45:11.000000000 +0200
+++ new/librsvg-2.40.13/rsvg-private.h 2016-01-06 01:56:07.000000000 +0100
@@ -394,6 +394,8 @@
gdouble width_or_height, gdouble font_size);
double _rsvg_css_normalize_font_size (RsvgState * state, RsvgDrawingCtx * ctx);
G_GNUC_INTERNAL
+double _rsvg_css_accumulate_baseline_shift (RsvgState * state, RsvgDrawingCtx * ctx);
+G_GNUC_INTERNAL
RsvgLength _rsvg_css_parse_length (const char *str);
G_GNUC_INTERNAL
void _rsvg_push_view_box (RsvgDrawingCtx * ctx, double w, double h);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/rsvg-styles.c new/librsvg-2.40.13/rsvg-styles.c
--- old/librsvg-2.40.12/rsvg-styles.c 2015-10-22 16:45:11.000000000 +0200
+++ new/librsvg-2.40.13/rsvg-styles.c 2016-01-06 02:36:33.000000000 +0100
@@ -118,6 +118,7 @@
cairo_matrix_init_identity (&state->personal_affine);
state->mask = NULL;
state->opacity = 0xff;
+ state->baseline_shift = 0.;
state->fill = rsvg_paint_server_parse (NULL, "#000");
state->fill_opacity = 0xff;
state->stroke_opacity = 0xff;
@@ -153,6 +154,7 @@
state->middleMarker = NULL;
state->endMarker = NULL;
+ state->has_baseline_shift = FALSE;
state->has_current_color = FALSE;
state->has_flood_color = FALSE;
state->has_flood_opacity = FALSE;
@@ -253,6 +255,8 @@
{
gint i;
+ if (function (dst->has_baseline_shift, src->has_baseline_shift))
+ dst->baseline_shift = src->baseline_shift;
if (function (dst->has_current_color, src->has_current_color))
dst->current_color = src->current_color;
if (function (dst->has_flood_color, src->has_flood_color))
@@ -513,6 +517,22 @@
} else if (g_str_equal (name, "mask")) {
g_free (state->mask);
state->mask = rsvg_get_url_string (value);
+ } else if (g_str_equal (name, "baseline-shift")) {
+ /* These values come from Inkscape's SP_CSS_BASELINE_SHIFT_(SUB/SUPER/BASELINE);
+ * see sp_style_merge_baseline_shift_from_parent()
+ */
+ if (g_str_equal (value, "sub")) {
+ state->has_baseline_shift = TRUE;
+ state->baseline_shift = -0.2;
+ } else if (g_str_equal (value, "super")) {
+ state->has_baseline_shift = TRUE;
+ state->baseline_shift = 0.4;
+ } else if (g_str_equal (value, "baseline")) {
+ state->has_baseline_shift = TRUE;
+ state->baseline_shift = 0.;
+ } else {
+ g_warning ("value \'%s\' for attribute \'baseline-shift\' is not supported; only 'sub', 'super', and 'baseline' are supported\n", value);
+ }
} else if (g_str_equal (name, "clip-path")) {
g_free (state->clip_path);
state->clip_path = rsvg_get_url_string (value);
@@ -861,7 +881,7 @@
void
rsvg_parse_style_pairs (RsvgHandle * ctx, RsvgState * state, RsvgPropertyBag * atts)
{
- rsvg_lookup_parse_style_pair (ctx, state, "a:adobe-blending-mode", atts);
+ rsvg_lookup_parse_style_pair (ctx, state, "baseline-shift", atts);
rsvg_lookup_parse_style_pair (ctx, state, "clip-path", atts);
rsvg_lookup_parse_style_pair (ctx, state, "clip-rule", atts);
rsvg_lookup_parse_style_pair (ctx, state, "color", atts);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/rsvg-styles.h new/librsvg-2.40.13/rsvg-styles.h
--- old/librsvg-2.40.12/rsvg-styles.h 2015-10-22 16:45:11.000000000 +0200
+++ new/librsvg-2.40.13/rsvg-styles.h 2016-01-06 01:49:51.000000000 +0100
@@ -83,6 +83,8 @@
char *mask;
char *clip_path;
guint8 opacity; /* 0..255 */
+ double baseline_shift;
+ gboolean has_baseline_shift;
RsvgPaintServer *fill;
gboolean has_fill_server;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/librsvg-2.40.12/rsvg-text.c new/librsvg-2.40.13/rsvg-text.c
--- old/librsvg-2.40.12/rsvg-text.c 2015-10-22 16:45:11.000000000 +0200
+++ new/librsvg-2.40.13/rsvg-text.c 2016-01-06 02:35:13.000000000 +0100
@@ -163,6 +163,7 @@
gdouble * x, gdouble * y, gboolean * lastwasspace,
gboolean usetextonly);
+/* This function is responsible of selecting render for a text element including its children and giving it the drawing context */
static void
_rsvg_node_text_type_children (RsvgNode * self, RsvgDrawingCtx * ctx,
gdouble * x, gdouble * y, gboolean * lastwasspace,
@@ -598,7 +599,8 @@
PangoLayout *layout;
PangoLayoutIter *iter;
RsvgState *state;
- gint w, h, offsetX, offsetY;
+ gint w, h;
+ double offset_x, offset_y, offset;
state = rsvg_current_state (ctx);
@@ -610,15 +612,17 @@
layout = rsvg_text_create_layout (ctx, state, text, context);
pango_layout_get_size (layout, &w, &h);
iter = pango_layout_get_iter (layout);
+ offset = pango_layout_iter_get_baseline (iter) / (double) PANGO_SCALE;
+ offset += _rsvg_css_accumulate_baseline_shift (state, ctx);
if (PANGO_GRAVITY_IS_VERTICAL (state->text_gravity)) {
- offsetX = -pango_layout_iter_get_baseline (iter) / (double)PANGO_SCALE;
- offsetY = 0;
+ offset_x = -offset;
+ offset_y = 0;
} else {
- offsetX = 0;
- offsetY = pango_layout_iter_get_baseline (iter) / (double)PANGO_SCALE;
+ offset_x = 0;
+ offset_y = offset;
}
pango_layout_iter_free (iter);
- ctx->render->render_pango_layout (ctx, layout, *x - offsetX, *y - offsetY);
+ ctx->render->render_pango_layout (ctx, layout, *x - offset_x, *y - offset_y);
if (PANGO_GRAVITY_IS_VERTICAL (state->text_gravity))
*y += w / (double)PANGO_SCALE;
else