You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by al...@apache.org on 2011/12/13 14:36:50 UTC

svn commit: r1213685 - in /incubator/ooo/branches/alg/svgreplacement/main/svgio: ./ inc/svgio/svgreader/ source/svgreader/

Author: alg
Date: Tue Dec 13 13:36:50 2011
New Revision: 1213685

URL: http://svn.apache.org/viewvc?rev=1213685&view=rev
Log:
svg: Added support for markers; css styles based on Id

Modified:
    incubator/ooo/branches/alg/svgreplacement/main/svgio/Library_svgio.mk
    incubator/ooo/branches/alg/svgreplacement/main/svgio/Package_inc.mk
    incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx
    incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx
    incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx
    incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgdocumenthandler.cxx
    incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgnode.cxx
    incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx
    incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstylenode.cxx
    incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx
    incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/Library_svgio.mk
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/Library_svgio.mk?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/Library_svgio.mk (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/Library_svgio.mk Tue Dec 13 13:36:50 2011
@@ -67,6 +67,7 @@ $(eval $(call gb_Library_add_exception_o
     svgio/source/svgreader/svggradientstopnode \
     svgio/source/svgreader/svgimagenode \
     svgio/source/svgreader/svglinenode \
+    svgio/source/svgreader/svgmarkernode \
     svgio/source/svgreader/svgmasknode \
     svgio/source/svgreader/svgnode \
     svgio/source/svgreader/svgpaint \

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/Package_inc.mk
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/Package_inc.mk?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/Package_inc.mk (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/Package_inc.mk Tue Dec 13 13:36:50 2011
@@ -33,6 +33,7 @@ $(eval $(call gb_Package_add_file,svgio_
 $(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgimagenode.hxx,svgio/svgreader/svgimagenode.hxx))
 $(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svglinenode.hxx,svgio/svgreader/svglinenode.hxx))
 $(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgnode.hxx,svgio/svgreader/svgnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgmarkernode.hxx,svgio/svgreader/svgmarkernode.hxx))
 $(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgmasknode.hxx,svgio/svgreader/svgmasknode.hxx))
 $(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgpaint.hxx,svgio/svgreader/svgpaint.hxx))
 $(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgpathnode.hxx,svgio/svgreader/svgpathnode.hxx))

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgstyleattributes.hxx Tue Dec 13 13:36:50 2011
@@ -30,7 +30,10 @@
 //////////////////////////////////////////////////////////////////////////////
 // predefines
 
-namespace svgio { namespace svgreader { class SvgGradientNode; }}
+namespace svgio { namespace svgreader { 
+    class SvgGradientNode; 
+    class SvgMarkerNode; 
+}}
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -166,10 +169,18 @@ namespace svgio
             TextAnchor                  maTextAnchor;
             SvgPaint                    maColor;
 
-            /// link to content. If maXLink is set, the node can be fetched on demand
+            /// link to content. If set, the node can be fetched on demand
             rtl::OUString               maClipPathXLink;
             rtl::OUString               maMaskXLink;
 
+            /// link to markers. If set, the node can be fetched on demand
+            rtl::OUString               maMarkerStartXLink;
+            const SvgMarkerNode*        mpMarkerStartXLink;
+            rtl::OUString               maMarkerMidXLink;
+            const SvgMarkerNode*        mpMarkerMidXLink;
+            rtl::OUString               maMarkerEndXLink;
+            const SvgMarkerNode*        mpMarkerEndXLink;
+
             /// bitfield
             bool                        maFillRule : 1; // true: NonZero, false: EvenOdd
             bool                        maFillRuleSet : 1;
@@ -196,6 +207,22 @@ namespace svgio
                 const basegfx::B2DPolyPolygon& rPath, 
                 drawinglayer::primitive2d::Primitive2DVector& rTarget,
                 const basegfx::B2DRange& rGeoRange) const;
