summaryrefslogtreecommitdiff
path: root/xmloff
diff options
context:
space:
mode:
authorThorsten Behrens <tbehrens@novell.com>2011-06-21 09:11:28 +0200
committerFridrich Štrba <fridrich.strba@bluewin.ch>2011-06-22 12:55:16 +0200
commitb036162d609b01e7b27e0eafc09cbd0192d95200 (patch)
tree6fe364b210c7a87fa753c101824594084a026be4 /xmloff
parent4f314412dee35856ae70a8331047f7c54e07073b (diff)
Teach LibreOffice proper svg:d support
Diffstat (limited to 'xmloff')
-rw-r--r--xmloff/inc/xexptran.hxx12
-rw-r--r--xmloff/source/draw/xexptran.cxx990
2 files changed, 48 insertions, 954 deletions
diff --git a/xmloff/inc/xexptran.hxx b/xmloff/inc/xexptran.hxx
index bd2c55d6557e..5fbd83500be6 100644
--- a/xmloff/inc/xexptran.hxx
+++ b/xmloff/inc/xexptran.hxx
@@ -30,11 +30,10 @@
#define _XEXPTRANSFORM_HXX
#include <rtl/ustring.hxx>
-#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
#include <com/sun/star/drawing/PointSequence.hpp>
-#include <com/sun/star/awt/Size.hpp>
-#include <com/sun/star/drawing/FlagSequenceSequence.hpp>
#include <com/sun/star/drawing/FlagSequence.hpp>
+#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/drawing/HomogenMatrix.hpp>
#include <tools/mapunit.hxx>
@@ -173,8 +172,7 @@ class SdXMLImExSvgDElement
sal_Int32 mnLastX;
sal_Int32 mnLastY;
- com::sun::star::drawing::PointSequenceSequence maPoly;
- com::sun::star::drawing::FlagSequenceSequence maFlag;
+ com::sun::star::drawing::PolyPolygonBezierCoords maPoly;
public:
SdXMLImExSvgDElement(const SdXMLImExViewBox& rViewBox);
@@ -194,8 +192,8 @@ public:
const rtl::OUString& GetExportString() const { return msString; }
bool IsClosed() const { return mbIsClosed; }
bool IsCurve() const { return mbIsCurve; }
- const com::sun::star::drawing::PointSequenceSequence& GetPointSequenceSequence() const { return maPoly; }
- const com::sun::star::drawing::FlagSequenceSequence& GetFlagSequenceSequence() const { return maFlag; }
+ const com::sun::star::drawing::PointSequenceSequence& GetPointSequenceSequence() const { return maPoly.Coordinates; }
+ const com::sun::star::drawing::FlagSequenceSequence& GetFlagSequenceSequence() const { return maPoly.Flags; }
};
diff --git a/xmloff/source/draw/xexptran.cxx b/xmloff/source/draw/xexptran.cxx
index 0834ea1218ec..a36e8e703f82 100644
--- a/xmloff/source/draw/xexptran.cxx
+++ b/xmloff/source/draw/xexptran.cxx
@@ -37,6 +37,9 @@
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/tuple/b3dtuple.hxx>
#include <basegfx/matrix/b3dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/tools/unotools.hxx>
#include <tools/string.hxx>
using ::rtl::OUString;
@@ -53,7 +56,19 @@ using namespace ::com::sun::star;
// Predeclarations
void Imp_SkipDouble(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen);
-void Imp_CalcVectorValues(::basegfx::B2DVector& aVec1, ::basegfx::B2DVector& aVec2, bool& bSameLength, bool& bSameDirection);
+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);
+}
+
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -1520,8 +1535,7 @@ SdXMLImExSvgDElement::SdXMLImExSvgDElement(const SdXMLImExViewBox& rViewBox)
mbIsCurve( false ),
mnLastX( 0L ),
mnLastY( 0L ),
- maPoly( 0L ),
- maFlag( 0L )
+ maPoly()
{
}
@@ -1583,6 +1597,8 @@ void SdXMLImExSvgDElement::AddPolygon(
const awt::Size& rObjectSize,
bool bClosed, bool bRelative)
{
+ // Leaving the export stuff for the while, should eventually also
+ // consolidated with basegfx svg support
DBG_ASSERT(pPoints, "Empty PointSequence handed over to SdXMLImExSvgDElement(!)");
sal_Int32 nCnt(pPoints->getLength());
@@ -2151,964 +2167,44 @@ void SdXMLImExSvgDElement::AddPolygon(
}
}
-// #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)
+ const SvXMLUnitConverter& /*rConv*/)
: msString( rNew ),
mrViewBox( rViewBox ),
mbIsClosed( false ),
mbIsCurve( false ),
mnLastX( 0L ),
mnLastY( 0L ),
- maPoly( 0L ),
- maFlag( 0L )
+ maPoly()
{
// 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!");
- (void)bEllipticalArc;
-
- 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' :
- {
- OSL_FAIL("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++;
- OSL_FAIL("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;
-
- 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;
- }
+ basegfx::B2DPolyPolygon aPoly;
+ basegfx::tools::importFromSvgD(aPoly,msString);
- 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);
+ mbIsCurve = aPoly.areControlPointsUsed();
+ mbIsClosed = aPoly.isClosed();
- 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' :
- {
- OSL_FAIL("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++;
- OSL_FAIL("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++;
- }
- }
- }
+ // object size and ViewBox size different?
+ basegfx::B2DHomMatrix aTransform;
+ const bool bScale(rObjectSize.Width != mrViewBox.GetWidth()
+ || rObjectSize.Height != mrViewBox.GetHeight());
+ const bool bTranslate(mrViewBox.GetX() != 0L || mrViewBox.GetY() != 0L);
+
+ if( bTranslate )
+ aTransform.translate(
+ -mrViewBox.GetX(),
+ -mrViewBox.GetY());
+ if( bScale )
+ aTransform.scale(
+ rObjectSize.Width / mrViewBox.GetWidth(),
+ rObjectSize.Height / mrViewBox.GetHeight());
+ aTransform.translate( rObjectPos.X, rObjectPos.Y );
+ aPoly.transform(aTransform);
+
+ basegfx::unotools::b2DPolyPolygonToPolyPolygonBezier(aPoly,maPoly);
}
// eof