[Libreoffice-commits] core.git: filter/source include/xmloff xmloff/source

Xisco Fauli anistenis at gmail.com
Tue Dec 22 05:13:38 PST 2015


 filter/source/svg/svgreader.cxx |  116 +++++++++++++++++++++++++++++++++++-----
 include/xmloff/xmltoken.hxx     |    1 
 xmloff/source/core/xmltoken.cxx |    1 
 3 files changed, 105 insertions(+), 13 deletions(-)

New commits:
commit 307421ba933361eaa34c12d23b0f261393ab51d8
Author: Xisco Fauli <anistenis at gmail.com>
Date:   Wed Dec 9 01:24:19 2015 +0100

    tdf#96181 SVG: Add support for <use> element
    
    Change-Id: Ia95c7e35158f8a4c6a597662524c74e1909983bb
    Reviewed-on: https://gerrit.libreoffice.org/20483
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Armin Le Grand <Armin.Le.Grand at cib.de>

diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx
index 4cd7080..5ae3281 100644
--- a/filter/source/svg/svgreader.cxx
+++ b/filter/source/svg/svgreader.cxx
@@ -159,7 +159,8 @@ struct AnnotatingVisitor
     AnnotatingVisitor(StatePool&                                        rStatePool,
                       StateMap&                                         rStateMap,
                       const State&                                       rInitialState,
-                      const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler) :
+                      const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
+                      std::vector< uno::Reference<xml::dom::XElement> >& rUseElementVector) :
         mnCurrStateId(0),
         maCurrState(),
         maParentStates(),
@@ -167,7 +168,9 @@ struct AnnotatingVisitor
         mrStateMap(rStateMap),
         mxDocumentHandler(xDocumentHandler),
         maGradientVector(),
-        maGradientStopVector()
+        maGradientStopVector(),
+        maElementVector(),
+        mrUseElementVector(rUseElementVector)
     {
         maParentStates.push_back(rInitialState);
     }
@@ -265,6 +268,70 @@ struct AnnotatingVisitor
                 }
                 break;
             }
+            case XML_USE:
+            {
+                uno::Reference<xml::dom::XNode> xNode(xAttributes->getNamedItem("href"));
+                if(xNode.is())
+                {
+                    const OUString sValue(xNode->getNodeValue());
+                    ElementRefMapType::iterator aFound=maElementIdMap.end();
+                    if ( sValue.copy(0,1) == "#" )
+                        aFound = maElementIdMap.find(sValue.copy(1));
+                    else
+                        aFound = maElementIdMap.find(sValue);
+                    if( aFound != maElementIdMap.end() )
+                    {
+                        uno::Reference<xml::dom::XElement> xRefElem(
+                            maElementVector[aFound->second]->cloneNode(true), uno::UNO_QUERY);
+
+                        xRefElem->removeAttribute("id");
+                        uno::Reference<xml::dom::XNode> xAttrNode;
+
+                        const sal_Int32 nNumAttrs( xAttributes->getLength() );
+                        OUString sAttributeValue;
+                        double x=0.0, y=0.0;
+                        for( sal_Int32 i=0; i<nNumAttrs; ++i )
+                        {
+                            sAttributeValue = xAttributes->item(i)->getNodeValue();
+                            const sal_Int32 nAttribId(
+                                getTokenId(xAttributes->item(i)->getNodeName()));
+
+                            switch(nAttribId)
+                            {
+                                case XML_ID:
+                                    maElementVector.push_back(xElem);
+                                    maElementIdMap.insert(std::make_pair(sAttributeValue,
+                                        maElementVector.size() - 1));
+                                    break;
+                                case XML_X:
+                                    x = convLength(sAttributeValue,maCurrState,'h');
+                                    break;
+                                case XML_Y:
+                                    y = convLength(sAttributeValue,maCurrState,'v');
+                                    break;
+                                case XML_TRANSFORM:
+                                    break;
+                                default:
+                                    OUString sAttributeName = xAttributes->item(i)->getNodeName();
+                                    xRefElem->setAttribute(sAttributeName, sAttributeValue);
+                                    break;
+                            }
+                        }
+                        std::stringstream ssAttrValue;
+                        ssAttrValue << xRefElem->getAttribute("transform");
+                        ssAttrValue << xElem->getAttribute("transform");
+                        ssAttrValue << " translate(" << x << "," << y << ")";
+
+                        OUString attrValue(OUString::createFromAscii (ssAttrValue.str().c_str()));
+                        xRefElem->setAttribute("transform", attrValue);
+
+                        mrUseElementVector.push_back(xRefElem);
+
+                        visitElements((*this), xRefElem, STYLE_ANNOTATOR);
+                    }
+                }
+                break;
+            }
             case XML_STOP:
             {
                 const sal_Int32 nNumAttrs( xAttributes->getLength() );
@@ -289,6 +356,7 @@ struct AnnotatingVisitor
                 // scan for style info
                 const sal_Int32 nNumAttrs( xAttributes->getLength() );
                 OUString sAttributeValue;
+
                 for( sal_Int32 i=0; i<nNumAttrs; ++i )
                 {
                     sAttributeValue = xAttributes->item(i)->getNodeValue();
@@ -297,8 +365,17 @@ struct AnnotatingVisitor
                     if( XML_STYLE == nTokenId )
                         parseStyle(sAttributeValue);
                     else
-                        parseAttribute(nTokenId,
-                                       sAttributeValue);
+                    {
+                        if( XML_ID == nTokenId )
+                        {
+                            maElementVector.push_back(xElem);
+                            maElementIdMap.insert(std::make_pair(sAttributeValue,
+                                maElementVector.size() - 1));
+                        }
+                        else
+                            parseAttribute(nTokenId,
+                                sAttributeValue);
+                    }
                 }
 
                 // all attributes parsed, can calc total CTM now
@@ -1218,18 +1295,23 @@ struct AnnotatingVisitor
     uno::Reference<xml::sax::XDocumentHandler> mxDocumentHandler;
     std::vector< Gradient >                    maGradientVector;
     std::vector< GradientStop >                maGradientStopVector;
+    std::vector< uno::Reference<xml::dom::XElement> > maElementVector;
+    std::vector< uno::Reference<xml::dom::XElement> >& mrUseElementVector;
     ElementRefMapType                          maGradientIdMap;
     ElementRefMapType                          maStopIdMap;
+    ElementRefMapType                          maElementIdMap;
 };
 
 /// Annotate svg styles with unique references to state pool
 static void annotateStyles( StatePool&                                        rStatePool,
                             StateMap&                                         rStateMap,
                             const State&                                       rInitialState,
-                            const uno::Reference<xml::dom::XElement>&         rElem,
-                            const uno::Reference<xml::sax::XDocumentHandler>& xDocHdl )
+                            uno::Reference<xml::dom::XElement>&         rElem,
+                            const uno::Reference<xml::sax::XDocumentHandler>& xDocHdl,
+                            std::vector< uno::Reference<xml::dom::XElement> >& rUseElementVector )
 {
-    AnnotatingVisitor aVisitor(rStatePool,rStateMap,rInitialState,xDocHdl);
+
+    AnnotatingVisitor aVisitor(rStatePool,rStateMap,rInitialState,xDocHdl,rUseElementVector);
     visitElements(aVisitor, rElem, STYLE_ANNOTATOR);
 }
 