+            bool prepare_singleMarker(
+                drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives,
+                basegfx::B2DHomMatrix& rMarkerTransform,
+                basegfx::B2DRange& rClipRange,
+                const SvgMarkerNode& rMarker) const;
+            void add_singleMarker(
+                drawinglayer::primitive2d::Primitive2DVector& rTarget,
+                const drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives,
+                const basegfx::B2DHomMatrix& rMarkerTransform,
+                const basegfx::B2DRange& rClipRange,
+                const SvgMarkerNode& rMarker,
+                const basegfx::B2DPolygon& rCandidate,
+                const sal_uInt32 nIndex) const;
+            void add_markers(
+                const basegfx::B2DPolyPolygon& rPath, 
+                drawinglayer::primitive2d::Primitive2DVector& rTarget) const;
 
         public:
             /// local attribute scanner
@@ -331,6 +358,22 @@ namespace svgio
             // MaskXLink content
             const rtl::OUString getMaskXLink() const { return maMaskXLink; }
             void setMaskXLink(const rtl::OUString& rNew) { maMaskXLink = rNew; }
+
+            // MarkerStartXLink content
+            const rtl::OUString getMarkerStartXLink() const;
+            const SvgMarkerNode* accessMarkerStartXLink() const;
+            void setMarkerStartXLink(const rtl::OUString& rNew) { maMarkerStartXLink = rNew; }
+
+            // MarkerMidXLink content
+            const rtl::OUString getMarkerMidXLink() const;
+            const SvgMarkerNode* accessMarkerMidXLink() const;
+            void setMarkerMidXLink(const rtl::OUString& rNew) { maMarkerMidXLink = rNew; }
+
+            // MarkerEndXLink content
+            const rtl::OUString getMarkerEndXLink() const;
+            const SvgMarkerNode* accessMarkerEndXLink() const;
+            void setMarkerEndXLink(const rtl::OUString& rNew) { maMarkerEndXLink = rNew; }
+
         };
     } // end of namespace svgreader
 } // end of namespace svgio

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx Tue Dec 13 13:36:50 2011
@@ -55,7 +55,7 @@ namespace svgio
             virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
             virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
             virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DVector& rTarget, bool bReferenced) const;
-            
+
             /// InfoProvider support for % values
             virtual const basegfx::B2DRange* getCurrentViewPort() const;
 

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/inc/svgio/svgreader/svgtoken.hxx Tue Dec 13 13:36:50 2011
@@ -91,6 +91,16 @@ namespace svgio
             SVGTokenMaskUnits,
             SVGTokenMaskContentUnits,
             SVGTokenClipRule,
+            SVGTokenMarker,
+            SVGTokenMarkerStart,
+            SVGTokenMarkerMid,
+            SVGTokenMarkerEnd,
+            SVGTokenRefX,
+            SVGTokenRefY,
+            SVGTokenMarkerUnits,
+            SVGTokenMarkerWidth,
+            SVGTokenMarkerHeight,
+            SVGTokenOrient,
 
             // AspectRatio and params
             SVGTokenPreserveAspectRatio,

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgdocumenthandler.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgdocumenthandler.cxx?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgdocumenthandler.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgdocumenthandler.cxx Tue Dec 13 13:36:50 2011
@@ -47,6 +47,7 @@
 #include <svgio/svgreader/svgimagenode.hxx>
 #include <svgio/svgreader/svgclippathnode.hxx>
 #include <svgio/svgreader/svgmasknode.hxx>
+#include <svgio/svgreader/svgmarkernode.hxx>
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -314,6 +315,15 @@ namespace svgio
                         break;
                     }
 
