Resolves: #i121801# Corrected handling of gradient transformations

(cherry picked from commit 4f49f1d95e8d0be7df259ad1458441fd858be735)

Conflicts:
	drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx
	svgio/source/svgreader/svgnode.cxx
	svgio/source/svgreader/svgstyleattributes.cxx

Change-Id: I155854692a9d1771826867d2666fc6174e2c9256
diff --git a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
index 0328070..756f7b0 100644
--- a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
@@ -280,12 +280,14 @@ namespace drawinglayer
        }

        SvgGradientHelper::SvgGradientHelper(
            const basegfx::B2DHomMatrix& rGradientTransform,
            const basegfx::B2DPolyPolygon& rPolyPolygon,
            const SvgGradientEntryVector& rGradientEntries,
            const basegfx::B2DPoint& rStart,
            bool bUseUnitCoordinates,
            SpreadMethod aSpreadMethod)
        :   maPolyPolygon(rPolyPolygon),
        :   maGradientTransform(rGradientTransform),
            maPolyPolygon(rPolyPolygon),
            maGradientEntries(rGradientEntries),
            maStart(rStart),
            maSpreadMethod(aSpreadMethod),
@@ -301,7 +303,8 @@ namespace drawinglayer
        {
            const SvgGradientHelper& rCompare = static_cast< const SvgGradientHelper& >(rSvgGradientHelper);

            return (getPolyPolygon() == rCompare.getPolyPolygon()
            return (getGradientTransform() == rCompare.getGradientTransform()
                && getPolyPolygon() == rCompare.getPolyPolygon()
                && getGradientEntries() == rCompare.getGradientEntries()
                && getStart() == rCompare.getStart()
                && getUseUnitCoordinates() == rCompare.getUseUnitCoordinates()
@@ -427,6 +430,11 @@ namespace drawinglayer
                    aUnitGradientToObject.translate(aStart.getX(), aStart.getY());
                }

                if(!getGradientTransform().isIdentity())
                {
                    aUnitGradientToObject = getGradientTransform() * aUnitGradientToObject;
                }

                // create inverse from it
                basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject);
                aObjectToUnitGradient.invert();
@@ -545,6 +553,7 @@ namespace drawinglayer
        }

        SvgLinearGradientPrimitive2D::SvgLinearGradientPrimitive2D(
            const basegfx::B2DHomMatrix& rGradientTransform,
            const basegfx::B2DPolyPolygon& rPolyPolygon,
            const SvgGradientEntryVector& rGradientEntries,
            const basegfx::B2DPoint& rStart,
@@ -552,7 +561,7 @@ namespace drawinglayer
            bool bUseUnitCoordinates,
            SpreadMethod aSpreadMethod)
        :   BufferedDecompositionPrimitive2D(),
            SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, bUseUnitCoordinates, aSpreadMethod),
            SvgGradientHelper(rGradientTransform, rPolyPolygon, rGradientEntries, rStart, bUseUnitCoordinates, aSpreadMethod),
            maEnd(rEnd)
        {
        }
@@ -748,6 +757,8 @@ namespace drawinglayer
                else
                {
                    // interpret in object coordinate system -> object aspect ratio will not scale result
                    // use X-Axis with radius, it was already made relative to object width when coming from
                    // SVG import
                    const double fRadius((aObjectTransform * basegfx::B2DVector(getRadius(), 0.0)).getLength());
                    const basegfx::B2DPoint aStart(aObjectTransform * getStart());

@@ -755,6 +766,11 @@ namespace drawinglayer
                    aUnitGradientToObject.translate(aStart.getX(), aStart.getY());
                }

                if(!getGradientTransform().isIdentity())
                {
                    aUnitGradientToObject = getGradientTransform() * aUnitGradientToObject;
                }

                // create inverse from it
                basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject);
                aObjectToUnitGradient.invert();
@@ -822,6 +838,7 @@ namespace drawinglayer
        }

        SvgRadialGradientPrimitive2D::SvgRadialGradientPrimitive2D(
            const basegfx::B2DHomMatrix& rGradientTransform,
            const basegfx::B2DPolyPolygon& rPolyPolygon,
            const SvgGradientEntryVector& rGradientEntries,
            const basegfx::B2DPoint& rStart,
@@ -830,7 +847,7 @@ namespace drawinglayer
            SpreadMethod aSpreadMethod,
            const basegfx::B2DPoint* pFocal)
        :   BufferedDecompositionPrimitive2D(),
            SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, bUseUnitCoordinates, aSpreadMethod),
            SvgGradientHelper(rGradientTransform, rPolyPolygon, rGradientEntries, rStart, bUseUnitCoordinates, aSpreadMethod),
            mfRadius(fRadius),
            maFocal(rStart),
            maFocalVector(0.0, 0.0),