@@ -1786,10 +1868,17 @@ struct ShapeWritingVisitor
 static void writeShapes( StatePool&                                        rStatePool,
                          StateMap&                                         rStateMap,
                          const uno::Reference<xml::dom::XElement>&         rElem,
-                         const uno::Reference<xml::sax::XDocumentHandler>& xDocHdl )
+                         const uno::Reference<xml::sax::XDocumentHandler>& xDocHdl,
+                         std::vector< uno::Reference<xml::dom::XElement> >& rUseElementVector )
 {
     ShapeWritingVisitor aVisitor(rStatePool,rStateMap,xDocHdl);
     visitElements(aVisitor, rElem, SHAPE_WRITER);
+
+    std::vector< uno::Reference<xml::dom::XElement> >::iterator it;
+    for ( it = rUseElementVector.begin() ; it != rUseElementVector.end(); ++it)
+    {
+        visitElements(aVisitor, *it, SHAPE_WRITER);
+    }
 }
 
 } // namespace
@@ -1906,6 +1995,7 @@ static void writeOfficeStyles(  StateMap&
 {
     OfficeStylesWritingVisitor aVisitor( rStateMap, xDocHdl );
     visitElements( aVisitor, rElem, STYLE_WRITER );
+
 }
 
 #if OSL_DEBUG_LEVEL > 2
@@ -2110,8 +2200,10 @@ bool SVGReader::parseAndConvert()
 
     StatePool aStatePool;
     StateMap  aStateMap;
+    std::vector< uno::Reference<xml::dom::XElement> > maUseElementVector;
+
     annotateStyles(aStatePool,aStateMap,aInitialState,
-                   xDocElem,m_xDocumentHandler);
+                   xDocElem,m_xDocumentHandler,maUseElementVector);
 
 #if OSL_DEBUG_LEVEL > 2
     dumpTree(xDocElem);
@@ -2119,8 +2211,6 @@ bool SVGReader::parseAndConvert()
 
     m_xDocumentHandler->endElement( "office:automatic-styles" );
 
-
-
     xAttrs->Clear();
     m_xDocumentHandler->startElement( "office:styles", xUnoAttrs);
     writeOfficeStyles( aStateMap,
@@ -2129,7 +2219,6 @@ bool SVGReader::parseAndConvert()
     m_xDocumentHandler->endElement( "office:styles" );
 
 
-
     m_xDocumentHandler->startElement( "office:master-styles", xUnoAttrs );
     xAttrs->Clear();
     xAttrs->AddAttribute( "style:name", "Default");
@@ -2155,7 +2244,8 @@ bool SVGReader::parseAndConvert()
     writeShapes(aStatePool,
                 aStateMap,
                 xDocElem,
-                m_xDocumentHandler);
+                m_xDocumentHandler,
+                maUseElementVector);
 
     m_xDocumentHandler->endElement( "draw:page" );
     m_xDocumentHandler->endElement( "office:drawing" );
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 062852b..5e3dcc0 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1931,6 +1931,7 @@ namespace xmloff { namespace token {
         XML_UPLIMIT,
         XML_UPRIGHT,
         XML_URL,
+        XML_USE,
         XML_USE_CAPTION,
         XML_USE_CELL_PROTECTION,
         XML_USE_CHART_OBJECTS,
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 0ebf728..1570301 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -1936,6 +1936,7 @@ namespace xmloff { namespace token {
         TOKEN( "uplimit",                         XML_UPLIMIT ),
         TOKEN( "upright",                         XML_UPRIGHT ),
         TOKEN( "url",                             XML_URL ),
+        TOKEN( "use",                             XML_USE ),
         TOKEN( "use-caption",                     XML_USE_CAPTION ),
         TOKEN( "use-cell-protection",             XML_USE_CELL_PROTECTION ),
         TOKEN( "use-chart-objects",               XML_USE_CHART_OBJECTS ),


More information about the Libreoffice-commits mailing list