+                    /// structural element marker
+                    case SVGTokenMarker:
+                    {
+                        /// new node for marker
+                        mpTarget = new SvgMarkerNode(maDocument, mpTarget);
+                        mpTarget->parseAttributes(xAttribs);
+                        break;
+                    }
+
                     default:
                     {
                         /// invalid token, ignore
@@ -377,6 +387,9 @@ namespace svgio
                     case SVGTokenClipPathNode:
                     case SVGTokenMask:
 
+                    /// structural element marker
+                    case SVGTokenMarker:
+
                     /// content handling after parsing
                     {
                         if(mpTarget)

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgnode.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgnode.cxx?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgnode.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgnode.cxx Tue Dec 13 13:36:50 2011
@@ -141,7 +141,8 @@ namespace svgio
                 if(SVGTokenDefs == getType() || 
                     SVGTokenSymbol == getType() ||
                     SVGTokenClipPathNode == getType() ||
-                    SVGTokenMask == getType())
+                    SVGTokenMarker == getType() ||
+                    SVGTokenMask == getType() )
                 {
                     // do not decompose defs or symbol nodes (these hold only style-like
                     // objects which may be used by referencing them) except when doing

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstyleattributes.cxx Tue Dec 13 13:36:50 2011
@@ -38,6 +38,8 @@
 #include <svgio/svgreader/svgmasknode.hxx>
 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
 #include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <svgio/svgreader/svgmarkernode.hxx>
+#include <basegfx/curve/b2dcubicbezier.hxx>
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -181,24 +183,31 @@ namespace svgio
 
         void SvgStyleAttributes::checkForCssStyle(const rtl::OUString& rClassStr) const
         {
-            if(!mpCssStyleParent && mrOwner.getClass())
+            if(!mpCssStyleParent)
             {
                 const SvgDocument& rDocument = mrOwner.getDocument();
+                const SvgStyleAttributes* pNew = 0;
 
                 if(rDocument.hasSvgStyleAttributesById())
                 {
-                    rtl::OUString aId(rtl::OUString::createFromAscii("."));
-                    aId = aId + *mrOwner.getClass();
-                    
-                    const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(aId);
-
-                    if(!pNew)
+                    if(mrOwner.getClass())
                     {
-                        aId = rClassStr + aId;
-                    
+                        rtl::OUString aId(rtl::OUString::createFromAscii("."));
+                        aId = aId + *mrOwner.getClass();
                         pNew = rDocument.findSvgStyleAttributesById(aId);
-                    }
 
+                        if(!pNew)
+                        {
+                            aId = rClassStr + aId;
+                    
+                            pNew = rDocument.findSvgStyleAttributesById(aId);
+                        }
+                    }
+                    else if(mrOwner.getId())
+                    {
+                        pNew = rDocument.findSvgStyleAttributesById(*mrOwner.getId());
+                    }
+                    
                     if(pNew)
                     {
                         // found css style, set as parent
@@ -622,6 +631,225 @@ namespace svgio
             }
         }
 
+        double get_markerRotation(
+            const SvgMarkerNode& rMarker,
+            const basegfx::B2DPolygon& rPolygon,
+            const sal_uInt32 nIndex)
+        {
+            double fAngle(0.0);
+            const sal_uInt32 nPointCount(rPolygon.count());
+
+            if(nPointCount)
+            {
+                if(rMarker.getOrientAuto())
+                {
+                    const bool bPrev(rPolygon.isClosed() || nIndex > 0);
+                    basegfx::B2DCubicBezier aSegment;
+                    basegfx::B2DVector aPrev;
+                    basegfx::B2DVector aNext;
+
+                    if(bPrev)
+                    {
+                        rPolygon.getBezierSegment((nIndex - 1) % nPointCount, aSegment);
+                        aPrev = aSegment.getTangent(1.0);
+                    }
+
+                    const bool bNext(rPolygon.isClosed() || nIndex + 1 < nPointCount);
+
+                    if(bNext)
+                    {
+                        rPolygon.getBezierSegment(nIndex % nPointCount, aSegment);
+                        aNext = aSegment.getTangent(0.0);
+                    }
+
+                    if(bPrev && bNext)
+                    {
+                        fAngle = atan2(aPrev.getY() + aNext.getY(), aPrev.getX() + aNext.getX());
+                    }
+                    else if(bPrev)
+                    {
+                        fAngle = atan2(aPrev.getY(), aPrev.getX());
+                    }
+                    else if(bNext)
+                    {
+                        fAngle = atan2(aNext.getY(), aNext.getX());
+                    }
+                }
+                else
+                {
+                    fAngle = rMarker.getAngle();
+                }
+            }
+
+            return fAngle;
+        }
+
+        bool SvgStyleAttributes::prepare_singleMarker(
+            drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives,
+            basegfx::B2DHomMatrix& rMarkerTransform,
+            basegfx::B2DRange& rClipRange,
+            const SvgMarkerNode& rMarker) const
+        {
+            // get marker primitive representation
+            rMarkerPrimitives = rMarker.getMarkerPrimitives();
+
+            if(rMarkerPrimitives.hasElements())
+            {
+                basegfx::B2DRange aPrimitiveRange;
+
+                if(rMarker.getViewBox())
+                {
+                    aPrimitiveRange = *rMarker.getViewBox();
+                }
+                else
+                {
+                    aPrimitiveRange = drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+                        rMarkerPrimitives,
+                        drawinglayer::geometry::ViewInformation2D());
+                }
+
+                if(aPrimitiveRange.getWidth() > 0.0 && aPrimitiveRange.getHeight() > 0.0)
+                {
+                    double fTargetWidth(rMarker.getMarkerWidth().isSet() ? rMarker.getMarkerWidth().solve(mrOwner, xcoordinate) : 0.0);
+                    double fTargetHeight(rMarker.getMarkerHeight().isSet() ? rMarker.getMarkerHeight().solve(mrOwner, xcoordinate) : 0.0);
+
+                    if(SvgMarkerNode::strokeWidth == rMarker.getMarkerUnits())
+                    {
+                        // relative to strokeWidth
+                        const double fStrokeWidth(getStrokeWidth().isSet() ? getStrokeWidth().solve(mrOwner, length) : 1.0);
+
+                        fTargetWidth *= fStrokeWidth;
+                        fTargetHeight *= fStrokeWidth;
+                    }
+
+                    if(fTargetWidth > 0.0 && fTargetHeight > 0.0)
+                    {
+                        const basegfx::B2DRange aTargetRange(0.0, 0.0, fTargetWidth, fTargetHeight);
+
+                        // subbstract refX, refY first, it's in marker local coordinates
+                        rMarkerTransform.identity();
+                        rMarkerTransform.translate(
+                            rMarker.getRefX().isSet() ? -rMarker.getRefX().solve(mrOwner, xcoordinate) : 0.0,
+                            rMarker.getRefY().isSet() ? -rMarker.getRefY().solve(mrOwner, ycoordinate) : 0.0);
+
+                        // create mapping
+                        const SvgAspectRatio& rRatio = rMarker.getSvgAspectRatio();
+
+                        if(rRatio.isSet())
+                        {
+                            // let mapping be created from SvgAspectRatio
+                            rMarkerTransform = rRatio.createMapping(aTargetRange, aPrimitiveRange) * rMarkerTransform;
+                            
+                            if(rRatio.isMeetOrSlice())
+                            {
+                                // need to clip
+                                rClipRange = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
+                            }
+                        }
+                        else
+                        {
+                            // choose default mapping
+                            rMarkerTransform = rRatio.createLinearMapping(aTargetRange, aPrimitiveRange) * rMarkerTransform;
+                        }
+
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        void SvgStyleAttributes::add_singleMarker(
+            drawinglayer::primitive2d::Primitive2DVector& rTarget,
+            const drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives,
+            const basegfx::B2DHomMatrix& rMarkerTransform,
+            const basegfx::B2DRange& rClipRange,
+            const SvgMarkerNode& rMarker,
+            const basegfx::B2DPolygon& rCandidate,
+            const sal_uInt32 nIndex) const
+        {
+            const sal_uInt32 nPointCount(rCandidate.count());
+
+            if(nPointCount)
+            {
+                // get and apply rotation
+                basegfx::B2DHomMatrix aCombinedTransform(rMarkerTransform);
+                aCombinedTransform.rotate(get_markerRotation(rMarker, rCandidate, nIndex));
+
+                // get and apply target position
+                const basegfx::B2DPoint aPoint(rCandidate.getB2DPoint(nIndex % nPointCount));
+                aCombinedTransform.translate(aPoint.getX(), aPoint.getY());
+
+                // add marker
+                rTarget.push_back(
+                    new drawinglayer::primitive2d::TransformPrimitive2D(
+                        aCombinedTransform,
+                        rMarkerPrimitives));
+            }
+        }
+
+        void SvgStyleAttributes::add_markers(
+            const basegfx::B2DPolyPolygon& rPath,
+            drawinglayer::primitive2d::Primitive2DVector& rTarget) const
+        {
+            // try to access linked markers
+            const SvgMarkerNode* pStart = accessMarkerStartXLink();
+            const SvgMarkerNode* pMid = accessMarkerMidXLink();
+            const SvgMarkerNode* pEnd = accessMarkerEndXLink();
+
+            if(pStart || pMid || pEnd)
+            {
+                const sal_uInt32 nCount(rPath.count());
+
+                for (sal_uInt32 a(0); a < nCount; a++)
+                {
+                    const basegfx::B2DPolygon aCandidate(rPath.getB2DPolygon(a));
+                    const sal_uInt32 nPointCount(aCandidate.count());
+
+                    if(nPointCount)
+                    {
+                        const sal_uInt32 nMarkerCount(aCandidate.isClosed() ? nPointCount + 1 : nPointCount);
+                        drawinglayer::primitive2d::Primitive2DSequence aMarkerPrimitives;
+                        basegfx::B2DHomMatrix aMarkerTransform;
+                        basegfx::B2DRange aClipRange;
+                        const SvgMarkerNode* pPrepared = 0;
+
+                        if(pStart)
+                        {
+                            if(prepare_singleMarker(aMarkerPrimitives, aMarkerTransform, aClipRange, *pStart))
+                            {
+                                pPrepared = pStart;
+                                add_singleMarker(rTarget, aMarkerPrimitives, aMarkerTransform, aClipRange, *pPrepared, aCandidate, 0);
+                            }
+                        }
+
+                        if(pMid && nMarkerCount > 2)
+                        {
+                            if(pMid == pPrepared || prepare_singleMarker(aMarkerPrimitives, aMarkerTransform, aClipRange, *pMid))
+                            {
+                                pPrepared = pMid;
+
+                                for(sal_uInt32 a(1); a < nMarkerCount - 1; a++)
+                                {
+                                    add_singleMarker(rTarget, aMarkerPrimitives, aMarkerTransform, aClipRange, *pPrepared, aCandidate, a);
+                                }
+                            }
+                        }
+
+                        if(pEnd)
+                        {
+                            if(pEnd == pPrepared || prepare_singleMarker(aMarkerPrimitives, aMarkerTransform, aClipRange, *pEnd))
+                            {
+                                pPrepared = pEnd;
+                                add_singleMarker(rTarget, aMarkerPrimitives, aMarkerTransform, aClipRange, *pPrepared, aCandidate, nMarkerCount - 1);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
         void SvgStyleAttributes::add_path(
             const basegfx::B2DPolyPolygon& rPath, 
             drawinglayer::primitive2d::Primitive2DVector& rTarget, 
@@ -651,23 +879,33 @@ namespace svgio
             }
 
             drawinglayer::primitive2d::Primitive2DVector aNewPrimitives;
-            basegfx::B2DPolyPolygon aPath(rPath);
-            const bool bNeedToCheckClipRule(SVGTokenPath == mrOwner.getType() || SVGTokenPolygon == mrOwner.getType());
-            const bool bClipPathIsNonzero(!bIsLine && bNeedToCheckClipRule && mbIsClipPathContent && mbClipRule);
-            const bool bFillRuleIsNonzero(!bIsLine && bNeedToCheckClipRule && !mbIsClipPathContent && getFillRule());
-
-            if(bClipPathIsNonzero || bFillRuleIsNonzero)
-            {
-                // nonzero is wanted, solve geometrically (see description on basegfx)
-                aPath = basegfx::tools::createNonzeroConform(aPath);
-            }
 
             if(!bIsLine)
             {
+                basegfx::B2DPolyPolygon aPath(rPath);
+                const bool bNeedToCheckClipRule(SVGTokenPath == mrOwner.getType() || SVGTokenPolygon == mrOwner.getType());
+                const bool bClipPathIsNonzero(!bIsLine && bNeedToCheckClipRule && mbIsClipPathContent && mbClipRule);
+                const bool bFillRuleIsNonzero(!bIsLine && bNeedToCheckClipRule && !mbIsClipPathContent && getFillRule());
+
+                if(bClipPathIsNonzero || bFillRuleIsNonzero)
+                {
+                    // nonzero is wanted, solve geometrically (see description on basegfx)
+                    aPath = basegfx::tools::createNonzeroConform(aPath);
+                }
+
                 add_fill(aPath, aNewPrimitives, aGeoRange);
             }
 
-            add_stroke(aPath, aNewPrimitives, aGeoRange);
+            add_stroke(rPath, aNewPrimitives, aGeoRange);
+
+            // Svg supports markers for path, polygon, polyline and line
+            if(SVGTokenPath == mrOwner.getType() ||         // path
+                SVGTokenPolygon == mrOwner.getType() ||     // polygon, polyline
+                SVGTokenLine == mrOwner.getType())          // line
+            {
+                // try to add markers
+                add_markers(rPath, aNewPrimitives);
+            }
 
             if(pTransform && !aNewPrimitives.empty())
             {
@@ -713,7 +951,12 @@ namespace svgio
             maColor(),
             maClipPathXLink(),
             maMaskXLink(),
-
+            maMarkerStartXLink(),
+            mpMarkerStartXLink(0),
+            maMarkerMidXLink(),
+            mpMarkerMidXLink(0),
+            maMarkerEndXLink(),
+            mpMarkerEndXLink(0),
             maFillRule(true),
             maFillRuleSet(false),
             mbIsClipPathContent(SVGTokenClipPathNode == mrOwner.getType()),
@@ -1283,6 +1526,27 @@ namespace svgio
                     }
                     break;
                 }
+                case SVGTokenMarker:
+                {
+                    readLocalUrl(aContent, maMarkerEndXLink);
+                    maMarkerStartXLink = maMarkerMidXLink = maMarkerEndXLink;
+                    break;
+                }
+                case SVGTokenMarkerStart:
+                {
+                    readLocalUrl(aContent, maMarkerStartXLink);
+                    break;
+                }
+                case SVGTokenMarkerMid:
+                {
+                    readLocalUrl(aContent, maMarkerMidXLink);
+                    break;
+                }
+                case SVGTokenMarkerEnd:
+                {
+                    readLocalUrl(aContent, maMarkerEndXLink);
+                    break;
+                }
             }
         }
 
@@ -1814,6 +2078,102 @@ namespace svgio
             return 0;
         }
 
+        const rtl::OUString SvgStyleAttributes::getMarkerStartXLink() const 
+        { 
+            if(maMarkerStartXLink.getLength())
+            {
+                return maMarkerStartXLink;
+            }
+
+            const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+            if(pSvgStyleAttributes)
+            {
+                return pSvgStyleAttributes->getMarkerStartXLink(); 
+            }
+
+            return rtl::OUString(); 
+        }
+
+        const SvgMarkerNode* SvgStyleAttributes::accessMarkerStartXLink() const
+        {
+            if(!mpMarkerStartXLink)
+            {
+                const rtl::OUString aMarker(getMarkerStartXLink());
+
+                if(aMarker.getLength())
+                {
+                    const_cast< SvgStyleAttributes* >(this)->mpMarkerStartXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerStartXLink()));
+                }
+            }
+
+            return mpMarkerStartXLink;
+        }
+
+        const rtl::OUString SvgStyleAttributes::getMarkerMidXLink() const 
+        { 
+            if(maMarkerMidXLink.getLength())
+            {
+                return maMarkerMidXLink;
+            }
+
+            const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+            if(pSvgStyleAttributes)
+            {
+                return pSvgStyleAttributes->getMarkerMidXLink(); 
+            }
+
+            return rtl::OUString(); 
+        }
+
+        const SvgMarkerNode* SvgStyleAttributes::accessMarkerMidXLink() const
+        {
+            if(!mpMarkerMidXLink)
+            {
+                const rtl::OUString aMarker(getMarkerMidXLink());
+
+                if(aMarker.getLength())
+                {
+                    const_cast< SvgStyleAttributes* >(this)->mpMarkerMidXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerMidXLink()));
+                }
+            }
+
+            return mpMarkerMidXLink;
+        }
+
+        const rtl::OUString SvgStyleAttributes::getMarkerEndXLink() const 
+        { 
+            if(maMarkerEndXLink.getLength())
+            {
+                return maMarkerEndXLink;
+            }
+
+            const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+            if(pSvgStyleAttributes)
+            {
+                return pSvgStyleAttributes->getMarkerEndXLink(); 
+            }
+
+            return rtl::OUString(); 
+        }
+
+        const SvgMarkerNode* SvgStyleAttributes::accessMarkerEndXLink() const
+        {
+            if(!mpMarkerEndXLink)
+            {
+                const rtl::OUString aMarker(getMarkerEndXLink());
+
+                if(aMarker.getLength())
+                {
+                    const_cast< SvgStyleAttributes* >(this)->mpMarkerEndXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerEndXLink()));
+                }
+            }
+
+            return mpMarkerEndXLink;
+        }
+
     } // end of namespace svgreader
 } // end of namespace svgio
 

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstylenode.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstylenode.cxx?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstylenode.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgstylenode.cxx Tue Dec 13 13:36:50 2011
@@ -82,6 +82,7 @@ namespace svgio
                 sal_Int32 nPos(0);
                 rtl::OUStringBuffer aTokenValue;
 
