diff options
author | Xisco Fauli <anistenis@gmail.com> | 2015-12-09 01:24:19 +0100 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@cib.de> | 2015-12-22 13:13:04 +0000 |
commit | 307421ba933361eaa34c12d23b0f261393ab51d8 (patch) | |
tree | bd5588be6f2332fd7f24487d56a7497548b6ecd3 | |
parent | 3b02908486c52a815b65efe93f41cbc53d5452c3 (diff) |
tdf#96181 SVG: Add support for <use> element
Change-Id: Ia95c7e35158f8a4c6a597662524c74e1909983bb
Reviewed-on: https://gerrit.libreoffice.org/20483
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
-rw-r--r-- | filter/source/svg/svgreader.cxx | 116 | ||||
-rw-r--r-- | include/xmloff/xmltoken.hxx | 1 | ||||
-rw-r--r-- | xmloff/source/core/xmltoken.cxx | 1 |
3 files changed, 105 insertions, 13 deletions
diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx index 4cd7080b8a9a..5ae3281ae329 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 062852b80357..5e3dcc03cc8f 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 0ebf728308f6..157030123106 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 ), |