diff options
Diffstat (limited to 'xmloff/source/draw')
-rw-r--r-- | xmloff/source/draw/XMLImageMapContext.cxx | 60 | ||||
-rw-r--r-- | xmloff/source/draw/XMLImageMapExport.cxx | 94 | ||||
-rw-r--r-- | xmloff/source/draw/shapeexport2.cxx | 429 | ||||
-rw-r--r-- | xmloff/source/draw/shapeexport3.cxx | 221 | ||||
-rw-r--r-- | xmloff/source/draw/xexptran.cxx | 3572 | ||||
-rw-r--r-- | xmloff/source/draw/ximp3dobject.cxx | 132 | ||||
-rw-r--r-- | xmloff/source/draw/ximpshap.cxx | 363 |
7 files changed, 2618 insertions, 2253 deletions
diff --git a/xmloff/source/draw/XMLImageMapContext.cxx b/xmloff/source/draw/XMLImageMapContext.cxx index bd304e17a587..17b5e94ee849 100644 --- a/xmloff/source/draw/XMLImageMapContext.cxx +++ b/xmloff/source/draw/XMLImageMapContext.cxx @@ -19,25 +19,18 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" #include "XMLImageMapContext.hxx" #include <rtl/ustrbuf.hxx> #include <com/sun/star/uno/Reference.h> #include <com/sun/star/beans/XPropertySet.hpp> -#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HPP #include <com/sun/star/beans/XPropertySetInfo.hpp> -#endif #include <com/sun/star/xml/sax/XAttributeList.hpp> #include <com/sun/star/container/XIndexContainer.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/drawing/PointSequenceSequence.hpp> - -#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP #include <com/sun/star/document/XEventsSupplier.hpp> -#endif #include <com/sun/star/awt/Rectangle.hpp> #include <xmloff/xmltoken.hxx> #include <xmloff/xmlimp.hxx> @@ -50,7 +43,8 @@ #include <xmloff/XMLEventsImportContext.hxx> #include "XMLStringBufferImportContext.hxx" #include <tools/debug.hxx> - +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> using namespace ::com::sun::star; using namespace ::xmloff::token; @@ -494,33 +488,43 @@ void XMLImageMapPolygonContext::ProcessAttribute( bValid = bViewBoxOK && bPointsOK; } -void XMLImageMapPolygonContext::Prepare( - Reference<XPropertySet> & rPropertySet) +void XMLImageMapPolygonContext::Prepare(Reference<XPropertySet> & rPropertySet) { // process view box - SdXMLImExViewBox aViewBox(sViewBoxString, - GetImport().GetMM100UnitConverter()); + SdXMLImExViewBox aViewBox(sViewBoxString, GetImport().GetMM100UnitConverter()); // get polygon sequence - awt::Point aPoint(aViewBox.GetX(), aViewBox.GetY()); - awt::Size aSize(aViewBox.GetWidth(), aViewBox.GetHeight()); - SdXMLImExPointsElement aPoints( sPointsString, aViewBox, aPoint, aSize, GetImport().GetMM100UnitConverter(), true ); - PointSequenceSequence aPointSeqSeq = aPoints.GetPointSequenceSequence(); + basegfx::B2DPolygon aPolygon; - // only use first element of sequence-sequence - if (aPointSeqSeq.getLength() > 0) + if(basegfx::tools::importFromSvgPoints(aPolygon, sPointsString)) { - Any aAny; - aAny <<= aPointSeqSeq[0]; - rPropertySet->setPropertyValue(sPolygon, aAny); + if(aPolygon.count()) + { + com::sun::star::drawing::PointSequence aPointSequence; + uno::Any aAny; + + basegfx::tools::B2DPolygonToUnoPointSequence(aPolygon, aPointSequence); + aAny <<= aPointSequence; + rPropertySet->setPropertyValue(sPolygon, aAny); + } } + //awt::Point aPoint(aViewBox.GetX(), aViewBox.GetY()); + //awt::Size aSize(aViewBox.GetWidth(), aViewBox.GetHeight()); + //SdXMLImExPointsElement aPoints( sPointsString, aViewBox, aPoint, aSize, GetImport().GetMM100UnitConverter(), true ); + //PointSequenceSequence aPointSeqSeq = aPoints.GetPointSequenceSequence(); + // + //// only use first element of sequence-sequence + //if (aPointSeqSeq.getLength() > 0) + //{ + // Any aAny; + // aAny <<= aPointSeqSeq[0]; + // rPropertySet->setPropertyValue(sPolygon, aAny); + //} // parent properties XMLImageMapObjectContext::Prepare(rPropertySet); } - - class XMLImageMapCircleContext : public XMLImageMapObjectContext { awt::Point aCenter; @@ -621,15 +625,6 @@ void XMLImageMapCircleContext::Prepare( XMLImageMapObjectContext::Prepare(rPropertySet); } - - - - - - - - - XMLImageMapContext::XMLImageMapContext( SvXMLImport& rImport, sal_uInt16 nPrefix, @@ -698,3 +693,4 @@ void XMLImageMapContext::EndElement() xPropertySet->setPropertyValue(sImageMap, uno::makeAny( xImageMap ) ); } +// eof diff --git a/xmloff/source/draw/XMLImageMapExport.cxx b/xmloff/source/draw/XMLImageMapExport.cxx index 67cc8f9adf27..89cf157f237a 100644 --- a/xmloff/source/draw/XMLImageMapExport.cxx +++ b/xmloff/source/draw/XMLImageMapExport.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" + #include "XMLImageMapExport.hxx" #include <rtl/ustring.hxx> #include <rtl/ustrbuf.hxx> @@ -32,10 +31,7 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/container/XIndexContainer.hpp> - -#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP #include <com/sun/star/document/XEventsSupplier.hpp> -#endif #include <com/sun/star/awt/Rectangle.hpp> #include <com/sun/star/awt/Point.hpp> #include <com/sun/star/awt/Size.hpp> @@ -46,8 +42,8 @@ #include <xmloff/XMLEventExport.hxx> #include <xmloff/xmluconv.hxx> #include "xexptran.hxx" - - +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> using namespace ::com::sun::star; using namespace ::xmloff::token; @@ -333,50 +329,60 @@ void XMLImageMapExport::ExportPolygon( PointSequence aPoly; aAny >>= aPoly; - // get bounding box (assume top-left to be 0,0) - sal_Int32 nWidth = 0; - sal_Int32 nHeight = 0; - sal_Int32 nLength = aPoly.getLength(); - const struct awt::Point* pPointPtr = aPoly.getConstArray(); - for ( sal_Int32 i = 0; i < nLength; i++ ) - { - sal_Int32 nPolyX = pPointPtr->X; - sal_Int32 nPolyY = pPointPtr->Y; - - if ( nPolyX > nWidth ) - nWidth = nPolyX; - if ( nPolyY > nHeight ) - nHeight = nPolyY; - - pPointPtr++; - } - DBG_ASSERT(nWidth > 0, "impossible Polygon found"); - DBG_ASSERT(nHeight > 0, "impossible Polygon found"); + const basegfx::B2DPolygon aPolygon( + basegfx::tools::UnoPointSequenceToB2DPolygon( + aPoly)); + const basegfx::B2DRange aPolygonRange(aPolygon.getB2DRange()); + +// TTTT: +// // get bounding box (assume top-left to be 0,0) +// sal_Int32 nWidth = 0; +// sal_Int32 nHeight = 0; +// sal_Int32 nLength = aPoly.getLength(); +// const struct awt::Point* pPointPtr = aPoly.getConstArray(); +// for ( sal_Int32 i = 0; i < nLength; i++ ) +// { +// sal_Int32 nPolyX = pPointPtr->X; +// sal_Int32 nPolyY = pPointPtr->Y; +// +// if ( nPolyX > nWidth ) +// nWidth = nPolyX; +// if ( nPolyY > nHeight ) +// nHeight = nPolyY; +// +// pPointPtr++; +// } +// DBG_ASSERT(nWidth > 0, "impossible Polygon found"); +// DBG_ASSERT(nHeight > 0, "impossible Polygon found"); // parameters svg:x, svg:y, svg:width, svg:height OUStringBuffer aBuffer; + mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, 0); - mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X, - aBuffer.makeStringAndClear() ); + mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X, aBuffer.makeStringAndClear() ); mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, 0); - mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y, - aBuffer.makeStringAndClear() ); - mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, nWidth); - mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH, - aBuffer.makeStringAndClear() ); - mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, nHeight); - mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT, - aBuffer.makeStringAndClear() ); + mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y, aBuffer.makeStringAndClear() ); + mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, aPolygonRange.getWidth()); + mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH, aBuffer.makeStringAndClear() ); + mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, aPolygonRange.getHeight()); + mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT, aBuffer.makeStringAndClear() ); // svg:viewbox - SdXMLImExViewBox aViewBox(0, 0, nWidth, nHeight); - mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, - aViewBox.GetExportString()); + SdXMLImExViewBox aViewBox(0.0, 0.0, aPolygonRange.getWidth(), aPolygonRange.getHeight()); + mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString()); // export point sequence - awt::Point aPoint(0, 0); - awt::Size aSize(nWidth, nHeight); - SdXMLImExPointsElement aPoints( &aPoly, aViewBox, aPoint, aSize, true); - mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_POINTS, - aPoints.GetExportString()); + const ::rtl::OUString aPointString( + basegfx::tools::exportToSvgPoints( + aPolygon)); + + mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString); + + // TTTT: + //awt::Point aPoint(0, 0); + //awt::Size aSize(nWidth, nHeight); + //SdXMLImExPointsElement aPoints( &aPoly, aViewBox, aPoint, aSize, true); + //mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_POINTS, aPoints.GetExportString()); } + +// eof diff --git a/xmloff/source/draw/shapeexport2.cxx b/xmloff/source/draw/shapeexport2.cxx index e80d933e892a..be1c3584d991 100644 --- a/xmloff/source/draw/shapeexport2.cxx +++ b/xmloff/source/draw/shapeexport2.cxx @@ -19,8 +19,6 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" #include "unointerfacetouniqueidentifiermapper.hxx" @@ -52,6 +50,9 @@ #include <basegfx/tuple/b2dtuple.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -138,30 +139,57 @@ void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple& rTR aTRScale.setX(1.0); } - mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(aTRScale.getX())); - aStr = sStringBuffer.makeStringAndClear(); - mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr); - // svg: height if(!(nFeatures & SEF_EXPORT_HEIGHT)) { aTRScale.setY(1.0); } + // svg:width and svg:height are not allowed negative, extract that and + // set back to absolute values + bool bMirrorX(basegfx::fTools::less(aTRScale.getX(), 0.0)); + bool bMirrorY(basegfx::fTools::less(aTRScale.getY(), 0.0)); + + if(bMirrorX) + { + aTRScale.setX(-aTRScale.getX()); + } + + if(bMirrorY) + { + aTRScale.setY(-aTRScale.getY()); + } + + // write positive svg:width + mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(aTRScale.getX())); + aStr = sStringBuffer.makeStringAndClear(); + mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr); + + // write positive svg:height mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(aTRScale.getY())); aStr = sStringBuffer.makeStringAndClear(); mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStr); - // decide if transformation is neccessary - sal_Bool bTransformationIsNeccessary(fTRShear != 0.0 || fTRRotate != 0.0); + // decide if transformation is neccessary, new is that mirrorings are now + // part of this to not write negative svg:width or svg:height entries + const bool bTransformationIsNeccessary(fTRShear != 0.0 || fTRRotate != 0.0 || bMirrorX || bMirrorY); if(bTransformationIsNeccessary) { // write transformation, but WITHOUT scale which is exported as size above SdXMLImExTransform2D aTransform; + if(bMirrorX || bMirrorY) + { + // add mirrorings if used + aTransform.AddScale(basegfx::B2DTuple(bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0)); + } + // Export Shear mirrored to stay compatible to ODF1.3 - aTransform.AddSkewX(atan(-fTRShear)); + if(!basegfx::fTools::equalZero(fTRShear)) + { + aTransform.AddSkewX(atan(-fTRShear)); + } // #i78696# // fTRRotate is mathematically correct, but due to the error @@ -169,17 +197,38 @@ void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple& rTR // uses the correctly oriented angle, it is necessary for compatibility to // mirror the angle here to stay at the old behaviour. There is a follow-up // task (#i78698#) to fix this in the next ODF FileFormat version - aTransform.AddRotate(-fTRRotate); + if(!basegfx::fTools::equalZero(fTRRotate)) + { + aTransform.AddRotate(-fTRRotate); + } + + // process translation; copy and evtl. detect non-writes + ::basegfx::B2DTuple aTRTranslate(rTRTranslate); - aTransform.AddTranslate(rTRTranslate); + if(!(nFeatures & SEF_EXPORT_X)) + { + aTRTranslate.setX(0.0); + } + + if(!(nFeatures & SEF_EXPORT_Y)) + { + aTRTranslate.setY(0.0); + } + + if(!basegfx::fTools::equalZero(aTRTranslate.getX()) || !basegfx::fTools::equalZero(aTRTranslate.getY())) + { + aTransform.AddTranslate(aTRTranslate); + } // does transformation need to be exported? if(aTransform.NeedsAction()) + { mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter())); + } } else { - // no shear, no rotate; just add object position to export and we are done + // no shear, no rotate, no mirror; just add object position to export and we are done if(nFeatures & SEF_EXPORT_X) { // svg: x @@ -923,21 +972,22 @@ void XMLShapeExport::ImpExportEllipseShape( void XMLShapeExport::ImpExportPolygonShape( const uno::Reference< drawing::XShape >& xShape, - XmlShapeType eShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint) + XmlShapeType /*eShapeType*/, sal_Int32 nFeatures, awt::Point* pRefPoint) // TTTT: eShapeType { const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY); + if(xPropSet.is()) { - sal_Bool bClosed(eShapeType == XmlShapeTypeDrawPolyPolygonShape - || eShapeType == XmlShapeTypeDrawClosedBezierShape); - sal_Bool bBezier(eShapeType == XmlShapeTypeDrawClosedBezierShape - || eShapeType == XmlShapeTypeDrawOpenBezierShape); +// sal_Bool bClosed(eShapeType == XmlShapeTypeDrawPolyPolygonShape +// || eShapeType == XmlShapeTypeDrawClosedBezierShape); +// sal_Bool bBezier(eShapeType == XmlShapeTypeDrawClosedBezierShape +// || eShapeType == XmlShapeTypeDrawOpenBezierShape); // get matrix ::basegfx::B2DHomMatrix aMatrix; ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet); - // decompose and correct abour pRefPoint + // decompose and correct about pRefPoint ::basegfx::B2DTuple aTRScale; double fTRShear(0.0); double fTRRotate(0.0); @@ -947,121 +997,185 @@ void XMLShapeExport::ImpExportPolygonShape( // use features and write ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures); - // create and export ViewBox - awt::Point aPoint(0, 0); - awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY())); - SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height); - mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString()); - - sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210# + //awt::Point aPoint(0, 0); + //awt::Size aSize(FRound(fabs(aTRScale.getX())), FRound(fabs(aTRScale.getY()))); - if(bBezier) - { - // get PolygonBezier - uno::Any aAny( xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))) ); - drawing::PolyPolygonBezierCoords* pSourcePolyPolygon = - (drawing::PolyPolygonBezierCoords*)aAny.getValue(); - - if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength()) - { - sal_Int32 nOuterCnt(pSourcePolyPolygon->Coordinates.getLength()); - drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->Coordinates.getArray(); - drawing::FlagSequence* pOuterFlags = pSourcePolyPolygon->Flags.getArray(); - - if(pOuterSequence && pOuterFlags) - { - // prepare svx:d element export - SdXMLImExSvgDElement aSvgDElement(aViewBox); + // create and export ViewBox. caution! for svg:ViewBox, use the absolute values (!) + SdXMLImExViewBox aViewBox(0.0, 0.0, fabs(aTRScale.getX()), fabs(aTRScale.getY())); - for(sal_Int32 a(0L); a < nOuterCnt; a++) - { - drawing::PointSequence* pSequence = pOuterSequence++; - drawing::FlagSequence* pFlags = pOuterFlags++; - - if(pSequence && pFlags) - { - aSvgDElement.AddPolygon(pSequence, pFlags, - aPoint, aSize, bClosed); - } - } + mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString()); - // write point array - mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); - } + // get polygon data + const uno::Any aAny(xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")))); + basegfx::B2DPolyPolygon aPolyPolygon; + const bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210# - // write object now - SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PATH, bCreateNewline, sal_True); + if(aAny.getValueType().equals(getCppuType((drawing::PolyPolygonBezierCoords*)0))) + { + aPolyPolygon = basegfx::tools::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(*(drawing::PolyPolygonBezierCoords*)aAny.getValue()); + } + else if(aAny.getValueType().equals(getCppuType((drawing::PointSequenceSequence*)0))) + { + aPolyPolygon = basegfx::tools::UnoPointSequenceSequenceToB2DPolyPolygon(*(drawing::PointSequenceSequence*)aAny.getValue()); + } - ImpExportDescription( xShape ); // #i68101# - ImpExportEvents( xShape ); - ImpExportGluePoints( xShape ); - ImpExportText( xShape ); - } + if(!aPolyPolygon.areControlPointsUsed() && 1 == aPolyPolygon.count()) + { + // simple polygon shape, can be written as svg:points sequence + const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(0)); + const ::rtl::OUString aPointString(basegfx::tools::exportToSvgPoints(aPolygon)); + + // write point array + mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString); + + // write object now + SvXMLElementExport aOBJ( + mrExport, + XML_NAMESPACE_DRAW, + aPolygon.isClosed() ? XML_POLYGON : XML_POLYLINE, + bCreateNewline, + sal_True); } else { - // get non-bezier polygon - uno::Any aAny( xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))) ); - drawing::PointSequenceSequence* pSourcePolyPolygon = (drawing::PointSequenceSequence*)aAny.getValue(); - - if(pSourcePolyPolygon && pSourcePolyPolygon->getLength()) - { - sal_Int32 nOuterCnt(pSourcePolyPolygon->getLength()); - - if(1L == nOuterCnt && !bBezier) - { - // simple polygon shape, can be written as svg:points sequence - drawing::PointSequence* pSequence = pSourcePolyPolygon->getArray(); - if(pSequence) - { - SdXMLImExPointsElement aPoints(pSequence, aViewBox, aPoint, aSize, bClosed); - - // write point array - mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPoints.GetExportString()); - } - - // write object now - SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, - bClosed ? XML_POLYGON : XML_POLYLINE , bCreateNewline, sal_True); - - ImpExportDescription( xShape ); // #i68101# - ImpExportEvents( xShape ); - ImpExportGluePoints( xShape ); - ImpExportText( xShape ); - } - else - { - // polypolygon or bezier, needs to be written as a svg:path sequence - drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray(); - if(pOuterSequence) - { - // prepare svx:d element export - SdXMLImExSvgDElement aSvgDElement(aViewBox); - - for(sal_Int32 a(0L); a < nOuterCnt; a++) - { - drawing::PointSequence* pSequence = pOuterSequence++; - if(pSequence) - { - aSvgDElement.AddPolygon(pSequence, 0L, aPoint, - aSize, bClosed); - } - } - - // write point array - mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); - } + // complex polygon shape, write as svg:d + const ::rtl::OUString aPolygonString( + basegfx::tools::exportToSvgD( + aPolyPolygon, + true, // bUseRelativeCoordinates + false)); // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now + + // write point array + mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString); + + // write object now + SvXMLElementExport aOBJ( + mrExport, + XML_NAMESPACE_DRAW, + XML_PATH, + bCreateNewline, + sal_True); + } - // write object now - SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PATH, bCreateNewline, sal_True); + ImpExportDescription( xShape ); // #i68101# + ImpExportEvents( xShape ); + ImpExportGluePoints( xShape ); + ImpExportText( xShape ); - ImpExportDescription( xShape ); // #i68101# - ImpExportEvents( xShape ); - ImpExportGluePoints( xShape ); - ImpExportText( xShape ); - } - } - } +// TTTT +// if(bBezier) +// { +// // get PolygonBezier +// uno::Any aAny( xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))) ); +// drawing::PolyPolygonBezierCoords* pSourcePolyPolygon = +// (drawing::PolyPolygonBezierCoords*)aAny.getValue(); +// +// if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength()) +// { +// sal_Int32 nOuterCnt(pSourcePolyPolygon->Coordinates.getLength()); +// drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->Coordinates.getArray(); +// drawing::FlagSequence* pOuterFlags = pSourcePolyPolygon->Flags.getArray(); +// +// if(pOuterSequence && pOuterFlags) +// { +// // prepare svx:d element export +// SdXMLImExSvgDElement aSvgDElement(aViewBox); +// +// for(sal_Int32 a(0L); a < nOuterCnt; a++) +// { +// drawing::PointSequence* pSequence = pOuterSequence++; +// drawing::FlagSequence* pFlags = pOuterFlags++; +// +// if(pSequence && pFlags) +// { +// aSvgDElement.AddPolygon(pSequence, pFlags, +// aPoint, aSize, bClosed); +// } +// } +// +// // write point array +// mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); +// } +// +// // write object now +// SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PATH, bCreateNewline, sal_True); +// +// ImpExportDescription( xShape ); // #i68101# +// ImpExportEvents( xShape ); +// ImpExportGluePoints( xShape ); +// ImpExportText( xShape ); +// } +// } +// else +// { +// // get non-bezier polygon +// uno::Any aAny( xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))) ); +// drawing::PointSequenceSequence* pSourcePolyPolygon = (drawing::PointSequenceSequence*)aAny.getValue(); +// +// if(pSourcePolyPolygon && pSourcePolyPolygon->getLength()) +// { +// sal_Int32 nOuterCnt(pSourcePolyPolygon->getLength()); +// +// if(1L == nOuterCnt && !bBezier) +// { +// // simple polygon shape, can be written as svg:points sequence +// drawing::PointSequence* pSequence = pSourcePolyPolygon->getArray(); +// if(pSequence) +// { +// const basegfx::B2DPolygon aPolygon( +// basegfx::tools::UnoPointSequenceToB2DPolygon( +// *pSequence)); +// const ::rtl::OUString aPointString( +// basegfx::tools::exportToSvgPoints( +// aPolygon)); +// // SdXMLImExPointsElement aPoints(pSequence, aViewBox, aPoint, aSize, bClosed); +// +// // write point array +// mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString); +// } +// +// // write object now +// SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, +// bClosed ? XML_POLYGON : XML_POLYLINE , bCreateNewline, sal_True); +// +// ImpExportDescription( xShape ); // #i68101# +// ImpExportEvents( xShape ); +// ImpExportGluePoints( xShape ); +// ImpExportText( xShape ); +// } +// else +// { +// // polypolygon or bezier, needs to be written as a svg:path sequence +// drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray(); +// if(pOuterSequence) +// { +// // prepare svx:d element export +// SdXMLImExSvgDElement aSvgDElement(aViewBox); +// +// for(sal_Int32 a(0L); a < nOuterCnt; a++) +// { +// drawing::PointSequence* pSequence = pOuterSequence++; +// if(pSequence) +// { +// aSvgDElement.AddPolygon(pSequence, 0L, aPoint, +// aSize, bClosed); +// } +// } +// +// // write point array +// mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); +// } +// +// // write object now +// SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PATH, bCreateNewline, sal_True); +// +// ImpExportDescription( xShape ); // #i68101# +// ImpExportEvents( xShape ); +// ImpExportGluePoints( xShape ); +// ImpExportText( xShape ); +// } +// } +// } } } @@ -1405,38 +1519,49 @@ void XMLShapeExport::ImpExportConnectorShape( if( xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("PolyPolygonBezier") ) ) >>= aAny ) { // get PolygonBezier - drawing::PolyPolygonBezierCoords* pSourcePolyPolygon = - (drawing::PolyPolygonBezierCoords*)aAny.getValue(); + drawing::PolyPolygonBezierCoords* pSourcePolyPolygon = (drawing::PolyPolygonBezierCoords*)aAny.getValue(); if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength()) { - sal_Int32 nOuterCnt(pSourcePolyPolygon->Coordinates.getLength()); - drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->Coordinates.getArray(); - drawing::FlagSequence* pOuterFlags = pSourcePolyPolygon->Flags.getArray(); - - if(pOuterSequence && pOuterFlags) - { - // prepare svx:d element export - awt::Point aPoint( 0, 0 ); - awt::Size aSize( 1, 1 ); - SdXMLImExViewBox aViewBox( 0, 0, 1, 1 ); - SdXMLImExSvgDElement aSvgDElement(aViewBox); - - for(sal_Int32 a(0L); a < nOuterCnt; a++) - { - drawing::PointSequence* pSequence = pOuterSequence++; - drawing::FlagSequence* pFlags = pOuterFlags++; - - if(pSequence && pFlags) - { - aSvgDElement.AddPolygon(pSequence, pFlags, - aPoint, aSize, sal_False ); - } - } - - // write point array - mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); - } + const basegfx::B2DPolyPolygon aPolyPolygon( + basegfx::tools::UnoPolyPolygonBezierCoordsToB2DPolyPolygon( + *pSourcePolyPolygon)); + const ::rtl::OUString aPolygonString( + basegfx::tools::exportToSvgD( + aPolyPolygon, + true, // bUseRelativeCoordinates + false)); // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now + + // write svg:d + mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString); +// TTTT +// sal_Int32 nOuterCnt(pSourcePolyPolygon->Coordinates.getLength()); +// drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->Coordinates.getArray(); +// drawing::FlagSequence* pOuterFlags = pSourcePolyPolygon->Flags.getArray(); +// +// if(pOuterSequence && pOuterFlags) +// { +// // prepare svx:d element export +// awt::Point aPoint( 0, 0 ); +// awt::Size aSize( 1, 1 ); +// SdXMLImExViewBox aViewBox( 0.0, 0.0, 1.0, 1.0 ); +// SdXMLImExSvgDElement aSvgDElement(aViewBox); +// +// for(sal_Int32 a(0L); a < nOuterCnt; a++) +// { +// drawing::PointSequence* pSequence = pOuterSequence++; +// drawing::FlagSequence* pFlags = pOuterFlags++; +// +// if(pSequence && pFlags) +// { +// aSvgDElement.AddPolygon(pSequence, pFlags, +// aPoint, aSize, sal_False ); +// } +// } +// +// // write point array +// mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); +// } } } diff --git a/xmloff/source/draw/shapeexport3.cxx b/xmloff/source/draw/shapeexport3.cxx index ff3dfb7de89f..c3ef92d1edc7 100644 --- a/xmloff/source/draw/shapeexport3.cxx +++ b/xmloff/source/draw/shapeexport3.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" + #include <com/sun/star/drawing/HomogenMatrix.hpp> #include <com/sun/star/drawing/PolyPolygonShape3D.hpp> #include <com/sun/star/drawing/ProjectionMode.hpp> @@ -32,10 +31,7 @@ #include <com/sun/star/drawing/CameraGeometry.hpp> #include <com/sun/star/drawing/DoubleSequence.hpp> #include <tools/gen.hxx> - -#ifndef _XMLOFF_SHAPEEXPORT_HXX #include <xmloff/shapeexport.hxx> -#endif #include "sdpropls.hxx" #include <tools/debug.hxx> #include <rtl/ustrbuf.hxx> @@ -44,8 +40,12 @@ #include "xexptran.hxx" #include <xmloff/xmltoken.hxx> #include <basegfx/vector/b3dvector.hxx> - -#include "xmloff/xmlnmspe.hxx" +#include <xmloff/xmlnmspe.hxx> +#include <basegfx/polygon/b3dpolypolygon.hxx> +#include <basegfx/polygon/b3dpolypolygontools.hxx> +#include <basegfx/matrix/b3dhommatrix.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -198,104 +198,137 @@ void XMLShapeExport::ImpExport3DShape( case XmlShapeTypeDraw3DLatheObject: case XmlShapeTypeDraw3DExtrudeObject: { - // write special 3DLathe/3DExtrude attributes + // write special 3DLathe/3DExtrude attributes, get 3D PolyPolygon as drawing::PolyPolygonShape3D aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPolyPolygon3D"))); drawing::PolyPolygonShape3D xPolyPolygon3D; aAny >>= xPolyPolygon3D; - // look for maximal values - double fXMin = 0; - double fXMax = 0; - double fYMin = 0; - double fYMax = 0; - sal_Bool bInit(sal_False); - sal_Int32 nOuterSequenceCount(xPolyPolygon3D.SequenceX.getLength()); - drawing::DoubleSequence* pInnerSequenceX = xPolyPolygon3D.SequenceX.getArray(); - drawing::DoubleSequence* pInnerSequenceY = xPolyPolygon3D.SequenceY.getArray(); - - sal_Int32 a; - for (a = 0; a < nOuterSequenceCount; a++) - { - sal_Int32 nInnerSequenceCount(pInnerSequenceX->getLength()); - double* pArrayX = pInnerSequenceX->getArray(); - double* pArrayY = pInnerSequenceY->getArray(); - - for(sal_Int32 b(0L); b < nInnerSequenceCount; b++) - { - double fX = *pArrayX++; - double fY = *pArrayY++; - - if(bInit) - { - if(fX > fXMax) - fXMax = fX; - - if(fX < fXMin) - fXMin = fX; - - if(fY > fYMax) - fYMax = fY; - - if(fY < fYMin) - fYMin = fY; - } - else - { - fXMin = fXMax = fX; - fYMin = fYMax = fY; - bInit = sal_True; - } - } - - pInnerSequenceX++; - pInnerSequenceY++; - } + // convert to 3D PolyPolygon + const basegfx::B3DPolyPolygon aPolyPolygon3D( + basegfx::tools::UnoPolyPolygonShape3DToB3DPolyPolygon( + xPolyPolygon3D)); + + // convert to 2D PolyPolygon using identity 3D transformation (just grep X and Y) + const basegfx::B3DHomMatrix aB3DHomMatrixFor2DConversion; + const basegfx::B2DPolyPolygon aPolyPolygon( + basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon( + aPolyPolygon3D, + aB3DHomMatrixFor2DConversion)); + + // get 2D range of it + const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange()); // export ViewBox - awt::Point aMinPoint(FRound(fXMin), FRound(fYMin)); - awt::Size aMaxSize(FRound(fXMax) - aMinPoint.X, FRound(fYMax) - aMinPoint.Y); SdXMLImExViewBox aViewBox( - aMinPoint.X, aMinPoint.Y, aMaxSize.Width, aMaxSize.Height); - mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, - aViewBox.GetExportString()); + aPolyPolygonRange.getMinX(), + aPolyPolygonRange.getMinY(), + aPolyPolygonRange.getWidth(), + aPolyPolygonRange.getHeight()); - // prepare svx:d element export - SdXMLImExSvgDElement aSvgDElement(aViewBox); - pInnerSequenceX = xPolyPolygon3D.SequenceX.getArray(); - pInnerSequenceY = xPolyPolygon3D.SequenceY.getArray(); + mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString()); - for (a = 0; a < nOuterSequenceCount; a++) - { - sal_Int32 nInnerSequenceCount(pInnerSequenceX->getLength()); - double* pArrayX = pInnerSequenceX->getArray(); - double* pArrayY = pInnerSequenceY->getArray(); - drawing::PointSequence aPoly(nInnerSequenceCount); - awt::Point* pInnerSequence = aPoly.getArray(); - - for(sal_Int32 b(0L); b < nInnerSequenceCount; b++) - { - double fX = *pArrayX++; - double fY = *pArrayY++; - - *pInnerSequence = awt::Point(FRound(fX), FRound(fY)); - pInnerSequence++; - } - - // calculate closed flag - awt::Point* pFirst = aPoly.getArray(); - awt::Point* pLast = pFirst + (nInnerSequenceCount - 1); - sal_Bool bClosed = (pFirst->X == pLast->X && pFirst->Y == pLast->Y); - - aSvgDElement.AddPolygon(&aPoly, 0L, aMinPoint, - aMaxSize, bClosed); - - // #80594# corrected error in PolyPolygon3D export for 3D XML - pInnerSequenceX++; - pInnerSequenceY++; - } + // prepare svg:d string + const ::rtl::OUString aPolygonString( + basegfx::tools::exportToSvgD( + aPolyPolygon, + true, // bUseRelativeCoordinates + false)); // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now // write point array - mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); + mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString); + + // TTTT + //// look for maximal values + //double fXMin = 0; + //double fXMax = 0; + //double fYMin = 0; + //double fYMax = 0; + //sal_Bool bInit(sal_False); + //sal_Int32 nOuterSequenceCount(xPolyPolygon3D.SequenceX.getLength()); + //drawing::DoubleSequence* pInnerSequenceX = xPolyPolygon3D.SequenceX.getArray(); + //drawing::DoubleSequence* pInnerSequenceY = xPolyPolygon3D.SequenceY.getArray(); + // + //sal_Int32 a; + //for (a = 0; a < nOuterSequenceCount; a++) + //{ + // sal_Int32 nInnerSequenceCount(pInnerSequenceX->getLength()); + // double* pArrayX = pInnerSequenceX->getArray(); + // double* pArrayY = pInnerSequenceY->getArray(); + // + // for(sal_Int32 b(0L); b < nInnerSequenceCount; b++) + // { + // double fX = *pArrayX++; + // double fY = *pArrayY++; + // + // if(bInit) + // { + // if(fX > fXMax) + // fXMax = fX; + // + // if(fX < fXMin) + // fXMin = fX; + // + // if(fY > fYMax) + // fYMax = fY; + // + // if(fY < fYMin) + // fYMin = fY; + // } + // else + // { + // fXMin = fXMax = fX; + // fYMin = fYMax = fY; + // bInit = sal_True; + // } + // } + // + // pInnerSequenceX++; + // pInnerSequenceY++; + //} + // + //// export ViewBox + //awt::Point aMinPoint(FRound(fXMin), FRound(fYMin)); + //awt::Size aMaxSize(FRound(fXMax) - aMinPoint.X, FRound(fYMax) - aMinPoint.Y); + //SdXMLImExViewBox aViewBox(fXMin, fYMin, fXMax - fXMin, fYMax - fYMin); + //mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString()); + // + //// prepare svx:d element export + //SdXMLImExSvgDElement aSvgDElement(aViewBox); + //pInnerSequenceX = xPolyPolygon3D.SequenceX.getArray(); + //pInnerSequenceY = xPolyPolygon3D.SequenceY.getArray(); + // + //for (a = 0; a < nOuterSequenceCount; a++) + //{ + // sal_Int32 nInnerSequenceCount(pInnerSequenceX->getLength()); + // double* pArrayX = pInnerSequenceX->getArray(); + // double* pArrayY = pInnerSequenceY->getArray(); + // drawing::PointSequence aPoly(nInnerSequenceCount); + // awt::Point* pInnerSequence = aPoly.getArray(); + // + // for(sal_Int32 b(0L); b < nInnerSequenceCount; b++) + // { + // double fX = *pArrayX++; + // double fY = *pArrayY++; + // + // *pInnerSequence = awt::Point(FRound(fX), FRound(fY)); + // pInnerSequence++; + // } + // + // // calculate closed flag + // awt::Point* pFirst = aPoly.getArray(); + // awt::Point* pLast = pFirst + (nInnerSequenceCount - 1); + // sal_Bool bClosed = (pFirst->X == pLast->X && pFirst->Y == pLast->Y); + // + // aSvgDElement.AddPolygon(&aPoly, 0L, aMinPoint, + // aMaxSize, bClosed); + // + // // #80594# corrected error in PolyPolygon3D export for 3D XML + // pInnerSequenceX++; + // pInnerSequenceY++; + //} + // + //// write point array + //mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); if(eShapeType == XmlShapeTypeDraw3DLatheObject) { diff --git a/xmloff/source/draw/xexptran.cxx b/xmloff/source/draw/xexptran.cxx index 96ecaf4243b9..9aee767bdd5f 100644 --- a/xmloff/source/draw/xexptran.cxx +++ b/xmloff/source/draw/xexptran.cxx @@ -1242,21 +1242,21 @@ void SdXMLImExTransform3D::GetFullTransform(::basegfx::B3DHomMatrix& rFullTrans) ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -SdXMLImExViewBox::SdXMLImExViewBox(sal_Int32 nX, sal_Int32 nY, sal_Int32 nW, sal_Int32 nH) -: mnX( nX ), - mnY( nY ), - mnW( nW ), - mnH( nH ) +SdXMLImExViewBox::SdXMLImExViewBox(double fX, double fY, double fW, double fH) +: mfX( fX ), + mfY( fY ), + mfW( fW ), + mfH( fH ) { } // #100617# Asked vincent hardy: svg:viewBox values may be double precision. SdXMLImExViewBox::SdXMLImExViewBox(const OUString& rNew, const SvXMLUnitConverter& rConv) : msString(rNew), - mnX( 0L ), - mnY( 0L ), - mnW( 1000L ), - mnH( 1000L ) + mfX( 0.0 ), + mfY( 0.0 ), + mfW( 1000.0 ), + mfH( 1000.0 ) { if(msString.getLength()) { @@ -1268,25 +1268,25 @@ SdXMLImExViewBox::SdXMLImExViewBox(const OUString& rNew, const SvXMLUnitConverte Imp_SkipSpaces(aStr, nPos, nLen); // get mX, #100617# be prepared for doubles - mnX = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnX)); + mfX = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfX); // skip spaces and commas Imp_SkipSpacesAndCommas(aStr, nPos, nLen); // get mY, #100617# be prepared for doubles - mnY = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnY)); + mfY = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfY); // skip spaces and commas Imp_SkipSpacesAndCommas(aStr, nPos, nLen); // get mW, #100617# be prepared for doubles - mnW = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnW)); + mfW = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfW); // skip spaces and commas Imp_SkipSpacesAndCommas(aStr, nPos, nLen); // get mH, #100617# be prepared for doubles - mnH = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnH)); + mfH = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfH); } } @@ -1295,16 +1295,16 @@ const OUString& SdXMLImExViewBox::GetExportString() OUString aNewString; OUString aEmptySpace(sal_Unicode(' ')); - Imp_PutNumberChar(aNewString, mnX); + Imp_PutNumberChar(aNewString, mfX); aNewString += aEmptySpace; - Imp_PutNumberChar(aNewString, mnY); + Imp_PutNumberChar(aNewString, mfY); aNewString += aEmptySpace; - Imp_PutNumberChar(aNewString, mnW); + Imp_PutNumberChar(aNewString, mfW); aNewString += aEmptySpace; - Imp_PutNumberChar(aNewString, mnH); + Imp_PutNumberChar(aNewString, mfH); // set new string msString = aNewString; @@ -1314,1776 +1314,1776 @@ const OUString& SdXMLImExViewBox::GetExportString() ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// - -SdXMLImExPointsElement::SdXMLImExPointsElement(drawing::PointSequence* pPoints, - const SdXMLImExViewBox& rViewBox, - const awt::Point& rObjectPos, - const awt::Size& rObjectSize, - const bool bClosed) -: maPoly( 0L ) -{ - DBG_ASSERT(pPoints, "Empty PointSequence handed over to SdXMLImExPointsElement(!)"); - - // add polygon to string - sal_Int32 nCnt(pPoints->getLength()); - - // #104076# Convert to string only when at last one point included - if(nCnt > 0) - { - OUString aNewString; - awt::Point* pArray = pPoints->getArray(); - - // last point same? Ignore it. - // #96328# ...but only when polygon is CLOSED - if(bClosed && (pArray->X == (pArray + (nCnt - 1))->X) && (pArray->Y == (pArray + (nCnt - 1))->Y)) - nCnt--; - - // object size and ViewBox size different? - bool bScale(rObjectSize.Width != rViewBox.GetWidth() - || rObjectSize.Height != rViewBox.GetHeight()); - bool bTranslate(rViewBox.GetX() != 0L || rViewBox.GetY() != 0L); - - for(sal_Int32 a(0L); a < nCnt; a++) - { - // prepare coordinates - sal_Int32 nX( pArray->X - rObjectPos.X ); - sal_Int32 nY( pArray->Y - rObjectPos.Y ); - - if(bScale && rObjectSize.Width && rObjectSize.Height) - { - nX = (nX * rViewBox.GetWidth()) / rObjectSize.Width; - nY = (nY * rViewBox.GetHeight()) / rObjectSize.Height; - } - - if(bTranslate) - { - nX += rViewBox.GetX(); - nY += rViewBox.GetY(); - } - - // X and comma - Imp_PutNumberChar(aNewString, nX); - aNewString += String(sal_Unicode(',')); - - // Y and space (not for last) - Imp_PutNumberChar(aNewString, nY); - if(a + 1 != nCnt) - aNewString += String(sal_Unicode(' ')); - - // next point - pArray++; - } - - // set new string - msString = aNewString; - } -} - -// #100617# svg:polyline or svg:polygon values may be double precision. -SdXMLImExPointsElement::SdXMLImExPointsElement(const OUString& rNew, - const SdXMLImExViewBox& rViewBox, - const awt::Point& rObjectPos, - const awt::Size& rObjectSize, - const SvXMLUnitConverter& rConv, - const bool bClosed) -: msString( rNew ), - maPoly( 0L ) -{ - // convert string to polygon - const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength()); - const sal_Int32 nLen(aStr.getLength()); - sal_Int32 nPos(0); - sal_Int32 nNumPoints(0L); - - // skip starting spaces - Imp_SkipSpaces(aStr, nPos, nLen); - - // count points in first loop - while(nPos < nLen) - { - // skip number, #100617# be prepared for doubles - Imp_SkipDouble(aStr, nPos, nLen); - - // skip spaces and commas - Imp_SkipSpacesAndCommas(aStr, nPos, nLen); - - // skip number, #100617# be prepared for doubles - Imp_SkipDouble(aStr, nPos, nLen); - - // skip spaces and commas - Imp_SkipSpacesAndCommas(aStr, nPos, nLen); - - // one more point - nNumPoints++; - } - - // second loop - if(nNumPoints) - { - nPos = 0; - maPoly.realloc(1); - drawing::PointSequence* pOuterSequence = maPoly.getArray(); - pOuterSequence->realloc(nNumPoints + (bClosed ? 1 : 0)); - awt::Point* pInnerSequence = pOuterSequence->getArray(); - - // object size and ViewBox size different? - bool bScale(rObjectSize.Width != rViewBox.GetWidth() - || rObjectSize.Height != rViewBox.GetHeight()); - bool bTranslate(rViewBox.GetX() != 0L || rViewBox.GetY() != 0L); - - // skip starting spaces - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen) - { - // prepare new parameter pair - sal_Int32 nX(0L); - sal_Int32 nY(0L); - - // get mX, #100617# be prepared for doubles - nX = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)nX)); - - // skip spaces and commas - Imp_SkipSpacesAndCommas(aStr, nPos, nLen); - - // get mY, #100617# be prepared for doubles - nY = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)nY)); - - // skip spaces and commas - Imp_SkipSpacesAndCommas(aStr, nPos, nLen); - - // prepare parameters - if(bTranslate) - { - nX -= rViewBox.GetX(); - nY -= rViewBox.GetY(); - } - - if(bScale && rViewBox.GetWidth() && rViewBox.GetHeight() ) - { - nX = (nX * rObjectSize.Width) / rViewBox.GetWidth(); - nY = (nY * rObjectSize.Height) / rViewBox.GetHeight(); - } - - nX += rObjectPos.X; - nY += rObjectPos.Y; - - // add new point - *pInnerSequence = awt::Point( nX, nY ); - pInnerSequence++; - } - - if(bClosed) - { - *pInnerSequence = *pOuterSequence->getArray(); - } - } -} - +// +//SdXMLImExPointsElement::SdXMLImExPointsElement(drawing::PointSequence* pPoints, +// const SdXMLImExViewBox& rViewBox, +// const awt::Point& rObjectPos, +// const awt::Size& rObjectSize, +// const bool bClosed) +//: maPoly( 0L ) +//{ +// DBG_ASSERT(pPoints, "Empty PointSequence handed over to SdXMLImExPointsElement(!)"); +// +// // add polygon to string +// sal_Int32 nCnt(pPoints->getLength()); +// +// // #104076# Convert to string only when at last one point included +// if(nCnt > 0) +// { +// OUString aNewString; +// awt::Point* pArray = pPoints->getArray(); +// +// // last point same? Ignore it. +// // #96328# ...but only when polygon is CLOSED +// if(bClosed && (pArray->X == (pArray + (nCnt - 1))->X) && (pArray->Y == (pArray + (nCnt - 1))->Y)) +// nCnt--; +// +// // object size and ViewBox size different? +// bool bScale(rObjectSize.Width != rViewBox.GetWidth() +// || rObjectSize.Height != rViewBox.GetHeight()); +// bool bTranslate(rViewBox.GetX() != 0L || rViewBox.GetY() != 0L); +// +// for(sal_Int32 a(0L); a < nCnt; a++) +// { +// // prepare coordinates +// sal_Int32 nX( pArray->X - rObjectPos.X ); +// sal_Int32 nY( pArray->Y - rObjectPos.Y ); +// +// if(bScale && rObjectSize.Width && rObjectSize.Height) +// { +// nX = (nX * rViewBox.GetWidth()) / rObjectSize.Width; +// nY = (nY * rViewBox.GetHeight()) / rObjectSize.Height; +// } +// +// if(bTranslate) +// { +// nX += rViewBox.GetX(); +// nY += rViewBox.GetY(); +// } +// +// // X and comma +// Imp_PutNumberChar(aNewString, nX); +// aNewString += String(sal_Unicode(',')); +// +// // Y and space (not for last) +// Imp_PutNumberChar(aNewString, nY); +// if(a + 1 != nCnt) +// aNewString += String(sal_Unicode(' ')); +// +// // next point +// pArray++; +// } +// +// // set new string +// msString = aNewString; +// } +//} +// +//// #100617# svg:polyline or svg:polygon values may be double precision. +//SdXMLImExPointsElement::SdXMLImExPointsElement(const OUString& rNew, +// const SdXMLImExViewBox& rViewBox, +// const awt::Point& rObjectPos, +// const awt::Size& rObjectSize, +// const SvXMLUnitConverter& rConv, +// const bool bClosed) +//: msString( rNew ), +// maPoly( 0L ) +//{ +// // convert string to polygon +// const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength()); +// const sal_Int32 nLen(aStr.getLength()); +// sal_Int32 nPos(0); +// sal_Int32 nNumPoints(0L); +// +// // skip starting spaces +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// // count points in first loop +// while(nPos < nLen) +// { +// // skip number, #100617# be prepared for doubles +// Imp_SkipDouble(aStr, nPos, nLen); +// +// // skip spaces and commas +// Imp_SkipSpacesAndCommas(aStr, nPos, nLen); +// +// // skip number, #100617# be prepared for doubles +// Imp_SkipDouble(aStr, nPos, nLen); +// +// // skip spaces and commas +// Imp_SkipSpacesAndCommas(aStr, nPos, nLen); +// +// // one more point +// nNumPoints++; +// } +// +// // second loop +// if(nNumPoints) +// { +// nPos = 0; +// maPoly.realloc(1); +// drawing::PointSequence* pOuterSequence = maPoly.getArray(); +// pOuterSequence->realloc(nNumPoints + (bClosed ? 1 : 0)); +// awt::Point* pInnerSequence = pOuterSequence->getArray(); +// +// // object size and ViewBox size different? +// bool bScale(rObjectSize.Width != rViewBox.GetWidth() +// || rObjectSize.Height != rViewBox.GetHeight()); +// bool bTranslate(rViewBox.GetX() != 0L || rViewBox.GetY() != 0L); +// +// // skip starting spaces +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen) +// { +// // prepare new parameter pair +// sal_Int32 nX(0L); +// sal_Int32 nY(0L); +// +// // get mX, #100617# be prepared for doubles +// nX = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)nX)); +// +// // skip spaces and commas +// Imp_SkipSpacesAndCommas(aStr, nPos, nLen); +// +// // get mY, #100617# be prepared for doubles +// nY = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)nY)); +// +// // skip spaces and commas +// Imp_SkipSpacesAndCommas(aStr, nPos, nLen); +// +// // prepare parameters +// if(bTranslate) +// { +// nX -= rViewBox.GetX(); +// nY -= rViewBox.GetY(); +// } +// +// if(bScale && rViewBox.GetWidth() && rViewBox.GetHeight() ) +// { +// nX = (nX * rObjectSize.Width) / rViewBox.GetWidth(); +// nY = (nY * rObjectSize.Height) / rViewBox.GetHeight(); +// } +// +// nX += rObjectPos.X; +// nY += rObjectPos.Y; +// +// // add new point +// *pInnerSequence = awt::Point( nX, nY ); +// pInnerSequence++; +// } +// +// if(bClosed) +// { +// *pInnerSequence = *pOuterSequence->getArray(); +// } +// } +//} +// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// - -SdXMLImExSvgDElement::SdXMLImExSvgDElement(const SdXMLImExViewBox& rViewBox) -: mrViewBox( rViewBox ), - mbIsClosed( false ), - mbIsCurve( false ), - mnLastX( 0L ), - mnLastY( 0L ), - maPoly( 0L ), - maFlag( 0L ) -{ -} - -void Imp_GetPrevPos(awt::Point*& pPrevPos1, - drawing::PolygonFlags& aPrevFlag1, - const bool bClosed, awt::Point* pPoints, - drawing::PolygonFlags* pFlags, const sal_Int32 nPos, - const sal_Int32 nCnt, const sal_Int32 nAdd) -{ - if(bClosed) - { - pPrevPos1 = pPoints + ((nPos + nCnt - nAdd) % nCnt); - aPrevFlag1 = *(pFlags + ((nPos + nCnt - nAdd) % nCnt)); - } - else if(nPos > (nAdd - 1)) - { - pPrevPos1 = pPoints + (nPos - nAdd); - aPrevFlag1 = *(pFlags + (nPos - nAdd)); - } - else - pPrevPos1 = 0L; -} - -void Imp_PrepareCoorExport(sal_Int32& nX, sal_Int32& nY, - const awt::Point* pPointArray, const awt::Point& rObjectPos, - const awt::Size& rObjectSize, const SdXMLImExViewBox& mrViewBox, - const bool bScale, const bool bTranslate) -{ - nX = pPointArray->X - rObjectPos.X; - nY = pPointArray->Y - rObjectPos.Y; - - if(bScale && rObjectSize.Width && rObjectSize.Height ) - { - nX = (nX * mrViewBox.GetWidth()) / rObjectSize.Width; - nY = (nY * mrViewBox.GetHeight()) / rObjectSize.Height; - } - - if(bTranslate) - { - nX += mrViewBox.GetX(); - nY += mrViewBox.GetY(); - } -} - -//#define TEST_QUADRATIC_CURVES -#ifdef TEST_QUADRATIC_CURVES -// To be able to test quadratic curve code: The code concerning to -// bDoTestHere can be used (see below). Construct shapes which have their control -// points on equal coordinates. When these are written, they can be -// forced to create correct 'Q' and 'T' statements using this flag. -// These may then be tested for import/exporting. -static bool bDoTestHere(true); -#endif // TEST_QUADRATIC_CURVES - -void SdXMLImExSvgDElement::AddPolygon( - drawing::PointSequence* pPoints, - drawing::FlagSequence* pFlags, - const awt::Point& rObjectPos, - const awt::Size& rObjectSize, - bool bClosed, bool bRelative) -{ - DBG_ASSERT(pPoints, "Empty PointSequence handed over to SdXMLImExSvgDElement(!)"); - - sal_Int32 nCnt(pPoints->getLength()); - - // #104076# Convert to string only when at last one point included - if(nCnt > 0) - { - // append polygon to string - OUString aNewString; - sal_Unicode aLastCommand = ' '; - awt::Point* pPointArray = pPoints->getArray(); - - // are the flags used at all? If not forget about them - if(pFlags) - { - sal_Int32 nFlagCnt(pFlags->getLength()); - - if(nFlagCnt) - { - bool bFlagsUsed(false); - drawing::PolygonFlags* pFlagArray = pFlags->getArray(); - - for(sal_Int32 a(0); !bFlagsUsed && a < nFlagCnt; a++) - if(drawing::PolygonFlags_NORMAL != *pFlagArray++) - bFlagsUsed = true; - - if(!bFlagsUsed) - pFlags = 0L; - } - else - { - pFlags = 0L; - } - } - - // object size and ViewBox size different? - bool bScale(rObjectSize.Width != mrViewBox.GetWidth() - || rObjectSize.Height != mrViewBox.GetHeight()); - bool bTranslate(mrViewBox.GetX() != 0L || mrViewBox.GetY() != 0L); - - // #87202# rework of point reduction: - // Test for Last point same -> closed, ignore last point. Take - // some more circumstances in account when looking at curve segments. - drawing::PolygonFlags* pFlagArray = (pFlags) ? pFlags->getArray() : 0L; - - // #121090# only reduce double start/end points if polygon *is* closed - if(bClosed && (pPointArray->X == (pPointArray + (nCnt - 1))->X) && (pPointArray->Y == (pPointArray + (nCnt - 1))->Y)) - { - if(pFlags) - { - // point needs to be ignored if point before it is - // NO control point. Else the last point is needed - // for exporting the last segment of the curve. That means - // that the last and the first point will be saved double, - // but SVG does not support a better solution here. - if(nCnt >= 2 && drawing::PolygonFlags_CONTROL != *(pFlagArray + (nCnt - 2))) - { - nCnt--; - } - } - else - { - // no curve, ignore last point - nCnt--; - } - } - - // bezier poly, handle curves - bool bDidWriteStart(false); - - for(sal_Int32 a(0L); a < nCnt; a++) - { - if(!pFlags || drawing::PolygonFlags_CONTROL != *pFlagArray) - { - bool bDidWriteAsCurve(false); - - if(bDidWriteStart) - { - if(pFlags) - { - // real curve point, get previous to see if it's a control point - awt::Point* pPrevPos1; - drawing::PolygonFlags aPrevFlag1; - - Imp_GetPrevPos(pPrevPos1, aPrevFlag1, bClosed, pPoints->getArray(), - pFlags->getArray(), a, nCnt, 1); - - if(pPrevPos1 && drawing::PolygonFlags_CONTROL == aPrevFlag1) - { - // get previous2 to see if it's a control point, too - awt::Point* pPrevPos2; - drawing::PolygonFlags aPrevFlag2; - - Imp_GetPrevPos(pPrevPos2, aPrevFlag2, bClosed, pPoints->getArray(), - pFlags->getArray(), a, nCnt, 2); - - if(pPrevPos2 && drawing::PolygonFlags_CONTROL == aPrevFlag2) - { - // get previous3 to see if it's a curve point and if, - // if it is fully symmetric or not - awt::Point* pPrevPos3; - drawing::PolygonFlags aPrevFlag3; - - Imp_GetPrevPos(pPrevPos3, aPrevFlag3, bClosed, pPoints->getArray(), - pFlags->getArray(), a, nCnt, 3); - - if(pPrevPos3) - { - // prepare coordinates - sal_Int32 nX, nY; - - Imp_PrepareCoorExport(nX, nY, pPointArray, rObjectPos, rObjectSize, - mrViewBox, bScale, bTranslate); - - // #100617# test if this curve segment may be written as - // a quadratic bezier - // That's the case if both control points are in the same place - // when they are prolonged to the common quadratic control point - // Left: P = (3P1 - P0) / 2 - // Right: P = (3P2 - P3) / 2 - bool bIsQuadratic(false); - const bool bEnableSaveQuadratic(false); - - sal_Int32 nPX_L(FRound((double)((3 * pPrevPos2->X) - pPrevPos3->X) / 2.0)); - sal_Int32 nPY_L(FRound((double)((3 * pPrevPos2->Y) - pPrevPos3->Y) / 2.0)); - sal_Int32 nPX_R(FRound((double)((3 * pPrevPos1->X) - pPointArray->X) / 2.0)); - sal_Int32 nPY_R(FRound((double)((3 * pPrevPos1->Y) - pPointArray->Y) / 2.0)); - sal_Int32 nDist(0); - - if(nPX_L != nPX_R) - { - nDist += abs(nPX_L - nPX_R); - } - - if(nPY_L != nPY_R) - { - nDist += abs(nPY_L - nPY_R); - } - - if(nDist <= BORDER_INTEGERS_ARE_EQUAL) - { - if(bEnableSaveQuadratic) - { - bIsQuadratic = true; - } - } - -#ifdef TEST_QUADRATIC_CURVES - if(bDoTestHere) - { - bIsQuadratic = false; - - if(pPrevPos1->X == pPrevPos2->X && pPrevPos1->Y == pPrevPos2->Y) - bIsQuadratic = true; - } -#endif // TEST_QUADRATIC_CURVES - - if(bIsQuadratic) - { -#ifdef TEST_QUADRATIC_CURVES - if(bDoTestHere) - { - bool bPrevPointIsSymmetric(false); - - if(drawing::PolygonFlags_SYMMETRIC == aPrevFlag3) - { - // get previous4 to see if it's a control point - awt::Point* pPrevPos4; - drawing::PolygonFlags aPrevFlag4; - - Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(), - pFlags->getArray(), a, nCnt, 4); - - if(drawing::PolygonFlags_CONTROL == aPrevFlag4) - { - // okay, prevPos3 is symmetric (c2) and prevPos4 - // is existing control point, the 's' statement can be used - bPrevPointIsSymmetric = true; - } - } - - if(bPrevPointIsSymmetric) - { - // write a shorthand/smooth quadratic curveto entry (T) - if(bRelative) - { - if(aLastCommand != sal_Unicode('t')) - aNewString += OUString(sal_Unicode('t')); - - Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); - - aLastCommand = sal_Unicode('t'); - } - else - { - if(aLastCommand != sal_Unicode('T')) - aNewString += OUString(sal_Unicode('T')); - - Imp_PutNumberCharWithSpace(aNewString, nX); - Imp_PutNumberCharWithSpace(aNewString, nY); - - aLastCommand = sal_Unicode('T'); - } - } - else - { - // prepare coordinates - sal_Int32 nX1, nY1; - - Imp_PrepareCoorExport(nX1, nY1, pPrevPos1, rObjectPos, rObjectSize, - mrViewBox, bScale, bTranslate); - - // write a quadratic curveto entry (Q) - if(bRelative) - { - if(aLastCommand != sal_Unicode('q')) - aNewString += OUString(sal_Unicode('q')); - - Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY); - Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); - - aLastCommand = sal_Unicode('q'); - } - else - { - if(aLastCommand != sal_Unicode('Q')) - aNewString += OUString(sal_Unicode('Q')); - - Imp_PutNumberCharWithSpace(aNewString, nX1); - Imp_PutNumberCharWithSpace(aNewString, nY1); - Imp_PutNumberCharWithSpace(aNewString, nX); - Imp_PutNumberCharWithSpace(aNewString, nY); - - aLastCommand = sal_Unicode('Q'); - } - } - } - else - { -#endif // TEST_QUADRATIC_CURVES - awt::Point aNewPoint(nPX_L, nPY_L); - bool bPrevPointIsSmooth(false); - - if(drawing::PolygonFlags_SMOOTH == aPrevFlag3) - { - // get previous4 to see if it's a control point - awt::Point* pPrevPos4; - drawing::PolygonFlags aPrevFlag4; - - Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(), - pFlags->getArray(), a, nCnt, 4); - - if(drawing::PolygonFlags_CONTROL == aPrevFlag4) - { - // okay, prevPos3 is smooth (c1) and prevPos4 - // is existing control point. Test if it's even symmetric - // and thus the 'T' statement may be used. - ::basegfx::B2DVector aVec1(pPrevPos4->X - pPrevPos3->X, pPrevPos4->Y - pPrevPos3->Y); - ::basegfx::B2DVector aVec2(aNewPoint.X - pPrevPos3->X, aNewPoint.Y - pPrevPos3->Y); - bool bSameLength(false); - bool bSameDirection(false); - - // get vector values - Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection); - - if(bSameLength && bSameDirection) - bPrevPointIsSmooth = true; - } - } - - if(bPrevPointIsSmooth) - { - // write a shorthand/smooth quadratic curveto entry (T) - if(bRelative) - { - if(aLastCommand != sal_Unicode('t')) - aNewString += String(sal_Unicode('t')); - - Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); - - aLastCommand = sal_Unicode('t'); - } - else - { - if(aLastCommand != sal_Unicode('T')) - aNewString += String(sal_Unicode('T')); - - Imp_PutNumberCharWithSpace(aNewString, nX); - Imp_PutNumberCharWithSpace(aNewString, nY); - - aLastCommand = sal_Unicode('T'); - } - } - else - { - // prepare coordinates - sal_Int32 nX1, nY1; - - Imp_PrepareCoorExport(nX1, nY1, &aNewPoint, rObjectPos, rObjectSize, - mrViewBox, bScale, bTranslate); - - // write a quadratic curveto entry (Q) - if(bRelative) - { - if(aLastCommand != sal_Unicode('q')) - aNewString += String(sal_Unicode('q')); - - Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY); - Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); - - aLastCommand = sal_Unicode('q'); - } - else - { - if(aLastCommand != sal_Unicode('Q')) - aNewString += String(sal_Unicode('Q')); - - Imp_PutNumberCharWithSpace(aNewString, nX1); - Imp_PutNumberCharWithSpace(aNewString, nY1); - Imp_PutNumberCharWithSpace(aNewString, nX); - Imp_PutNumberCharWithSpace(aNewString, nY); - - aLastCommand = sal_Unicode('Q'); - } - } -#ifdef TEST_QUADRATIC_CURVES - } -#endif // TEST_QUADRATIC_CURVES - } - else - { - bool bPrevPointIsSymmetric(false); - - if(drawing::PolygonFlags_SYMMETRIC == aPrevFlag3) - { - // get previous4 to see if it's a control point - awt::Point* pPrevPos4; - drawing::PolygonFlags aPrevFlag4; - - Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(), - pFlags->getArray(), a, nCnt, 4); - - if(drawing::PolygonFlags_CONTROL == aPrevFlag4) - { - // okay, prevPos3 is symmetric (c2) and prevPos4 - // is existing control point, the 's' statement can be used - bPrevPointIsSymmetric = true; - } - } - - // prepare coordinates - sal_Int32 nX2, nY2; - - Imp_PrepareCoorExport(nX2, nY2, pPrevPos1, rObjectPos, rObjectSize, - mrViewBox, bScale, bTranslate); - - if(bPrevPointIsSymmetric) - { - // write a shorthand/smooth curveto entry (S) - if(bRelative) - { - if(aLastCommand != sal_Unicode('s')) - aNewString += String(sal_Unicode('s')); - - Imp_PutNumberCharWithSpace(aNewString, nX2 - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY2 - mnLastY); - Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); - - aLastCommand = sal_Unicode('s'); - } - else - { - if(aLastCommand != sal_Unicode('S')) - aNewString += String(sal_Unicode('S')); - - Imp_PutNumberCharWithSpace(aNewString, nX2); - Imp_PutNumberCharWithSpace(aNewString, nY2); - Imp_PutNumberCharWithSpace(aNewString, nX); - Imp_PutNumberCharWithSpace(aNewString, nY); - - aLastCommand = sal_Unicode('S'); - } - } - else - { - // prepare coordinates - sal_Int32 nX1, nY1; - - Imp_PrepareCoorExport(nX1, nY1, pPrevPos2, rObjectPos, rObjectSize, - mrViewBox, bScale, bTranslate); - - // write a curveto entry (C) - if(bRelative) - { - if(aLastCommand != sal_Unicode('c')) - aNewString += String(sal_Unicode('c')); - - Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY); - Imp_PutNumberCharWithSpace(aNewString, nX2 - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY2 - mnLastY); - Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); - - aLastCommand = sal_Unicode('c'); - } - else - { - if(aLastCommand != sal_Unicode('C')) - aNewString += String(sal_Unicode('C')); - - Imp_PutNumberCharWithSpace(aNewString, nX1); - Imp_PutNumberCharWithSpace(aNewString, nY1); - Imp_PutNumberCharWithSpace(aNewString, nX2); - Imp_PutNumberCharWithSpace(aNewString, nY2); - Imp_PutNumberCharWithSpace(aNewString, nX); - Imp_PutNumberCharWithSpace(aNewString, nY); - - aLastCommand = sal_Unicode('C'); - } - } - } - - // remember that current point IS written - bDidWriteAsCurve = true; - - // remember new last position - mnLastX = nX; - mnLastY = nY; - } - } - } - } - } - - if(!bDidWriteAsCurve) - { - // current point not yet written, prepare coordinates - sal_Int32 nX, nY; - - Imp_PrepareCoorExport(nX, nY, pPointArray, rObjectPos, rObjectSize, - mrViewBox, bScale, bTranslate); - - if(bDidWriteStart) - { - // write as normal point - if(mnLastX == nX) - { - if(bRelative) - { - if(aLastCommand != sal_Unicode('v')) - aNewString += String(sal_Unicode('v')); - - Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); - - aLastCommand = sal_Unicode('v'); - } - else - { - if(aLastCommand != sal_Unicode('V')) - aNewString += String(sal_Unicode('V')); - - Imp_PutNumberCharWithSpace(aNewString, nY); - - aLastCommand = sal_Unicode('V'); - } - } - else if(mnLastY == nY) - { - if(bRelative) - { - if(aLastCommand != sal_Unicode('h')) - aNewString += String(sal_Unicode('h')); - - Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); - - aLastCommand = sal_Unicode('h'); - } - else - { - if(aLastCommand != sal_Unicode('H')) - aNewString += String(sal_Unicode('H')); - - Imp_PutNumberCharWithSpace(aNewString, nX); - - aLastCommand = sal_Unicode('H'); - } - } - else - { - if(bRelative) - { - if(aLastCommand != sal_Unicode('l')) - aNewString += String(sal_Unicode('l')); - - Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); - - aLastCommand = sal_Unicode('l'); - } - else - { - if(aLastCommand != sal_Unicode('L')) - aNewString += String(sal_Unicode('L')); - - Imp_PutNumberCharWithSpace(aNewString, nX); - Imp_PutNumberCharWithSpace(aNewString, nY); - - aLastCommand = sal_Unicode('L'); - } - } - } - else - { - // write as start point - if(bRelative) - { - aNewString += String(sal_Unicode('m')); - - Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); - Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); - - aLastCommand = sal_Unicode('l'); - } - else - { - aNewString += String(sal_Unicode('M')); - - Imp_PutNumberCharWithSpace(aNewString, nX); - Imp_PutNumberCharWithSpace(aNewString, nY); - - aLastCommand = sal_Unicode('L'); - } - - // remember start written - bDidWriteStart = true; - } - - // remember new last position - mnLastX = nX; - mnLastY = nY; - } - } - - // next point - pPointArray++; - pFlagArray++; - } - - // close path if closed poly - if(bClosed) - { - if(bRelative) - aNewString += String(sal_Unicode('z')); - else - aNewString += String(sal_Unicode('Z')); - } - - // append new string - msString += aNewString; - } -} - -// #100617# Linear double reader -double Imp_ImportDoubleAndSpaces( - double fRetval, const OUString& rStr, sal_Int32& rPos, - const sal_Int32 nLen, const SvXMLUnitConverter& rConv) -{ - fRetval = Imp_GetDoubleChar(rStr, rPos, nLen, rConv, fRetval); - Imp_SkipSpacesAndCommas(rStr, rPos, nLen); - return fRetval; -} - -// #100617# Allow to read doubles, too. This will need to be changed to -// the usage of Imp_ImportDoubleAndSpaces(...). For now, this is sufficient -// since the interface cannot transport doubles. -sal_Int32 Imp_ImportNumberAndSpaces( - sal_Int32 nRetval, const OUString& rStr, sal_Int32& rPos, - const sal_Int32 nLen, const SvXMLUnitConverter& rConv) -{ - nRetval = FRound(Imp_ImportDoubleAndSpaces(double(nRetval), rStr, rPos, nLen, rConv)); - Imp_SkipSpacesAndCommas(rStr, rPos, nLen); - return nRetval; -} - -void Imp_PrepareCoorImport(sal_Int32& nX, sal_Int32& nY, - const awt::Point& rObjectPos, const awt::Size& rObjectSize, - const SdXMLImExViewBox& rViewBox, const bool bScale, const bool bTranslate) -{ - if(bTranslate) - { - nX -= rViewBox.GetX(); - nY -= rViewBox.GetY(); - } - - if(bScale && rViewBox.GetWidth() && rViewBox.GetHeight()) - { - nX = (nX * rObjectSize.Width) / rViewBox.GetWidth(); - nY = (nY * rObjectSize.Height) / rViewBox.GetHeight(); - } - - nX += rObjectPos.X; - nY += rObjectPos.Y; -} - -void Imp_AddExportPoints(sal_Int32 nX, sal_Int32 nY, - awt::Point* pPoints, drawing::PolygonFlags* pFlags, - const sal_Int32 nInnerIndex, - drawing::PolygonFlags eFlag) -{ - if(pPoints) - pPoints[nInnerIndex] = awt::Point( nX, nY ); - - if(pFlags) - pFlags[nInnerIndex] = eFlag; -} - -void Imp_CalcVectorValues(::basegfx::B2DVector& aVec1, ::basegfx::B2DVector& aVec2, bool& bSameLength, bool& bSameDirection) -{ - const sal_Int32 nLen1(FRound(aVec1.getLength())); - const sal_Int32 nLen2(FRound(aVec2.getLength())); - aVec1.normalize(); - aVec2.normalize(); - aVec1 += aVec2; - const sal_Int32 nLen3(FRound(aVec1.getLength() * ((nLen1 + nLen2) / 2.0))); - - bSameLength = (abs(nLen1 - nLen2) <= BORDER_INTEGERS_ARE_EQUAL); - bSameDirection = (nLen3 <= BORDER_INTEGERS_ARE_EQUAL); -} - -void Imp_CorrectPolygonFlag(const sal_uInt32 nInnerIndex, const awt::Point* const pInnerSequence, - drawing::PolygonFlags* const pInnerFlags, const sal_Int32 nX1, const sal_Int32 nY1) -{ - if(nInnerIndex) - { - const awt::Point aPPrev1 = pInnerSequence[nInnerIndex - 1]; - - if(nInnerIndex > 1) - { - const awt::Point aPPrev2 = pInnerSequence[nInnerIndex - 2]; - const drawing::PolygonFlags aFPrev2 = pInnerFlags[nInnerIndex - 2]; - ::basegfx::B2DVector aVec1(aPPrev2.X - aPPrev1.X, aPPrev2.Y - aPPrev1.Y); - ::basegfx::B2DVector aVec2(nX1 - aPPrev1.X, nY1 - aPPrev1.Y); - bool bSameLength(false); - bool bSameDirection(false); - - // get vector values - Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection); - - if(drawing::PolygonFlags_CONTROL == aFPrev2) - { - // point before is a control point - if(bSameDirection) - { - if(bSameLength) - { - // set to PolygonFlags_SYMMETRIC - pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SYMMETRIC; - } - else - { - // set to PolygonFlags_SMOOTH - pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH; - } - } - else - { - // set to PolygonFlags_NORMAL - pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL; - } - } - else - { - // point before is a simple curve point - if(bSameDirection) - { - // set to PolygonFlags_SMOOTH - pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH; - } - else - { - // set to PolygonFlags_NORMAL - pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL; - } - } - } - else - { - // no point before starpoint, set type to PolygonFlags_NORMAL - pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL; - } - } -} - -SdXMLImExSvgDElement::SdXMLImExSvgDElement(const OUString& rNew, - const SdXMLImExViewBox& rViewBox, - const awt::Point& rObjectPos, - const awt::Size& rObjectSize, - const SvXMLUnitConverter& rConv) -: msString( rNew ), - mrViewBox( rViewBox ), - mbIsClosed( false ), - mbIsCurve( false ), - mnLastX( 0L ), - mnLastY( 0L ), - maPoly( 0L ), - maFlag( 0L ) -{ - // convert string to polygon - const OUString aStr(msString.getStr(), msString.getLength()); - const sal_Int32 nLen(aStr.getLength()); - sal_Int32 nPos(0); - sal_Int32 nNumPolys(0L); - bool bEllipticalArc(false); - - // object size and ViewBox size different? - bool bScale(rObjectSize.Width != mrViewBox.GetWidth() - || rObjectSize.Height != mrViewBox.GetHeight()); - bool bTranslate(mrViewBox.GetX() != 0L || mrViewBox.GetY() != 0L); - - // first loop: count polys and get flags - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen) - { - switch(aStr[nPos++]) - { - case 'Z' : - case 'z' : - { - break; - } - case 'M' : - case 'm' : - { - nNumPolys++; - break; - } - case 'S' : - case 's' : - case 'C' : - case 'c' : - case 'Q' : - case 'q' : - case 'T' : - case 't' : - { - mbIsCurve = true; - break; - } - case 'L' : - case 'l' : - case 'H' : - case 'h' : - case 'V' : - case 'v' : - { - // normal, interpreted values. All okay. - break; - } - case 'A' : - case 'a' : - { - // Not yet interpreted value. - bEllipticalArc = true; - break; - } - } - } - - DBG_ASSERT(!bEllipticalArc, "XMLIMP: non-interpreted tags in svg:d element!"); - - if(nNumPolys) - { - // alloc arrays - maPoly.realloc(nNumPolys); - if(IsCurve()) - maFlag.realloc(nNumPolys); - - // get outer sequences - drawing::PointSequence* pOuterSequence = maPoly.getArray(); - drawing::FlagSequence* pOuterFlags = (IsCurve()) ? maFlag.getArray() : 0L; - - // prepare new loop, count - sal_uInt32 nPointCount(0L); - nPos = 0; - Imp_SkipSpaces(aStr, nPos, nLen); - - // #104076# reset closed flag for next to be started polygon - mbIsClosed = false; - - while(nPos < nLen) - { - switch(aStr[nPos]) - { - case 'z' : - case 'Z' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - // #104076# remember closed state of current polygon - mbIsClosed = true; - - break; - } - case 'm' : - case 'M' : - { - // new poly starts, end-process current poly - if(nPointCount) - { - // #104076# If this partial polygon is closed, use one more point - // to represent that - if(mbIsClosed) - { - nPointCount++; - } - - pOuterSequence->realloc(nPointCount); - pOuterSequence++; - - if(pOuterFlags) - { - pOuterFlags->realloc(nPointCount); - pOuterFlags++; - } - - // reset point count for next polygon - nPointCount = 0L; - } - - // #104076# reset closed flag for next to be started polygon - mbIsClosed = false; - - // NO break, continue in next case - } - case 'L' : - case 'l' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - nPointCount++; - } - break; - } - case 'H' : - case 'h' : - case 'V' : - case 'v' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - nPointCount++; - } - break; - } - case 'S' : - case 's' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - nPointCount += 3; - } - break; - } - case 'C' : - case 'c' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - nPointCount += 3; - } - break; - } - - // #100617# quadratic beziers, supported as cubic ones - case 'Q' : - case 'q' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - - // use three points since quadratic is imported as cubic - nPointCount += 3; - } - break; - } - - // #100617# relative quadratic beziers, supported as cubic ones - case 'T' : - case 't' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - - // use three points since quadratic is imported as cubic - nPointCount += 3; - } - break; - } - - // #100617# not yet supported: elliptical arc - case 'A' : - case 'a' : - { - DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (elliptical arc)!"); - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - } - break; - } - - default: - { - nPos++; - DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (unknown)!"); - break; - } - } - } - - // alloc last poly (when points used) - if(nPointCount) - { - // #104076# If this partial polygon is closed, use one more point - // to represent that - if(mbIsClosed) - { - nPointCount++; - } - - pOuterSequence->realloc(nPointCount); - pOuterSequence++; - - if(pOuterFlags) - { - pOuterFlags->realloc(nPointCount); - pOuterFlags++; - } - } - - // set pointers back - pOuterSequence = maPoly.getArray(); - pOuterFlags = (IsCurve()) ? maFlag.getArray() : 0L; - awt::Point* pNotSoInnerSequence = 0L; - drawing::PolygonFlags* pNotSoInnerFlags = 0L; - sal_uInt32 nInnerIndex(0L); - - // prepare new loop, read points - nPos = 0; - Imp_SkipSpaces(aStr, nPos, nLen); - - // #104076# reset closed flag for next to be started polygon - mbIsClosed = false; - - while(nPos < nLen) - { - bool bRelative(false); - - switch(aStr[nPos]) - { - case 'z' : - case 'Z' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - // #104076# remember closed state of current polygon - mbIsClosed = true; - - // closed: add first point again - // sal_Int32 nX(pInnerSequence[0].X); - // sal_Int32 nY(pInnerSequence[0].Y); - // Imp_AddExportPoints(nX, nY, pInnerSequence, pInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); - - break; - } - - case 'm' : - { - bRelative = true; - } - case 'M' : - { - // #104076# end-process current poly - if(mbIsClosed) - { - if(pNotSoInnerSequence) - { - // closed: add first point again - sal_Int32 nX(pNotSoInnerSequence[0].X); - sal_Int32 nY(pNotSoInnerSequence[0].Y); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); - } - - // reset closed flag for next to be started polygon - mbIsClosed = false; - } - - // next poly - pNotSoInnerSequence = pOuterSequence->getArray(); - pOuterSequence++; - - if(pOuterFlags) - { - pNotSoInnerFlags = pOuterFlags->getArray(); - pOuterFlags++; - } - - nInnerIndex = 0L; - - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - - if(bRelative) - { - nX += mnLastX; - nY += mnLastY; - } - - // set last position - mnLastX = nX; - mnLastY = nY; - - // calc transform and add point and flag - Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); - } - break; - } - - case 'l' : - { - bRelative = true; - } - case 'L' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - - if(bRelative) - { - nX += mnLastX; - nY += mnLastY; - } - - // set last position - mnLastX = nX; - mnLastY = nY; - - // calc transform and add point and flag - Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); - } - break; - } - - case 'h' : - { - bRelative = true; - } - case 'H' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY(mnLastY); - - if(bRelative) - nX += mnLastX; - - // set last position - mnLastX = nX; - - // calc transform and add point and flag - Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); - } - break; - } - - case 'v' : - { - bRelative = true; - } - case 'V' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - sal_Int32 nX(mnLastX); - sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - - if(bRelative) - nY += mnLastY; - - // set last position - mnLastY = nY; - - // calc transform and add point and flag - Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); - } - break; - } - - case 's' : - { - bRelative = true; - } - case 'S' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - sal_Int32 nX1; - sal_Int32 nY1; - sal_Int32 nX2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - - if(bRelative) - { - nX2 += mnLastX; - nY2 += mnLastY; - nX += mnLastX; - nY += mnLastY; - } - - // set last position - mnLastX = nX; - mnLastY = nY; - - // calc transform for new points - Imp_PrepareCoorImport(nX2, nY2, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - - // one more thing is known: the previous real point is PolygonFlags_SYMMETRIC - // and the Point X1,Y1 can be constructed by mirroring the point before it. - nX1 = nX2; - nY1 = nY2; - if(nInnerIndex) - { - awt::Point aPPrev1 = pNotSoInnerSequence[nInnerIndex - 1]; - - if(nInnerIndex > 1) - { - awt::Point aPPrev2 = pNotSoInnerSequence[nInnerIndex - 2]; - nX1 = aPPrev1.X -(aPPrev2.X - aPPrev1.X); - nY1 = aPPrev1.Y -(aPPrev2.Y - aPPrev1.Y); - } - - // set curve point to symmetric - pNotSoInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SYMMETRIC; - } - - // add calculated control point - Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); - - // add new points and set flags - Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); - } - break; - } - - case 'c' : - { - bRelative = true; - } - case 'C' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - sal_Int32 nX1(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY1(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nX2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - - if(bRelative) - { - nX1 += mnLastX; - nY1 += mnLastY; - nX2 += mnLastX; - nY2 += mnLastY; - nX += mnLastX; - nY += mnLastY; - } - - // set last position - mnLastX = nX; - mnLastY = nY; - - // calc transform for new points - Imp_PrepareCoorImport(nX1, nY1, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - Imp_PrepareCoorImport(nX2, nY2, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - - // correct polygon flag for previous point - Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1); - - // add new points and set flags - Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); - Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); - } - break; - } - - // #100617# quadratic beziers are imported as cubic - case 'q' : - { - bRelative = true; - } - case 'Q' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - sal_Int32 nXX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nYY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - - if(bRelative) - { - nXX += mnLastX; - nYY += mnLastY; - nX += mnLastX; - nY += mnLastY; - } - - // set last position - mnLastX = nX; - mnLastY = nY; - - // calc transform for new points - Imp_PrepareCoorImport(nXX, nYY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - - // calculate X1,X2 - awt::Point aPPrev1 = (nInnerIndex) ? pNotSoInnerSequence[nInnerIndex-1] : pNotSoInnerSequence[0]; - sal_Int32 nX1 = FRound((double)((nXX * 2) + aPPrev1.X) / 3.0); - sal_Int32 nY1 = FRound((double)((nYY * 2) + aPPrev1.Y) / 3.0); - sal_Int32 nX2 = FRound((double)((nXX * 2) + nX) / 3.0); - sal_Int32 nY2 = FRound((double)((nYY * 2) + nY) / 3.0); - - // correct polygon flag for previous point - Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1); - - // add new points and set flags - Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); - Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); - } - break; - } - - // #100617# relative quadratic beziers are imported as cubic - case 't' : - { - bRelative = true; - } - case 'T' : - { - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - sal_Int32 nXX; - sal_Int32 nYY; - sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); - - if(bRelative) - { - nX += mnLastX; - nY += mnLastY; - } - - // set last position - mnLastX = nX; - mnLastY = nY; - - // calc transform for new points - Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); - - // one more thing is known: the previous real point is PolygonFlags_SYMMETRIC - // and the Point X1,Y1 can be constructed by mirroring the point before it. - nXX = nX; - nYY = nY; - awt::Point aPPrev1 = pNotSoInnerSequence[0]; - - if(nInnerIndex) - { - aPPrev1 = pNotSoInnerSequence[nInnerIndex - 1]; - - if(nInnerIndex > 1) - { - awt::Point aPPrev2 = pNotSoInnerSequence[nInnerIndex - 2]; - nXX = aPPrev1.X -(aPPrev2.X - aPPrev1.X); - nYY = aPPrev1.Y -(aPPrev2.Y - aPPrev1.Y); - } - - // set curve point to smooth here, since length - // is changed and thus only c1 can be used. - pNotSoInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH; - } - - // calculate X1,X2 - sal_Int32 nX1 = FRound((double)((nXX * 2) + aPPrev1.X) / 3.0); - sal_Int32 nY1 = FRound((double)((nYY * 2) + aPPrev1.Y) / 3.0); - sal_Int32 nX2 = FRound((double)((nXX * 2) + nX) / 3.0); - sal_Int32 nY2 = FRound((double)((nYY * 2) + nY) / 3.0); - - // correct polygon flag for previous point - Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1); - - // add new points and set flags - Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); - Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); - } - break; - } - - // #100617# not yet supported: elliptical arc - case 'A' : - case 'a' : - { - DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (elliptical arc)!"); - nPos++; - Imp_SkipSpaces(aStr, nPos, nLen); - - while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) - { - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); - } - break; - } - - default: - { - nPos++; - DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (unknown)!"); - break; - } - } - } - - // #104076# end-process closed state of last poly - if(mbIsClosed) - { - if(pNotSoInnerSequence) - { - // closed: add first point again - sal_Int32 nX(pNotSoInnerSequence[0].X); - sal_Int32 nY(pNotSoInnerSequence[0].Y); - Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); - } - } - - // #87202# If it's a curve and it's closed the last point maybe too much - // and just exported since SVG does not allow special handling of same - // start and end point, remove this last point. - // Evtl. correct the last curve flags, too. - if(IsCurve() && IsClosed()) - { - // make one more loop over the PolyPolygon - pOuterSequence = maPoly.getArray(); - pOuterFlags = maFlag.getArray(); - sal_Int32 nOuterCnt(maPoly.getLength()); - - for(sal_Int32 a(0); a < nOuterCnt; a++) - { - // get Polygon pointers - awt::Point* pInnerSequence = pOuterSequence->getArray(); - drawing::PolygonFlags* pInnerFlags = pOuterFlags->getArray(); - sal_Int32 nInnerCnt(pOuterSequence->getLength()); - - while( nInnerCnt >= 2 - && ((pInnerSequence + (nInnerCnt - 2))->X == (pInnerSequence + (nInnerCnt - 1))->X) - && ((pInnerSequence + (nInnerCnt - 2))->Y == (pInnerSequence + (nInnerCnt - 1))->Y) - && drawing::PolygonFlags_CONTROL != *(pInnerFlags + (nInnerCnt - 2))) - { - // remove last point from array - pOuterSequence->realloc(nInnerCnt - 1); - pOuterFlags->realloc(nInnerCnt - 1); - - // get new pointers - pInnerSequence = pOuterSequence->getArray(); - pInnerFlags = pOuterFlags->getArray(); - nInnerCnt = pOuterSequence->getLength(); - } - - // now evtl. correct the last curve flags - if(nInnerCnt >= 4) - { - if( pInnerSequence->X == (pInnerSequence + (nInnerCnt - 1))->X - && pInnerSequence->Y == (pInnerSequence + (nInnerCnt - 1))->Y - && drawing::PolygonFlags_CONTROL == *(pInnerFlags + 1) - && drawing::PolygonFlags_CONTROL == *(pInnerFlags + (nInnerCnt - 2))) - { - awt::Point aPrev = *(pInnerSequence + (nInnerCnt - 2)); - awt::Point aCurr = *pInnerSequence; - awt::Point aNext = *(pInnerSequence + 1); - ::basegfx::B2DVector aVec1(aPrev.X - aCurr.X, aPrev.Y - aCurr.Y); - ::basegfx::B2DVector aVec2(aNext.X - aCurr.X, aNext.Y - aCurr.Y); - bool bSameLength(false); - bool bSameDirection(false); - - // get vector values - Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection); - - // set correct flag value - if(bSameDirection) - { - if(bSameLength) - { - // set to PolygonFlags_SYMMETRIC - *pInnerFlags = drawing::PolygonFlags_SYMMETRIC; - *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_SYMMETRIC; - } - else - { - // set to PolygonFlags_SMOOTH - *pInnerFlags = drawing::PolygonFlags_SMOOTH; - *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_SMOOTH; - } - } - else - { - // set to PolygonFlags_NORMAL - *pInnerFlags = drawing::PolygonFlags_NORMAL; - *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_NORMAL; - } - } - } - - // switch to next Polygon - pOuterSequence++; - pOuterFlags++; - } - } - } -} +// +//SdXMLImExSvgDElement::SdXMLImExSvgDElement(const SdXMLImExViewBox& rViewBox) +//: mrViewBox( rViewBox ), +// mbIsClosed( false ), +// mbIsCurve( false ), +// mnLastX( 0L ), +// mnLastY( 0L ), +// maPoly( 0L ), +// maFlag( 0L ) +//{ +//} +// +//void Imp_GetPrevPos(awt::Point*& pPrevPos1, +// drawing::PolygonFlags& aPrevFlag1, +// const bool bClosed, awt::Point* pPoints, +// drawing::PolygonFlags* pFlags, const sal_Int32 nPos, +// const sal_Int32 nCnt, const sal_Int32 nAdd) +//{ +// if(bClosed) +// { +// pPrevPos1 = pPoints + ((nPos + nCnt - nAdd) % nCnt); +// aPrevFlag1 = *(pFlags + ((nPos + nCnt - nAdd) % nCnt)); +// } +// else if(nPos > (nAdd - 1)) +// { +// pPrevPos1 = pPoints + (nPos - nAdd); +// aPrevFlag1 = *(pFlags + (nPos - nAdd)); +// } +// else +// pPrevPos1 = 0L; +//} +// +//void Imp_PrepareCoorExport(sal_Int32& nX, sal_Int32& nY, +// const awt::Point* pPointArray, const awt::Point& rObjectPos, +// const awt::Size& rObjectSize, const SdXMLImExViewBox& mrViewBox, +// const bool bScale, const bool bTranslate) +//{ +// nX = pPointArray->X - rObjectPos.X; +// nY = pPointArray->Y - rObjectPos.Y; +// +// if(bScale && rObjectSize.Width && rObjectSize.Height ) +// { +// nX = (nX * mrViewBox.GetWidth()) / rObjectSize.Width; +// nY = (nY * mrViewBox.GetHeight()) / rObjectSize.Height; +// } +// +// if(bTranslate) +// { +// nX += mrViewBox.GetX(); +// nY += mrViewBox.GetY(); +// } +//} +// +////#define TEST_QUADRATIC_CURVES +//#ifdef TEST_QUADRATIC_CURVES +//// To be able to test quadratic curve code: The code concerning to +//// bDoTestHere can be used (see below). Construct shapes which have their control +//// points on equal coordinates. When these are written, they can be +//// forced to create correct 'Q' and 'T' statements using this flag. +//// These may then be tested for import/exporting. +//static bool bDoTestHere(true); +//#endif // TEST_QUADRATIC_CURVES +// +//void SdXMLImExSvgDElement::AddPolygon( +// drawing::PointSequence* pPoints, +// drawing::FlagSequence* pFlags, +// const awt::Point& rObjectPos, +// const awt::Size& rObjectSize, +// bool bClosed, bool bRelative) +//{ +// DBG_ASSERT(pPoints, "Empty PointSequence handed over to SdXMLImExSvgDElement(!)"); +// +// sal_Int32 nCnt(pPoints->getLength()); +// +// // #104076# Convert to string only when at last one point included +// if(nCnt > 0) +// { +// // append polygon to string +// OUString aNewString; +// sal_Unicode aLastCommand = ' '; +// awt::Point* pPointArray = pPoints->getArray(); +// +// // are the flags used at all? If not forget about them +// if(pFlags) +// { +// sal_Int32 nFlagCnt(pFlags->getLength()); +// +// if(nFlagCnt) +// { +// bool bFlagsUsed(false); +// drawing::PolygonFlags* pFlagArray = pFlags->getArray(); +// +// for(sal_Int32 a(0); !bFlagsUsed && a < nFlagCnt; a++) +// if(drawing::PolygonFlags_NORMAL != *pFlagArray++) +// bFlagsUsed = true; +// +// if(!bFlagsUsed) +// pFlags = 0L; +// } +// else +// { +// pFlags = 0L; +// } +// } +// +// // object size and ViewBox size different? +// bool bScale(rObjectSize.Width != mrViewBox.GetWidth() +// || rObjectSize.Height != mrViewBox.GetHeight()); +// bool bTranslate(mrViewBox.GetX() != 0L || mrViewBox.GetY() != 0L); +// +// // #87202# rework of point reduction: +// // Test for Last point same -> closed, ignore last point. Take +// // some more circumstances in account when looking at curve segments. +// drawing::PolygonFlags* pFlagArray = (pFlags) ? pFlags->getArray() : 0L; +// +// // #121090# only reduce double start/end points if polygon *is* closed +// if(bClosed && (pPointArray->X == (pPointArray + (nCnt - 1))->X) && (pPointArray->Y == (pPointArray + (nCnt - 1))->Y)) +// { +// if(pFlags) +// { +// // point needs to be ignored if point before it is +// // NO control point. Else the last point is needed +// // for exporting the last segment of the curve. That means +// // that the last and the first point will be saved double, +// // but SVG does not support a better solution here. +// if(nCnt >= 2 && drawing::PolygonFlags_CONTROL != *(pFlagArray + (nCnt - 2))) +// { +// nCnt--; +// } +// } +// else +// { +// // no curve, ignore last point +// nCnt--; +// } +// } +// +// // bezier poly, handle curves +// bool bDidWriteStart(false); +// +// for(sal_Int32 a(0L); a < nCnt; a++) +// { +// if(!pFlags || drawing::PolygonFlags_CONTROL != *pFlagArray) +// { +// bool bDidWriteAsCurve(false); +// +// if(bDidWriteStart) +// { +// if(pFlags) +// { +// // real curve point, get previous to see if it's a control point +// awt::Point* pPrevPos1; +// drawing::PolygonFlags aPrevFlag1; +// +// Imp_GetPrevPos(pPrevPos1, aPrevFlag1, bClosed, pPoints->getArray(), +// pFlags->getArray(), a, nCnt, 1); +// +// if(pPrevPos1 && drawing::PolygonFlags_CONTROL == aPrevFlag1) +// { +// // get previous2 to see if it's a control point, too +// awt::Point* pPrevPos2; +// drawing::PolygonFlags aPrevFlag2; +// +// Imp_GetPrevPos(pPrevPos2, aPrevFlag2, bClosed, pPoints->getArray(), +// pFlags->getArray(), a, nCnt, 2); +// +// if(pPrevPos2 && drawing::PolygonFlags_CONTROL == aPrevFlag2) +// { +// // get previous3 to see if it's a curve point and if, +// // if it is fully symmetric or not +// awt::Point* pPrevPos3; +// drawing::PolygonFlags aPrevFlag3; +// +// Imp_GetPrevPos(pPrevPos3, aPrevFlag3, bClosed, pPoints->getArray(), +// pFlags->getArray(), a, nCnt, 3); +// +// if(pPrevPos3) +// { +// // prepare coordinates +// sal_Int32 nX, nY; +// +// Imp_PrepareCoorExport(nX, nY, pPointArray, rObjectPos, rObjectSize, +// mrViewBox, bScale, bTranslate); +// +// // #100617# test if this curve segment may be written as +// // a quadratic bezier +// // That's the case if both control points are in the same place +// // when they are prolonged to the common quadratic control point +// // Left: P = (3P1 - P0) / 2 +// // Right: P = (3P2 - P3) / 2 +// bool bIsQuadratic(false); +// const bool bEnableSaveQuadratic(false); +// +// sal_Int32 nPX_L(FRound((double)((3 * pPrevPos2->X) - pPrevPos3->X) / 2.0)); +// sal_Int32 nPY_L(FRound((double)((3 * pPrevPos2->Y) - pPrevPos3->Y) / 2.0)); +// sal_Int32 nPX_R(FRound((double)((3 * pPrevPos1->X) - pPointArray->X) / 2.0)); +// sal_Int32 nPY_R(FRound((double)((3 * pPrevPos1->Y) - pPointArray->Y) / 2.0)); +// sal_Int32 nDist(0); +// +// if(nPX_L != nPX_R) +// { +// nDist += abs(nPX_L - nPX_R); +// } +// +// if(nPY_L != nPY_R) +// { +// nDist += abs(nPY_L - nPY_R); +// } +// +// if(nDist <= BORDER_INTEGERS_ARE_EQUAL) +// { +// if(bEnableSaveQuadratic) +// { +// bIsQuadratic = true; +// } +// } +// +//#ifdef TEST_QUADRATIC_CURVES +// if(bDoTestHere) +// { +// bIsQuadratic = false; +// +// if(pPrevPos1->X == pPrevPos2->X && pPrevPos1->Y == pPrevPos2->Y) +// bIsQuadratic = true; +// } +//#endif // TEST_QUADRATIC_CURVES +// +// if(bIsQuadratic) +// { +//#ifdef TEST_QUADRATIC_CURVES +// if(bDoTestHere) +// { +// bool bPrevPointIsSymmetric(false); +// +// if(drawing::PolygonFlags_SYMMETRIC == aPrevFlag3) +// { +// // get previous4 to see if it's a control point +// awt::Point* pPrevPos4; +// drawing::PolygonFlags aPrevFlag4; +// +// Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(), +// pFlags->getArray(), a, nCnt, 4); +// +// if(drawing::PolygonFlags_CONTROL == aPrevFlag4) +// { +// // okay, prevPos3 is symmetric (c2) and prevPos4 +// // is existing control point, the 's' statement can be used +// bPrevPointIsSymmetric = true; +// } +// } +// +// if(bPrevPointIsSymmetric) +// { +// // write a shorthand/smooth quadratic curveto entry (T) +// if(bRelative) +// { +// if(aLastCommand != sal_Unicode('t')) +// aNewString += OUString(sal_Unicode('t')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); +// +// aLastCommand = sal_Unicode('t'); +// } +// else +// { +// if(aLastCommand != sal_Unicode('T')) +// aNewString += OUString(sal_Unicode('T')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX); +// Imp_PutNumberCharWithSpace(aNewString, nY); +// +// aLastCommand = sal_Unicode('T'); +// } +// } +// else +// { +// // prepare coordinates +// sal_Int32 nX1, nY1; +// +// Imp_PrepareCoorExport(nX1, nY1, pPrevPos1, rObjectPos, rObjectSize, +// mrViewBox, bScale, bTranslate); +// +// // write a quadratic curveto entry (Q) +// if(bRelative) +// { +// if(aLastCommand != sal_Unicode('q')) +// aNewString += OUString(sal_Unicode('q')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY); +// Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); +// +// aLastCommand = sal_Unicode('q'); +// } +// else +// { +// if(aLastCommand != sal_Unicode('Q')) +// aNewString += OUString(sal_Unicode('Q')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX1); +// Imp_PutNumberCharWithSpace(aNewString, nY1); +// Imp_PutNumberCharWithSpace(aNewString, nX); +// Imp_PutNumberCharWithSpace(aNewString, nY); +// +// aLastCommand = sal_Unicode('Q'); +// } +// } +// } +// else +// { +//#endif // TEST_QUADRATIC_CURVES +// awt::Point aNewPoint(nPX_L, nPY_L); +// bool bPrevPointIsSmooth(false); +// +// if(drawing::PolygonFlags_SMOOTH == aPrevFlag3) +// { +// // get previous4 to see if it's a control point +// awt::Point* pPrevPos4; +// drawing::PolygonFlags aPrevFlag4; +// +// Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(), +// pFlags->getArray(), a, nCnt, 4); +// +// if(drawing::PolygonFlags_CONTROL == aPrevFlag4) +// { +// // okay, prevPos3 is smooth (c1) and prevPos4 +// // is existing control point. Test if it's even symmetric +// // and thus the 'T' statement may be used. +// ::basegfx::B2DVector aVec1(pPrevPos4->X - pPrevPos3->X, pPrevPos4->Y - pPrevPos3->Y); +// ::basegfx::B2DVector aVec2(aNewPoint.X - pPrevPos3->X, aNewPoint.Y - pPrevPos3->Y); +// bool bSameLength(false); +// bool bSameDirection(false); +// +// // get vector values +// Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection); +// +// if(bSameLength && bSameDirection) +// bPrevPointIsSmooth = true; +// } +// } +// +// if(bPrevPointIsSmooth) +// { +// // write a shorthand/smooth quadratic curveto entry (T) +// if(bRelative) +// { +// if(aLastCommand != sal_Unicode('t')) +// aNewString += String(sal_Unicode('t')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); +// +// aLastCommand = sal_Unicode('t'); +// } +// else +// { +// if(aLastCommand != sal_Unicode('T')) +// aNewString += String(sal_Unicode('T')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX); +// Imp_PutNumberCharWithSpace(aNewString, nY); +// +// aLastCommand = sal_Unicode('T'); +// } +// } +// else +// { +// // prepare coordinates +// sal_Int32 nX1, nY1; +// +// Imp_PrepareCoorExport(nX1, nY1, &aNewPoint, rObjectPos, rObjectSize, +// mrViewBox, bScale, bTranslate); +// +// // write a quadratic curveto entry (Q) +// if(bRelative) +// { +// if(aLastCommand != sal_Unicode('q')) +// aNewString += String(sal_Unicode('q')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY); +// Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); +// +// aLastCommand = sal_Unicode('q'); +// } +// else +// { +// if(aLastCommand != sal_Unicode('Q')) +// aNewString += String(sal_Unicode('Q')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX1); +// Imp_PutNumberCharWithSpace(aNewString, nY1); +// Imp_PutNumberCharWithSpace(aNewString, nX); +// Imp_PutNumberCharWithSpace(aNewString, nY); +// +// aLastCommand = sal_Unicode('Q'); +// } +// } +//#ifdef TEST_QUADRATIC_CURVES +// } +//#endif // TEST_QUADRATIC_CURVES +// } +// else +// { +// bool bPrevPointIsSymmetric(false); +// +// if(drawing::PolygonFlags_SYMMETRIC == aPrevFlag3) +// { +// // get previous4 to see if it's a control point +// awt::Point* pPrevPos4; +// drawing::PolygonFlags aPrevFlag4; +// +// Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(), +// pFlags->getArray(), a, nCnt, 4); +// +// if(drawing::PolygonFlags_CONTROL == aPrevFlag4) +// { +// // okay, prevPos3 is symmetric (c2) and prevPos4 +// // is existing control point, the 's' statement can be used +// bPrevPointIsSymmetric = true; +// } +// } +// +// // prepare coordinates +// sal_Int32 nX2, nY2; +// +// Imp_PrepareCoorExport(nX2, nY2, pPrevPos1, rObjectPos, rObjectSize, +// mrViewBox, bScale, bTranslate); +// +// if(bPrevPointIsSymmetric) +// { +// // write a shorthand/smooth curveto entry (S) +// if(bRelative) +// { +// if(aLastCommand != sal_Unicode('s')) +// aNewString += String(sal_Unicode('s')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX2 - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY2 - mnLastY); +// Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); +// +// aLastCommand = sal_Unicode('s'); +// } +// else +// { +// if(aLastCommand != sal_Unicode('S')) +// aNewString += String(sal_Unicode('S')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX2); +// Imp_PutNumberCharWithSpace(aNewString, nY2); +// Imp_PutNumberCharWithSpace(aNewString, nX); +// Imp_PutNumberCharWithSpace(aNewString, nY); +// +// aLastCommand = sal_Unicode('S'); +// } +// } +// else +// { +// // prepare coordinates +// sal_Int32 nX1, nY1; +// +// Imp_PrepareCoorExport(nX1, nY1, pPrevPos2, rObjectPos, rObjectSize, +// mrViewBox, bScale, bTranslate); +// +// // write a curveto entry (C) +// if(bRelative) +// { +// if(aLastCommand != sal_Unicode('c')) +// aNewString += String(sal_Unicode('c')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY); +// Imp_PutNumberCharWithSpace(aNewString, nX2 - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY2 - mnLastY); +// Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); +// +// aLastCommand = sal_Unicode('c'); +// } +// else +// { +// if(aLastCommand != sal_Unicode('C')) +// aNewString += String(sal_Unicode('C')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX1); +// Imp_PutNumberCharWithSpace(aNewString, nY1); +// Imp_PutNumberCharWithSpace(aNewString, nX2); +// Imp_PutNumberCharWithSpace(aNewString, nY2); +// Imp_PutNumberCharWithSpace(aNewString, nX); +// Imp_PutNumberCharWithSpace(aNewString, nY); +// +// aLastCommand = sal_Unicode('C'); +// } +// } +// } +// +// // remember that current point IS written +// bDidWriteAsCurve = true; +// +// // remember new last position +// mnLastX = nX; +// mnLastY = nY; +// } +// } +// } +// } +// } +// +// if(!bDidWriteAsCurve) +// { +// // current point not yet written, prepare coordinates +// sal_Int32 nX, nY; +// +// Imp_PrepareCoorExport(nX, nY, pPointArray, rObjectPos, rObjectSize, +// mrViewBox, bScale, bTranslate); +// +// if(bDidWriteStart) +// { +// // write as normal point +// if(mnLastX == nX) +// { +// if(bRelative) +// { +// if(aLastCommand != sal_Unicode('v')) +// aNewString += String(sal_Unicode('v')); +// +// Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); +// +// aLastCommand = sal_Unicode('v'); +// } +// else +// { +// if(aLastCommand != sal_Unicode('V')) +// aNewString += String(sal_Unicode('V')); +// +// Imp_PutNumberCharWithSpace(aNewString, nY); +// +// aLastCommand = sal_Unicode('V'); +// } +// } +// else if(mnLastY == nY) +// { +// if(bRelative) +// { +// if(aLastCommand != sal_Unicode('h')) +// aNewString += String(sal_Unicode('h')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); +// +// aLastCommand = sal_Unicode('h'); +// } +// else +// { +// if(aLastCommand != sal_Unicode('H')) +// aNewString += String(sal_Unicode('H')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX); +// +// aLastCommand = sal_Unicode('H'); +// } +// } +// else +// { +// if(bRelative) +// { +// if(aLastCommand != sal_Unicode('l')) +// aNewString += String(sal_Unicode('l')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); +// +// aLastCommand = sal_Unicode('l'); +// } +// else +// { +// if(aLastCommand != sal_Unicode('L')) +// aNewString += String(sal_Unicode('L')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX); +// Imp_PutNumberCharWithSpace(aNewString, nY); +// +// aLastCommand = sal_Unicode('L'); +// } +// } +// } +// else +// { +// // write as start point +// if(bRelative) +// { +// aNewString += String(sal_Unicode('m')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); +// Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); +// +// aLastCommand = sal_Unicode('l'); +// } +// else +// { +// aNewString += String(sal_Unicode('M')); +// +// Imp_PutNumberCharWithSpace(aNewString, nX); +// Imp_PutNumberCharWithSpace(aNewString, nY); +// +// aLastCommand = sal_Unicode('L'); +// } +// +// // remember start written +// bDidWriteStart = true; +// } +// +// // remember new last position +// mnLastX = nX; +// mnLastY = nY; +// } +// } +// +// // next point +// pPointArray++; +// pFlagArray++; +// } +// +// // close path if closed poly +// if(bClosed) +// { +// if(bRelative) +// aNewString += String(sal_Unicode('z')); +// else +// aNewString += String(sal_Unicode('Z')); +// } +// +// // append new string +// msString += aNewString; +// } +//} +// +//// #100617# Linear double reader +//double Imp_ImportDoubleAndSpaces( +// double fRetval, const OUString& rStr, sal_Int32& rPos, +// const sal_Int32 nLen, const SvXMLUnitConverter& rConv) +//{ +// fRetval = Imp_GetDoubleChar(rStr, rPos, nLen, rConv, fRetval); +// Imp_SkipSpacesAndCommas(rStr, rPos, nLen); +// return fRetval; +//} +// +//// #100617# Allow to read doubles, too. This will need to be changed to +//// the usage of Imp_ImportDoubleAndSpaces(...). For now, this is sufficient +//// since the interface cannot transport doubles. +//sal_Int32 Imp_ImportNumberAndSpaces( +// sal_Int32 nRetval, const OUString& rStr, sal_Int32& rPos, +// const sal_Int32 nLen, const SvXMLUnitConverter& rConv) +//{ +// nRetval = FRound(Imp_ImportDoubleAndSpaces(double(nRetval), rStr, rPos, nLen, rConv)); +// Imp_SkipSpacesAndCommas(rStr, rPos, nLen); +// return nRetval; +//} +// +//void Imp_PrepareCoorImport(sal_Int32& nX, sal_Int32& nY, +// const awt::Point& rObjectPos, const awt::Size& rObjectSize, +// const SdXMLImExViewBox& rViewBox, const bool bScale, const bool bTranslate) +//{ +// if(bTranslate) +// { +// nX -= rViewBox.GetX(); +// nY -= rViewBox.GetY(); +// } +// +// if(bScale && rViewBox.GetWidth() && rViewBox.GetHeight()) +// { +// nX = (nX * rObjectSize.Width) / rViewBox.GetWidth(); +// nY = (nY * rObjectSize.Height) / rViewBox.GetHeight(); +// } +// +// nX += rObjectPos.X; +// nY += rObjectPos.Y; +//} +// +//void Imp_AddExportPoints(sal_Int32 nX, sal_Int32 nY, +// awt::Point* pPoints, drawing::PolygonFlags* pFlags, +// const sal_Int32 nInnerIndex, +// drawing::PolygonFlags eFlag) +//{ +// if(pPoints) +// pPoints[nInnerIndex] = awt::Point( nX, nY ); +// +// if(pFlags) +// pFlags[nInnerIndex] = eFlag; +//} +// +//void Imp_CalcVectorValues(::basegfx::B2DVector& aVec1, ::basegfx::B2DVector& aVec2, bool& bSameLength, bool& bSameDirection) +//{ +// const sal_Int32 nLen1(FRound(aVec1.getLength())); +// const sal_Int32 nLen2(FRound(aVec2.getLength())); +// aVec1.normalize(); +// aVec2.normalize(); +// aVec1 += aVec2; +// const sal_Int32 nLen3(FRound(aVec1.getLength() * ((nLen1 + nLen2) / 2.0))); +// +// bSameLength = (abs(nLen1 - nLen2) <= BORDER_INTEGERS_ARE_EQUAL); +// bSameDirection = (nLen3 <= BORDER_INTEGERS_ARE_EQUAL); +//} +// +//void Imp_CorrectPolygonFlag(const sal_uInt32 nInnerIndex, const awt::Point* const pInnerSequence, +// drawing::PolygonFlags* const pInnerFlags, const sal_Int32 nX1, const sal_Int32 nY1) +//{ +// if(nInnerIndex) +// { +// const awt::Point aPPrev1 = pInnerSequence[nInnerIndex - 1]; +// +// if(nInnerIndex > 1) +// { +// const awt::Point aPPrev2 = pInnerSequence[nInnerIndex - 2]; +// const drawing::PolygonFlags aFPrev2 = pInnerFlags[nInnerIndex - 2]; +// ::basegfx::B2DVector aVec1(aPPrev2.X - aPPrev1.X, aPPrev2.Y - aPPrev1.Y); +// ::basegfx::B2DVector aVec2(nX1 - aPPrev1.X, nY1 - aPPrev1.Y); +// bool bSameLength(false); +// bool bSameDirection(false); +// +// // get vector values +// Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection); +// +// if(drawing::PolygonFlags_CONTROL == aFPrev2) +// { +// // point before is a control point +// if(bSameDirection) +// { +// if(bSameLength) +// { +// // set to PolygonFlags_SYMMETRIC +// pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SYMMETRIC; +// } +// else +// { +// // set to PolygonFlags_SMOOTH +// pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH; +// } +// } +// else +// { +// // set to PolygonFlags_NORMAL +// pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL; +// } +// } +// else +// { +// // point before is a simple curve point +// if(bSameDirection) +// { +// // set to PolygonFlags_SMOOTH +// pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH; +// } +// else +// { +// // set to PolygonFlags_NORMAL +// pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL; +// } +// } +// } +// else +// { +// // no point before starpoint, set type to PolygonFlags_NORMAL +// pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL; +// } +// } +//} +// +//SdXMLImExSvgDElement::SdXMLImExSvgDElement(const OUString& rNew, +// const SdXMLImExViewBox& rViewBox, +// const awt::Point& rObjectPos, +// const awt::Size& rObjectSize, +// const SvXMLUnitConverter& rConv) +//: msString( rNew ), +// mrViewBox( rViewBox ), +// mbIsClosed( false ), +// mbIsCurve( false ), +// mnLastX( 0L ), +// mnLastY( 0L ), +// maPoly( 0L ), +// maFlag( 0L ) +//{ +// // convert string to polygon +// const OUString aStr(msString.getStr(), msString.getLength()); +// const sal_Int32 nLen(aStr.getLength()); +// sal_Int32 nPos(0); +// sal_Int32 nNumPolys(0L); +// bool bEllipticalArc(false); +// +// // object size and ViewBox size different? +// bool bScale(rObjectSize.Width != mrViewBox.GetWidth() +// || rObjectSize.Height != mrViewBox.GetHeight()); +// bool bTranslate(mrViewBox.GetX() != 0L || mrViewBox.GetY() != 0L); +// +// // first loop: count polys and get flags +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen) +// { +// switch(aStr[nPos++]) +// { +// case 'Z' : +// case 'z' : +// { +// break; +// } +// case 'M' : +// case 'm' : +// { +// nNumPolys++; +// break; +// } +// case 'S' : +// case 's' : +// case 'C' : +// case 'c' : +// case 'Q' : +// case 'q' : +// case 'T' : +// case 't' : +// { +// mbIsCurve = true; +// break; +// } +// case 'L' : +// case 'l' : +// case 'H' : +// case 'h' : +// case 'V' : +// case 'v' : +// { +// // normal, interpreted values. All okay. +// break; +// } +// case 'A' : +// case 'a' : +// { +// // Not yet interpreted value. +// bEllipticalArc = true; +// break; +// } +// } +// } +// +// DBG_ASSERT(!bEllipticalArc, "XMLIMP: non-interpreted tags in svg:d element!"); +// +// if(nNumPolys) +// { +// // alloc arrays +// maPoly.realloc(nNumPolys); +// if(IsCurve()) +// maFlag.realloc(nNumPolys); +// +// // get outer sequences +// drawing::PointSequence* pOuterSequence = maPoly.getArray(); +// drawing::FlagSequence* pOuterFlags = (IsCurve()) ? maFlag.getArray() : 0L; +// +// // prepare new loop, count +// sal_uInt32 nPointCount(0L); +// nPos = 0; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// // #104076# reset closed flag for next to be started polygon +// mbIsClosed = false; +// +// while(nPos < nLen) +// { +// switch(aStr[nPos]) +// { +// case 'z' : +// case 'Z' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// // #104076# remember closed state of current polygon +// mbIsClosed = true; +// +// break; +// } +// case 'm' : +// case 'M' : +// { +// // new poly starts, end-process current poly +// if(nPointCount) +// { +// // #104076# If this partial polygon is closed, use one more point +// // to represent that +// if(mbIsClosed) +// { +// nPointCount++; +// } +// +// pOuterSequence->realloc(nPointCount); +// pOuterSequence++; +// +// if(pOuterFlags) +// { +// pOuterFlags->realloc(nPointCount); +// pOuterFlags++; +// } +// +// // reset point count for next polygon +// nPointCount = 0L; +// } +// +// // #104076# reset closed flag for next to be started polygon +// mbIsClosed = false; +// +// // NO break, continue in next case +// } +// case 'L' : +// case 'l' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// nPointCount++; +// } +// break; +// } +// case 'H' : +// case 'h' : +// case 'V' : +// case 'v' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// nPointCount++; +// } +// break; +// } +// case 'S' : +// case 's' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// nPointCount += 3; +// } +// break; +// } +// case 'C' : +// case 'c' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// nPointCount += 3; +// } +// break; +// } +// +// // #100617# quadratic beziers, supported as cubic ones +// case 'Q' : +// case 'q' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// +// // use three points since quadratic is imported as cubic +// nPointCount += 3; +// } +// break; +// } +// +// // #100617# relative quadratic beziers, supported as cubic ones +// case 'T' : +// case 't' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// +// // use three points since quadratic is imported as cubic +// nPointCount += 3; +// } +// break; +// } +// +// // #100617# not yet supported: elliptical arc +// case 'A' : +// case 'a' : +// { +// DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (elliptical arc)!"); +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// } +// break; +// } +// +// default: +// { +// nPos++; +// DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (unknown)!"); +// break; +// } +// } +// } +// +// // alloc last poly (when points used) +// if(nPointCount) +// { +// // #104076# If this partial polygon is closed, use one more point +// // to represent that +// if(mbIsClosed) +// { +// nPointCount++; +// } +// +// pOuterSequence->realloc(nPointCount); +// pOuterSequence++; +// +// if(pOuterFlags) +// { +// pOuterFlags->realloc(nPointCount); +// pOuterFlags++; +// } +// } +// +// // set pointers back +// pOuterSequence = maPoly.getArray(); +// pOuterFlags = (IsCurve()) ? maFlag.getArray() : 0L; +// awt::Point* pNotSoInnerSequence = 0L; +// drawing::PolygonFlags* pNotSoInnerFlags = 0L; +// sal_uInt32 nInnerIndex(0L); +// +// // prepare new loop, read points +// nPos = 0; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// // #104076# reset closed flag for next to be started polygon +// mbIsClosed = false; +// +// while(nPos < nLen) +// { +// bool bRelative(false); +// +// switch(aStr[nPos]) +// { +// case 'z' : +// case 'Z' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// // #104076# remember closed state of current polygon +// mbIsClosed = true; +// +// // closed: add first point again +// // sal_Int32 nX(pInnerSequence[0].X); +// // sal_Int32 nY(pInnerSequence[0].Y); +// // Imp_AddExportPoints(nX, nY, pInnerSequence, pInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); +// +// break; +// } +// +// case 'm' : +// { +// bRelative = true; +// } +// case 'M' : +// { +// // #104076# end-process current poly +// if(mbIsClosed) +// { +// if(pNotSoInnerSequence) +// { +// // closed: add first point again +// sal_Int32 nX(pNotSoInnerSequence[0].X); +// sal_Int32 nY(pNotSoInnerSequence[0].Y); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); +// } +// +// // reset closed flag for next to be started polygon +// mbIsClosed = false; +// } +// +// // next poly +// pNotSoInnerSequence = pOuterSequence->getArray(); +// pOuterSequence++; +// +// if(pOuterFlags) +// { +// pNotSoInnerFlags = pOuterFlags->getArray(); +// pOuterFlags++; +// } +// +// nInnerIndex = 0L; +// +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// +// if(bRelative) +// { +// nX += mnLastX; +// nY += mnLastY; +// } +// +// // set last position +// mnLastX = nX; +// mnLastY = nY; +// +// // calc transform and add point and flag +// Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); +// } +// break; +// } +// +// case 'l' : +// { +// bRelative = true; +// } +// case 'L' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// +// if(bRelative) +// { +// nX += mnLastX; +// nY += mnLastY; +// } +// +// // set last position +// mnLastX = nX; +// mnLastY = nY; +// +// // calc transform and add point and flag +// Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); +// } +// break; +// } +// +// case 'h' : +// { +// bRelative = true; +// } +// case 'H' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY(mnLastY); +// +// if(bRelative) +// nX += mnLastX; +// +// // set last position +// mnLastX = nX; +// +// // calc transform and add point and flag +// Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); +// } +// break; +// } +// +// case 'v' : +// { +// bRelative = true; +// } +// case 'V' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// sal_Int32 nX(mnLastX); +// sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// +// if(bRelative) +// nY += mnLastY; +// +// // set last position +// mnLastY = nY; +// +// // calc transform and add point and flag +// Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); +// } +// break; +// } +// +// case 's' : +// { +// bRelative = true; +// } +// case 'S' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// sal_Int32 nX1; +// sal_Int32 nY1; +// sal_Int32 nX2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// +// if(bRelative) +// { +// nX2 += mnLastX; +// nY2 += mnLastY; +// nX += mnLastX; +// nY += mnLastY; +// } +// +// // set last position +// mnLastX = nX; +// mnLastY = nY; +// +// // calc transform for new points +// Imp_PrepareCoorImport(nX2, nY2, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// +// // one more thing is known: the previous real point is PolygonFlags_SYMMETRIC +// // and the Point X1,Y1 can be constructed by mirroring the point before it. +// nX1 = nX2; +// nY1 = nY2; +// if(nInnerIndex) +// { +// awt::Point aPPrev1 = pNotSoInnerSequence[nInnerIndex - 1]; +// +// if(nInnerIndex > 1) +// { +// awt::Point aPPrev2 = pNotSoInnerSequence[nInnerIndex - 2]; +// nX1 = aPPrev1.X -(aPPrev2.X - aPPrev1.X); +// nY1 = aPPrev1.Y -(aPPrev2.Y - aPPrev1.Y); +// } +// +// // set curve point to symmetric +// pNotSoInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SYMMETRIC; +// } +// +// // add calculated control point +// Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); +// +// // add new points and set flags +// Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); +// } +// break; +// } +// +// case 'c' : +// { +// bRelative = true; +// } +// case 'C' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// sal_Int32 nX1(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY1(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nX2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// +// if(bRelative) +// { +// nX1 += mnLastX; +// nY1 += mnLastY; +// nX2 += mnLastX; +// nY2 += mnLastY; +// nX += mnLastX; +// nY += mnLastY; +// } +// +// // set last position +// mnLastX = nX; +// mnLastY = nY; +// +// // calc transform for new points +// Imp_PrepareCoorImport(nX1, nY1, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// Imp_PrepareCoorImport(nX2, nY2, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// +// // correct polygon flag for previous point +// Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1); +// +// // add new points and set flags +// Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); +// Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); +// } +// break; +// } +// +// // #100617# quadratic beziers are imported as cubic +// case 'q' : +// { +// bRelative = true; +// } +// case 'Q' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// sal_Int32 nXX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nYY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// +// if(bRelative) +// { +// nXX += mnLastX; +// nYY += mnLastY; +// nX += mnLastX; +// nY += mnLastY; +// } +// +// // set last position +// mnLastX = nX; +// mnLastY = nY; +// +// // calc transform for new points +// Imp_PrepareCoorImport(nXX, nYY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// +// // calculate X1,X2 +// awt::Point aPPrev1 = (nInnerIndex) ? pNotSoInnerSequence[nInnerIndex-1] : pNotSoInnerSequence[0]; +// sal_Int32 nX1 = FRound((double)((nXX * 2) + aPPrev1.X) / 3.0); +// sal_Int32 nY1 = FRound((double)((nYY * 2) + aPPrev1.Y) / 3.0); +// sal_Int32 nX2 = FRound((double)((nXX * 2) + nX) / 3.0); +// sal_Int32 nY2 = FRound((double)((nYY * 2) + nY) / 3.0); +// +// // correct polygon flag for previous point +// Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1); +// +// // add new points and set flags +// Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); +// Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); +// } +// break; +// } +// +// // #100617# relative quadratic beziers are imported as cubic +// case 't' : +// { +// bRelative = true; +// } +// case 'T' : +// { +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// sal_Int32 nXX; +// sal_Int32 nYY; +// sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); +// +// if(bRelative) +// { +// nX += mnLastX; +// nY += mnLastY; +// } +// +// // set last position +// mnLastX = nX; +// mnLastY = nY; +// +// // calc transform for new points +// Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); +// +// // one more thing is known: the previous real point is PolygonFlags_SYMMETRIC +// // and the Point X1,Y1 can be constructed by mirroring the point before it. +// nXX = nX; +// nYY = nY; +// awt::Point aPPrev1 = pNotSoInnerSequence[0]; +// +// if(nInnerIndex) +// { +// aPPrev1 = pNotSoInnerSequence[nInnerIndex - 1]; +// +// if(nInnerIndex > 1) +// { +// awt::Point aPPrev2 = pNotSoInnerSequence[nInnerIndex - 2]; +// nXX = aPPrev1.X -(aPPrev2.X - aPPrev1.X); +// nYY = aPPrev1.Y -(aPPrev2.Y - aPPrev1.Y); +// } +// +// // set curve point to smooth here, since length +// // is changed and thus only c1 can be used. +// pNotSoInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH; +// } +// +// // calculate X1,X2 +// sal_Int32 nX1 = FRound((double)((nXX * 2) + aPPrev1.X) / 3.0); +// sal_Int32 nY1 = FRound((double)((nYY * 2) + aPPrev1.Y) / 3.0); +// sal_Int32 nX2 = FRound((double)((nXX * 2) + nX) / 3.0); +// sal_Int32 nY2 = FRound((double)((nYY * 2) + nY) / 3.0); +// +// // correct polygon flag for previous point +// Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1); +// +// // add new points and set flags +// Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); +// Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); +// } +// break; +// } +// +// // #100617# not yet supported: elliptical arc +// case 'A' : +// case 'a' : +// { +// DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (elliptical arc)!"); +// nPos++; +// Imp_SkipSpaces(aStr, nPos, nLen); +// +// while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) +// { +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); +// } +// break; +// } +// +// default: +// { +// nPos++; +// DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (unknown)!"); +// break; +// } +// } +// } +// +// // #104076# end-process closed state of last poly +// if(mbIsClosed) +// { +// if(pNotSoInnerSequence) +// { +// // closed: add first point again +// sal_Int32 nX(pNotSoInnerSequence[0].X); +// sal_Int32 nY(pNotSoInnerSequence[0].Y); +// Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); +// } +// } +// +// // #87202# If it's a curve and it's closed the last point maybe too much +// // and just exported since SVG does not allow special handling of same +// // start and end point, remove this last point. +// // Evtl. correct the last curve flags, too. +// if(IsCurve() && IsClosed()) +// { +// // make one more loop over the PolyPolygon +// pOuterSequence = maPoly.getArray(); +// pOuterFlags = maFlag.getArray(); +// sal_Int32 nOuterCnt(maPoly.getLength()); +// +// for(sal_Int32 a(0); a < nOuterCnt; a++) +// { +// // get Polygon pointers +// awt::Point* pInnerSequence = pOuterSequence->getArray(); +// drawing::PolygonFlags* pInnerFlags = pOuterFlags->getArray(); +// sal_Int32 nInnerCnt(pOuterSequence->getLength()); +// +// while( nInnerCnt >= 2 +// && ((pInnerSequence + (nInnerCnt - 2))->X == (pInnerSequence + (nInnerCnt - 1))->X) +// && ((pInnerSequence + (nInnerCnt - 2))->Y == (pInnerSequence + (nInnerCnt - 1))->Y) +// && drawing::PolygonFlags_CONTROL != *(pInnerFlags + (nInnerCnt - 2))) +// { +// // remove last point from array +// pOuterSequence->realloc(nInnerCnt - 1); +// pOuterFlags->realloc(nInnerCnt - 1); +// +// // get new pointers +// pInnerSequence = pOuterSequence->getArray(); +// pInnerFlags = pOuterFlags->getArray(); +// nInnerCnt = pOuterSequence->getLength(); +// } +// +// // now evtl. correct the last curve flags +// if(nInnerCnt >= 4) +// { +// if( pInnerSequence->X == (pInnerSequence + (nInnerCnt - 1))->X +// && pInnerSequence->Y == (pInnerSequence + (nInnerCnt - 1))->Y +// && drawing::PolygonFlags_CONTROL == *(pInnerFlags + 1) +// && drawing::PolygonFlags_CONTROL == *(pInnerFlags + (nInnerCnt - 2))) +// { +// awt::Point aPrev = *(pInnerSequence + (nInnerCnt - 2)); +// awt::Point aCurr = *pInnerSequence; +// awt::Point aNext = *(pInnerSequence + 1); +// ::basegfx::B2DVector aVec1(aPrev.X - aCurr.X, aPrev.Y - aCurr.Y); +// ::basegfx::B2DVector aVec2(aNext.X - aCurr.X, aNext.Y - aCurr.Y); +// bool bSameLength(false); +// bool bSameDirection(false); +// +// // get vector values +// Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection); +// +// // set correct flag value +// if(bSameDirection) +// { +// if(bSameLength) +// { +// // set to PolygonFlags_SYMMETRIC +// *pInnerFlags = drawing::PolygonFlags_SYMMETRIC; +// *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_SYMMETRIC; +// } +// else +// { +// // set to PolygonFlags_SMOOTH +// *pInnerFlags = drawing::PolygonFlags_SMOOTH; +// *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_SMOOTH; +// } +// } +// else +// { +// // set to PolygonFlags_NORMAL +// *pInnerFlags = drawing::PolygonFlags_NORMAL; +// *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_NORMAL; +// } +// } +// } +// +// // switch to next Polygon +// pOuterSequence++; +// pOuterFlags++; +// } +// } +// } +//} // eof diff --git a/xmloff/source/draw/ximp3dobject.cxx b/xmloff/source/draw/ximp3dobject.cxx index d4a17da6b37f..e350cb0b1888 100644 --- a/xmloff/source/draw/ximp3dobject.cxx +++ b/xmloff/source/draw/ximp3dobject.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" + #include <comphelper/extract.hxx> #include "ximp3dobject.hxx" #include <xmloff/XMLShapeStyleContext.hxx> @@ -37,6 +36,9 @@ #include <xmloff/xmltoken.hxx> #include <com/sun/star/drawing/PolyPolygonShape3D.hpp> #include <com/sun/star/drawing/DoubleSequence.hpp> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b3dpolypolygontools.hxx> using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -440,62 +442,92 @@ SdXML3DPolygonBasedShapeContext::~SdXML3DPolygonBasedShapeContext() void SdXML3DPolygonBasedShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList) { uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY); + if(xPropSet.is()) { // set parameters if(maPoints.getLength() && maViewBox.getLength()) { - SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter()); - awt::Point aMinPoint(aViewBox.GetX(), aViewBox.GetY()); - awt::Size aMaxSize(aViewBox.GetWidth(), aViewBox.GetHeight()); - SdXMLImExSvgDElement aPoints(maPoints, aViewBox, - aMinPoint, aMaxSize, GetImport().GetMM100UnitConverter()); - - // convert to double sequences - drawing::PointSequenceSequence& xPoSeSe = - (drawing::PointSequenceSequence&)aPoints.GetPointSequenceSequence(); - sal_Int32 nOuterSequenceCount = xPoSeSe.getLength(); - drawing::PointSequence* pInnerSequence = xPoSeSe.getArray(); - - drawing::PolyPolygonShape3D xPolyPolygon3D; - xPolyPolygon3D.SequenceX.realloc(nOuterSequenceCount); - xPolyPolygon3D.SequenceY.realloc(nOuterSequenceCount); - xPolyPolygon3D.SequenceZ.realloc(nOuterSequenceCount); - drawing::DoubleSequence* pOuterSequenceX = xPolyPolygon3D.SequenceX.getArray(); - drawing::DoubleSequence* pOuterSequenceY = xPolyPolygon3D.SequenceY.getArray(); - drawing::DoubleSequence* pOuterSequenceZ = xPolyPolygon3D.SequenceZ.getArray(); - - for(sal_Int32 a(0L); a < nOuterSequenceCount; a++) - { - sal_Int32 nInnerSequenceCount(pInnerSequence->getLength()); - awt::Point* pArray = pInnerSequence->getArray(); - - pOuterSequenceX->realloc(nInnerSequenceCount); - pOuterSequenceY->realloc(nInnerSequenceCount); - pOuterSequenceZ->realloc(nInnerSequenceCount); - double* pInnerSequenceX = pOuterSequenceX->getArray(); - double* pInnerSequenceY = pOuterSequenceY->getArray(); - double* pInnerSequenceZ = pOuterSequenceZ->getArray(); + // import 2d PolyPolygon from svg:d + basegfx::B2DPolyPolygon aPolyPolygon; - for(sal_Int32 b(0L); b < nInnerSequenceCount; b++) - { - *pInnerSequenceX++ = pArray->X; - *pInnerSequenceY++ = pArray->Y; - *pInnerSequenceZ++ = 0.0; - pArray++; - } - pInnerSequence++; - - pOuterSequenceX++; - pOuterSequenceY++; - pOuterSequenceZ++; + if(basegfx::tools::importFromSvgD( + aPolyPolygon, + maPoints)) + { + // convert to 3D PolyPolygon + const basegfx::B3DPolyPolygon aB3DPolyPolygon( + basegfx::tools::createB3DPolyPolygonFromB2DPolyPolygon( + aPolyPolygon)); + + // convert to UNO API class PolyPolygonShape3D + drawing::PolyPolygonShape3D xPolyPolygon3D; + basegfx::tools::B3DPolyPolygonToUnoPolyPolygonShape3D( + aB3DPolyPolygon, + xPolyPolygon3D); + + // set polygon data + uno::Any aAny; + aAny <<= xPolyPolygon3D; + xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPolyPolygon3D")), aAny); + } + else + { + OSL_ENSURE(false, "Error on importing svg:d for 3D PolyPolygon (!)"); } - // set poly - uno::Any aAny; - aAny <<= xPolyPolygon3D; - xPropSet->setPropertyValue( - OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPolyPolygon3D")), aAny); + // TTTT + //SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter()); + //awt::Point aMinPoint(aViewBox.GetX(), aViewBox.GetY()); + //awt::Size aMaxSize(aViewBox.GetWidth(), aViewBox.GetHeight()); + //SdXMLImExSvgDElement aPoints(maPoints, aViewBox, + // aMinPoint, aMaxSize, GetImport().GetMM100UnitConverter()); + // + //// convert to double sequences + //drawing::PointSequenceSequence& xPoSeSe = + // (drawing::PointSequenceSequence&)aPoints.GetPointSequenceSequence(); + //sal_Int32 nOuterSequenceCount = xPoSeSe.getLength(); + //drawing::PointSequence* pInnerSequence = xPoSeSe.getArray(); + // + //drawing::PolyPolygonShape3D xPolyPolygon3D; + //xPolyPolygon3D.SequenceX.realloc(nOuterSequenceCount); + //xPolyPolygon3D.SequenceY.realloc(nOuterSequenceCount); + //xPolyPolygon3D.SequenceZ.realloc(nOuterSequenceCount); + //drawing::DoubleSequence* pOuterSequenceX = xPolyPolygon3D.SequenceX.getArray(); + //drawing::DoubleSequence* pOuterSequenceY = xPolyPolygon3D.SequenceY.getArray(); + //drawing::DoubleSequence* pOuterSequenceZ = xPolyPolygon3D.SequenceZ.getArray(); + // + //for(sal_Int32 a(0L); a < nOuterSequenceCount; a++) + //{ + // sal_Int32 nInnerSequenceCount(pInnerSequence->getLength()); + // awt::Point* pArray = pInnerSequence->getArray(); + // + // pOuterSequenceX->realloc(nInnerSequenceCount); + // pOuterSequenceY->realloc(nInnerSequenceCount); + // pOuterSequenceZ->realloc(nInnerSequenceCount); + // double* pInnerSequenceX = pOuterSequenceX->getArray(); + // double* pInnerSequenceY = pOuterSequenceY->getArray(); + // double* pInnerSequenceZ = pOuterSequenceZ->getArray(); + // + // for(sal_Int32 b(0L); b < nInnerSequenceCount; b++) + // { + // *pInnerSequenceX++ = pArray->X; + // *pInnerSequenceY++ = pArray->Y; + // *pInnerSequenceZ++ = 0.0; + // pArray++; + // } + // pInnerSequence++; + // + // pOuterSequenceX++; + // pOuterSequenceY++; + // pOuterSequenceZ++; + //} + // + //// set poly + //uno::Any aAny; + //aAny <<= xPolyPolygon3D; + //xPropSet->setPropertyValue( + // OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPolyPolygon3D")), aAny); } // call parent diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx index 5ef6d2067435..a5b646108c35 100644 --- a/xmloff/source/draw/ximpshap.cxx +++ b/xmloff/source/draw/ximpshap.cxx @@ -84,6 +84,9 @@ #include <memory.h> #include <basegfx/vector/b2dvector.hxx> #include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -1297,20 +1300,55 @@ void SdXMLPolygonShapeContext::StartElement(const uno::Reference< xml::sax::XAtt // set polygon if(maPoints.getLength() && maViewBox.getLength()) { - SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter()); - awt::Size aSize(aViewBox.GetWidth(), aViewBox.GetHeight()); - if (maSize.Width != 0 && maSize.Height !=0) + const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter()); + basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight()); + + // TTTT: Is this correct? It overrides ViewBox stuff; OTOH it makes no + // sense to have the geometry content size different from object size + if(maSize.Width != 0 && maSize.Height !=0) { - aSize = maSize; + aSize.setX(maSize.Width); + aSize.setY(maSize.Height); } - awt::Point aPosition(aViewBox.GetX(), aViewBox.GetY()); - SdXMLImExPointsElement aPoints(maPoints, aViewBox, - aPosition, aSize, GetImport().GetMM100UnitConverter(), mbClosed); - uno::Any aAny; - aAny <<= aPoints.GetPointSequenceSequence(); - xPropSet->setPropertyValue( - OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny); + basegfx::B2DPolygon aPolygon; + + if(basegfx::tools::importFromSvgPoints(aPolygon, maPoints)) + { + if(aPolygon.count()) + { + const basegfx::B2DRange aSourceRange( + aViewBox.GetX(), aViewBox.GetY(), + aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight()); + const basegfx::B2DRange aTargetRange( + aViewBox.GetX(), aViewBox.GetY(), + aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY()); + + if(!aSourceRange.equal(aTargetRange)) + { + aPolygon.transform( + basegfx::tools::createSourceRangeTargetRangeTransform( + aSourceRange, + aTargetRange)); + } + + com::sun::star::drawing::PointSequenceSequence aPointSequenceSequence; + uno::Any aAny; + + basegfx::tools::B2DPolyPolygonToUnoPointSequenceSequence(basegfx::B2DPolyPolygon(aPolygon), aPointSequenceSequence); + aAny <<= aPointSequenceSequence; + xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny); + } + } + + //awt::Point aPosition(aViewBox.GetX(), aViewBox.GetY()); + //SdXMLImExPointsElement aPoints(maPoints, aViewBox, + // aPosition, aSize, GetImport().GetMM100UnitConverter(), mbClosed); + // + //uno::Any aAny; + //aAny <<= aPoints.GetPointSequenceSequence(); + //xPropSet->setPropertyValue( + // OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny); } } @@ -1371,86 +1409,192 @@ void SdXMLPathShapeContext::StartElement(const uno::Reference< xml::sax::XAttrib // create polygon shape if(maD.getLength()) { - // prepare some of the parameters - SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter()); - awt::Size aSize(aViewBox.GetWidth(), aViewBox.GetHeight()); - awt::Point aPosition(aViewBox.GetX(), aViewBox.GetY()); - if (maSize.Width != 0 && maSize.Height !=0) - { - aSize = maSize; - } - SdXMLImExSvgDElement aPoints(maD, aViewBox, - aPosition, aSize, GetImport().GetMM100UnitConverter()); + const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter()); + basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight()); - const char* pService; - // now create shape - if(aPoints.IsCurve()) - { - if(aPoints.IsClosed()) - { - pService = "com.sun.star.drawing.ClosedBezierShape"; - } - else - { - pService = "com.sun.star.drawing.OpenBezierShape"; - } - } - else + // TTTT: Is this correct? It overrides ViewBox stuff; OTOH it makes no + // sense to have the geometry content size different from object size + if(maSize.Width != 0 && maSize.Height !=0) { - if(aPoints.IsClosed()) - { - pService = "com.sun.star.drawing.PolyPolygonShape"; - } - else - { - pService = "com.sun.star.drawing.PolyLineShape"; - } + aSize.setX(maSize.Width); + aSize.setY(maSize.Height); } - // Add, set Style and properties from base shape - AddShape(pService); + basegfx::B2DPolyPolygon aPolyPolygon; - // #89344# test for mxShape.is() and not for mxShapes.is() to support - // shape import helper classes WITHOUT XShapes (member mxShapes). This - // is used by the writer. - if( mxShape.is() ) + if(basegfx::tools::importFromSvgD(aPolyPolygon, maD)) { - SetStyle(); - SetLayer(); - - // set local parameters on shape - uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY); - if(xPropSet.is()) + if(aPolyPolygon.count()) { - uno::Any aAny; + const basegfx::B2DRange aSourceRange( + aViewBox.GetX(), aViewBox.GetY(), + aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight()); + const basegfx::B2DRange aTargetRange( + aViewBox.GetX(), aViewBox.GetY(), + aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY()); - // set svg:d - if(maD.getLength()) + if(!aSourceRange.equal(aTargetRange)) { - if(aPoints.IsCurve()) - { - drawing::PolyPolygonBezierCoords aSourcePolyPolygon( - aPoints.GetPointSequenceSequence(), - aPoints.GetFlagSequenceSequence()); + aPolyPolygon.transform( + basegfx::tools::createSourceRangeTargetRangeTransform( + aSourceRange, + aTargetRange)); + } + + // create shape + const char* pService; - aAny <<= aSourcePolyPolygon; - xPropSet->setPropertyValue( - OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny); + if(aPolyPolygon.areControlPointsUsed()) + { + if(aPolyPolygon.isClosed()) + { + pService = "com.sun.star.drawing.ClosedBezierShape"; } else { - aAny <<= aPoints.GetPointSequenceSequence(); - xPropSet->setPropertyValue( - OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny); + pService = "com.sun.star.drawing.OpenBezierShape"; + } + } + else + { + if(aPolyPolygon.isClosed()) + { + pService = "com.sun.star.drawing.PolyPolygonShape"; + } + else + { + pService = "com.sun.star.drawing.PolyLineShape"; } } - } - // set pos, size, shear and rotate - SetTransformation(); + // #89344# test for mxShape.is() and not for mxShapes.is() to support + // shape import helper classes WITHOUT XShapes (member mxShapes). This + // is used by the writer. + if( mxShape.is() ) + { + SetStyle(); + SetLayer(); - SdXMLShapeContext::StartElement(xAttrList); + // set local parameters on shape + uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY); + + if(xPropSet.is()) + { + uno::Any aAny; + + // set polygon data + if(aPolyPolygon.areControlPointsUsed()) + { + drawing::PolyPolygonBezierCoords aSourcePolyPolygon; + + basegfx::tools::B2DPolyPolygonToUnoPolyPolygonBezierCoords( + aPolyPolygon, + aSourcePolyPolygon); + aAny <<= aSourcePolyPolygon; + } + else + { + drawing::PointSequenceSequence aSourcePolyPolygon; + + basegfx::tools::B2DPolyPolygonToUnoPointSequenceSequence( + aPolyPolygon, + aSourcePolyPolygon); + aAny <<= aSourcePolyPolygon; + } + + xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny); + } + + // set pos, size, shear and rotate + SetTransformation(); + + SdXMLShapeContext::StartElement(xAttrList); + } + } } + + // TTTT + //// prepare some of the parameters + //SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter()); + //awt::Size aSize(aViewBox.GetWidth(), aViewBox.GetHeight()); + //awt::Point aPosition(aViewBox.GetX(), aViewBox.GetY()); + //if (maSize.Width != 0 && maSize.Height !=0) + //{ + // aSize = maSize; + //} + // + //SdXMLImExSvgDElement aPoints(maD, aViewBox, + // aPosition, aSize, GetImport().GetMM100UnitConverter()); + // + //const char* pService; + //// now create shape + //if(aPoints.IsCurve()) + //{ + // if(aPoints.IsClosed()) + // { + // pService = "com.sun.star.drawing.ClosedBezierShape"; + // } + // else + // { + // pService = "com.sun.star.drawing.OpenBezierShape"; + // } + //} + //else + //{ + // if(aPoints.IsClosed()) + // { + // pService = "com.sun.star.drawing.PolyPolygonShape"; + // } + // else + // { + // pService = "com.sun.star.drawing.PolyLineShape"; + // } + //} + // + //// Add, set Style and properties from base shape + //AddShape(pService); + // + //// #89344# test for mxShape.is() and not for mxShapes.is() to support + //// shape import helper classes WITHOUT XShapes (member mxShapes). This + //// is used by the writer. + //if( mxShape.is() ) + //{ + // SetStyle(); + // SetLayer(); + // + // // set local parameters on shape + // uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY); + // if(xPropSet.is()) + // { + // uno::Any aAny; + // + // // set svg:d + // if(maD.getLength()) + // { + // if(aPoints.IsCurve()) + // { + // drawing::PolyPolygonBezierCoords aSourcePolyPolygon( + // aPoints.GetPointSequenceSequence(), + // aPoints.GetFlagSequenceSequence()); + // + // aAny <<= aSourcePolyPolygon; + // xPropSet->setPropertyValue( + // OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny); + // } + // else + // { + // aAny <<= aPoints.GetPointSequenceSequence(); + // xPropSet->setPropertyValue( + // OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry")), aAny); + // } + // } + // } + // + // // set pos, size, shear and rotate + // SetTransformation(); + // + // SdXMLShapeContext::StartElement(xAttrList); + //} } } @@ -1808,32 +1952,61 @@ void SdXMLConnectorShapeContext::processAttribute( sal_uInt16 nPrefix, const ::r } if( IsXMLToken( rLocalName, XML_D ) ) { - SdXMLImExViewBox aViewBox( 0, 0, 1, 1 ); - awt::Point aPoint( 0, 0 ); - awt::Size aSize( 1, 1 ); - - SdXMLImExSvgDElement aPoints( rValue, aViewBox, - aPoint, aSize, GetImport().GetMM100UnitConverter() ); + basegfx::B2DPolyPolygon aPolyPolygon; - if ( aPoints.IsCurve() ) - { - drawing::PolyPolygonBezierCoords aSourcePolyPolygon( - aPoints.GetPointSequenceSequence(), - aPoints.GetFlagSequenceSequence()); - maPath <<= aSourcePolyPolygon; - } - else + if(basegfx::tools::importFromSvgD(aPolyPolygon, rValue)) { - const drawing::PointSequenceSequence& rOuterSeq = aPoints.GetPointSequenceSequence(); - drawing::FlagSequenceSequence aFlagSeqSeq( rOuterSeq.getLength() ); - for ( int a = 0; a < rOuterSeq.getLength(); a++ ) - aFlagSeqSeq[ a ] = drawing::FlagSequence( rOuterSeq[ a ].getLength() ); + if(aPolyPolygon.count()) + { + // set polygon data + if(aPolyPolygon.areControlPointsUsed()) + { + drawing::PolyPolygonBezierCoords aSourcePolyPolygon; - drawing::PolyPolygonBezierCoords aSourcePolyPolygon( - aPoints.GetPointSequenceSequence(), - aFlagSeqSeq ); - maPath <<= aSourcePolyPolygon; + basegfx::tools::B2DPolyPolygonToUnoPolyPolygonBezierCoords( + aPolyPolygon, + aSourcePolyPolygon); + maPath <<= aSourcePolyPolygon; + } + else + { + drawing::PointSequenceSequence aSourcePolyPolygon; + + basegfx::tools::B2DPolyPolygonToUnoPointSequenceSequence( + aPolyPolygon, + aSourcePolyPolygon); + maPath <<= aSourcePolyPolygon; + } + } } + + // TTTT + //SdXMLImExViewBox aViewBox( 0.0, 0.0, 1.0, 1.0 ); + //awt::Point aPoint( 0, 0 ); + //awt::Size aSize( 1, 1 ); + // + //SdXMLImExSvgDElement aPoints( rValue, aViewBox, + // aPoint, aSize, GetImport().GetMM100UnitConverter() ); + // + //if ( aPoints.IsCurve() ) + //{ + // drawing::PolyPolygonBezierCoords aSourcePolyPolygon( + // aPoints.GetPointSequenceSequence(), + // aPoints.GetFlagSequenceSequence()); + // maPath <<= aSourcePolyPolygon; + //} + //else + //{ + // const drawing::PointSequenceSequence& rOuterSeq = aPoints.GetPointSequenceSequence(); + // drawing::FlagSequenceSequence aFlagSeqSeq( rOuterSeq.getLength() ); + // for ( int a = 0; a < rOuterSeq.getLength(); a++ ) + // aFlagSeqSeq[ a ] = drawing::FlagSequence( rOuterSeq[ a ].getLength() ); + // + // drawing::PolyPolygonBezierCoords aSourcePolyPolygon( + // aPoints.GetPointSequenceSequence(), + // aFlagSeqSeq ); + // maPath <<= aSourcePolyPolygon; + //} } } } |