+                skip_char(aContent, sal_Unicode(' '), sal_Unicode('#'), nPos, nLen);
                 copyToLimiter(aContent, sal_Unicode('{'), nPos, aTokenValue, nLen);
                 const rtl::OUString aStyleName = aTokenValue.makeStringAndClear().trim();
 

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx Tue Dec 13 13:36:50 2011
@@ -82,6 +82,16 @@ namespace svgio
         static rtl::OUString aSVGStrMaskUnits(rtl::OUString::createFromAscii("maskUnits")); 
         static rtl::OUString aSVGStrMaskContentUnits(rtl::OUString::createFromAscii("maskContentUnits")); 
         static rtl::OUString aSVGStrClipRule(rtl::OUString::createFromAscii("clip-rule")); 
+        static rtl::OUString aSVGStrMarker(rtl::OUString::createFromAscii("marker")); 
+        static rtl::OUString aSVGStrMarkerStart(rtl::OUString::createFromAscii("marker-start")); 
+        static rtl::OUString aSVGStrMarkerMid(rtl::OUString::createFromAscii("marker-mid")); 
+        static rtl::OUString aSVGStrMarkerEnd(rtl::OUString::createFromAscii("marker-end")); 
+        static rtl::OUString aSVGStrRefX(rtl::OUString::createFromAscii("refX")); 
+        static rtl::OUString aSVGStrRefY(rtl::OUString::createFromAscii("refY")); 
+        static rtl::OUString aSVGStrMarkerUnits(rtl::OUString::createFromAscii("markerUnits")); 
+        static rtl::OUString aSVGStrMarkerWidth(rtl::OUString::createFromAscii("markerWidth")); 
+        static rtl::OUString aSVGStrMarkerHeight(rtl::OUString::createFromAscii("markerHeight")); 
+        static rtl::OUString aSVGStrOrient(rtl::OUString::createFromAscii("orient")); 
 
         static rtl::OUString aSVGStrPreserveAspectRatio(rtl::OUString::createFromAscii("preserveAspectRatio")); 
         static rtl::OUString aSVGStrDefer(rtl::OUString::createFromAscii("defer")); 
