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/01 17:26:53 UTC

svn commit: r1209140 [8/11] - in /incubator/ooo/branches/alg/svgreplacement/main: ./ basegfx/inc/basegfx/matrix/ basegfx/inc/basegfx/polygon/ basegfx/source/polygon/ cppcanvas/source/mtfrenderer/ drawinglayer/ drawinglayer/inc/drawinglayer/primitive2d/...

Added: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtextnode.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtextnode.cxx?rev=1209140&view=auto
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtextnode.cxx (added)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtextnode.cxx Thu Dec  1 16:25:17 2011
@@ -0,0 +1,277 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgtextnode.hxx>
+#include <svgio/svgreader/svgcharacternode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <svgio/svgreader/svgtrefnode.hxx>
+#include <svgio/svgreader/svgtextpathnode.hxx>
+#include <svgio/svgreader/svgtspannode.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+    namespace svgreader
+    {
+        SvgTextNode::SvgTextNode(
+            SvgDocument& rDocument,
+            SvgNode* pParent)
+        :   SvgNode(SVGTokenText, rDocument, pParent),
+            maSvgStyleAttributes(*this),
+            mpaTransform(0),
+            maSvgTextPositions()
+        {
+        }
+
+        SvgTextNode::~SvgTextNode()
+        {
+            if(mpaTransform) delete mpaTransform;
+        }
+
+        const SvgStyleAttributes* SvgTextNode::getSvgStyleAttributes() const
+        {
+            static rtl::OUString aClassStr(rtl::OUString::createFromAscii("text"));
+            maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+            return &maSvgStyleAttributes;
+        }
+
+        void SvgTextNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+        {
+            // call parent
+            SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+            // read style attributes
+            maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+            // read text position attributes
+            maSvgTextPositions.parseTextPositionAttributes(rTokenName, aSVGToken, aContent);
+
+            // parse own
+            switch(aSVGToken)
+            {
+                case SVGTokenStyle:
+                {
+                    maSvgStyleAttributes.readStyle(aContent);
+                    break;
+                }
+                case SVGTokenTransform:
+                {
+                    const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+                    if(!aMatrix.isIdentity())
+                    {
+                        setTransform(&aMatrix);
+                    }
+                    break;
+                }
+            }
+        }
+
+        void SvgTextNode::addTextPrimitives(const SvgNode& rCandidate, drawinglayer::primitive2d::Primitive2DVector& rTarget, drawinglayer::primitive2d::Primitive2DVector& rSource) const
+        {
+            if(!rSource.empty())
+            {
+                const SvgStyleAttributes* pAttributes = rCandidate.getSvgStyleAttributes();
+
+                if(pAttributes)
+                {
+                    // add text with taking all Fill/Stroke attributes into account
+                    pAttributes->add_text(rTarget, rSource);
+                }
+                else
+                {
+                    // should not happen, every subnode from SvgTextNode will at least
+                    // return the attributes from SvgTextNode. Nonetheless, add text
+                    rTarget.insert(rTarget.end(), rSource.begin(), rSource.end());
+                }
+            }
+        }
+
+        void SvgTextNode::DecomposeChild(const SvgNode& rCandidate, drawinglayer::primitive2d::Primitive2DVector& rTarget, SvgTextPosition& rSvgTextPosition) const
+        {
+            switch(rCandidate.getType())
+            {
+                case SVGTokenCharacter:
+                {
+                    // direct SvgTextPathNode derivates, decompose them
+                    const SvgCharacterNode& rSvgCharacterNode = static_cast< const SvgCharacterNode& >(rCandidate);
+                    rSvgCharacterNode.decomposeText(rTarget, rSvgTextPosition);
+                    break;
+                }
+                case SVGTokenTextPath:
+                {
+                    // direct TextPath decompose
+                    const SvgTextPathNode& rSvgTextPathNode = static_cast< const SvgTextPathNode& >(rCandidate);
+                    const SvgNodeVector& rChildren = rSvgTextPathNode.getChildren();
+                    const sal_uInt32 nCount(rChildren.size());
+
+                    if(nCount && rSvgTextPathNode.isValid())
+                    {
+                        // remember original TextStart to later detect hor/ver offsets
+                        const basegfx::B2DPoint aTextStart(rSvgTextPosition.getPosition());
+                        drawinglayer::primitive2d::Primitive2DVector aNewTarget;
+
+                        // decompose to regular TextPrimitives
+                        for(sal_uInt32 a(0); a < nCount; a++)
+                        {
+                            DecomposeChild(*rChildren[a], aNewTarget, rSvgTextPosition);
+                        }
+
+                        if(!aNewTarget.empty())
+                        {
+                            const drawinglayer::primitive2d::Primitive2DSequence aPathContent(Primitive2DVectorToPrimitive2DSequence(aNewTarget));
+                            aNewTarget.clear();
+
+                            // dismantle TextPrimitives and map them on curve/path
+                            rSvgTextPathNode.decomposePathNode(aPathContent, aNewTarget, aTextStart);
+                        }
+
+                        if(!aNewTarget.empty())
+                        {
+                            addTextPrimitives(rCandidate, rTarget, aNewTarget);
+                        }
+                    }
+
+                    break;
+                }
+                case SVGTokenTspan:
+                {
+                    // Tspan may have children, call recursively
+                    const SvgTspanNode& rSvgTspanNode = static_cast< const SvgTspanNode& >(rCandidate);
+                    const SvgNodeVector& rChildren = rSvgTspanNode.getChildren();
+                    const sal_uInt32 nCount(rChildren.size());
+
+                    if(nCount)
+                    {
+                        SvgTextPosition aSvgTextPosition(&rSvgTextPosition, rSvgTspanNode, rSvgTspanNode.getSvgTextPositions());
+                        drawinglayer::primitive2d::Primitive2DVector aNewTarget;
+
+                        for(sal_uInt32 a(0); a < nCount; a++)
+                        {
+                            DecomposeChild(*rChildren[a], aNewTarget, aSvgTextPosition);
+                        }
+
+                        rSvgTextPosition.setPosition(aSvgTextPosition.getPosition());
+                        
+                        if(!aNewTarget.empty())
+                        {
+                            addTextPrimitives(rCandidate, rTarget, aNewTarget);
+                        }
+                    }
+                    break;
+                }
+                case SVGTokenTref:
+                {
+                    const SvgTrefNode& rSvgTrefNode = static_cast< const SvgTrefNode& >(rCandidate);
+                    const SvgTextNode* pRefText = rSvgTrefNode.getReferencedSvgTextNode();
+
+                    if(pRefText)
+                    {
+                        const SvgNodeVector& rChildren = pRefText->getChildren();
+                        const sal_uInt32 nCount(rChildren.size());
+                        drawinglayer::primitive2d::Primitive2DVector aNewTarget;
+
+                        if(nCount)
+                        {
+                            for(sal_uInt32 a(0); a < nCount; a++)
+                            {
+                                const SvgNode& rChildCandidate = *rChildren[a];
+                                const_cast< SvgNode& >(rChildCandidate).setAlternativeParent(this);
+    
+                                DecomposeChild(rChildCandidate, aNewTarget, rSvgTextPosition);
+                                const_cast< SvgNode& >(rChildCandidate).setAlternativeParent(0);
+                            }
+                            
+                            if(!aNewTarget.empty())
+                            {
+                                addTextPrimitives(rCandidate, rTarget, aNewTarget);
+                            }
+                        }
+                    }
+
+                    break;
+                }
+                default:
+                {
+                    OSL_ENSURE(false, "Unexpected node in text token (!)");
+                    break;
+                }
+            }
+        }
+
+        void SvgTextNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DVector& rTarget, bool bReferenced) const
+        {
+            // text has a group of child nodes, allowed are SVGTokenCharacter, SVGTokenTspan,
+            // SVGTokenTref and SVGTokenTextPath. These increase a given current text position
+            const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+            if(pStyle && !getChildren().empty())
+            {
+                SvgTextPosition aSvgTextPosition(0, *this, getSvgTextPositions());
+                drawinglayer::primitive2d::Primitive2DVector aNewTarget;
+                const SvgNodeVector& rChildren = getChildren();
+                const sal_uInt32 nCount(rChildren.size());
+
+                for(sal_uInt32 a(0); a < nCount; a++)
+                {
+                    const SvgNode& rCandidate = *rChildren[a];
+    
+                    DecomposeChild(rCandidate, aNewTarget, aSvgTextPosition);
+                }
+                
+                if(!aNewTarget.empty())
+                {
+                    drawinglayer::primitive2d::Primitive2DVector aNewTarget2;
+
+                    addTextPrimitives(*this, aNewTarget2, aNewTarget);
+                    aNewTarget = aNewTarget2;
+                }
+
+                if(!aNewTarget.empty())
+                {
+                    if(getTransform())
+                    {
+                        // create embedding group element with transformation
+                        rTarget.push_back(
+                            new drawinglayer::primitive2d::TransformPrimitive2D(
+                                *getTransform(),
+                                Primitive2DVectorToPrimitive2DSequence(aNewTarget)));
+                        aNewTarget.clear();
+                    }
+                    else
+                    {
+                        // append to current target
+                        rTarget.insert(rTarget.end(), aNewTarget.begin(), aNewTarget.end());
+                    }
+                }
+            }
+        }
+    } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof

Added: incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtextpathnode.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtextpathnode.cxx?rev=1209140&view=auto
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtextpathnode.cxx (added)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtextpathnode.cxx Thu Dec  1 16:25:17 2011
@@ -0,0 +1,527 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgtextpathnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <svgio/svgreader/svgpathnode.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+#include <svgio/svgreader/svgtrefnode.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/textbreakuphelper.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <basegfx/curve/b2dcubicbezier.hxx>
+#include <basegfx/curve/b2dbeziertools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+    namespace svgreader
+    {
+        class pathTextBreakupHelper : public drawinglayer::primitive2d::TextBreakupHelper
+        {
+        private:
+            const basegfx::B2DPolygon&      mrPolygon;
+            const double                    mfBasegfxPathLength;
+            const double                    mfUserToBasegfx;
+            double                          mfPosition;
+            const basegfx::B2DPoint&        mrTextStart;
+
+            const sal_uInt32                mnMaxIndex;
+            sal_uInt32                      mnIndex;
+            basegfx::B2DCubicBezier         maCurrentSegment;
+            basegfx::B2DCubicBezierHelper*  mpB2DCubicBezierHelper;
+            double                          mfCurrentSegmentLength;
+            double                          mfSegmentStartPosition;
+
+        protected:
+            /// allow user callback to allow changes to the new TextTransformation. Default
+            /// does nothing.
+            virtual bool allowChange(sal_uInt32 nCount, basegfx::B2DHomMatrix& rNewTransform, sal_uInt32 nIndex, sal_uInt32 nLength);
+
+            void freeB2DCubicBezierHelper();
+            basegfx::B2DCubicBezierHelper* getB2DCubicBezierHelper();
+            void advanceToPosition(double fNewPosition);
+
+        public:
+            pathTextBreakupHelper(
+                const drawinglayer::primitive2d::Primitive2DReference& rxSource,
+                const basegfx::B2DPolygon& rPolygon,
+                const double fBasegfxPathLength,
+                const double fUserToBasegfx,
+                double fPosition,
+                const basegfx::B2DPoint& rTextStart);
+            virtual ~pathTextBreakupHelper();
+
+            // read access to evtl. advanced position
+            double getPosition() const { return mfPosition; }
+
+            // get length of given text
+            double getLength(const rtl::OUString& rText) const;
+        };
+
+        double pathTextBreakupHelper::getLength(const rtl::OUString& rText) const
+        {
+            const sal_uInt32 nLength(rText.getLength());
+
+            if(nLength)
+            {
+                return getTextLayouter().getTextWidth(rText, 0, nLength);
+            }
+            
+            return 0.0;
+        }
+
+        void pathTextBreakupHelper::freeB2DCubicBezierHelper()
+        {
+            if(mpB2DCubicBezierHelper)
+            {
+                delete mpB2DCubicBezierHelper;
+                mpB2DCubicBezierHelper = 0;
+            }
+        }
+
+        basegfx::B2DCubicBezierHelper* pathTextBreakupHelper::getB2DCubicBezierHelper()
+        {
+            if(!mpB2DCubicBezierHelper && maCurrentSegment.isBezier())
+            {
+                mpB2DCubicBezierHelper = new basegfx::B2DCubicBezierHelper(maCurrentSegment);
+            }
+
+            return mpB2DCubicBezierHelper;
+        }
+
+        void pathTextBreakupHelper::advanceToPosition(double fNewPosition)
+        {
+            while(mfSegmentStartPosition + mfCurrentSegmentLength < fNewPosition && mnIndex < mnMaxIndex)
+            {
+                mfSegmentStartPosition += mfCurrentSegmentLength;
+                mnIndex++;
+
+                if(mnIndex < mnMaxIndex)
+                {
+                    freeB2DCubicBezierHelper();
+                    mrPolygon.getBezierSegment(mnIndex % mrPolygon.count(), maCurrentSegment);
+                    maCurrentSegment.testAndSolveTrivialBezier();
+                    mfCurrentSegmentLength = getB2DCubicBezierHelper()
+                        ? getB2DCubicBezierHelper()->getLength()
+                        : maCurrentSegment.getLength();
+                }
+            }
+
+            mfPosition = fNewPosition;
+        }
+
+        pathTextBreakupHelper::pathTextBreakupHelper(
+            const drawinglayer::primitive2d::Primitive2DReference& rxSource,
+            const basegfx::B2DPolygon& rPolygon,
+            const double fBasegfxPathLength,
+            const double fUserToBasegfx,
+            double fPosition,
+            const basegfx::B2DPoint& rTextStart)
+        :   drawinglayer::primitive2d::TextBreakupHelper(rxSource),
+            mrPolygon(rPolygon),
+            mfBasegfxPathLength(fBasegfxPathLength),
+            mfUserToBasegfx(fUserToBasegfx),
+            mfPosition(0.0),
+            mrTextStart(rTextStart),
+            mnMaxIndex(rPolygon.isClosed() ? rPolygon.count() : rPolygon.count() - 1),
+            mnIndex(0),
+            maCurrentSegment(),
+            mpB2DCubicBezierHelper(0),
+            mfCurrentSegmentLength(0.0),
+            mfSegmentStartPosition(0.0)
+        {
+            mrPolygon.getBezierSegment(mnIndex % mrPolygon.count(), maCurrentSegment);
+            mfCurrentSegmentLength = maCurrentSegment.getLength();
+
+            advanceToPosition(fPosition);
+        }
+
+        pathTextBreakupHelper::~pathTextBreakupHelper()
+        {
+            freeB2DCubicBezierHelper();
+        }
+
+        bool pathTextBreakupHelper::allowChange(sal_uInt32 nCount, basegfx::B2DHomMatrix& rNewTransform, sal_uInt32 nIndex, sal_uInt32 nLength)
+        {
+            bool bRetval(false);
+
+            if(mfPosition < mfBasegfxPathLength && nLength && getCastedSource() && mnIndex < mnMaxIndex)
+            {
+                const double fSnippetWidth(
+                    getTextLayouter().getTextWidth(
+                        getCastedSource()->getText(),
+                        nIndex,
+                        nLength));
+
+                if(basegfx::fTools::more(fSnippetWidth, 0.0))
+                {
+                    const ::rtl::OUString aText(getCastedSource()->getText());
+                    const ::rtl::OUString aTrimmedChars(aText.copy(nIndex, nLength).trim());
+                    const double fEndPos(mfPosition + fSnippetWidth);
+
+                    if(aTrimmedChars.getLength() && (mfPosition < mfBasegfxPathLength || fEndPos > 0.0))
+                    {
+                        const double fHalfSnippetWidth(fSnippetWidth * 0.5);
+
+                        advanceToPosition(mfPosition + fHalfSnippetWidth);
+
+                        // create representation for this snippet
+                        bRetval = true;
+
+                        // get target position and tangent in that pint
+                        basegfx::B2DPoint aPosition(0.0, 0.0);
+                        basegfx::B2DVector aTangent(0.0, 1.0);
+
+                        if(mfPosition < 0.0)
+                        {
+                            // snippet center is left of first segment, but right edge is on it (SVG allows that)
+                            aTangent = maCurrentSegment.getTangent(0.0);
+                            aTangent.normalize();
+                            aPosition = maCurrentSegment.getStartPoint() + (aTangent * (mfPosition - mfSegmentStartPosition));
+                        }
+                        else if(mfPosition > mfBasegfxPathLength)
+                        {
+                            // snippet center is right of last segment, but left edge is on it (SVG allows that)
+                            aTangent = maCurrentSegment.getTangent(1.0);
+                            aTangent.normalize();
+                            aPosition = maCurrentSegment.getEndPoint() + (aTangent * (mfPosition - mfSegmentStartPosition));
+                        }
+                        else
+                        {
+                            // snippet center inside segment, interpolate
+                            double fBezierDistance(mfPosition - mfSegmentStartPosition);
+                            
+                            if(getB2DCubicBezierHelper())
+                            {
+                                // use B2DCubicBezierHelper to bridge the non-linear gap between
+                                // length and bezier distances (if it's a bezier segment)
+                                fBezierDistance = getB2DCubicBezierHelper()->distanceToRelative(fBezierDistance);
+                            }
+                            else
+                            {
+                                // linear relationship, make relative to segment length
+                                fBezierDistance = fBezierDistance / mfCurrentSegmentLength;
+                            }
+
+                            aPosition = maCurrentSegment.interpolatePoint(fBezierDistance);
+                            aTangent = maCurrentSegment.getTangent(fBezierDistance);
+                            aTangent.normalize();
+                        }
+
+                        // detect evtl. hor/ver translations (depends on text direction)
+                        const basegfx::B2DPoint aBasePoint(rNewTransform * basegfx::B2DPoint(0.0, 0.0));
+                        const basegfx::B2DVector aOffset(aBasePoint - mrTextStart);
+
+                        if(!basegfx::fTools::equalZero(aOffset.getY()))
+                        {
+                            // ...and apply
+                            aPosition.setY(aPosition.getY() + aOffset.getY());
+                        }
+
+                        // move target position from snippet center to left text start
+                        aPosition -= fHalfSnippetWidth * aTangent;
+
+                        // remove current translation
+                        rNewTransform.translate(-aBasePoint.getX(), -aBasePoint.getY());
+
+                        // rotate due to tangent
+                        rNewTransform.rotate(atan2(aTangent.getY(), aTangent.getX()));
+
+                        // add new translation
+                        rNewTransform.translate(aPosition.getX(), aPosition.getY());
+                    }
+                            
+                    // advance to end
+                    advanceToPosition(fEndPos);
+                }
+            }
+
+            return bRetval;
+        }
+
+    } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+    namespace svgreader
+    {
+        void SvgTextPathNode::tryToFindLink()
+        {
+            if(!mpXLink && maXLink.getLength())
+            {
+                mpXLink = dynamic_cast< const SvgPathNode* >(getDocument().findSvgNodeById(maXLink));
+            }
+        }
+
+        SvgTextPathNode::SvgTextPathNode(
+            SvgDocument& rDocument,
+            SvgNode* pParent)
+        :   SvgNode(SVGTokenTextPath, rDocument, pParent),
+            maSvgStyleAttributes(*this),
+            maXLink(),
+            mpXLink(0),
+            maStartOffset(),
+            mbMethod(true),
+            mbSpacing(false)
+        {
+        }
+
+        SvgTextPathNode::~SvgTextPathNode()
+        {
+        }
+
+        const SvgStyleAttributes* SvgTextPathNode::getSvgStyleAttributes() const
+        {
+            return &maSvgStyleAttributes;
+        }
+
+        void SvgTextPathNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+        {
+            // call parent
+            SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+            // read style attributes
+            maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+            // parse own
+            switch(aSVGToken)
+            {
+                case SVGTokenStyle:
+                {
+                    maSvgStyleAttributes.readStyle(aContent);
+                    break;
+                }
+                case SVGTokenStartOffset:
+                {
+                    SvgNumber aNum;
+
+                    if(readSingleNumber(aContent, aNum))
+                    {
+                        if(aNum.isPositive())
+                        {
+                            setStartOffset(aNum);
+                        }
+                    }
+                    break;
+                }
+                case SVGTokenMethod:
+                {
+                    if(aContent.getLength())
+                    {
+                        static rtl::OUString aStrAlign(rtl::OUString::createFromAscii("align"));
+                        static rtl::OUString aStrStretch(rtl::OUString::createFromAscii("stretch"));
+
+                        if(aContent.match(aStrAlign))
+                        {
+                            setMethod(true);
+                        }
+                        else if(aContent.match(aStrStretch))
+                        {
+                            setMethod(false);
+                        }
+                    }
+                    break;
+                }
+                case SVGTokenSpacing:
+                {
+                    if(aContent.getLength())
+                    {
+                        static rtl::OUString aStrAuto(rtl::OUString::createFromAscii("auto"));
+                        static rtl::OUString aStrExact(rtl::OUString::createFromAscii("exact"));
+
+                        if(aContent.match(aStrAuto))
+                        {
+                            setSpacing(true);
+                        }
+                        else if(aContent.match(aStrExact))
+                        {
+                            setSpacing(false);
+                        }
+                    }
+                    break;
+                }
+                case SVGTokenXlinkHref:
+                {
+                    const sal_Int32 nLen(aContent.getLength());
+
+                    if(nLen && sal_Unicode('#') == aContent[0])
+                    {
+                        maXLink = aContent.copy(1);
+                        tryToFindLink();
+                    }
+                    break;
+                }
+            }
+        }
+
+        const SvgPathNode* SvgTextPathNode::getReferencedSvgPathNode() const
+        {
+            const_cast< SvgTextPathNode* >(this)->tryToFindLink();
+
+            return mpXLink;
+        }
+
+        bool SvgTextPathNode::isValid() const
+        {
+            const SvgPathNode* pSvgPathNode = getReferencedSvgPathNode();
+
+            if(!pSvgPathNode)
+            {
+                return false;
+            }
+
+            const basegfx::B2DPolyPolygon* pPolyPolyPath = pSvgPathNode->getPath();
+
+            if(!pPolyPolyPath || !pPolyPolyPath->count())
+            {
+                return false;
+            }
+
+            const basegfx::B2DPolygon aPolygon(pPolyPolyPath->getB2DPolygon(0));
+
+            if(!aPolygon.count())
+            {
+                return false;
+            }
+
+            const double fBasegfxPathLength(basegfx::tools::getLength(aPolygon));
+
+            if(basegfx::fTools::equalZero(fBasegfxPathLength))
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        void SvgTextPathNode::decomposePathNode(
+            const drawinglayer::primitive2d::Primitive2DSequence& rPathContent, 
+            drawinglayer::primitive2d::Primitive2DVector& rTarget, 
+            const basegfx::B2DPoint& rTextStart) const
+        {
+            if(rPathContent.hasElements())
+            {
+                const SvgPathNode* pSvgPathNode = getReferencedSvgPathNode();
+
+                if(pSvgPathNode)
+                {
+                    const basegfx::B2DPolyPolygon* pPolyPolyPath = pSvgPathNode->getPath();
+
+                    if(pPolyPolyPath && pPolyPolyPath->count())
+                    {
+                        basegfx::B2DPolygon aPolygon(pPolyPolyPath->getB2DPolygon(0));
+
+                        if(pSvgPathNode->getTransform())
+                        {
+                            aPolygon.transform(*pSvgPathNode->getTransform());
+                        }
+
+                        const double fBasegfxPathLength(basegfx::tools::getLength(aPolygon));
+
+                        if(!basegfx::fTools::equalZero(fBasegfxPathLength))
+                        {
+                            double fUserToBasegfx(1.0); // multiply: user->basegfx, divide: basegfx->user
+
+                            if(pSvgPathNode->getPathLength().isSet())
+                            {
+                                const double fUserLength(pSvgPathNode->getPathLength().solve(*this, length));
+
+                                if(fUserLength > 0.0 && !basegfx::fTools::equal(fUserLength, fBasegfxPathLength))
+                                {
+                                    fUserToBasegfx = fUserLength / fBasegfxPathLength;
+                                }
+                            }
+
+                            double fPosition(0.0);
+                            
+                            if(getStartOffset().isSet())
+                            {
+                                if(Unit_percent == getStartOffset().getUnit())
+                                {
+                                    // percent are relative to path length
+                                    fPosition = getStartOffset().getNumber() * 0.01 * fBasegfxPathLength;
+                                }
+                                else
+                                {
+                                    fPosition = getStartOffset().solve(*this, length) * fUserToBasegfx;
+                                }
+                            }
+
+                            if(fPosition >= 0.0)
+                            {
+                                const sal_Int32 nLength(rPathContent.getLength());
+                                sal_Int32 nCurrent(0);
+
+                                while(fPosition < fBasegfxPathLength && nCurrent < nLength)
+                                {
+                                    const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pCandidate = 0;
+                                    const drawinglayer::primitive2d::Primitive2DReference xReference(rPathContent[nCurrent]);
+                                    
+                                    if(xReference.is())
+                                    {
+                                        pCandidate = dynamic_cast< const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* >(xReference.get());
+                                    }
+
+                                    if(pCandidate)
+                                    {
+                                        pathTextBreakupHelper aPathTextBreakupHelper(
+                                            xReference,
+                                            aPolygon,
+                                            fBasegfxPathLength,
+                                            fUserToBasegfx,
+                                            fPosition,
+                                            rTextStart);
+
+                                        const drawinglayer::primitive2d::Primitive2DSequence aResult(
+                                            aPathTextBreakupHelper.getResult(drawinglayer::primitive2d::BreakupUnit_character));
+
+                                        if(aResult.hasElements())
+                                        {
+                                            rTarget.push_back(new drawinglayer::primitive2d::GroupPrimitive2D(aResult));
+                                        }
+
+                                        // advance position to consumed
+                                        fPosition = aPathTextBreakupHelper.getPosition();
+                                    }
+
+                                    nCurrent++;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+    } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof

Added: 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=1209140&view=auto
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx (added)
+++ incubator/ooo/branches/alg/svgreplacement/main/svgio/source/svgreader/svgtoken.cxx Thu Dec  1 16:25:17 2011
@@ -0,0 +1,275 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgtoken.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+    namespace svgreader
+    {
+        static rtl::OUString aSVGStrWidth(rtl::OUString::createFromAscii("width"));
+        static rtl::OUString aSVGStrHeight(rtl::OUString::createFromAscii("height"));
+        static rtl::OUString aSVGStrViewBox(rtl::OUString::createFromAscii("viewBox"));
+        static rtl::OUString aSVGStrTransform(rtl::OUString::createFromAscii("transform"));
+        static rtl::OUString aSVGStrStyle(rtl::OUString::createFromAscii("style"));
+        static rtl::OUString aSVGStrD(rtl::OUString::createFromAscii("d"));
+        static rtl::OUString aSVGStrX(rtl::OUString::createFromAscii("x"));
+        static rtl::OUString aSVGStrY(rtl::OUString::createFromAscii("y"));
+        static rtl::OUString aSVGStrXmlns(rtl::OUString::createFromAscii("xmlns")); 
+        static rtl::OUString aSVGStrVersion(rtl::OUString::createFromAscii("version")); 
+        static rtl::OUString aSVGStrId(rtl::OUString::createFromAscii("id")); 
+        static rtl::OUString aSVGStrRx(rtl::OUString::createFromAscii("rx")); 
+        static rtl::OUString aSVGStrRy(rtl::OUString::createFromAscii("ry")); 
+        static rtl::OUString aSVGStrPoints(rtl::OUString::createFromAscii("points")); 
+        static rtl::OUString aSVGStrDx(rtl::OUString::createFromAscii("dx")); 
+        static rtl::OUString aSVGStrDy(rtl::OUString::createFromAscii("dy")); 
+        static rtl::OUString aSVGStrRotate(rtl::OUString::createFromAscii("rotate")); 
+        static rtl::OUString aSVGStrTextLength(rtl::OUString::createFromAscii("textLength")); 
+        static rtl::OUString aSVGStrLengthAdjust(rtl::OUString::createFromAscii("lengthAdjust")); 
+        static rtl::OUString aSVGStrFont(rtl::OUString::createFromAscii("font")); 
+        static rtl::OUString aSVGStrFontFamily(rtl::OUString::createFromAscii("font-family")); 
+        static rtl::OUString aSVGStrFontSize(rtl::OUString::createFromAscii("font-size")); 
+        static rtl::OUString aSVGStrFontSizeAdjust(rtl::OUString::createFromAscii("font-size-adjust")); 
+        static rtl::OUString aSVGStrFontStretch(rtl::OUString::createFromAscii("font-stretch")); 
+        static rtl::OUString aSVGStrFontStyle(rtl::OUString::createFromAscii("font-style")); 
+        static rtl::OUString aSVGStrFontVariant(rtl::OUString::createFromAscii("font-variant")); 
+        static rtl::OUString aSVGStrFontWeight(rtl::OUString::createFromAscii("font-weight")); 
+        static rtl::OUString aSVGStrDirection(rtl::OUString::createFromAscii("direction")); 
+        static rtl::OUString aSVGStrLetterSpacing(rtl::OUString::createFromAscii("letter-spacing")); 
+        static rtl::OUString aSVGStrTextDecoration(rtl::OUString::createFromAscii("text-decoration")); 
+        static rtl::OUString aSVGStrUnicodeBidi(rtl::OUString::createFromAscii("unicode-bidi")); 
+        static rtl::OUString aSVGStrWordSpacing(rtl::OUString::createFromAscii("word-spacing")); 
+        static rtl::OUString aSVGStrTspan(rtl::OUString::createFromAscii("tspan")); 
+        static rtl::OUString aSVGStrTref(rtl::OUString::createFromAscii("tref")); 
+        static rtl::OUString aSVGStrTextPath(rtl::OUString::createFromAscii("textPath")); 
+        static rtl::OUString aSVGStrStartOffset(rtl::OUString::createFromAscii("startOffset")); 
+        static rtl::OUString aSVGStrMethod(rtl::OUString::createFromAscii("method")); 
+        static rtl::OUString aSVGStrSpacing(rtl::OUString::createFromAscii("spacing")); 
+        static rtl::OUString aSVGStrTextAlign(rtl::OUString::createFromAscii("text-align")); 
+        static rtl::OUString aSVGStrPathLength(rtl::OUString::createFromAscii("pathLength")); 
+        static rtl::OUString aSVGStrType(rtl::OUString::createFromAscii("type")); 
+        static rtl::OUString aSVGStrClass(rtl::OUString::createFromAscii("class")); 
+        static rtl::OUString aSVGStrTextAnchor(rtl::OUString::createFromAscii("text-anchor")); 
+        static rtl::OUString aSVGStrXmlSpace(rtl::OUString::createFromAscii("xml:space")); 
+
+        static rtl::OUString aSVGStrPreserveAspectRatio(rtl::OUString::createFromAscii("preserveAspectRatio")); 
+        static rtl::OUString aSVGStrDefer(rtl::OUString::createFromAscii("defer")); 
+        static rtl::OUString aSVGStrNone(rtl::OUString::createFromAscii("none")); 
+        static rtl::OUString aSVGStrXMinYMin(rtl::OUString::createFromAscii("xMinYMin")); 
+        static rtl::OUString aSVGStrXMidYMin(rtl::OUString::createFromAscii("xMidYMin")); 
+        static rtl::OUString aSVGStrXMaxYMin(rtl::OUString::createFromAscii("xMaxYMin")); 
+        static rtl::OUString aSVGStrXMinYMid(rtl::OUString::createFromAscii("xMinYMid")); 
+        static rtl::OUString aSVGStrXMidYMid(rtl::OUString::createFromAscii("xMidYMid")); 
+        static rtl::OUString aSVGStrXMaxYMid(rtl::OUString::createFromAscii("xMaxYMid")); 
+        static rtl::OUString aSVGStrXMinYMax(rtl::OUString::createFromAscii("xMinYMax")); 
+        static rtl::OUString aSVGStrXMidYMax(rtl::OUString::createFromAscii("xMidYMax")); 
+        static rtl::OUString aSVGStrXMaxYMax(rtl::OUString::createFromAscii("xMaxYMax")); 
+        static rtl::OUString aSVGStrMeet(rtl::OUString::createFromAscii("meet")); 
+        static rtl::OUString aSVGStrSlice(rtl::OUString::createFromAscii("slice")); 
+
+        static rtl::OUString aSVGStrDefs(rtl::OUString::createFromAscii("defs")); 
+        static rtl::OUString aSVGStrG(rtl::OUString::createFromAscii("g"));
+        static rtl::OUString aSVGStrSvg(rtl::OUString::createFromAscii("svg"));
+        static rtl::OUString aSVGStrSymbol(rtl::OUString::createFromAscii("symbol"));
+        static rtl::OUString aSVGStrUse(rtl::OUString::createFromAscii("use"));
+
+        static rtl::OUString aSVGStrCircle(rtl::OUString::createFromAscii("circle"));
+        static rtl::OUString aSVGStrEllipse(rtl::OUString::createFromAscii("ellipse"));
+        static rtl::OUString aSVGStrLine(rtl::OUString::createFromAscii("line"));
+        static rtl::OUString aSVGStrPath(rtl::OUString::createFromAscii("path"));
+        static rtl::OUString aSVGStrPolygon(rtl::OUString::createFromAscii("polygon")); 
+        static rtl::OUString aSVGStrPolyline(rtl::OUString::createFromAscii("polyline")); 
+        static rtl::OUString aSVGStrRect(rtl::OUString::createFromAscii("rect")); 
+        static rtl::OUString aSVGStrImage(rtl::OUString::createFromAscii("image")); 
+        
+        static rtl::OUString aSVGStrLinearGradient(rtl::OUString::createFromAscii("linearGradient")); 
+        static rtl::OUString aSVGStrRadialGradient(rtl::OUString::createFromAscii("radialGradient")); 
+        static rtl::OUString aSVGStrStop(rtl::OUString::createFromAscii("stop")); 
+        static rtl::OUString aSVGStrOffset(rtl::OUString::createFromAscii("offset")); 
+        static rtl::OUString aSVGStrX1(rtl::OUString::createFromAscii("x1")); 
+        static rtl::OUString aSVGStrY1(rtl::OUString::createFromAscii("y1")); 
+        static rtl::OUString aSVGStrX2(rtl::OUString::createFromAscii("x2")); 
+        static rtl::OUString aSVGStrY2(rtl::OUString::createFromAscii("y2")); 
+        static rtl::OUString aSVGStrCx(rtl::OUString::createFromAscii("cx")); 
+        static rtl::OUString aSVGStrCy(rtl::OUString::createFromAscii("cy")); 
+        static rtl::OUString aSVGStrFx(rtl::OUString::createFromAscii("fx")); 
+        static rtl::OUString aSVGStrFy(rtl::OUString::createFromAscii("fy")); 
+        static rtl::OUString aSVGStrR(rtl::OUString::createFromAscii("r")); 
+        static rtl::OUString aSVGStrGradientUnits(rtl::OUString::createFromAscii("gradientUnits")); 
+        static rtl::OUString aSVGStrGradientTransform(rtl::OUString::createFromAscii("gradientTransform")); 
+        static rtl::OUString aSVGStrSpreadMethod(rtl::OUString::createFromAscii("spreadMethod")); 
+        static rtl::OUString aSVGStrXlinkHref(rtl::OUString::createFromAscii("xlink:href")); 
+        static rtl::OUString aSVGStrStopColor(rtl::OUString::createFromAscii("stop-color")); 
+        static rtl::OUString aSVGStrStopOpacity(rtl::OUString::createFromAscii("stop-opacity")); 
+
+        static rtl::OUString aSVGStrFill(rtl::OUString::createFromAscii("fill"));
+        static rtl::OUString aSVGStrFillOpacity(rtl::OUString::createFromAscii("fill-opacity")); 
+        static rtl::OUString aSVGStrFillRule(rtl::OUString::createFromAscii("fill-rule")); 
+
+        static rtl::OUString aSVGStrStroke(rtl::OUString::createFromAscii("stroke"));
+        static rtl::OUString aSVGStrStrokeDasharray(rtl::OUString::createFromAscii("stroke-dasharray")); 
+        static rtl::OUString aSVGStrStrokeDashoffset(rtl::OUString::createFromAscii("stroke-dashoffset")); 
+        static rtl::OUString aSVGStrStrokeLinecap(rtl::OUString::createFromAscii("stroke-linecap")); 
+        static rtl::OUString aSVGStrStrokeLinejoin(rtl::OUString::createFromAscii("stroke-linejoin")); 
+        static rtl::OUString aSVGStrStrokeMiterlimit(rtl::OUString::createFromAscii("stroke-miterlimit")); 
+        static rtl::OUString aSVGStrStrokeOpacity(rtl::OUString::createFromAscii("stroke-opacity")); 
+        static rtl::OUString aSVGStrStrokeWidth(rtl::OUString::createFromAscii("stroke-width")); 
+
+        static rtl::OUString aSVGStrText(rtl::OUString::createFromAscii("text")); 
+
+        SVGToken StrToSVGToken(const rtl::OUString& rStr)
+        {
+            typedef std::hash_map< rtl::OUString, SVGToken, rtl::OUStringHash > SVGTokenMapper;
+            typedef std::pair< rtl::OUString, SVGToken > SVGTokenValueType;
+            static SVGTokenMapper aSVGTokenMapperList;
+
+            if(aSVGTokenMapperList.empty())
+            {
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrWidth, SVGTokenWidth));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrHeight, SVGTokenHeight));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrViewBox, SVGTokenViewBox));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTransform, SVGTokenTransform));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStyle, SVGTokenStyle));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrD, SVGTokenD));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrX, SVGTokenX));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrY, SVGTokenY));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXmlns, SVGTokenXmlns));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrVersion, SVGTokenVersion));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrId, SVGTokenId));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRx, SVGTokenRx));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRy, SVGTokenRy));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPoints, SVGTokenPoints));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDx, SVGTokenDx));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDy, SVGTokenDy));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRotate, SVGTokenRotate));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFont, SVGTokenFont));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontFamily, SVGTokenFontFamily));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontSize, SVGTokenFontSize));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontSizeAdjust, SVGTokenFontSizeAdjust));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontStretch, SVGTokenFontStretch));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontStyle, SVGTokenFontStyle));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontVariant, SVGTokenFontVariant));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontWeight, SVGTokenFontWeight));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDirection, SVGTokenDirection));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrLetterSpacing, SVGTokenLetterSpacing));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTextDecoration, SVGTokenTextDecoration));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrUnicodeBidi, SVGTokenUnicodeBidi));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrWordSpacing, SVGTokenWordSpacing));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTspan, SVGTokenTspan));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTref, SVGTokenTref));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTextPath, SVGTokenTextPath));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStartOffset, SVGTokenStartOffset));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMethod, SVGTokenMethod));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSpacing, SVGTokenSpacing));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTextAlign, SVGTokenTextAlign));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPathLength, SVGTokenPathLength));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrType, SVGTokenType));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrClass, SVGTokenClass));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTextAnchor, SVGTokenTextAnchor));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXmlSpace, SVGTokenXmlSpace));
+
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPreserveAspectRatio, SVGTokenPreserveAspectRatio));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDefer, SVGTokenDefer));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrNone, SVGTokenNone));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMinYMin, SVGTokenXMinYMin));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMidYMin, SVGTokenXMidYMin));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMaxYMin, SVGTokenXMaxYMin));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMinYMid, SVGTokenXMinYMid));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMidYMid, SVGTokenXMidYMid));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMaxYMid, SVGTokenXMaxYMid));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMinYMax, SVGTokenXMinYMax));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMidYMax, SVGTokenXMidYMax));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMaxYMax, SVGTokenXMaxYMax));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMeet, SVGTokenMeet));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSlice, SVGTokenSlice));
+                
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDefs, SVGTokenDefs));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrG, SVGTokenG));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSvg, SVGTokenSvg));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSymbol, SVGTokenSymbol));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrUse, SVGTokenUse));
+
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrCircle, SVGTokenCircle));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrEllipse, SVGTokenEllipse));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrLine, SVGTokenLine));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPath, SVGTokenPath));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPolygon, SVGTokenPolygon));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPolyline, SVGTokenPolyline));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRect, SVGTokenRect));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrImage, SVGTokenImage));
+                
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrLinearGradient, SVGTokenLinearGradient));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRadialGradient, SVGTokenRadialGradient));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStop, SVGTokenStop));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrOffset, SVGTokenOffset));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrX1, SVGTokenX1));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrY1, SVGTokenY1));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrX2, SVGTokenX2));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrY2, SVGTokenY2));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrCx, SVGTokenCx));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrCy, SVGTokenCy));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFx, SVGTokenFx));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFy, SVGTokenFy));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrR, SVGTokenR));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrGradientUnits, SVGTokenGradientUnits));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrGradientTransform, SVGTokenGradientTransform));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSpreadMethod, SVGTokenSpreadMethod));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXlinkHref, SVGTokenXlinkHref));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStopColor, SVGTokenStopColor));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStopOpacity, SVGTokenStopOpacity));
+                
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFill, SVGTokenFill));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFillOpacity, SVGTokenFillOpacity));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFillRule, SVGTokenFillRule));
+
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStroke, SVGTokenStroke));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeDasharray, SVGTokenStrokeDasharray));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeDashoffset, SVGTokenStrokeDashoffset));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeLinecap, SVGTokenStrokeLinecap));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeLinejoin, SVGTokenStrokeLinejoin));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeMiterlimit, SVGTokenStrokeMiterlimit));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeOpacity, SVGTokenStrokeOpacity));
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeWidth, SVGTokenStrokeWidth));
+
+                aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrText, SVGTokenText));
+            }
+
+            const SVGTokenMapper::const_iterator aResult(aSVGTokenMapperList.find(rStr));
+
+            if(aResult == aSVGTokenMapperList.end())
+            {
+                return SVGTokenUnknown;
+            }
+            else
+            {
+                return aResult->second;
+            }
+        }
+    } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof