From f21e7f8d5875f0cb7592279ac515124b8ca7186c Mon Sep 17 00:00:00 2001 From: "Chr. Rossmanith" Date: Fri, 18 May 2012 21:07:41 +0200 Subject: SVG: handle degenerate cases of the basic shapes correctly Change-Id: I2dc488ba38ca5f63c716f5f7327b47769d289fff --- filter/source/svg/svgreader.cxx | 158 ++++++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 78 deletions(-) (limited to 'filter/source') diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx index ecbc844c60b5..92b8fb97214f 100644 --- a/filter/source/svg/svgreader.cxx +++ b/filter/source/svg/svgreader.cxx @@ -75,56 +75,6 @@ namespace svgi namespace { -void lcl_RectAttrs2Polygon( const uno::Reference& xAttributes, const State& rCurrState, basegfx::B2DPolygon& rPoly ) -{ - // collect attributes - const sal_Int32 nNumAttrs( xAttributes->getLength() ); - rtl::OUString sAttributeValue; - bool bRxSeen=false, bRySeen=false; - double x=0.0,y=0.0,width=0.0,height=0.0,rx=0.0,ry=0.0; - for( sal_Int32 i=0; iitem(i)->getNodeValue(); - const sal_Int32 nAttribId( - getTokenId(xAttributes->item(i)->getNodeName())); - switch(nAttribId) - { - case XML_X: - x = convLength(sAttributeValue,rCurrState,'h'); - break; - case XML_Y: - y = convLength(sAttributeValue,rCurrState,'v'); - break; - case XML_WIDTH: - width = convLength(sAttributeValue,rCurrState,'h'); - break; - case XML_HEIGHT: - height = convLength(sAttributeValue,rCurrState,'v'); - break; - case XML_RX: - rx = convLength(sAttributeValue,rCurrState,'h'); - bRxSeen=true; - break; - case XML_RY: - ry = convLength(sAttributeValue,rCurrState,'v'); - bRySeen=true; - break; - default: - // skip - break; - } - } - - if( bRxSeen && !bRySeen ) - ry = rx; - else if( bRySeen && !bRxSeen ) - rx = ry; - - rPoly = basegfx::tools::createPolygonFromRect( - basegfx::B2DRange(x,y,x+width,y+height), - rx/(0.5*width), ry/(0.5*height) ); -} - /** visits all children of the specified type with the given functor */ template void visitChildren(const Func& rFunc, @@ -1097,7 +1047,7 @@ struct AnnotatingVisitor maGradientVector.back().maStops.back()].maStopColor ); break; default: - OSL_TRACE("unhandled token %s", getTokenName(nTokenId)); + SAL_INFO("svg", "unhandled token " << getTokenName(nTokenId)); break; } } @@ -1307,17 +1257,20 @@ struct ShapeWritingVisitor } } - rtl::OUString sLinePath = "M"+rtl::OUString::valueOf(x1)+"," - +rtl::OUString::valueOf(y1)+"L"+rtl::OUString::valueOf(x2)+"," - +rtl::OUString::valueOf(y2); - basegfx::B2DPolyPolygon aPoly; - basegfx::tools::importFromSvgD(aPoly, sLinePath); + if ( x1 != x2 || y1 != y2 ) { + rtl::OUString sLinePath = "M"+rtl::OUString::valueOf(x1)+"," + +rtl::OUString::valueOf(y1)+"L"+rtl::OUString::valueOf(x2)+"," + +rtl::OUString::valueOf(y2); + basegfx::B2DPolyPolygon aPoly; + basegfx::tools::importFromSvgD(aPoly, sLinePath); + + writePathShape(xAttrs, + xUnoAttrs, + xElem, + sStyleId, + basegfx::B2DPolyPolygon(aPoly)); + } - writePathShape(xAttrs, - xUnoAttrs, - xElem, - sStyleId, - basegfx::B2DPolyPolygon(aPoly)); break; } case XML_POLYGON: @@ -1338,14 +1291,61 @@ struct ShapeWritingVisitor } case XML_RECT: { - basegfx::B2DPolygon aPoly; + // collect attributes + const sal_Int32 nNumAttrs( xAttributes->getLength() ); + rtl::OUString sAttributeValue; + bool bRxSeen=false, bRySeen=false; + double x=0.0,y=0.0,width=0.0,height=0.0,rx=0.0,ry=0.0; + for( sal_Int32 i=0; iitem(i)->getNodeValue(); + const sal_Int32 nAttribId( + getTokenId(xAttributes->item(i)->getNodeName())); + switch(nAttribId) + { + case XML_X: + x = convLength(sAttributeValue,maCurrState,'h'); + break; + case XML_Y: + y = convLength(sAttributeValue,maCurrState,'v'); + break; + case XML_WIDTH: + width = convLength(sAttributeValue,maCurrState,'h'); + break; + case XML_HEIGHT: + height = convLength(sAttributeValue,maCurrState,'v'); + break; + case XML_RX: + rx = convLength(sAttributeValue,maCurrState,'h'); + bRxSeen=true; + break; + case XML_RY: + ry = convLength(sAttributeValue,maCurrState,'v'); + bRySeen=true; + break; + default: + // skip + break; + } + } - lcl_RectAttrs2Polygon( xAttributes, maCurrState, aPoly ); - writePathShape(xAttrs, - xUnoAttrs, - xElem, - sStyleId, - basegfx::B2DPolyPolygon(aPoly)); + if ( (width > 0) && (height > 0) ) { + if( bRxSeen && !bRySeen ) + ry = rx; + else if( bRySeen && !bRxSeen ) + rx = ry; + + basegfx::B2DPolygon aPoly; + aPoly = basegfx::tools::createPolygonFromRect( + basegfx::B2DRange(x,y,x+width,y+height), + rx/(0.5*width), ry/(0.5*height) ); + + writePathShape(xAttrs, + xUnoAttrs, + xElem, + sStyleId, + basegfx::B2DPolyPolygon(aPoly)); + } break; } case XML_PATH: @@ -1388,11 +1388,12 @@ struct ShapeWritingVisitor } } - writeEllipseShape(xAttrs, - xUnoAttrs, - xElem, - sStyleId, - basegfx::B2DEllipse(basegfx::B2DPoint(cx, cy), basegfx::B2DTuple(r,r))); + if ( r > 0 ) + writeEllipseShape(xAttrs, + xUnoAttrs, + xElem, + sStyleId, + basegfx::B2DEllipse(basegfx::B2DPoint(cx, cy), basegfx::B2DTuple(r,r))); break; } case XML_ELLIPSE: @@ -1425,11 +1426,12 @@ struct ShapeWritingVisitor } } - writeEllipseShape(xAttrs, - xUnoAttrs, - xElem, - sStyleId, - basegfx::B2DEllipse(basegfx::B2DPoint(cx, cy), basegfx::B2DTuple(rx,ry))); + if ( rx > 0 && ry > 0 ) + writeEllipseShape(xAttrs, + xUnoAttrs, + xElem, + sStyleId, + basegfx::B2DEllipse(basegfx::B2DPoint(cx, cy), basegfx::B2DTuple(rx,ry))); break; } case XML_IMAGE: -- cgit