@@ -206,6 +216,16 @@ namespace svgio
                 aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMaskUnits, SVGTokenMaskUnits));
                 aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMaskContentUnits, SVGTokenMaskContentUnits));
                 aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrClipRule, SVGTokenClipRule));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarker, SVGTokenMarker));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerStart, SVGTokenMarkerStart));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerMid, SVGTokenMarkerMid));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerEnd, SVGTokenMarkerEnd));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRefX, SVGTokenRefX));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRefY, SVGTokenRefY));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerUnits, SVGTokenMarkerUnits));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerWidth, SVGTokenMarkerWidth));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerHeight, SVGTokenMarkerHeight));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrOrient, SVGTokenOrient));
 
                 aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPreserveAspectRatio, SVGTokenPreserveAspectRatio));
                 aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDefer, SVGTokenDefer));

Modified: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx?rev=1213685&r1=1213684&r2=1213685&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtools.cxx Tue Dec 13 13:36:50 2011
@@ -1106,8 +1106,8 @@ namespace svgio
                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
 
-                                    const double fX(aX.solve(rInfoProvider, xcoordinate));
-                                    const double fY(aY.solve(rInfoProvider, ycoordinate));
+                                    const double fX(aX.isSet() ? aX.solve(rInfoProvider, xcoordinate) : 0.0);
+                                    const double fY(aY.isSet() ? aY.solve(rInfoProvider, ycoordinate) : 0.0);
 
                                     if(!basegfx::fTools::equalZero(fX) || !basegfx::fTools::equalZero(fY))
                                     {