diff --git a/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx b/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx
index f3fc2bc..dc6aa42 100644
--- a/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/svggradientprimitive2d.hxx
@@ -93,6 +93,9 @@ namespace drawinglayer
        class SvgGradientHelper
        {
        private:
            /// the extra gradient transform
            basegfx::B2DHomMatrix       maGradientTransform;

            /// geometric definition, the geometry to be filled
            basegfx::B2DPolyPolygon     maPolyPolygon;

@@ -147,6 +150,7 @@ namespace drawinglayer
        public:
            /// constructor
            SvgGradientHelper(
                const basegfx::B2DHomMatrix& rGradientTransform,
                const basegfx::B2DPolyPolygon& rPolyPolygon,
                const SvgGradientEntryVector& rGradientEntries,
                const basegfx::B2DPoint& rStart,
@@ -155,6 +159,7 @@ namespace drawinglayer
	    virtual ~SvgGradientHelper() {}

            /// data read access
            const basegfx::B2DHomMatrix& getGradientTransform() const { return maGradientTransform; }
            const basegfx::B2DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; }
            const SvgGradientEntryVector& getGradientEntries() const { return maGradientEntries; }
            const basegfx::B2DPoint& getStart() const { return maStart; }
@@ -197,6 +202,7 @@ namespace drawinglayer
        public:
            /// constructor
            SvgLinearGradientPrimitive2D(
                const basegfx::B2DHomMatrix& rGradientTransform,
                const basegfx::B2DPolyPolygon& rPolyPolygon,
                const SvgGradientEntryVector& rGradientEntries,
                const basegfx::B2DPoint& rStart,
@@ -265,6 +271,7 @@ namespace drawinglayer
        public:
            /// constructor
            SvgRadialGradientPrimitive2D(
                const basegfx::B2DHomMatrix& rGradientTransform,
                const basegfx::B2DPolyPolygon& rPolyPolygon,
                const SvgGradientEntryVector& rGradientEntries,
                const basegfx::B2DPoint& rStart,
diff --git a/svgio/inc/svgio/svgreader/svgnode.hxx b/svgio/inc/svgio/svgreader/svgnode.hxx
index 2aa2816..725fb5c 100644
--- a/svgio/inc/svgio/svgreader/svgnode.hxx
+++ b/svgio/inc/svgio/svgreader/svgnode.hxx
@@ -79,6 +79,11 @@ namespace svgio
            Display_inherit
        };

        // helper to convert a string associated with a token of type SVGTokenDisplay
        // to the enum Display. Empty trings return the default 'Display_inline' with
        // which members should be initialized
        Display getDisplayFromContent(const rtl::OUString& aContent);

        class SvgNode : private boost::noncopyable, public InfoProvider
        {
        private:
diff --git a/svgio/source/svgreader/svggnode.cxx b/svgio/source/svgreader/svggnode.cxx
index d185340..4f3e23b 100644
--- a/svgio/source/svgreader/svggnode.cxx
+++ b/svgio/source/svgreader/svggnode.cxx
@@ -90,7 +90,7 @@ namespace svgio
            {
                const double fOpacity(pStyle->getOpacity().getNumber());

                if(fOpacity > 0.0)
                if(fOpacity > 0.0 && Display_none != getDisplay())
                {
                    drawinglayer::primitive2d::Primitive2DSequence aContent;

diff --git a/svgio/source/svgreader/svgnode.cxx b/svgio/source/svgreader/svgnode.cxx
index c4cc265..bbd21d2 100644
--- a/svgio/source/svgreader/svgnode.cxx
+++ b/svgio/source/svgreader/svgnode.cxx
@@ -219,6 +219,107 @@ namespace svgio
            }
        }

        Display getDisplayFromContent(const rtl::OUString& aContent)
        {
            if(aContent.getLength())
            {
                static rtl::OUString aStrInline(rtl::OUString::createFromAscii("inline"));
                static rtl::OUString aStrBlock(rtl::OUString::createFromAscii("block"));
                static rtl::OUString aStrList_item(rtl::OUString::createFromAscii("list-item"));
                static rtl::OUString aStrRun_in(rtl::OUString::createFromAscii("run-in"));
                static rtl::OUString aStrCompact(rtl::OUString::createFromAscii("compact"));
                static rtl::OUString aStrMarker(rtl::OUString::createFromAscii("marker"));
                static rtl::OUString aStrTable(rtl::OUString::createFromAscii("table"));
                static rtl::OUString aStrInline_table(rtl::OUString::createFromAscii("inline-table"));
                static rtl::OUString aStrTable_row_group(rtl::OUString::createFromAscii("table-row-group"));
                static rtl::OUString aStrTable_header_group(rtl::OUString::createFromAscii("table-header-group"));
                static rtl::OUString aStrTable_footer_group(rtl::OUString::createFromAscii("table-footer-group"));
                static rtl::OUString aStrTable_row(rtl::OUString::createFromAscii("table-row"));
                static rtl::OUString aStrTable_column_group(rtl::OUString::createFromAscii("table-column-group"));
                static rtl::OUString aStrTable_column(rtl::OUString::createFromAscii("table-column"));
                static rtl::OUString aStrTable_cell(rtl::OUString::createFromAscii("table-cell"));
                static rtl::OUString aStrTable_caption(rtl::OUString::createFromAscii("table-caption"));
                static rtl::OUString aStrNone(rtl::OUString::createFromAscii("none"));
                static rtl::OUString aStrInherit(rtl::OUString::createFromAscii("inherit"));

                if(aContent.match(aStrInline))
                {
                    return Display_inline;
                }
                else if(aContent.match(aStrNone))
                {
                    return Display_none;
                }
                else if(aContent.match(aStrInherit))
                {
                    return Display_inherit;
                }
                else if(aContent.match(aStrBlock))
                {
                    return Display_block;
                }
                else if(aContent.match(aStrList_item))
                {
                    return Display_list_item;
                }
                else if(aContent.match(aStrRun_in))
                {
                    return Display_run_in;
                }
                else if(aContent.match(aStrCompact))
                {
                    return Display_compact;
                }
                else if(aContent.match(aStrMarker))
                {
                    return Display_marker;
                }
                else if(aContent.match(aStrTable))
                {
                    return Display_table;
                }
                else if(aContent.match(aStrInline_table))
                {
                    return Display_inline_table;
                }
                else if(aContent.match(aStrTable_row_group))
                {
                    return Display_table_row_group;
                }
                else if(aContent.match(aStrTable_header_group))
                {
                    return Display_table_header_group;
                }
                else if(aContent.match(aStrTable_footer_group))
                {
                    return Display_table_footer_group;
                }
                else if(aContent.match(aStrTable_row))
                {
                    return Display_table_row;
                }
                else if(aContent.match(aStrTable_column_group))
                {
                    return Display_table_column_group;
                }
                else if(aContent.match(aStrTable_column))
                {
                    return Display_table_column;
                }
                else if(aContent.match(aStrTable_cell))
                {
                    return Display_table_cell;
                }
                else if(aContent.match(aStrTable_caption))
                {
                    return Display_table_caption;
                }
            }

            // return the default
            return Display_inline;
        }

        void SvgNode::parseAttribute(const OUString& /*rTokenName*/, SVGToken aSVGToken, const OUString& aContent)
        {
            switch(aSVGToken)
@@ -261,97 +362,7 @@ namespace svgio
                {
                    if(aContent.getLength())
                    {
                        static rtl::OUString aStrInline(rtl::OUString::createFromAscii("inline"));
                        static rtl::OUString aStrBlock(rtl::OUString::createFromAscii("block"));
                        static rtl::OUString aStrList_item(rtl::OUString::createFromAscii("list-item"));
                        static rtl::OUString aStrRun_in(rtl::OUString::createFromAscii("run-in"));
                        static rtl::OUString aStrCompact(rtl::OUString::createFromAscii("compact"));
                        static rtl::OUString aStrMarker(rtl::OUString::createFromAscii("marker"));
                        static rtl::OUString aStrTable(rtl::OUString::createFromAscii("table"));
                        static rtl::OUString aStrInline_table(rtl::OUString::createFromAscii("inline-table"));
                        static rtl::OUString aStrTable_row_group(rtl::OUString::createFromAscii("table-row-group"));
                        static rtl::OUString aStrTable_header_group(rtl::OUString::createFromAscii("table-header-group"));
                        static rtl::OUString aStrTable_footer_group(rtl::OUString::createFromAscii("table-footer-group"));
                        static rtl::OUString aStrTable_row(rtl::OUString::createFromAscii("table-row"));
                        static rtl::OUString aStrTable_column_group(rtl::OUString::createFromAscii("table-column-group"));
                        static rtl::OUString aStrTable_column(rtl::OUString::createFromAscii("table-column"));
                        static rtl::OUString aStrTable_cell(rtl::OUString::createFromAscii("table-cell"));
                        static rtl::OUString aStrTable_caption(rtl::OUString::createFromAscii("table-caption"));
                        static rtl::OUString aStrNone(rtl::OUString::createFromAscii("none"));
                        static rtl::OUString aStrInherit(rtl::OUString::createFromAscii("inherit"));

                        if(aContent.match(aStrInline))
                        {
                            setDisplay(Display_inline);
                        }
                        else if(aContent.match(aStrNone))
                        {
                            setDisplay(Display_none);
                        }
                        else if(aContent.match(aStrInherit))
                        {
                            setDisplay(Display_inherit);
                        }
                        else if(aContent.match(aStrBlock))
                        {
                            setDisplay(Display_block);
                        }
                        else if(aContent.match(aStrList_item))
                        {
                            setDisplay(Display_list_item);
                        }
                        else if(aContent.match(aStrRun_in))
                        {
                            setDisplay(Display_run_in);
                        }
                        else if(aContent.match(aStrCompact))
                        {
                            setDisplay(Display_compact);
                        }
                        else if(aContent.match(aStrMarker))
                        {
                            setDisplay(Display_marker);
                        }
                        else if(aContent.match(aStrTable))
                        {
                            setDisplay(Display_table);
                        }
                        else if(aContent.match(aStrInline_table))
                        {
                            setDisplay(Display_inline_table);
                        }
                        else if(aContent.match(aStrTable_row_group))
                        {
                            setDisplay(Display_table_row_group);
                        }
                        else if(aContent.match(aStrTable_header_group))
                        {
                            setDisplay(Display_table_header_group);
                        }
                        else if(aContent.match(aStrTable_footer_group))
                        {
                            setDisplay(Display_table_footer_group);
                        }
                        else if(aContent.match(aStrTable_row))
                        {
                            setDisplay(Display_table_row);
                        }
                        else if(aContent.match(aStrTable_column_group))
                        {
                            setDisplay(Display_table_column_group);
                        }
                        else if(aContent.match(aStrTable_column))
                        {
                            setDisplay(Display_table_column);
                        }
                        else if(aContent.match(aStrTable_cell))
                        {
                            setDisplay(Display_table_cell);
                        }
                        else if(aContent.match(aStrTable_caption))
                        {
                            setDisplay(Display_table_caption);
                        }
                        setDisplay(getDisplayFromContent(aContent));
                    }
                    break;
                }
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
index 7b8a8a5..8d9c406 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -309,10 +309,11 @@ namespace svgio
            if(!aSvgGradientEntryVector.empty())
            {
                basegfx::B2DHomMatrix aGeoToUnit;
                basegfx::B2DHomMatrix aGradientTransform;

                if(rFillGradient.getGradientTransform())
                {
                    aGeoToUnit = *rFillGradient.getGradientTransform();
                    aGradientTransform = *rFillGradient.getGradientTransform();
                }

                if(userSpaceOnUse == rFillGradient.getGradientUnits())
@@ -357,6 +358,7 @@ namespace svgio
                    drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
                        rTarget,
                        new drawinglayer::primitive2d::SvgLinearGradientPrimitive2D(
                            aGradientTransform,
                            rPath,
                            aSvgGradientEntryVector,
                            aStart,
@@ -418,6 +420,7 @@ namespace svgio
                    drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
                        rTarget,
                        new drawinglayer::primitive2d::SvgRadialGradientPrimitive2D(
                            aGradientTransform,
                            rPath,
                            aSvgGradientEntryVector,
                            aStart,
@@ -1779,6 +1782,18 @@ namespace svgio
                    readLocalUrl(aContent, maMarkerEndXLink);
                    break;
                }
                case SVGTokenDisplay:
                {
                    // There may be display:none statements inside of style defines, e.g. the following line:
                    // style="display:none"
                    // taken from a svg example; this needs to be parsed and set at the owning node. Do not call
                    // mrOwner.parseAttribute(...) here, this would lead to a recursion
                    if(aContent.getLength())
                    {
                        mrOwner.setDisplay(getDisplayFromContent(aContent));
                    }
                    break;
                }
                default:
                {
                    break;