diff options
author | Armin Le Grand <alg@apache.org> | 2013-08-01 16:14:31 +0000 |
---|---|---|
committer | Armin Le Grand <alg@apache.org> | 2013-08-01 16:14:31 +0000 |
commit | 269719ba0422aaf8f49cf3d579972ef2070716be (patch) | |
tree | 1324a224eb65ad2e8818dea2d0f2a7b24dd1d808 | |
parent | 8a6f84ce896f41a7a1f97b06d1e053c51cbba95e (diff) |
commit to safe ongoing work
40 files changed, 3852 insertions, 4269 deletions
diff --git a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx index d66803644c90..b718896313e8 100644 --- a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx +++ b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx @@ -29,6 +29,7 @@ #include <basegfx/vector/b2dvector.hxx> #include <com/sun/star/drawing/HomogenMatrix3.hpp> #include <basegfx/point/b2dpoint.hxx> +#include <basegfx/range/b2drange.hxx> namespace rtl { class OUString; } @@ -160,6 +161,11 @@ namespace basegfx fRadiant); } + /// special for the case to map from source range to target range + B2DHomMatrix createSourceRangeTargetRangeTransform( + const B2DRange& rSourceRange, + const B2DRange& rTargetRange); + /* tooling methods for converting API matrices (drawing::HomogenMatrix3) to B2DHomMatrix */ @@ -387,9 +393,6 @@ namespace basegfx }; } // end of namespace tools - /// Returns a string with svg's "matrix(m00,m10,m01,m11,m02,m12)" representation - ::rtl::OUString exportToSvg( const B2DHomMatrix& rMatrix ); - } // end of namespace basegfx /////////////////////////////////////////////////////////////////////////////// diff --git a/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx b/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx index 99a7423f41bc..c1470fc8c281 100644 --- a/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx +++ b/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx @@ -549,6 +549,38 @@ namespace basegfx com::sun::star::drawing::PointSequence& rPointSequenceRetval, com::sun::star::drawing::FlagSequence& rFlagSequenceRetval); + /** Read poly-polygon from SVG. + + This function imports a poly-polygon from an SVG points + attribute (a plain list of coordinate pairs). + + @param o_rPoly + The output polygon. Note that svg:points can only define a + single polygon + + @param rSvgPointsAttribute + A valid SVG points attribute string + + @return true, if the string was successfully parsed + */ + bool importFromSvgPoints( B2DPolygon& o_rPoly, + const ::rtl::OUString& rSvgPointsAttribute ); + + /** Write poly-polygon to SVG. + + This function imports a non-bezier polygon to SVG points + (a plain list of coordinate pairs). + + @param rPoly + The polygon to export + + @param rSvgPointsAttribute + A valid SVG points attribute string + + @return true, if the string was successfully parsed + */ + ::rtl::OUString exportToSvgPoints( const B2DPolygon& rPoly ); + } // end of namespace tools } // end of namespace basegfx diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx index c9cb8b3a7d88..5b1b20479cdd 100644 --- a/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx +++ b/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx @@ -139,23 +139,32 @@ namespace basegfx bool importFromSvgD( B2DPolyPolygon& o_rPolyPoly, const ::rtl::OUString& rSvgDAttribute ); - /** Read poly-polygon from SVG. + /** Export poly-polygon to SVG. - This function imports a poly-polygon from an SVG points - attribute (a plain list of coordinate pairs). + This function exports a poly-polygon into an SVG-D + statement. Currently, output of relative point sequences + is not yet supported (might cause slightly larger output) - @param o_rPoly - The output polygon. Note that svg:points can only define a - single polygon + @param rPolyPoly + The poly-polygon to export - @param rSvgPointsAttribute - A valid SVG points attribute string + @param bUseRelativeCoordinates + When true, all coordinate values are exported as relative + to the current position. This tends to save some space, + since fewer digits needs to be written. - @return true, if the string was successfully parsed - */ - bool importFromSvgPoints( B2DPolygon& o_rPoly, - const ::rtl::OUString& rSvgPointsAttribute ); + @param bDetectQuadraticBeziers + When true, the export tries to detect cubic bezier + segments in the input polygon, which can be represented by + quadratic bezier segments. Note that the generated string + causes versions prior to OOo2.0 to crash. + @return the generated SVG-D statement (the XML d attribute + value alone, without any "<path ...>" or "d="...") + */ + ::rtl::OUString exportToSvgD( const B2DPolyPolygon& rPolyPoly, + bool bUseRelativeCoordinates=true, + bool bDetectQuadraticBeziers=true ); // grow for polyPolygon. Move all geometry in each point in the direction of the normal in that point // with the given amount. Value may be negative. @@ -214,33 +223,6 @@ namespace basegfx */ bool isRectangle( const B2DPolyPolygon& rPoly ); - /** Export poly-polygon to SVG. - - This function exports a poly-polygon into an SVG-D - statement. Currently, output of relative point sequences - is not yet supported (might cause slightly larger output) - - @param rPolyPoly - The poly-polygon to export - - @param bUseRelativeCoordinates - When true, all coordinate values are exported as relative - to the current position. This tends to save some space, - since fewer digits needs to be written. - - @param bDetectQuadraticBeziers - When true, the export tries to detect cubic bezier - segments in the input polygon, which can be represented by - quadratic bezier segments. Note that the generated string - causes versions prior to OOo2.0 to crash. - - @return the generated SVG-D statement (the XML d attribute - value alone, without any "<path ...>" or "d="...") - */ - ::rtl::OUString exportToSvgD( const B2DPolyPolygon& rPolyPoly, - bool bUseRelativeCoordinates=true, - bool bDetectQuadraticBeziers=true ); - // #i76891# Try to remove existing curve segments if they are simply edges B2DPolyPolygon simplifyCurveSegments(const B2DPolyPolygon& rCandidate); diff --git a/basegfx/source/inc/PolygonPoint.hxx b/basegfx/source/inc/PolygonPoint.hxx deleted file mode 100644 index e251302cd8ce..000000000000 --- a/basegfx/source/inc/PolygonPoint.hxx +++ /dev/null @@ -1,534 +0,0 @@ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ - - - -#ifndef _POLYGON_POINT_HXX -#define _POLYGON_POINT_HXX - -#include <vector> - -////////////////////////////////////////////////////////////////////////////// - -template < class Point > class SimplePointEntry -{ - Point maPoint; - -public: - SimplePointEntry() - : maPoint(Point::getEmptyPoint()) - { - } - - SimplePointEntry(const Point& rInitPoint) - : maPoint(rInitPoint) - { - } - - const Point& getPoint() const - { - return maPoint; - } - - void setPoint(const Point& rValue) - { - maPoint = rValue; - } - - bool operator==(const SimplePointEntry& rEntry) const - { - return (maPoint == rEntry.maPoint); - } -}; - -////////////////////////////////////////////////////////////////////////////// - -template < class Vector > class SimpleBezierEntry -{ - Vector maBackward; - Vector maForward; - -public: - SimpleBezierEntry() - : maBackward(Vector::getEmptyVector()), - maForward(Vector::getEmptyVector()) - { - } - - SimpleBezierEntry(const Vector& rInitBackward, const Vector& rInitForward) - : maBackward(rInitBackward), - maForward(rInitForward) - { - } - - const Vector& getBackwardVector() const - { - return maBackward; - } - - void setBackwardVector(const Vector& rValue) - { - maBackward = rValue; - } - - const Vector& getForwardVector() const - { - return maForward; - } - - void setForwardVector(const Vector& rValue) - { - maForward = rValue; - } - - bool isBezierNeeded() - { - if(maBackward != Vector::getEmptyVector() || maForward != Vector::getEmptyVector()) - return true; - return false; - } - - bool operator==(const SimpleBezierEntry& rEntry) const - { - return ((maBackward == rEntry.maBackward) && (maForward == rEntry.maForward)); - } - - void doInvertForFlip() - { - maBackward = -maBackward; - maForward = -maForward; - } -}; - -////////////////////////////////////////////////////////////////////////////// - -template < class Point, class Vector > class PolygonPointList -{ - typedef SimplePointEntry< Point > LocalSimplePointEntry; - typedef SimpleBezierEntry< Vector > LocalSimpleBezierEntry; - typedef ::std::vector< LocalSimplePointEntry > SimplePointVector; - typedef ::std::vector< LocalSimpleBezierEntry > SimpleBezierVector; - - sal_uInt32 mnBezierCount; - SimplePointVector maPoints; - SimpleBezierVector* mpVectors; - - bool mbIsClosed : 1; - - void implTryToReduceToPointVector() - { - if(!mnBezierCount && mpVectors) - { - delete mpVectors; - mpVectors = 0L; - } - } - -public: - bool isBezier() const - { - return bool(mnBezierCount); - } - - bool isClosed() const - { - return bool(mbIsClosed); - } - - void setClosed(bool bNew) - { - mbIsClosed = bNew; - } - - sal_uInt32 count() const - { - return maPoints.size(); - } - - PolygonPointList() - : mnBezierCount(0L), - mpVectors(0L), - mbIsClosed(false) - { - // complete initialization with defaults - } - - PolygonPointList(const PolygonPointList& rSource) - : mnBezierCount(0L), - maPoints(rSource.maPoints), - mpVectors(0L), - mbIsClosed(rSource.mbIsClosed) - { - // complete initialization using copy - if(rSource.mpVectors && rSource.mnBezierCount) - { - mpVectors = new SimpleBezierVector(*rSource.mpVectors); - mnBezierCount = rSource.mnBezierCount; - } - } - - PolygonPointList(const PolygonPointList& rSource, sal_uInt32 nIndex, sal_uInt32 nCount) - : mnBezierCount(0L), - maPoints(nCount), - mpVectors(0L), - mbIsClosed(rSource.mbIsClosed) - { - // complete initialization using partly copy - if(nCount) - { - // copy point data - { - SimplePointVector::const_iterator aStart(rSource.maPoints.begin()); - aStart += nIndex; - SimplePointVector::const_iterator aEnd(aStart); - aEnd += nCount; - maPoints.insert(0L, aStart, aEnd); - } - - // copy bezier data - if(rSource.mpVectors && rSource.mnBezierCount) - { - mpVectors = new SimpleBezierVector(); - mpVectors->reserve(nCount); - - SimpleBezierVector::iterator aStart(mpVectors->begin()); - aStart += nIndex; - SimpleBezierVector::iterator aEnd(aStart); - aEnd += nCount; - - for( ; aStart != aEnd; ++aStart ) - { - if(aStart->IsBezierNeeded()) - { - mnBezierCount++; - } - - mpVectors->push_back(*aStart); - } - - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - } - } - } - - ~PolygonPointList() - { - if(mpVectors) - { - delete mpVectors; - } - } - - bool isEqual(const PolygonPointList& rPointList) const - { - // same point count? - if(maPoints.size() != rPointList.maPoints.size()) - return false; - - // if zero points the polys are equal - if(!maPoints.size()) - return true; - - // if bezier count used it needs to be equal - if(mnBezierCount != rPointList.mnBezierCount) - return false; - - // compare point content - if(maPoints != rPointList.maPoints) - return false; - - // beziercounts are equal: if it's zero, we are done - if(!mnBezierCount) - return true; - - // beziercounts are equal and not zero; compare them - OSL_ENSURE(0L != mpVectors, "Error: Bezier list needs to exist here(!)"); - OSL_ENSURE(0L != rPointList.mpVectors, "Error: Bezier list needs to exist here(!)"); - - return (*mpVectors == *rPointList.mpVectors); - } - - const Point& getPoint(sal_uInt32 nIndex) const - { - return maPoints[nIndex].getPoint(); - } - - void setPoint(sal_uInt32 nIndex, const Point& rValue) - { - maPoints[nIndex].setPoint(rValue); - } - - const Vector& getBackwardVector(sal_uInt32 nIndex) const - { - if(mpVectors) - return ((*mpVectors)[nIndex]).getBackwardVector(); - else - return Vector::getEmptyVector(); - } - - void setBackwardVector(sal_uInt32 nIndex, const Vector& rValue) - { - if(mpVectors) - { - LocalSimpleBezierEntry& rDest = (*mpVectors)[nIndex]; - bool bBezierNeededBefore(rDest.isBezierNeeded()); - ((*mpVectors)[nIndex]).setBackwardVector(rValue); - bool bBezierNeededAfter(rDest.isBezierNeeded()); - - if(bBezierNeededBefore != bBezierNeededAfter) - { - if(bBezierNeededAfter) - mnBezierCount++; - else - mnBezierCount--; - } - } - else - { - bool bEmptyVector(rValue == Vector::getEmptyVector()); - - if(bEmptyVector) - return; - - mpVectors = new SimpleBezierVector(maPoints.size()); - ((*mpVectors)[nIndex]).setBackwardVector(rValue); - mnBezierCount++; - } - } - - const Vector& getForwardVector(sal_uInt32 nIndex) const - { - if(mpVectors) - return ((*mpVectors)[nIndex]).getForwardVector(); - else - return Vector::getEmptyVector(); - } - - void setForwardVector(sal_uInt32 nIndex, const Vector& rValue) - { - if(mpVectors) - { - LocalSimpleBezierEntry& rDest = (*mpVectors)[nIndex]; - bool bBezierNeededBefore(rDest.isBezierNeeded()); - ((*mpVectors)[nIndex]).setForwardVector(rValue); - bool bBezierNeededAfter(rDest.isBezierNeeded()); - - if(bBezierNeededBefore != bBezierNeededAfter) - { - if(bBezierNeededAfter) - mnBezierCount++; - else - mnBezierCount--; - } - } - else - { - bool bEmptyVector(rValue == Vector::getEmptyVector()); - - if(bEmptyVector) - return; - - mpVectors = new SimpleBezierVector(maPoints.size()); - ((*mpVectors)[nIndex]).setForwardVector(rValue); - mnBezierCount++; - } - } - - void insert(sal_uInt32 nIndex, const Point& rPoint, sal_uInt32 nCount) - { - if(nCount) - { - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - - // add nCount copies of rPoint - { - LocalSimplePointEntry aNode(rPoint); - SimplePointVector::iterator aIndex(maPoints.begin()); - aIndex += nIndex; - maPoints.insert(aIndex, nCount, aNode); - } - - // add nCount empty entries to keep indices synchronized - if(mpVectors) - { - LocalSimpleBezierEntry aNode; - SimpleBezierVector::iterator aIndex(mpVectors->begin()); - aIndex += nIndex; - mpVectors->insert(aIndex, nCount, aNode); - } - } - } - - void insert(sal_uInt32 nIndex, const PolygonPointList& rSource) - { - const sal_uInt32 nCount(rSource.maPoints.size()); - - if(nCount) - { - // instert point data - { - SimplePointVector::iterator aIndex(maPoints.begin()); - aIndex += nIndex; - - SimplePointVector::const_iterator aStart(rSource.maPoints.begin()); - SimplePointVector::const_iterator aEnd(rSource.maPoints.end()); - - maPoints.insert(aIndex, aStart, aEnd); - } - - // insert bezier data - if(rSource.mpVectors && rSource.mnBezierCount) - { - SimpleBezierVector::iterator aIndex(mpVectors->begin()); - aIndex += nIndex; - - SimpleBezierVector::iterator aStart(rSource.mpVectors->begin()); - SimpleBezierVector::iterator aEnd(rSource.mpVectors->end()); - - if(!mpVectors) - { - mpVectors = new SimpleBezierVector(maPoints.size() - nCount); - } - - mpVectors->insert(aIndex, aStart, aEnd); - - mnBezierCount += rSource.mnBezierCount; - } - else - { - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - - // add nCount empty entries to keep indices synchronized - if(mpVectors) - { - LocalSimpleBezierEntry aNode; - SimpleBezierVector::iterator aIndex(mpVectors->begin()); - aIndex += nIndex; - mpVectors->insert(aIndex, nCount, aNode); - } - } - } - } - - void remove(sal_uInt32 nIndex, sal_uInt32 nCount) - { - if(nCount) - { - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - - // remove point data - { - SimplePointVector::iterator aStart(maPoints.begin()); - aStart += nIndex; - const SimplePointVector::iterator aEnd(aStart + nCount); - - maPoints.erase(aStart, aEnd); - } - - // remove bezier data - if(mpVectors) - { - SimpleBezierVector::iterator aStart(mpVectors->begin()); - aStart += nIndex; - const SimpleBezierVector::iterator aEnd(aStart + nCount); - - // take care for correct mnBezierCount BEFORE erase - if(mnBezierCount) - { - SimpleBezierVector::iterator aTestIter(aStart); - - for( ; mnBezierCount && aTestIter != aEnd; ++aTestIter) - { - if(aTestIter->isBezierNeeded()) - mnBezierCount--; - } - } - - if(mnBezierCount) - { - // erase nodes - mpVectors->erase(aStart, aEnd); - } - else - { - // try to reduce, maybe 0L == mnBezierCount - implTryToReduceToPointVector(); - } - } - } - } - - void flip() - { - if(maPoints.size() > 1) - { - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - - // calculate half size - const sal_uInt32 nHalfSize(maPoints.size() >> 1L); - - // flip point data - { - SimplePointVector::iterator aStart(maPoints.begin()); - SimplePointVector::iterator aEnd(maPoints.end()); - - for(sal_uInt32 a(0); a < nHalfSize; a++) - { - LocalSimplePointEntry aTemp = *aStart; - *aStart++ = *aEnd; - *aEnd-- = aTemp; - } - } - - // flip bezier data - if(mpVectors) - { - SimpleBezierVector::iterator aStart(mpVectors->begin()); - SimpleBezierVector::iterator aEnd(mpVectors->end()); - - for(sal_uInt32 a(0); a < nHalfSize; a++) - { - LocalSimpleBezierEntry aTemp = *aStart; - aTemp.doInvertForFlip(); - *aStart = *aEnd; - aStart->doInvertForFlip(); - aStart++; - *aEnd-- = aTemp; - } - - // also flip vectors of middle point (if existing) - if(maPoints.size() % 2) - { - (*mpVectors)[nHalfSize].doInvertForFlip(); - } - } - } - } -}; - -////////////////////////////////////////////////////////////////////////////// - -#endif _POLYGON_POINT_HXX diff --git a/basegfx/source/inc/polygontemplate.hxx b/basegfx/source/inc/polygontemplate.hxx deleted file mode 100644 index df8678e6a21d..000000000000 --- a/basegfx/source/inc/polygontemplate.hxx +++ /dev/null @@ -1,534 +0,0 @@ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ - - - -#ifndef _POLYGON_TEMPLATE_HXX -#define _POLYGON_TEMPLATE_HXX - -#include <vector> - -////////////////////////////////////////////////////////////////////////////// - -template < class Point > class ImplSimplePointEntry -{ - Point maPoint; - -public: - ImplSimplePointEntry() - : maPoint(Point::getEmptyPoint()) - { - } - - ImplSimplePointEntry(const Point& rInitPoint) - : maPoint(rInitPoint) - { - } - - const Point& getPoint() const - { - return maPoint; - } - - void setPoint(const Point& rValue) - { - maPoint = rValue; - } - - bool operator==(const ImplSimplePointEntry& rEntry) const - { - return (maPoint == rEntry.maPoint); - } -}; - -////////////////////////////////////////////////////////////////////////////// - -template < class Vector > class ImplSimpleBezierEntry -{ - Vector maBackward; - Vector maForward; - -public: - ImplSimpleBezierEntry() - : maBackward(Vector::getEmptyVector()), - maForward(Vector::getEmptyVector()) - { - } - - ImplSimpleBezierEntry(const Vector& rInitBackward, const Vector& rInitForward) - : maBackward(rInitBackward), - maForward(rInitForward) - { - } - - const Vector& getBackwardVector() const - { - return maBackward; - } - - void setBackwardVector(const Vector& rValue) - { - maBackward = rValue; - } - - const Vector& getForwardVector() const - { - return maForward; - } - - void setForwardVector(const Vector& rValue) - { - maForward = rValue; - } - - bool isBezierNeeded() - { - if(!maBackward.equalZero() || !maForward.equalZero()) - return true; - return false; - } - - bool operator==(const ImplSimpleBezierEntry& rEntry) const - { - return ((maBackward == rEntry.maBackward) && (maForward == rEntry.maForward)); - } - - void doInvertForFlip() - { - maBackward = -maBackward; - maForward = -maForward; - } -}; - -////////////////////////////////////////////////////////////////////////////// - -template < class Point, class Vector > class ImplPolygonTemplate -{ - typedef ImplSimplePointEntry< Point > LocalImplSimplePointEntry; - typedef ImplSimpleBezierEntry< Vector > LocalImplSimpleBezierEntry; - typedef ::std::vector< LocalImplSimplePointEntry > SimplePointVector; - typedef ::std::vector< LocalImplSimpleBezierEntry > SimpleBezierVector; - - sal_uInt32 mnBezierCount; - SimplePointVector maPoints; - SimpleBezierVector* mpVectors; - - bool mbIsClosed : 1; - - void implTryToReduceToPointVector() - { - if(!mnBezierCount && mpVectors) - { - delete mpVectors; - mpVectors = 0L; - } - } - -public: - bool isBezier() const - { - return bool(mnBezierCount); - } - - bool isClosed() const - { - return bool(mbIsClosed); - } - - void setClosed(bool bNew) - { - mbIsClosed = bNew; - } - - sal_uInt32 count() const - { - return maPoints.size(); - } - - ImplPolygonTemplate() - : mnBezierCount(0L), - mpVectors(0L), - mbIsClosed(false) - { - // complete initialization with defaults - } - - ImplPolygonTemplate(const ImplPolygonTemplate& rSource) - : mnBezierCount(0L), - maPoints(rSource.maPoints), - mpVectors(0L), - mbIsClosed(rSource.mbIsClosed) - { - // complete initialization using copy - if(rSource.mpVectors && rSource.mnBezierCount) - { - mpVectors = new SimpleBezierVector(*rSource.mpVectors); - mnBezierCount = rSource.mnBezierCount; - } - } - - ImplPolygonTemplate(const ImplPolygonTemplate& rSource, sal_uInt32 nIndex, sal_uInt32 nCount) - : mnBezierCount(0L), - maPoints(nCount), - mpVectors(0L), - mbIsClosed(rSource.mbIsClosed) - { - // complete initialization using partly copy - if(nCount) - { - // copy point data - { - SimplePointVector::const_iterator aStart(rSource.maPoints.begin()); - aStart += nIndex; - SimplePointVector::const_iterator aEnd(aStart); - aEnd += nCount; - maPoints.insert(0L, aStart, aEnd); - } - - // copy bezier data - if(rSource.mpVectors && rSource.mnBezierCount) - { - mpVectors = new SimpleBezierVector(); - mpVectors->reserve(nCount); - - SimpleBezierVector::iterator aStart(mpVectors->begin()); - aStart += nIndex; - SimpleBezierVector::iterator aEnd(aStart); - aEnd += nCount; - - for( ; aStart != aEnd; ++aStart ) - { - if(aStart->isBezierNeeded()) - { - mnBezierCount++; - } - - mpVectors->push_back(*aStart); - } - - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - } - } - } - - ~ImplPolygonTemplate() - { - if(mpVectors) - { - delete mpVectors; - } - } - - bool isEqual(const ImplPolygonTemplate& rPointList) const - { - // same point count? - if(maPoints.size() != rPointList.maPoints.size()) - return false; - - // if zero points the polys are equal - if(!maPoints.size()) - return true; - - // if bezier count used it needs to be equal - if(mnBezierCount != rPointList.mnBezierCount) - return false; - - // compare point content - if(maPoints != rPointList.maPoints) - return false; - - // beziercounts are equal: if it's zero, we are done - if(!mnBezierCount) - return true; - - // beziercounts are equal and not zero; compare them - OSL_ENSURE(0L != mpVectors, "Error: Bezier list needs to exist here(!)"); - OSL_ENSURE(0L != rPointList.mpVectors, "Error: Bezier list needs to exist here(!)"); - - return (*mpVectors == *rPointList.mpVectors); - } - - const Point& getPoint(sal_uInt32 nIndex) const - { - return maPoints[nIndex].getPoint(); - } - - void setPoint(sal_uInt32 nIndex, const Point& rValue) - { - maPoints[nIndex].setPoint(rValue); - } - - const Vector& getBackwardVector(sal_uInt32 nIndex) const - { - if(mpVectors) - return ((*mpVectors)[nIndex]).getBackwardVector(); - else - return Vector::getEmptyVector(); - } - - void setBackwardVector(sal_uInt32 nIndex, const Vector& rValue) - { - if(mpVectors) - { - LocalImplSimpleBezierEntry& rDest = (*mpVectors)[nIndex]; - bool bBezierNeededBefore(rDest.isBezierNeeded()); - ((*mpVectors)[nIndex]).setBackwardVector(rValue); - bool bBezierNeededAfter(rDest.isBezierNeeded()); - - if(bBezierNeededBefore != bBezierNeededAfter) - { - if(bBezierNeededAfter) - mnBezierCount++; - else - mnBezierCount--; - } - } - else - { - bool bEmptyVector(rValue.equalZero()); - - if(bEmptyVector) - return; - - mpVectors = new SimpleBezierVector(maPoints.size()); - ((*mpVectors)[nIndex]).setBackwardVector(rValue); - mnBezierCount++; - } - } - - const Vector& getForwardVector(sal_uInt32 nIndex) const - { - if(mpVectors) - return ((*mpVectors)[nIndex]).getForwardVector(); - else - return Vector::getEmptyVector(); - } - - void setForwardVector(sal_uInt32 nIndex, const Vector& rValue) - { - if(mpVectors) - { - LocalImplSimpleBezierEntry& rDest = (*mpVectors)[nIndex]; - bool bBezierNeededBefore(rDest.isBezierNeeded()); - ((*mpVectors)[nIndex]).setForwardVector(rValue); - bool bBezierNeededAfter(rDest.isBezierNeeded()); - - if(bBezierNeededBefore != bBezierNeededAfter) - { - if(bBezierNeededAfter) - mnBezierCount++; - else - mnBezierCount--; - } - } - else - { - bool bEmptyVector(rValue.equalZero()); - - if(bEmptyVector) - return; - - mpVectors = new SimpleBezierVector(maPoints.size()); - ((*mpVectors)[nIndex]).setForwardVector(rValue); - mnBezierCount++; - } - } - - void insert(sal_uInt32 nIndex, const Point& rPoint, sal_uInt32 nCount) - { - if(nCount) - { - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - - // add nCount copies of rPoint - { - LocalImplSimplePointEntry aNode(rPoint); - SimplePointVector::iterator aIndex(maPoints.begin()); - aIndex += nIndex; - maPoints.insert(aIndex, nCount, aNode); - } - - // add nCount empty entries to keep indices synchronized - if(mpVectors) - { - LocalImplSimpleBezierEntry aNode; - SimpleBezierVector::iterator aIndex(mpVectors->begin()); - aIndex += nIndex; - mpVectors->insert(aIndex, nCount, aNode); - } - } - } - - void insert(sal_uInt32 nIndex, const ImplPolygonTemplate& rSource) - { - const sal_uInt32 nCount(rSource.maPoints.size()); - - if(nCount) - { - // instert point data - { - SimplePointVector::iterator aIndex(maPoints.begin()); - aIndex += nIndex; - - SimplePointVector::const_iterator aStart(rSource.maPoints.begin()); - SimplePointVector::const_iterator aEnd(rSource.maPoints.end()); - - maPoints.insert(aIndex, aStart, aEnd); - } - - // insert bezier data - if(rSource.mpVectors && rSource.mnBezierCount) - { - SimpleBezierVector::iterator aIndex(mpVectors->begin()); - aIndex += nIndex; - - SimpleBezierVector::iterator aStart(rSource.mpVectors->begin()); - SimpleBezierVector::iterator aEnd(rSource.mpVectors->end()); - - if(!mpVectors) - { - mpVectors = new SimpleBezierVector(maPoints.size() - nCount); - } - - mpVectors->insert(aIndex, aStart, aEnd); - - mnBezierCount += rSource.mnBezierCount; - } - else - { - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - - // add nCount empty entries to keep indices synchronized - if(mpVectors) - { - LocalImplSimpleBezierEntry aNode; - SimpleBezierVector::iterator aIndex(mpVectors->begin()); - aIndex += nIndex; - mpVectors->insert(aIndex, nCount, aNode); - } - } - } - } - - void remove(sal_uInt32 nIndex, sal_uInt32 nCount) - { - if(nCount) - { - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - - // remove point data - { - SimplePointVector::iterator aStart(maPoints.begin()); - aStart += nIndex; - const SimplePointVector::iterator aEnd(aStart + nCount); - - maPoints.erase(aStart, aEnd); - } - - // remove bezier data - if(mpVectors) - { - SimpleBezierVector::iterator aStart(mpVectors->begin()); - aStart += nIndex; - const SimpleBezierVector::iterator aEnd(aStart + nCount); - - // take care for correct mnBezierCount BEFORE erase - if(mnBezierCount) - { - SimpleBezierVector::iterator aTestIter(aStart); - - for( ; mnBezierCount && aTestIter != aEnd; ++aTestIter) - { - if(aTestIter->isBezierNeeded()) - mnBezierCount--; - } - } - - if(mnBezierCount) - { - // erase nodes - mpVectors->erase(aStart, aEnd); - } - else - { - // try to reduce, maybe 0L == mnBezierCount - implTryToReduceToPointVector(); - } - } - } - } - - void flip() - { - if(maPoints.size() > 1) - { - // maybe vectors are not needed anymore, try to reduce memory footprint - implTryToReduceToPointVector(); - - // calculate half size - const sal_uInt32 nHalfSize(maPoints.size() >> 1L); - - // flip point data - { - SimplePointVector::iterator aStart(maPoints.begin()); - SimplePointVector::iterator aEnd(maPoints.end()); - - for(sal_uInt32 a(0); a < nHalfSize; a++) - { - LocalImplSimplePointEntry aTemp = *aStart; - *aStart++ = *aEnd; - *aEnd-- = aTemp; - } - } - - // flip bezier data - if(mpVectors) - { - SimpleBezierVector::iterator aStart(mpVectors->begin()); - SimpleBezierVector::iterator aEnd(mpVectors->end()); - - for(sal_uInt32 a(0); a < nHalfSize; a++) - { - LocalImplSimpleBezierEntry aTemp = *aStart; - aTemp.doInvertForFlip(); - *aStart = *aEnd; - aStart->doInvertForFlip(); - aStart++; - *aEnd-- = aTemp; - } - - // also flip vectors of middle point (if existing) - if(maPoints.size() % 2) - { - (*mpVectors)[nHalfSize].doInvertForFlip(); - } - } - } - } -}; - -////////////////////////////////////////////////////////////////////////////// - -#endif _POLYGON_TEMPLATE_HXX diff --git a/basegfx/source/inc/stringconversiontools.hxx b/basegfx/source/inc/stringconversiontools.hxx new file mode 100755 index 000000000000..568772fde4b5 --- /dev/null +++ b/basegfx/source/inc/stringconversiontools.hxx @@ -0,0 +1,114 @@ +/************************************************************** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + *************************************************************/ + +#ifndef _STRINGCONVERSIONTOOLS_HXX +#define _STRINGCONVERSIONTOOLS_HXX + +#include <sal/types.h> +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> + +namespace basegfx +{ + namespace internal + { + void lcl_skipSpaces(sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen); + + void lcl_skipSpacesAndCommas(sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen); + + inline bool lcl_isOnNumberChar(const sal_Unicode aChar, bool bSignAllowed = true) + { + const bool bPredicate( (sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) + || (bSignAllowed && sal_Unicode('+') == aChar) + || (bSignAllowed && sal_Unicode('-') == aChar) ); + + return bPredicate; + } + + inline bool lcl_isOnNumberChar(const ::rtl::OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true) + { + return lcl_isOnNumberChar(rStr[nPos], + bSignAllowed); + } + + bool lcl_getDoubleChar(double& o_fRetval, + sal_Int32& io_rPos, + const ::rtl::OUString& rStr); + + bool lcl_importDoubleAndSpaces( double& o_fRetval, + sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen ); + + bool lcl_importNumberAndSpaces(sal_Int32& o_nRetval, + sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen); + + void lcl_skipNumber(sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen); + + void lcl_skipDouble(sal_Int32& io_rPos, + const ::rtl::OUString& rStr); + + inline void lcl_skipNumberAndSpacesAndCommas(sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen) + { + lcl_skipNumber(io_rPos, rStr, nLen); + lcl_skipSpacesAndCommas(io_rPos, rStr, nLen); + } + + // #100617# Allow to skip doubles, too. + inline void lcl_skipDoubleAndSpacesAndCommas(sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen) + { + lcl_skipDouble(io_rPos, rStr); + lcl_skipSpacesAndCommas(io_rPos, rStr, nLen); + } + + inline void lcl_putNumberChar( ::rtl::OUStringBuffer& rStr, + double fValue ) + { + rStr.append( fValue ); + } + + void lcl_putNumberCharWithSpace( ::rtl::OUStringBuffer& rStr, + double fValue, + double fOldValue, + bool bUseRelativeCoordinates ); + + inline sal_Unicode lcl_getCommand( sal_Char cUpperCaseCommand, + sal_Char cLowerCaseCommand, + bool bUseRelativeCoordinates ) + { + return bUseRelativeCoordinates ? cLowerCaseCommand : cUpperCaseCommand; + } + } // namespace internal +} // namespace basegfx + +#endif /* _STRINGCONVERSIONTOOLS_HXX */ diff --git a/basegfx/source/matrix/b2dhommatrixtools.cxx b/basegfx/source/matrix/b2dhommatrixtools.cxx index 08652adadea0..900430da2799 100644 --- a/basegfx/source/matrix/b2dhommatrixtools.cxx +++ b/basegfx/source/matrix/b2dhommatrixtools.cxx @@ -27,37 +27,12 @@ #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <rtl/ustring.hxx> #include <rtl/ustrbuf.hxx> +#include <stringconversiontools.hxx> /////////////////////////////////////////////////////////////////////////////// namespace basegfx { - ::rtl::OUString exportToSvg( const B2DHomMatrix& rMatrix ) - { - rtl::OUStringBuffer aStrBuf; - aStrBuf.appendAscii("matrix("); - - aStrBuf.append(rMatrix.get(0,0)); - aStrBuf.appendAscii(", "); - - aStrBuf.append(rMatrix.get(1,0)); - aStrBuf.appendAscii(", "); - - aStrBuf.append(rMatrix.get(0,1)); - aStrBuf.appendAscii(", "); - - aStrBuf.append(rMatrix.get(1,1)); - aStrBuf.appendAscii(", "); - - aStrBuf.append(rMatrix.get(0,2)); - aStrBuf.appendAscii(", "); - - aStrBuf.append(rMatrix.get(1,2)); - aStrBuf.appendAscii(")"); - - return aStrBuf.makeStringAndClear(); - } - namespace tools { void createSinCosOrthogonal(double& o_rSin, double& o_rCos, double fRadiant) @@ -461,6 +436,46 @@ namespace basegfx return aRetval; } + /// special for the case to map from source range to target range + B2DHomMatrix createSourceRangeTargetRangeTransform( + const B2DRange& rSourceRange, + const B2DRange& rTargetRange) + { + B2DHomMatrix aRetval; + + if(&rSourceRange == &rTargetRange) + { + return aRetval; + } + + if(!fTools::equalZero(rSourceRange.getMinX()) || !fTools::equalZero(rSourceRange.getMinY())) + { + aRetval.set(0, 2, -rSourceRange.getMinX()); + aRetval.set(1, 2, -rSourceRange.getMinY()); + } + + const double fSourceW(rSourceRange.getWidth()); + const double fSourceH(rSourceRange.getHeight()); + const bool bDivX(!fTools::equalZero(fSourceW) && !fTools::equal(fSourceW, 1.0)); + const bool bDivY(!fTools::equalZero(fSourceH) && !fTools::equal(fSourceH, 1.0)); + const double fScaleX(bDivX ? rTargetRange.getWidth() / fSourceW : rTargetRange.getWidth()); + const double fScaleY(bDivY ? rTargetRange.getHeight() / fSourceH : rTargetRange.getHeight()); + + if(!fTools::equalZero(fScaleX) || !fTools::equalZero(fScaleY)) + { + aRetval.scale(fScaleX, fScaleY); + } + + if(!fTools::equalZero(rTargetRange.getMinX()) || !fTools::equalZero(rTargetRange.getMinY())) + { + aRetval.translate( + rTargetRange.getMinX(), + rTargetRange.getMinY()); + } + + return aRetval; + } + /* tooling methods for converting API matrices (drawing::HomogenMatrix3) to B2DHomMatrix */ @@ -496,7 +511,6 @@ namespace basegfx rMatrixOut.Line3.Column2 = rMatrixIn.get(2, 1); rMatrixOut.Line3.Column3 = rMatrixIn.get(2, 2); } - } // end of namespace tools } // end of namespace basegfx diff --git a/basegfx/source/matrix/makefile.mk b/basegfx/source/matrix/makefile.mk index 02bfb07b2f96..f5ab83678012 100644 --- a/basegfx/source/matrix/makefile.mk +++ b/basegfx/source/matrix/makefile.mk @@ -26,7 +26,7 @@ PRJNAME=basegfx TARGET=matrix #UNOUCRRDB=$(SOLARBINDIR)$/applicat.rdb -#ENABLE_EXCEPTIONS=FALSE +ENABLE_EXCEPTIONS=TRUE #USE_DEFFILE=TRUE # --- Settings ---------------------------------- diff --git a/basegfx/source/polygon/b2dpolygon.cxx b/basegfx/source/polygon/b2dpolygon.cxx index f542072cfcc7..1fef1a89ef8e 100644 --- a/basegfx/source/polygon/b2dpolygon.cxx +++ b/basegfx/source/polygon/b2dpolygon.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basegfx.hxx" + #include <osl/diagnose.h> #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/point/b2dpoint.hxx> diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx index afbb7e5e823c..de646323fc97 100644 --- a/basegfx/source/polygon/b2dpolygontools.cxx +++ b/basegfx/source/polygon/b2dpolygontools.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basegfx.hxx" + #include <basegfx/numeric/ftools.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> #include <osl/diagnose.h> diff --git a/basegfx/source/polygon/b2dpolypolygon.cxx b/basegfx/source/polygon/b2dpolypolygon.cxx index 87152ccf83e8..e201ef3fbcbd 100644 --- a/basegfx/source/polygon/b2dpolypolygon.cxx +++ b/basegfx/source/polygon/b2dpolypolygon.cxx @@ -19,17 +19,15 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basegfx.hxx" + #include <basegfx/polygon/b2dpolypolygon.hxx> #include <osl/diagnose.h> #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <rtl/instance.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> - #include <functional> #include <vector> #include <algorithm> diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx index e05f16045341..c2d6d65f9c64 100644 --- a/basegfx/source/polygon/b2dpolypolygontools.cxx +++ b/basegfx/source/polygon/b2dpolypolygontools.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basegfx.hxx" + #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <osl/diagnose.h> #include <basegfx/polygon/b2dpolypolygon.hxx> diff --git a/basegfx/source/polygon/b2dsvgpolypolygon.cxx b/basegfx/source/polygon/b2dsvgpolypolygon.cxx index cdd99f0a34cf..c5babb9545a6 100644 --- a/basegfx/source/polygon/b2dsvgpolypolygon.cxx +++ b/basegfx/source/polygon/b2dsvgpolypolygon.cxx @@ -32,240 +32,12 @@ #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <rtl/ustring.hxx> #include <rtl/math.hxx> +#include <stringconversiontools.hxx> namespace basegfx { namespace tools { - namespace - { - void lcl_skipSpaces(sal_Int32& io_rPos, - const ::rtl::OUString& rStr, - const sal_Int32 nLen) - { - while( io_rPos < nLen && - sal_Unicode(' ') == rStr[io_rPos] ) - { - ++io_rPos; - } - } - - void lcl_skipSpacesAndCommas(sal_Int32& io_rPos, - const ::rtl::OUString& rStr, - const sal_Int32 nLen) - { - while(io_rPos < nLen - && (sal_Unicode(' ') == rStr[io_rPos] || sal_Unicode(',') == rStr[io_rPos])) - { - ++io_rPos; - } - } - - inline bool lcl_isOnNumberChar(const sal_Unicode aChar, bool bSignAllowed = true) - { - const bool bPredicate( (sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) - || (bSignAllowed && sal_Unicode('+') == aChar) - || (bSignAllowed && sal_Unicode('-') == aChar) ); - - return bPredicate; - } - - inline bool lcl_isOnNumberChar(const ::rtl::OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true) - { - return lcl_isOnNumberChar(rStr[nPos], - bSignAllowed); - } - - bool lcl_getDoubleChar(double& o_fRetval, - sal_Int32& io_rPos, - const ::rtl::OUString& rStr, - const sal_Int32 /*nLen*/) - { - sal_Unicode aChar( rStr[io_rPos] ); - ::rtl::OUStringBuffer sNumberString; - - if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) - { - sNumberString.append(rStr[io_rPos]); - aChar = rStr[++io_rPos]; - } - - while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) - || sal_Unicode('.') == aChar) - { - sNumberString.append(rStr[io_rPos]); - aChar = rStr[++io_rPos]; - } - - if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar) - { - sNumberString.append(rStr[io_rPos]); - aChar = rStr[++io_rPos]; - - if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) - { - sNumberString.append(rStr[io_rPos]); - aChar = rStr[++io_rPos]; - } - - while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) - { - sNumberString.append(rStr[io_rPos]); - aChar = rStr[++io_rPos]; - } - } - - if(sNumberString.getLength()) - { - rtl_math_ConversionStatus eStatus; - o_fRetval = ::rtl::math::stringToDouble( sNumberString.makeStringAndClear(), - (sal_Unicode)('.'), - (sal_Unicode)(','), - &eStatus, - NULL ); - return ( eStatus == rtl_math_ConversionStatus_Ok ); - } - - return false; - } - - bool lcl_importDoubleAndSpaces( double& o_fRetval, - sal_Int32& io_rPos, - const ::rtl::OUString& rStr, - const sal_Int32 nLen ) - { - if( !lcl_getDoubleChar(o_fRetval, io_rPos, rStr, nLen) ) - return false; - - lcl_skipSpacesAndCommas(io_rPos, rStr, nLen); - - return true; - } - - bool lcl_importNumberAndSpaces(sal_Int32& o_nRetval, - sal_Int32& io_rPos, - const ::rtl::OUString& rStr, - const sal_Int32 nLen) - { - sal_Unicode aChar( rStr[io_rPos] ); - ::rtl::OUStringBuffer sNumberString; - - if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) - { - sNumberString.append(rStr[io_rPos]); - aChar = rStr[++io_rPos]; - } - - while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) - { - sNumberString.append(rStr[io_rPos]); - aChar = rStr[++io_rPos]; - } - - if(sNumberString.getLength()) - { - o_nRetval = sNumberString.makeStringAndClear().toInt32(); - lcl_skipSpacesAndCommas(io_rPos, rStr, nLen); - - return true; - } - - return false; - } - - void lcl_skipNumber(sal_Int32& io_rPos, - const ::rtl::OUString& rStr, - const sal_Int32 nLen) - { - bool bSignAllowed(true); - - while(io_rPos < nLen && lcl_isOnNumberChar(rStr, io_rPos, bSignAllowed)) - { - bSignAllowed = false; - ++io_rPos; - } - } - - void lcl_skipDouble(sal_Int32& io_rPos, - const ::rtl::OUString& rStr, - const sal_Int32 /*nLen*/) - { - sal_Unicode aChar( rStr[io_rPos] ); - - if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) - aChar = rStr[++io_rPos]; - - while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) - || sal_Unicode('.') == aChar) - { - aChar = rStr[++io_rPos]; - } - - if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar) - { - aChar = rStr[++io_rPos]; - - if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) - aChar = rStr[++io_rPos]; - - while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) - { - aChar = rStr[++io_rPos]; - } - } - } - void lcl_skipNumberAndSpacesAndCommas(sal_Int32& io_rPos, - const ::rtl::OUString& rStr, - const sal_Int32 nLen) - { - lcl_skipNumber(io_rPos, rStr, nLen); - lcl_skipSpacesAndCommas(io_rPos, rStr, nLen); - } - - // #100617# Allow to skip doubles, too. - void lcl_skipDoubleAndSpacesAndCommas(sal_Int32& io_rPos, - const ::rtl::OUString& rStr, - const sal_Int32 nLen) - { - lcl_skipDouble(io_rPos, rStr, nLen); - lcl_skipSpacesAndCommas(io_rPos, rStr, nLen); - } - - void lcl_putNumberChar( ::rtl::OUStringBuffer& rStr, - double fValue ) - { - rStr.append( fValue ); - } - - void lcl_putNumberCharWithSpace( ::rtl::OUStringBuffer& rStr, - double fValue, - double fOldValue, - bool bUseRelativeCoordinates ) - { - if( bUseRelativeCoordinates ) - fValue -= fOldValue; - - const sal_Int32 aLen( rStr.getLength() ); - if(aLen) - { - if( lcl_isOnNumberChar(rStr.charAt(aLen - 1), false) && - fValue >= 0.0 ) - { - rStr.append( sal_Unicode(' ') ); - } - } - - lcl_putNumberChar(rStr, fValue); - } - - inline sal_Unicode lcl_getCommand( sal_Char cUpperCaseCommand, - sal_Char cLowerCaseCommand, - bool bUseRelativeCoordinates ) - { - return bUseRelativeCoordinates ? cLowerCaseCommand : cUpperCaseCommand; - } - } - bool importFromSvgD(B2DPolyPolygon& o_rPolyPolygon, const ::rtl::OUString& rSvgDStatement) { o_rPolyPolygon.clear(); @@ -277,7 +49,7 @@ namespace basegfx B2DPolygon aCurrPoly; // skip initial whitespace - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); while(nPos < nLen) { @@ -291,7 +63,7 @@ namespace basegfx case 'Z' : { nPos++; - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); // remember closed state of current polygon bIsClosed = true; @@ -332,14 +104,14 @@ namespace basegfx } nPos++; - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); - while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos)) + while(nPos < nLen && ::basegfx::internal::lcl_isOnNumberChar(rSvgDStatement, nPos)) { double nX, nY; - if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; if(bRelative) { @@ -365,13 +137,13 @@ namespace basegfx case 'H' : { nPos++; - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); - while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos)) + while(nPos < nLen && ::basegfx::internal::lcl_isOnNumberChar(rSvgDStatement, nPos)) { double nX, nY(nLastY); - if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; if(bRelative) { @@ -395,13 +167,13 @@ namespace basegfx case 'V' : { nPos++; - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); - while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos)) + while(nPos < nLen && ::basegfx::internal::lcl_isOnNumberChar(rSvgDStatement, nPos)) { double nX(nLastX), nY; - if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; if(bRelative) { @@ -425,17 +197,17 @@ namespace basegfx case 'S' : { nPos++; - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); - while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos)) + while(nPos < nLen && ::basegfx::internal::lcl_isOnNumberChar(rSvgDStatement, nPos)) { double nX, nY; double nX2, nY2; - if(!lcl_importDoubleAndSpaces(nX2, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY2, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX2, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY2, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; if(bRelative) { @@ -484,20 +256,20 @@ namespace basegfx case 'C' : { nPos++; - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); - while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos)) + while(nPos < nLen && ::basegfx::internal::lcl_isOnNumberChar(rSvgDStatement, nPos)) { double nX, nY; double nX1, nY1; double nX2, nY2; - if(!lcl_importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nX2, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY2, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX2, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY2, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; if(bRelative) { @@ -534,17 +306,17 @@ namespace basegfx case 'Q' : { nPos++; - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); - while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos)) + while(nPos < nLen && ::basegfx::internal::lcl_isOnNumberChar(rSvgDStatement, nPos)) { double nX, nY; double nX1, nY1; - if(!lcl_importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; if(bRelative) { @@ -585,14 +357,14 @@ namespace basegfx case 'T' : { nPos++; - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); - while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos)) + while(nPos < nLen && ::basegfx::internal::lcl_isOnNumberChar(rSvgDStatement, nPos)) { double nX, nY; - if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; if(bRelative) { @@ -659,21 +431,21 @@ namespace basegfx case 'A' : { nPos++; - lcl_skipSpaces(nPos, rSvgDStatement, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgDStatement, nLen); - while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos)) + while(nPos < nLen && ::basegfx::internal::lcl_isOnNumberChar(rSvgDStatement, nPos)) { double nX, nY; double fRX, fRY, fPhi; sal_Int32 bLargeArcFlag, bSweepFlag; - if(!lcl_importDoubleAndSpaces(fRX, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(fRY, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(fPhi, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importNumberAndSpaces(bLargeArcFlag, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importNumberAndSpaces(bSweepFlag, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(fRX, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(fRY, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(fPhi, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importNumberAndSpaces(bLargeArcFlag, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importNumberAndSpaces(bSweepFlag, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; if(bRelative) { @@ -858,23 +630,46 @@ namespace basegfx double nX, nY; // skip initial whitespace - lcl_skipSpaces(nPos, rSvgPointsAttribute, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgPointsAttribute, nLen); while(nPos < nLen) { - if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgPointsAttribute, nLen)) return false; - if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgPointsAttribute, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nX, nPos, rSvgPointsAttribute, nLen)) return false; + if(!::basegfx::internal::lcl_importDoubleAndSpaces(nY, nPos, rSvgPointsAttribute, nLen)) return false; // add point o_rPoly.append(B2DPoint(nX, nY)); // skip to next number, or finish - lcl_skipSpaces(nPos, rSvgPointsAttribute, nLen); + ::basegfx::internal::lcl_skipSpaces(nPos, rSvgPointsAttribute, nLen); } return true; } + ::rtl::OUString exportToSvgPoints( const B2DPolygon& rPoly ) + { + OSL_ENSURE(!rPoly.areControlPointsUsed(), "exportToSvgPoints: Only non-bezier polygons allowed (!)"); + const sal_uInt32 nPointCount(rPoly.count()); + ::rtl::OUStringBuffer aResult; + + for(sal_uInt32 a(0); a < nPointCount; a++) + { + const basegfx::B2DPoint aPoint(rPoly.getB2DPoint(a)); + + if(a) + { + aResult.append(sal_Unicode(' ')); + } + + ::basegfx::internal::lcl_putNumberChar(aResult, aPoint.getX()); + aResult.append(sal_Unicode(',')); + ::basegfx::internal::lcl_putNumberChar(aResult, aPoint.getY()); + } + + return aResult.makeStringAndClear(); + } + ::rtl::OUString exportToSvgD( const B2DPolyPolygon& rPolyPolygon, bool bUseRelativeCoordinates, @@ -898,10 +693,10 @@ namespace basegfx // handle polygon start point B2DPoint aEdgeStart(aPolygon.getB2DPoint(0)); - aResult.append(lcl_getCommand('M', 'm', bUseRelativeCoordinates)); - lcl_putNumberCharWithSpace(aResult, aEdgeStart.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aEdgeStart.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); - aLastSVGCommand = lcl_getCommand('L', 'l', bUseRelativeCoordinates); + aResult.append(::basegfx::internal::lcl_getCommand('M', 'm', bUseRelativeCoordinates)); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeStart.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeStart.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + aLastSVGCommand = ::basegfx::internal::lcl_getCommand('L', 'l', bUseRelativeCoordinates); aCurrentSVGPosition = aEdgeStart; for(sal_uInt32 nIndex(0); nIndex < nEdgeCount; nIndex++) @@ -955,7 +750,7 @@ namespace basegfx // approximately equal, export as quadratic bezier if(bSymmetricAtEdgeStart) { - const sal_Unicode aCommand(lcl_getCommand('T', 't', bUseRelativeCoordinates)); + const sal_Unicode aCommand(::basegfx::internal::lcl_getCommand('T', 't', bUseRelativeCoordinates)); if(aLastSVGCommand != aCommand) { @@ -963,14 +758,14 @@ namespace basegfx aLastSVGCommand = aCommand; } - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); aLastSVGCommand = aCommand; aCurrentSVGPosition = aEdgeEnd; } else { - const sal_Unicode aCommand(lcl_getCommand('Q', 'q', bUseRelativeCoordinates)); + const sal_Unicode aCommand(::basegfx::internal::lcl_getCommand('Q', 'q', bUseRelativeCoordinates)); if(aLastSVGCommand != aCommand) { @@ -978,10 +773,10 @@ namespace basegfx aLastSVGCommand = aCommand; } - lcl_putNumberCharWithSpace(aResult, aLeft.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aLeft.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aLeft.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aLeft.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); aLastSVGCommand = aCommand; aCurrentSVGPosition = aEdgeEnd; } @@ -991,7 +786,7 @@ namespace basegfx // export as cubic bezier if(bSymmetricAtEdgeStart) { - const sal_Unicode aCommand(lcl_getCommand('S', 's', bUseRelativeCoordinates)); + const sal_Unicode aCommand(::basegfx::internal::lcl_getCommand('S', 's', bUseRelativeCoordinates)); if(aLastSVGCommand != aCommand) { @@ -999,16 +794,16 @@ namespace basegfx aLastSVGCommand = aCommand; } - lcl_putNumberCharWithSpace(aResult, aControlEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aControlEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aControlEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aControlEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); aLastSVGCommand = aCommand; aCurrentSVGPosition = aEdgeEnd; } else { - const sal_Unicode aCommand(lcl_getCommand('C', 'c', bUseRelativeCoordinates)); + const sal_Unicode aCommand(::basegfx::internal::lcl_getCommand('C', 'c', bUseRelativeCoordinates)); if(aLastSVGCommand != aCommand) { @@ -1016,12 +811,12 @@ namespace basegfx aLastSVGCommand = aCommand; } - lcl_putNumberCharWithSpace(aResult, aControlEdgeStart.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aControlEdgeStart.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aControlEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aControlEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aControlEdgeStart.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aControlEdgeStart.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aControlEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aControlEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); aLastSVGCommand = aCommand; aCurrentSVGPosition = aEdgeEnd; } @@ -1047,7 +842,7 @@ namespace basegfx else if(bXEqual) { // export as vertical line - const sal_Unicode aCommand(lcl_getCommand('V', 'v', bUseRelativeCoordinates)); + const sal_Unicode aCommand(::basegfx::internal::lcl_getCommand('V', 'v', bUseRelativeCoordinates)); if(aLastSVGCommand != aCommand) { @@ -1055,13 +850,13 @@ namespace basegfx aLastSVGCommand = aCommand; } - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); aCurrentSVGPosition = aEdgeEnd; } else if(bYEqual) { // export as horizontal line - const sal_Unicode aCommand(lcl_getCommand('H', 'h', bUseRelativeCoordinates)); + const sal_Unicode aCommand(::basegfx::internal::lcl_getCommand('H', 'h', bUseRelativeCoordinates)); if(aLastSVGCommand != aCommand) { @@ -1069,13 +864,13 @@ namespace basegfx aLastSVGCommand = aCommand; } - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); aCurrentSVGPosition = aEdgeEnd; } else { // export as line - const sal_Unicode aCommand(lcl_getCommand('L', 'l', bUseRelativeCoordinates)); + const sal_Unicode aCommand(::basegfx::internal::lcl_getCommand('L', 'l', bUseRelativeCoordinates)); if(aLastSVGCommand != aCommand) { @@ -1083,8 +878,8 @@ namespace basegfx aLastSVGCommand = aCommand; } - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); - lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates); + ::basegfx::internal::lcl_putNumberCharWithSpace(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates); aCurrentSVGPosition = aEdgeEnd; } } @@ -1097,7 +892,7 @@ namespace basegfx // close path if closed poly (Z and z are equivalent here, but looks nicer when case is matched) if(aPolygon.isClosed()) { - aResult.append(lcl_getCommand('Z', 'z', bUseRelativeCoordinates)); + aResult.append(::basegfx::internal::lcl_getCommand('Z', 'z', bUseRelativeCoordinates)); } } } diff --git a/basegfx/source/polygon/b3dpolypolygon.cxx b/basegfx/source/polygon/b3dpolypolygon.cxx index 6381ab2cd1ab..573da3422c86 100644 --- a/basegfx/source/polygon/b3dpolypolygon.cxx +++ b/basegfx/source/polygon/b3dpolypolygon.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basegfx.hxx" + #include <osl/diagnose.h> #include <basegfx/polygon/b3dpolypolygon.hxx> #include <basegfx/polygon/b3dpolygon.hxx> diff --git a/basegfx/source/polygon/b3dpolypolygontools.cxx b/basegfx/source/polygon/b3dpolypolygontools.cxx index 3efd70f8b68e..4a3b7653eaf9 100644 --- a/basegfx/source/polygon/b3dpolypolygontools.cxx +++ b/basegfx/source/polygon/b3dpolypolygontools.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basegfx.hxx" + #include <basegfx/polygon/b3dpolypolygontools.hxx> #include <basegfx/range/b3drange.hxx> #include <basegfx/polygon/b3dpolypolygon.hxx> diff --git a/basegfx/source/tools/makefile.mk b/basegfx/source/tools/makefile.mk index 41acba6cfa6f..676eb51b9de0 100644 --- a/basegfx/source/tools/makefile.mk +++ b/basegfx/source/tools/makefile.mk @@ -40,6 +40,7 @@ SLOFILES= $(SLO)$/b2dclipstate.obj \ $(SLO)$/keystoplerp.obj \ $(SLO)$/liangbarsky.obj \ $(SLO)$/tools.obj \ + $(SLO)$/stringconversiontools.obj \ $(SLO)$/unopolypolygon.obj # --- Targets ---------------------------------- diff --git a/basegfx/source/tools/stringconversiontools.cxx b/basegfx/source/tools/stringconversiontools.cxx new file mode 100755 index 000000000000..01fbf268826a --- /dev/null +++ b/basegfx/source/tools/stringconversiontools.cxx @@ -0,0 +1,214 @@ +/************************************************************** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + *************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" + +#include <stringconversiontools.hxx> +#include <rtl/math.hxx> + +namespace basegfx +{ + namespace internal + { + void lcl_skipSpaces(sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen) + { + while( io_rPos < nLen && + sal_Unicode(' ') == rStr[io_rPos] ) + { + ++io_rPos; + } + } + + void lcl_skipSpacesAndCommas(sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen) + { + while(io_rPos < nLen + && (sal_Unicode(' ') == rStr[io_rPos] || sal_Unicode(',') == rStr[io_rPos])) + { + ++io_rPos; + } + } + + bool lcl_getDoubleChar(double& o_fRetval, + sal_Int32& io_rPos, + const ::rtl::OUString& rStr) + { + sal_Unicode aChar( rStr[io_rPos] ); + ::rtl::OUStringBuffer sNumberString; + + if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) + { + sNumberString.append(rStr[io_rPos]); + aChar = rStr[++io_rPos]; + } + + while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) + || sal_Unicode('.') == aChar) + { + sNumberString.append(rStr[io_rPos]); + aChar = rStr[++io_rPos]; + } + + if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar) + { + sNumberString.append(rStr[io_rPos]); + aChar = rStr[++io_rPos]; + + if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) + { + sNumberString.append(rStr[io_rPos]); + aChar = rStr[++io_rPos]; + } + + while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) + { + sNumberString.append(rStr[io_rPos]); + aChar = rStr[++io_rPos]; + } + } + + if(sNumberString.getLength()) + { + rtl_math_ConversionStatus eStatus; + o_fRetval = ::rtl::math::stringToDouble( sNumberString.makeStringAndClear(), + (sal_Unicode)('.'), + (sal_Unicode)(','), + &eStatus, + NULL ); + return ( eStatus == rtl_math_ConversionStatus_Ok ); + } + + return false; + } + + bool lcl_importDoubleAndSpaces( double& o_fRetval, + sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen ) + { + if( !lcl_getDoubleChar(o_fRetval, io_rPos, rStr) ) + return false; + + lcl_skipSpacesAndCommas(io_rPos, rStr, nLen); + + return true; + } + + bool lcl_importNumberAndSpaces(sal_Int32& o_nRetval, + sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen) + { + sal_Unicode aChar( rStr[io_rPos] ); + ::rtl::OUStringBuffer sNumberString; + + if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) + { + sNumberString.append(rStr[io_rPos]); + aChar = rStr[++io_rPos]; + } + + while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) + { + sNumberString.append(rStr[io_rPos]); + aChar = rStr[++io_rPos]; + } + + if(sNumberString.getLength()) + { + o_nRetval = sNumberString.makeStringAndClear().toInt32(); + lcl_skipSpacesAndCommas(io_rPos, rStr, nLen); + + return true; + } + + return false; + } + + void lcl_skipNumber(sal_Int32& io_rPos, + const ::rtl::OUString& rStr, + const sal_Int32 nLen) + { + bool bSignAllowed(true); + + while(io_rPos < nLen && lcl_isOnNumberChar(rStr, io_rPos, bSignAllowed)) + { + bSignAllowed = false; + ++io_rPos; + } + } + + void lcl_skipDouble(sal_Int32& io_rPos, + const ::rtl::OUString& rStr) + { + sal_Unicode aChar( rStr[io_rPos] ); + + if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) + aChar = rStr[++io_rPos]; + + while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) + || sal_Unicode('.') == aChar) + { + aChar = rStr[++io_rPos]; + } + + if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar) + { + aChar = rStr[++io_rPos]; + + if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) + aChar = rStr[++io_rPos]; + + while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) + { + aChar = rStr[++io_rPos]; + } + } + } + + void lcl_putNumberCharWithSpace( ::rtl::OUStringBuffer& rStr, + double fValue, + double fOldValue, + bool bUseRelativeCoordinates ) + { + if( bUseRelativeCoordinates ) + fValue -= fOldValue; + + const sal_Int32 aLen( rStr.getLength() ); + if(aLen) + { + if( lcl_isOnNumberChar(rStr.charAt(aLen - 1), false) && + fValue >= 0.0 ) + { + rStr.append( sal_Unicode(' ') ); + } + } + + lcl_putNumberChar(rStr, fValue); + } + } // namespace internal +} + +// eof diff --git a/sd/source/ui/animations/motionpathtag.cxx b/sd/source/ui/animations/motionpathtag.cxx index d0fef527fe40..77656c29b707 100644 --- a/sd/source/ui/animations/motionpathtag.cxx +++ b/sd/source/ui/animations/motionpathtag.cxx @@ -502,9 +502,8 @@ bool MotionPathTag::MouseButtonDown( const MouseEvent& rMEvt, SmartHdl& rHdl ) if(bNewObj) aPt = mrView.GetSnapPos(aPt); - bool bClosed0(mpPathObj->IsClosedObj()); - - sal_uInt32 nInsPointNum = mpPathObj->InsPointOld(Point(basegfx::fround(aPt.getX()), basegfx::fround(aPt.getY())), bNewObj); + const bool bClosed0(mpPathObj->IsClosedObj()); + const sal_uInt32 nInsPointNum(mpPathObj->InsPointOld(aPt, bNewObj)); if(bClosed0 != mpPathObj->IsClosedObj()) { diff --git a/svx/inc/svx/sdrselection.hxx b/svx/inc/svx/sdrselection.hxx index 8fc5c5e04124..4ca9d889b752 100644 --- a/svx/inc/svx/sdrselection.hxx +++ b/svx/inc/svx/sdrselection.hxx @@ -104,6 +104,7 @@ namespace sdr public: /// constructor Selection(SdrView& rSdrView); + virtual ~Selection(); /// test if selection change is pending bool isSelectionChangePending() const; diff --git a/svx/inc/svx/svdopath.hxx b/svx/inc/svx/svdopath.hxx index 2d069b4d988e..8662e54497f8 100644 --- a/svx/inc/svx/svdopath.hxx +++ b/svx/inc/svx/svdopath.hxx @@ -40,7 +40,7 @@ class ImpPathForDragAndCreate; class SdrPathObjGeoData : public SdrObjGeoData { public: - basegfx::B2DPolyPolygon maPathPolygon; + basegfx::B2DPolyPolygon maPathPolyPolygon; SdrPathObjGeoData(); virtual ~SdrPathObjGeoData(); @@ -67,13 +67,13 @@ class SVX_DLLPUBLIC SdrPathObj : public SdrTextObj private: friend class ImpPathForDragAndCreate; -protected: - virtual sdr::contact::ViewContact* CreateObjectSpecificViewContact(); - // the geometry data in object coordinates. This means that it is not // in normalized form. To get it in normalized form You need to transform // with the inverse of the object matrix - basegfx::B2DPolyPolygon maPathPolygon; + basegfx::B2DPolyPolygon maPathPolyPolygon; + +protected: + virtual sdr::contact::ViewContact* CreateObjectSpecificViewContact(); // for isolation of old Drag/Create code ImpPathForDragAndCreate* mpDAC; @@ -84,9 +84,12 @@ protected: ImpPathForDragAndCreate& impGetDAC(const SdrView& rView) const; void impDeleteDAC() const; - // helper for adapting the object transformation when the geometry - // (maPathPolygon) in world coordinates has changed - void impAdaptTransformation(); + // helper to adapt transformation to changed gometry, needs to be called every time + // when maPathPolyPolygon changes. It ensures that the transformation is adapted in + // a way that the geometry in logic coordinates (0, 0, 1, 1) exactly fits so that the + // object tramsformation is correct in the sense of always transforming the object + // to object coordinates + void impSetPathPolyPolygonWithTransformationAdaption(const basegfx::B2DPolyPolygon& maNew); virtual ~SdrPathObj(); @@ -150,23 +153,21 @@ public: virtual void SetObjectPoint(const basegfx::B2DPoint& rPnt, sal_uInt32 nHdlNum); // insert point - sal_uInt32 InsPointOld(const Point& rPos, sal_Bool bNewObj); - sal_uInt32 InsPoint(const Point& rPos, sal_Bool bNewObj); + sal_uInt32 InsPointOld(const basegfx::B2DPoint& rPos, bool bNewObj); + sal_uInt32 InsPoint(const basegfx::B2DPoint& rPos, bool bNewObj); // split at tis point SdrObject* RipPoint(sal_uInt32 nHdlNum, sal_uInt32& rNewPt0Index); virtual SdrObject* DoConvertToPolygonObject(bool bBezier, bool bAddText) const; + + // get/setSdrObjectTransformation virtual void setSdrObjectTransformation(const basegfx::B2DHomMatrix& rTransformation); // get/set polygon data in object coordiates - basegfx::B2DPolyPolygon getB2DPolyPolygonInObjectCoordinates() const; + const basegfx::B2DPolyPolygon& getB2DPolyPolygonInObjectCoordinates() const; void setB2DPolyPolygonInObjectCoordinates(const basegfx::B2DPolyPolygon& rPathPoly); - // get/set polygon data in normalized coordiates - basegfx::B2DPolyPolygon getB2DPolyPolygonInNormalizedCoordinates() const; - void setB2DPolyPolygonInNormalizedCoordinates(const basegfx::B2DPolyPolygon& rPathPoly); - // helpers for states bool isClosed() const; bool isLine() const; diff --git a/svx/inc/svx/unoshape.hxx b/svx/inc/svx/unoshape.hxx index 6ac9f9eea507..06fd8a1b2f5c 100644 --- a/svx/inc/svx/unoshape.hxx +++ b/svx/inc/svx/unoshape.hxx @@ -111,7 +111,7 @@ enum SvxShapeKind SvxShapeKind_None, // OBJ_NONE SvxShapeKind_Group, // OBJ_GRUP SvxShapeKind_Rectangle, // OBJ_RECT - SvxShapeKind_Circle, // OBJ_CIRC + SvxShapeKind_Circle, // OBJ_CIRC and removed old ones (OBJ_SECT, OBJ_CARC, OBJ_CCUT) SvxShapeKind_Path, // OBJ_POLY and removed old ones (OBJ_LINE, OBJ_PLIN, OBJ_PATHLINE, OBJ_PATHFILL, OBJ_FREELINE, OBJ_FREEFILL, OBJ_PATHPOLY, OBJ_PATHPLIN) SvxShapeKind_Text, // OBJ_TEXT, OBJ_TITLETEXT, OBJ_OUTLINETEXT SvxShapeKind_Graphic, // OBJ_GRAF diff --git a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx index fb91f94eb497..69193c7879de 100644 --- a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx @@ -77,12 +77,8 @@ namespace sdr // prepare object transformation and unit polygon (direct model data) basegfx::B2DHomMatrix aObjectMatrix; - const bool bIsLine( - !aUnitPolyPolygon.areControlPointsUsed() - && 1 == nPolyCount - && 2 == aUnitPolyPolygon.getB2DPolygon(0).count()); - if(bIsLine) + if(GetPathObj().isLine()) { // special handling for single line mode (2 points) const basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0)); @@ -104,9 +100,13 @@ namespace sdr } else { - // get transformation and unit polygon - aUnitPolyPolygon = GetPathObj().getB2DPolyPolygonInNormalizedCoordinates(); + // get transformation in unified coordinates aObjectMatrix = GetPathObj().getSdrObjectTransformation(); + aUnitPolyPolygon = GetPathObj().getB2DPolyPolygonInObjectCoordinates(); + + basegfx::B2DHomMatrix aInverse(aObjectMatrix); + aInverse.invert(); + aUnitPolyPolygon.transform(aInverse); } // create primitive. Always create primitives to allow the decomposition of diff --git a/svx/source/sdr/properties/attributeproperties.cxx b/svx/source/sdr/properties/attributeproperties.cxx index be75e4f0db4f..46935306c8c0 100644 --- a/svx/source/sdr/properties/attributeproperties.cxx +++ b/svx/source/sdr/properties/attributeproperties.cxx @@ -343,9 +343,8 @@ namespace sdr if(!pTargetStyleSheet) { // use correct default stylesheet #119287# - // this should not happen, all SDrObjects should have a default StyleSheet, so cloning - // one without is an error. Still add one, but assert user - OSL_ENSURE(false, "Cloning SdrObject without SfxStyleSheet, all should have a default StyleSheet (!)"); + // As long as Writer and Calc use no StyleSheets for SdrObjects it may be okay to have none, so + // just try to get the model default const SdrGrafObj* pIsSdrGrafObj = dynamic_cast< const SdrGrafObj* >(&GetSdrObject()); const SdrOle2Obj* pIsSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(&GetSdrObject()); diff --git a/svx/source/sidebar/possize/PosSizePropertyPanel.cxx b/svx/source/sidebar/possize/PosSizePropertyPanel.cxx index 97b471ae3f03..b8a9dbb9fe45 100644 --- a/svx/source/sidebar/possize/PosSizePropertyPanel.cxx +++ b/svx/source/sidebar/possize/PosSizePropertyPanel.cxx @@ -81,7 +81,6 @@ PosSizePropertyPanel::PosSizePropertyPanel( mpFtFlip(new FixedText(this, SVX_RES(FT_FLIP))), mpFlipTbxBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)), mpFlipTbx(sfx2::sidebar::ControlFactory::CreateToolBox(mpFlipTbxBackground.get(), SVX_RES(TBX_FLIP))), - maRect(), mpView(0), mlOldWidth(1), mlOldHeight(1), @@ -202,20 +201,17 @@ void PosSizePropertyPanel::ShowMenu (void) namespace { - bool hasText(const SdrView& rSdrView) + bool hasSingeObjectWithTextSelected(const SdrView& rSdrView) { - const SdrMarkList& rMarkList = rSdrView.GetMarkedObjectList(); + SdrObject* pObj = rSdrView.getSelectedIfSingle(); - if(1 == rMarkList.GetMarkCount()) + if(pObj) { - const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier()); if((pObj->GetObjInventor() == SdrInventor) && (OBJ_TEXT == eKind || OBJ_TITLETEXT == eKind || OBJ_OUTLINETEXT == eKind)) { - const SdrTextObj* pSdrTextObj = dynamic_cast< const SdrTextObj* >(pObj); - - if(pSdrTextObj && pSdrTextObj->HasText()) + if(pObj->HasText()) { return true; } @@ -308,8 +304,8 @@ void PosSizePropertyPanel::Initialize() if ( mpView != NULL ) { - maUIScale = mpView->GetModel()->GetUIScale(); - mbAdjustEnabled = hasText(*mpView); + maUIScale = mpView->getSdrModelFromSdrView().GetUIScale(); + mbAdjustEnabled = hasSingeObjectWithTextSelected(*mpView); } mePoolUnit = maTransfWidthControl.GetCoreMetric(); @@ -775,7 +771,7 @@ void PosSizePropertyPanel::NotifyItemUpdate( if ( mpView == NULL ) return; - mbAdjustEnabled = hasText(*mpView); + mbAdjustEnabled = hasSingeObjectWithTextSelected(*mpView); // Pool unit and dialog unit may have changed, make sure that we // have the current values. @@ -999,16 +995,16 @@ void PosSizePropertyPanel::NotifyItemUpdate( } const sal_Int32 nCombinedContext(maContext.GetCombinedContext_DI()); - const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + const SdrObjectVector aMarkList(mpView->getSelectedSdrObjectVectorFromSdrMarkView()); - switch (rMarkList.GetMarkCount()) + switch (aMarkList.size()) { case 0: break; case 1: { - const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + const SdrObject* pObj = aMarkList[0]; const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier()); if(((nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_Draw) @@ -1030,9 +1026,9 @@ void PosSizePropertyPanel::NotifyItemUpdate( sal_uInt16 nMarkObj = 0; bool isNoEdge = true; - while(isNoEdge && rMarkList.GetMark(nMarkObj)) + while(isNoEdge && nMarkObj < aMarkList.size()) { - const SdrObject* pObj = rMarkList.GetMark(nMarkObj)->GetMarkedSdrObj(); + const SdrObject* pObj = aMarkList[nMarkObj++]; const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier()); if(((nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_Draw) @@ -1043,7 +1039,6 @@ void PosSizePropertyPanel::NotifyItemUpdate( isNoEdge = false; break; } - nMarkObj++; } if(!isNoEdge) @@ -1090,7 +1085,7 @@ void PosSizePropertyPanel::executeSize() { if ( mpMtrWidth->IsValueModified() || mpMtrHeight->IsValueModified()) { - Fraction aUIScale = mpView->GetModel()->GetUIScale(); + Fraction aUIScale = mpView->getSdrModelFromSdrView().GetUIScale(); // get Width double nWidth = (double)mpMtrWidth->GetValue( meDlgUnit ); @@ -1137,26 +1132,20 @@ void PosSizePropertyPanel::executePosX() if ( mpMtrPosX->IsValueModified()) { long lX = GetCoreValue( *mpMtrPosX, mePoolUnit ); - if( mbMtrPosXMirror ) + + if( mbMtrPosXMirror ) // TTTT: Check if needed and what it does + { lX = -lX; - long lY = GetCoreValue( *mpMtrPosY, mePoolUnit ); + } - Size aPageSize; - Rectangle aRect; - maRect = mpView->GetAllMarkedRect(); - aRect = mpView->GetAllMarkedRect(); + const Fraction aUIScale(mpView->getSdrModelFromSdrView().GetUIScale()); - Fraction aUIScale = mpView->GetModel()->GetUIScale(); lX += maAnchorPos.X(); lX = Fraction( lX ) * aUIScale; - lY += maAnchorPos.Y(); - lY = Fraction( lY ) * aUIScale; - SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,(sal_uInt32) lX); - SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,(sal_uInt32) lY); + const SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,(sal_uInt32) lX); - GetBindings()->GetDispatcher()->Execute( - SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aPosXItem, 0L ); + GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aPosXItem, 0L); } } @@ -1166,25 +1155,15 @@ void PosSizePropertyPanel::executePosY() { if ( mpMtrPosY->IsValueModified() ) { - long lX = GetCoreValue( *mpMtrPosX, mePoolUnit ); long lY = GetCoreValue( *mpMtrPosY, mePoolUnit ); + const Fraction aUIScale = mpView->getSdrModelFromSdrView().GetUIScale(); - Size aPageSize; - Rectangle aRect; - maRect = mpView->GetAllMarkedRect(); - aRect = mpView->GetAllMarkedRect(); - - Fraction aUIScale = mpView->GetModel()->GetUIScale(); - lX += maAnchorPos.X(); - lX = Fraction( lX ) * aUIScale; lY += maAnchorPos.Y(); lY = Fraction( lY ) * aUIScale; - SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,(sal_uInt32) lX); - SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,(sal_uInt32) lY); + const SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,(sal_uInt32) lY); - GetBindings()->GetDispatcher()->Execute( - SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aPosYItem, 0L ); + GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aPosYItem, 0L); } } diff --git a/svx/source/svdraw/sdrselection.cxx b/svx/source/svdraw/sdrselection.cxx index 66c20af8d340..cce02a4eb090 100644 --- a/svx/source/svdraw/sdrselection.cxx +++ b/svx/source/svdraw/sdrselection.cxx @@ -282,6 +282,11 @@ namespace sdr { } + Selection::~Selection() + { + Stop(); + } + void Selection::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) { const SdrBaseHint* pSdrHint = dynamic_cast< const SdrBaseHint* >(&rHint); diff --git a/svx/source/svdraw/svddrgv.cxx b/svx/source/svdraw/svddrgv.cxx index d1448924ec00..c2d987adb9d9 100644 --- a/svx/source/svdraw/svddrgv.cxx +++ b/svx/source/svdraw/svddrgv.cxx @@ -749,13 +749,11 @@ bool SdrDragView::ImpBegInsObjPoint(bool bIdxZwang, sal_uInt32 /*nIdx*/, const b if(bIdxZwang) { - const Point aOldPoint(basegfx::fround(aPt.getX()), basegfx::fround(aPt.getY())); - mnInsPointNum = pMarkedPath->InsPoint(aOldPoint, bNewObj); + mnInsPointNum = pMarkedPath->InsPoint(aPt, bNewObj); } else { - const Point aOldPoint(basegfx::fround(aPt.getX()), basegfx::fround(aPt.getY())); - mnInsPointNum = pMarkedPath->InsPointOld(aOldPoint, bNewObj); + mnInsPointNum = pMarkedPath->InsPointOld(aPt, bNewObj); } if(bClosed0 != pMarkedPath->IsClosedObj()) diff --git a/svx/source/svdraw/svdopath.cxx b/svx/source/svdraw/svdopath.cxx index f2d36809895e..ea25c0221b2c 100644 --- a/svx/source/svdraw/svdopath.cxx +++ b/svx/source/svdraw/svdopath.cxx @@ -19,8 +19,6 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svx.hxx" @@ -39,12 +37,6 @@ #include <svx/svdview.hxx> // fuer MovCreate bei Freihandlinien #include <svx/svdglob.hxx> // Stringcache #include <svx/svdstr.hrc> // Objektname - -#ifdef _MSC_VER -#pragma optimize ("",off) -#pragma warning(disable: 4748) // "... because optimizations are disabled ..." -#endif - #include <svx/xlnwtit.hxx> #include <svx/xlnclit.hxx> #include <svx/xflclit.hxx> @@ -90,6 +82,8 @@ inline sal_uInt16 GetNextPnt(sal_uInt16 nPnt, sal_uInt16 nPntMax, bool bClosed) return nPnt; } +////////////////////////////////////////////////////////////////////////////// + struct ImpSdrPathDragData : public SdrDragStatUserData { XPolygon aXP; // Ausschnitt aud dem Originalpolygon @@ -221,7 +215,7 @@ void ImpSdrPathDragData::ResetPoly(const SdrPathObj& rPO) aXP[4]=aTmpXP[nNextNextPnt0]; aXP.SetFlags(4,aTmpXP.GetFlags(nNextNextPnt0)); } -/*************************************************************************/ +////////////////////////////////////////////////////////////////////////////// struct ImpPathCreateUser : public SdrDragStatUserData { @@ -369,7 +363,7 @@ XPolygon ImpPathCreateUser::GetLinePoly() const return aXP; } -/*************************************************************************/ +////////////////////////////////////////////////////////////////////////////// class ImpPathForDragAndCreate { @@ -1613,7 +1607,7 @@ Pointer ImpPathForDragAndCreate::GetCreatePointer() const return Pointer(POINTER_CROSS); } -/*************************************************************************/ +////////////////////////////////////////////////////////////////////////////// SdrPathObjGeoData::SdrPathObjGeoData() { @@ -1624,100 +1618,143 @@ SdrPathObjGeoData::~SdrPathObjGeoData() } ////////////////////////////////////////////////////////////////////////////// -// DrawContact section -void SdrPathObj::impAdaptTransformation() +void SdrPathObj::impSetPathPolyPolygonWithTransformationAdaption(const basegfx::B2DPolyPolygon& rNew) { - basegfx::B2DHomMatrix aHelpMatrix; + // nothing to adapt when geometry does not change + if(getB2DPolyPolygonInObjectCoordinates() == rNew) + { + return; + } + + static bool bRsetCoordinateSystemAfterWasLine(true); - if(maPathPolygon.count()) + if(bRsetCoordinateSystemAfterWasLine && isLine()) { - if(isLine()) - { - // create unit transformation so that (0,0) is 1st point and (1,0) is 2nd point - const basegfx::B2DPoint aPointA(maPathPolygon.getB2DPolygon(0).getB2DPoint(0)); - const basegfx::B2DPoint aPointB(maPathPolygon.getB2DPolygon(0).getB2DPoint(1)); - const basegfx::B2DVector aDelta(aPointB - aPointA); + // the SdrPathObj has two basic states, line and other. Line is for two points + // and no bezier, it uses a specialized geometry (unified line from 0.0, to 1.0) + // and a specialized transformation which shows the rotation of the line what is + // wanted. + // When a third point is added that mode is left and the regular one entered, in + // this conversion when using the code below keeping the rotation of the former + // line object. This is not wrong and works as intended, but is irritating for the + // user, e.g: + // - when drawing a freehand or multi-line (non-bezier) polygon, it will be rotated + // after construction due to keeping the rotation of the first added line + // - this is also used e.g. in contour editors where it is not wanted + // - it is different from the behaviour of AOO before + // For this reason this is disabled and the old behaviour activated by adding this + // case to esp. change back to the most trivial transformation in the transition + // between line status and other. To try out the also possible new alternative, + // change the value of bRsetCoordinateSystemAfterWasLine to false. + const basegfx::B2DRange aRangeNewGeometry(rNew.getB2DRange()); + + maPathPolyPolygon = rNew; + maSdrObjectTransformation.setB2DHomMatrix( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aRangeNewGeometry.getRange(), + aRangeNewGeometry.getMinimum())); + return; + } + + // set new geometry + maPathPolyPolygon = rNew; + + if(!rNew.areControlPointsUsed() + && 1 == rNew.count() + && 2 == rNew.getB2DPolygon(0).count()) + { + // new geometry is a non-curved line, create unit transformation so that (0,0) is + // 1st point and (1,0) is 2nd point + const basegfx::B2DPoint aPointA(rNew.getB2DPolygon(0).getB2DPoint(0)); + const basegfx::B2DPoint aPointB(rNew.getB2DPolygon(0).getB2DPoint(1)); + const basegfx::B2DVector aDelta(aPointB - aPointA); - aHelpMatrix = basegfx::tools::createScaleRotateTranslateB2DHomMatrix( - basegfx::B2DTuple(aDelta.getLength(), 0.0), + maSdrObjectTransformation.setB2DHomMatrix( + basegfx::tools::createScaleRotateTranslateB2DHomMatrix( + basegfx::B2DTuple(aDelta.getLength(), 1.0), atan2(aDelta.getY(), aDelta.getX()), - aPointA); - } - else - { - // get range - basegfx::B2DRange aRange(maPathPolygon.getB2DRange()); + aPointA)); + return; + } - if(!aRange.isEmpty()) - { - // break up current transformation - basegfx::B2DTuple aScale; - basegfx::B2DTuple aTranslate; - double fRotate, fShearX; - getSdrObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX); - - // to keep mirrorX, mirrorY, rotation and shear, create a transformation - // containing those values - if(basegfx::fTools::less(aScale.getX(), 0.0)) - { - aHelpMatrix.scale(-1.0, 1.0); - aScale.setX(-1.0); - } + // get range of the target geometry + const basegfx::B2DRange aRangeNewGeometry(rNew.getB2DRange()); - if(basegfx::fTools::less(aScale.getY(), 0.0)) - { - aHelpMatrix.scale(1.0, -1.0); - aScale.setY(-1.0); - } + if(aRangeNewGeometry.isEmpty()) + { + // no geometry, set default + maSdrObjectTransformation.setB2DHomMatrix(basegfx::B2DHomMatrix()); + return; + } - if(!basegfx::fTools::equalZero(fShearX)) - { - aHelpMatrix.shearX(fShearX); - } + if(basegfx::fTools::equalZero(aRangeNewGeometry.getWidth()) && basegfx::fTools::equalZero(aRangeNewGeometry.getHeight())) + { + // single point geometry, use translation + maSdrObjectTransformation.setB2DHomMatrix( + basegfx::tools::createTranslateB2DHomMatrix( + aRangeNewGeometry.getMinimum())); + return; + } - if(!basegfx::fTools::equalZero(fRotate)) - { - aHelpMatrix.rotate(fRotate); - } + // break up current transformation + basegfx::B2DTuple aScale; + basegfx::B2DTuple aTranslate; + double fRotate, fShearX; - if(!aHelpMatrix.isIdentity()) - { - // create inverse from it and back-transform polygon - basegfx::B2DPolyPolygon aBackTransformed(maPathPolygon); - basegfx::B2DHomMatrix aInverseHelpMatrix(aHelpMatrix); - aInverseHelpMatrix.invert(); - aBackTransformed.transform(aInverseHelpMatrix); - - // update range - aRange = aBackTransformed.getB2DRange(); - - // extract scale and translate. Transform topLeft from it back - // to transformed state to get original topLeft (rotation center). - // Be careful not to delete mirrorings - aTranslate = aHelpMatrix * aRange.getMinimum(); - aScale *= aRange.getRange(); - } - else - { - // extract translate and scale straightforward - aTranslate = aRange.getMinimum(); - aScale = aRange.getRange(); - } + maSdrObjectTransformation.getB2DHomMatrix().decompose(aScale, aTranslate, fRotate, fShearX); - // create new transformation - aHelpMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( - aScale, - fShearX, - fRotate, - aTranslate); - } - } + // to preserve mirrorX, mirrorY, rotation and shear, create a transformation + // containing those values in aHelpMatrix + basegfx::B2DHomMatrix aHelpMatrix; + + if(basegfx::fTools::less(aScale.getX(), 0.0)) + { + aHelpMatrix.scale(-1.0, 1.0); } - // set adapted transformation, but do not change the - // polygon data; that IS the defining part in this case - maSdrObjectTransformation = aHelpMatrix; + if(basegfx::fTools::less(aScale.getY(), 0.0)) + { + aHelpMatrix.scale(1.0, -1.0); + } + + if(!basegfx::fTools::equalZero(fShearX)) + { + aHelpMatrix.shearX(fShearX); + } + + if(!basegfx::fTools::equalZero(fRotate)) + { + aHelpMatrix.rotate(fRotate); + } + + if(!aHelpMatrix.isIdentity()) + { + // create inverse from it and back-transform polygon + basegfx::B2DPolyPolygon aBackTransformed(rNew); + basegfx::B2DHomMatrix aInverseHelpMatrix(aHelpMatrix); + + aInverseHelpMatrix.invert(); + aBackTransformed.transform(aInverseHelpMatrix); + + // get range of new geometry in unit coordinates + const basegfx::B2DRange aUnitRange(aBackTransformed.getB2DRange()); + const basegfx::B2DHomMatrix aNewTransform( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aUnitRange.getRange(), + aUnitRange.getMinimum())); + + maSdrObjectTransformation.setB2DHomMatrix( + aHelpMatrix * aNewTransform); + } + else + { + // use translate and scale straightforward from new geometry + maSdrObjectTransformation.setB2DHomMatrix( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aRangeNewGeometry.getRange(), + aRangeNewGeometry.getMinimum())); + } } sdr::contact::ViewContact* SdrPathObj::CreateObjectSpecificViewContact() @@ -1729,10 +1766,10 @@ SdrPathObj::SdrPathObj( SdrModel& rSdrModel, const basegfx::B2DPolyPolygon& rPathPoly) : SdrTextObj(rSdrModel), - maPathPolygon(rPathPoly), + maPathPolyPolygon(), mpDAC(0) { - impAdaptTransformation(); + impSetPathPolyPolygonWithTransformationAdaption(rPathPoly); } SdrPathObj::~SdrPathObj() @@ -1752,7 +1789,7 @@ void SdrPathObj::copyDataFromSdrObject(const SdrObject& rSource) SdrTextObj::copyDataFromSdrObject(rSource); // copy local data - maPathPolygon = pSource->getB2DPolyPolygonInObjectCoordinates(); + maPathPolyPolygon = pSource->getB2DPolyPolygonInObjectCoordinates(); } else { @@ -1778,9 +1815,9 @@ bool SdrPathObj::IsClosedObj() const void SdrPathObj::ImpSetClosed(bool bClose) { - for(sal_uInt32 a(0); a < maPathPolygon.count(); a++) + for(sal_uInt32 a(0); a < getB2DPolyPolygonInObjectCoordinates().count(); a++) { - basegfx::B2DPolygon aCandidate(maPathPolygon.getB2DPolygon(a)); + basegfx::B2DPolygon aCandidate(getB2DPolyPolygonInObjectCoordinates().getB2DPolygon(a)); if(bClose != aCandidate.isClosed()) { @@ -1796,9 +1833,9 @@ void SdrPathObj::ImpSetClosed(bool bClose) basegfx::tools::closeWithGeometryChange(aCandidate); } - // no need to use impAdaptTransformation here, - // the geometry gets not changed in it's dimensions - maPathPolygon.setB2DPolygon(a, aCandidate); + // no need to adapt transformation here, the geometry gets not changed + // in it's dimensions by triggering open/closed state + maPathPolyPolygon.setB2DPolygon(a, aCandidate); } } } @@ -2100,8 +2137,6 @@ void SdrPathObj::GetPlusHdl(SdrHdlList& rHdlList, const SdrObject& rSdrObject, c } } -//////////////////////////////////////////////////////////////////////////////////////////////////// - SdrPathObjType SdrPathObj::getSdrPathObjType() const { if(isLine()) @@ -2109,9 +2144,9 @@ SdrPathObjType SdrPathObj::getSdrPathObjType() const return PathType_Line; } - if(maPathPolygon.isClosed()) + if(getB2DPolyPolygonInObjectCoordinates().isClosed()) { - if(maPathPolygon.areControlPointsUsed()) + if(getB2DPolyPolygonInObjectCoordinates().areControlPointsUsed()) { return PathType_ClosedBezier; } @@ -2122,7 +2157,7 @@ SdrPathObjType SdrPathObj::getSdrPathObjType() const } else { - if(maPathPolygon.areControlPointsUsed()) + if(getB2DPolyPolygonInObjectCoordinates().areControlPointsUsed()) { return PathType_OpenBezier; } @@ -2213,8 +2248,6 @@ basegfx::B2DPolyPolygon SdrPathObj::getSpecialDragPoly(const SdrDragStat& rDrag) return aRetval; } -//////////////////////////////////////////////////////////////////////////////////////////////////// - bool SdrPathObj::BegCreate(SdrDragStat& rDrag) { impDeleteDAC(); @@ -2383,35 +2416,34 @@ void SdrPathObj::SetObjectPoint(const basegfx::B2DPoint& rPnt, sal_uInt32 nHdlNu if(PolyPolygonEditor::GetRelativePolyPoint(getB2DPolyPolygonInObjectCoordinates(), nHdlNum, nPoly, nPnt)) { basegfx::B2DPolygon aNewPolygon(getB2DPolyPolygonInObjectCoordinates().getB2DPolygon(nPoly)); - const basegfx::B2DRange aRangeBefore(aNewPolygon.getB2DRange()); - aNewPolygon.setB2DPoint(nPnt, rPnt); - const basegfx::B2DRange aRangeAfter(aNewPolygon.getB2DRange()); - maPathPolygon.setB2DPolygon(nPoly, aNewPolygon); - if(aRangeBefore != aRangeAfter) + if(rPnt != aNewPolygon.getB2DPoint(nPnt)) { - // need to adapt when geometric size has changed - impAdaptTransformation(); + basegfx::B2DPolyPolygon aNewPathPolyPolygon(getB2DPolyPolygonInObjectCoordinates()); + aNewPolygon.setB2DPoint(nPnt, rPnt); + aNewPathPolyPolygon.setB2DPolygon(nPoly, aNewPolygon); + + // set geometry and adapt transformation + impSetPathPolyPolygonWithTransformationAdaption(aNewPathPolyPolygon); } } } -sal_uInt32 SdrPathObj::InsPointOld(const Point& rPos, sal_Bool bNewObj) +sal_uInt32 SdrPathObj::InsPointOld(const basegfx::B2DPoint& rPos, bool bNewObj) { sal_uInt32 nNewHdl; if(bNewObj) { - nNewHdl = InsPoint(rPos, sal_True); + nNewHdl = InsPoint(rPos, true); } else { // look for smallest distance data - const basegfx::B2DPoint aTestPoint(rPos.X(), rPos.Y()); sal_uInt32 nSmallestPolyIndex(0L); sal_uInt32 nSmallestEdgeIndex(0L); double fSmallestCut; - basegfx::tools::getSmallestDistancePointToPolyPolygon(getB2DPolyPolygonInObjectCoordinates(), aTestPoint, nSmallestPolyIndex, nSmallestEdgeIndex, fSmallestCut); + basegfx::tools::getSmallestDistancePointToPolyPolygon(getB2DPolyPolygonInObjectCoordinates(), rPos, nSmallestPolyIndex, nSmallestEdgeIndex, fSmallestCut); // create old polygon index from it sal_uInt32 nPolyIndex(nSmallestEdgeIndex); @@ -2421,50 +2453,48 @@ sal_uInt32 SdrPathObj::InsPointOld(const Point& rPos, sal_Bool bNewObj) nPolyIndex += getB2DPolyPolygonInObjectCoordinates().getB2DPolygon(a).count(); } - nNewHdl = InsPoint(rPos, sal_False); + nNewHdl = InsPoint(rPos, false); } return nNewHdl; } -sal_uInt32 SdrPathObj::InsPoint(const Point& rPos, sal_Bool bNewObj) +sal_uInt32 SdrPathObj::InsPoint(const basegfx::B2DPoint& rPos, bool bNewObj) { sal_uInt32 nNewHdl; + basegfx::B2DPolyPolygon aNewPathPolyPolygon(getB2DPolyPolygonInObjectCoordinates()); if(bNewObj) { basegfx::B2DPolygon aNewPoly; - const basegfx::B2DPoint aPoint(rPos.X(), rPos.Y()); - aNewPoly.append(aPoint); + aNewPoly.append(rPos); aNewPoly.setClosed(isClosed()); - maPathPolygon.append(aNewPoly); - impAdaptTransformation(); + aNewPathPolyPolygon.append(aNewPoly); + impSetPathPolyPolygonWithTransformationAdaption(aNewPathPolyPolygon); nNewHdl = getB2DPolyPolygonInObjectCoordinates().allPointCount(); } else { // look for smallest distance data - const basegfx::B2DPoint aTestPoint(rPos.X(), rPos.Y()); sal_uInt32 nSmallestPolyIndex(0L); sal_uInt32 nSmallestEdgeIndex(0L); - double fSmallestCut; - basegfx::tools::getSmallestDistancePointToPolyPolygon(getB2DPolyPolygonInObjectCoordinates(), aTestPoint, nSmallestPolyIndex, nSmallestEdgeIndex, fSmallestCut); + double fSmallestCut(0.0); + basegfx::tools::getSmallestDistancePointToPolyPolygon(getB2DPolyPolygonInObjectCoordinates(), rPos, nSmallestPolyIndex, nSmallestEdgeIndex, fSmallestCut); basegfx::B2DPolygon aCandidate(getB2DPolyPolygonInObjectCoordinates().getB2DPolygon(nSmallestPolyIndex)); - const basegfx::B2DRange aRangeBefore(aCandidate.getB2DRange()); const bool bBefore(!aCandidate.isClosed() && 0L == nSmallestEdgeIndex && 0.0 == fSmallestCut); const bool bAfter(!aCandidate.isClosed() && aCandidate.count() == nSmallestEdgeIndex + 2L && 1.0 == fSmallestCut); if(bBefore) { // before first point - aCandidate.insert(0L, aTestPoint); + aCandidate.insert(0L, rPos); if(aCandidate.areControlPointsUsed()) { if(aCandidate.isNextControlPointUsed(1)) { - aCandidate.setNextControlPoint(0, interpolate(aTestPoint, aCandidate.getB2DPoint(1), (1.0 / 3.0))); - aCandidate.setPrevControlPoint(1, interpolate(aTestPoint, aCandidate.getB2DPoint(1), (2.0 / 3.0))); + aCandidate.setNextControlPoint(0, interpolate(rPos, aCandidate.getB2DPoint(1), (1.0 / 3.0))); + aCandidate.setPrevControlPoint(1, interpolate(rPos, aCandidate.getB2DPoint(1), (2.0 / 3.0))); } } @@ -2473,14 +2503,14 @@ sal_uInt32 SdrPathObj::InsPoint(const Point& rPos, sal_Bool bNewObj) else if(bAfter) { // after last point - aCandidate.append(aTestPoint); + aCandidate.append(rPos); if(aCandidate.areControlPointsUsed()) { if(aCandidate.isPrevControlPointUsed(aCandidate.count() - 2)) { - aCandidate.setNextControlPoint(aCandidate.count() - 2, interpolate(aCandidate.getB2DPoint(aCandidate.count() - 2), aTestPoint, (1.0 / 3.0))); - aCandidate.setPrevControlPoint(aCandidate.count() - 1, interpolate(aCandidate.getB2DPoint(aCandidate.count() - 2), aTestPoint, (2.0 / 3.0))); + aCandidate.setNextControlPoint(aCandidate.count() - 2, interpolate(aCandidate.getB2DPoint(aCandidate.count() - 2), rPos, (1.0 / 3.0))); + aCandidate.setPrevControlPoint(aCandidate.count() - 1, interpolate(aCandidate.getB2DPoint(aCandidate.count() - 2), rPos, (2.0 / 3.0))); } } @@ -2512,11 +2542,11 @@ sal_uInt32 SdrPathObj::InsPoint(const Point& rPos, sal_Bool bNewObj) // split and insert hit point aBezier.split(fSmallestCut, &aBezierA, &aBezierB); - aCandidate.insert(nSmallestEdgeIndex + 1, aTestPoint); + aCandidate.insert(nSmallestEdgeIndex + 1, rPos); // since we inserted hit point and not split point, we need to add an offset // to the control points to get the C1 continuity we want to achieve - const basegfx::B2DVector aOffset(aTestPoint - aBezierA.getEndPoint()); + const basegfx::B2DVector aOffset(rPos - aBezierA.getEndPoint()); aCandidate.setNextControlPoint(nSmallestEdgeIndex, aBezierA.getControlPointA() + aOffset); aCandidate.setPrevControlPoint(nSmallestEdgeIndex + 1, aBezierA.getControlPointB() + aOffset); aCandidate.setNextControlPoint(nSmallestEdgeIndex + 1, aBezierB.getControlPointA() + aOffset); @@ -2524,26 +2554,20 @@ sal_uInt32 SdrPathObj::InsPoint(const Point& rPos, sal_Bool bNewObj) } else { - aCandidate.insert(nSmallestEdgeIndex + 1L, aTestPoint); + aCandidate.insert(nSmallestEdgeIndex + 1L, rPos); } nNewHdl = nSmallestEdgeIndex + 1L; } - const basegfx::B2DRange aRangeAfter(aCandidate.getB2DRange()); - maPathPolygon.setB2DPolygon(nSmallestPolyIndex, aCandidate); + aNewPathPolyPolygon.setB2DPolygon(nSmallestPolyIndex, aCandidate); + impSetPathPolyPolygonWithTransformationAdaption(aNewPathPolyPolygon); // create old polygon index from it for(sal_uInt32 a(0L); a < nSmallestPolyIndex; a++) { nNewHdl += getB2DPolyPolygonInObjectCoordinates().getB2DPolygon(a).count(); } - - if(aRangeBefore != aRangeAfter) - { - // need to adapt when geometric size has changed - impAdaptTransformation(); - } } return nNewHdl; @@ -2646,19 +2670,19 @@ void SdrPathObj::SaveGeoData(SdrObjGeoData& rGeo) const { SdrTextObj::SaveGeoData(rGeo); SdrPathObjGeoData& rPGeo = (SdrPathObjGeoData&) rGeo; - rPGeo.maPathPolygon = getB2DPolyPolygonInObjectCoordinates(); + rPGeo.maPathPolyPolygon = getB2DPolyPolygonInObjectCoordinates(); } void SdrPathObj::RestGeoData(const SdrObjGeoData& rGeo) { SdrTextObj::RestGeoData(rGeo); - SdrPathObjGeoData& rPGeo=(SdrPathObjGeoData&)rGeo; - maPathPolygon=rPGeo.maPathPolygon; + SdrPathObjGeoData& rPGeo = (SdrPathObjGeoData&)rGeo; + maPathPolyPolygon = rPGeo.maPathPolyPolygon; } -basegfx::B2DPolyPolygon SdrPathObj::getB2DPolyPolygonInObjectCoordinates() const +const basegfx::B2DPolyPolygon& SdrPathObj::getB2DPolyPolygonInObjectCoordinates() const { - return maPathPolygon; + return maPathPolyPolygon; } void SdrPathObj::setB2DPolyPolygonInObjectCoordinates(const basegfx::B2DPolyPolygon& rPathPoly) @@ -2666,31 +2690,11 @@ void SdrPathObj::setB2DPolyPolygonInObjectCoordinates(const basegfx::B2DPolyPoly if(getB2DPolyPolygonInObjectCoordinates() != rPathPoly) { const SdrObjectChangeBroadcaster aSdrObjectChangeBroadcaster(*this); - maPathPolygon=rPathPoly; - impAdaptTransformation(); + impSetPathPolyPolygonWithTransformationAdaption(rPathPoly); SetChanged(); } } -basegfx::B2DPolyPolygon SdrPathObj::getB2DPolyPolygonInNormalizedCoordinates() const -{ - basegfx::B2DHomMatrix aInverse(getSdrObjectTransformation()); - basegfx::B2DPolyPolygon aRetval(getB2DPolyPolygonInObjectCoordinates()); - - aInverse.invert(); - aRetval.transform(aInverse); - - return aRetval; -} - -void SdrPathObj::setB2DPolyPolygonInNormalizedCoordinates(const basegfx::B2DPolyPolygon& rPathPoly) -{ - basegfx::B2DPolyPolygon aNew(rPathPoly); - - aNew.transform(getSdrObjectTransformation()); - setB2DPolyPolygonInObjectCoordinates(aNew); -} - void SdrPathObj::ToggleClosed() { const SdrObjectChangeBroadcaster aSdrObjectChangeBroadcaster(*this); @@ -2722,51 +2726,51 @@ void SdrPathObj::impDeleteDAC() const void SdrPathObj::setSdrObjectTransformation(const basegfx::B2DHomMatrix& rTransformation) { - if(isLine()) - { - // call parent - SdrTextObj::setSdrObjectTransformation(rTransformation); - - // apply new transformation to (0,0) and (1,0) to create the polygon data - basegfx::B2DPolygon aLine; - - aLine.append(rTransformation * basegfx::B2DPoint(0.0, 0.0)); - aLine.append(rTransformation * basegfx::B2DPoint(1.0, 0.0)); - maPathPolygon = basegfx::B2DPolyPolygon(aLine); - } - else + if(rTransformation != maSdrObjectTransformation.getB2DHomMatrix()) { - // remember current ObjectTransformation - basegfx::B2DHomMatrix aOldObjectTransformation(getSdrObjectTransformation()); - - // call parent - SdrTextObj::setSdrObjectTransformation(rTransformation); - - // need to adapt the object-coordinate representation of maPathPolygon - const basegfx::B2DHomMatrix aNewObjectTransformation(getSdrObjectTransformation()); + if(isLine()) + { + // apply new transformation to (0,0) and (1,0) to create the polygon data + basegfx::B2DPolygon aLine; - if(aOldObjectTransformation != aNewObjectTransformation) + aLine.append(rTransformation * basegfx::B2DPoint(0.0, 0.0)); + aLine.append(rTransformation * basegfx::B2DPoint(1.0, 0.0)); + maPathPolyPolygon = basegfx::B2DPolyPolygon(aLine); + } + else { - aOldObjectTransformation.invert(); - aOldObjectTransformation = aNewObjectTransformation * aOldObjectTransformation; - maPathPolygon.transform(aOldObjectTransformation); + if(getB2DPolyPolygonInObjectCoordinates().count()) + { + // need to adapt the object-coordinate representation of maPathPolyPolygon. + // take out old and apply new transformation + basegfx::B2DHomMatrix aCombined(maSdrObjectTransformation.getB2DHomMatrix()); + + aCombined.invert(); + aCombined = rTransformation * aCombined; + maPathPolyPolygon.transform(aCombined); + } } } + + // call parent + SdrTextObj::setSdrObjectTransformation(rTransformation); } bool SdrPathObj::isClosed() const { - return maPathPolygon.isClosed(); + return getB2DPolyPolygonInObjectCoordinates().isClosed(); } bool SdrPathObj::isLine() const { - return (1 == maPathPolygon.count() && 2 == maPathPolygon.getB2DPolygon(0).count()); + return !getB2DPolyPolygonInObjectCoordinates().areControlPointsUsed() + && 1 == getB2DPolyPolygonInObjectCoordinates().count() + && 2 == getB2DPolyPolygonInObjectCoordinates().getB2DPolygon(0).count(); } bool SdrPathObj::isBezier() const { - return maPathPolygon.areControlPointsUsed(); + return getB2DPolyPolygonInObjectCoordinates().areControlPointsUsed(); } ////////////////////////////////////////////////////////////////////////////// diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx index 82553cc568de..09b29afd37b3 100644 --- a/svx/source/unodraw/unoshape.cxx +++ b/svx/source/unodraw/unoshape.cxx @@ -223,8 +223,8 @@ SvxShapeKind SdrObjectCreatorInventorToSvxShapeKind(sal_uInt16 nIdent, sal_uInt3 // SdrObject, map case OBJ_GRUP: return SvxShapeKind_Group; case OBJ_RECT: return SvxShapeKind_Rectangle; - case OBJ_CIRC: return SvxShapeKind_Circle; - case OBJ_POLY: return SvxShapeKind_Path; + case OBJ_CIRC: return SvxShapeKind_Circle; // and removed old ones (OBJ_SECT, OBJ_CARC, OBJ_CCUT) + case OBJ_POLY: return SvxShapeKind_Path; // and removed old ones (OBJ_LINE, OBJ_PLIN, OBJ_PATHLINE, OBJ_PATHFILL, OBJ_FREELINE, OBJ_FREEFILL, OBJ_PATHPOLY, OBJ_PATHPLIN) case OBJ_TEXT: case OBJ_TITLETEXT: case OBJ_OUTLINETEXT: @@ -254,7 +254,7 @@ void SvxShapeKindToSdrObjectCreatorInventor(SvxShapeKind aSvxShapeKind, sal_uInt case SvxShapeKind_None: nIdent = OBJ_NONE; nInvent = SdrInventor; break; // OBJ_NONE case SvxShapeKind_Group: nIdent = OBJ_GRUP; nInvent = SdrInventor; break; // OBJ_GRUP case SvxShapeKind_Rectangle: nIdent = OBJ_RECT; nInvent = SdrInventor; break; // OBJ_RECT - case SvxShapeKind_Circle: nIdent = OBJ_CIRC; nInvent = SdrInventor; break; // OBJ_CIRC + case SvxShapeKind_Circle: nIdent = OBJ_CIRC; nInvent = SdrInventor; break; // OBJ_CIRC and removed old ones (OBJ_SECT, OBJ_CARC, OBJ_CCUT) case SvxShapeKind_Path: nIdent = OBJ_POLY; nInvent = SdrInventor; break; // OBJ_POLY and removed old ones (OBJ_LINE, OBJ_PLIN, OBJ_PATHLINE, OBJ_PATHFILL, OBJ_FREELINE, OBJ_FREEFILL, OBJ_PATHPOLY, OBJ_PATHPLIN) case SvxShapeKind_Text: nIdent = OBJ_TEXT; nInvent = SdrInventor; break; // OBJ_TEXT, OBJ_TITLETEXT, OBJ_OUTLINETEXT case SvxShapeKind_Graphic: nIdent = OBJ_GRAF; nInvent = SdrInventor; break; // OBJ_GRAF @@ -1486,6 +1486,63 @@ OUString SAL_CALL SvxShape::getShapeType() throw(uno::RuntimeException) { OUString aName; + if(SvxShapeKind_Path == mpImpl->meSvxShapeKind && mpObj.is()) + { + const SdrPathObj* pSdrPathObj = dynamic_cast< const SdrPathObj* >(mpObj.get()); + + if(pSdrPathObj) + { + // SvxShapeKinds are reduced, there is only one remaining type for + // path data, the SvxShapeKind_Path. Thus, the old types are all mapped + // to that SvxShapeKind (see also aTypeNameToSvxShapeKindMapper). + // + // "LineShape" + // "PolyPolygonShape" + // "PolyLineShape" + // "OpenBezierShape" + // "ClosedBezierShape" + // + // Some are not used in export resp. mapped to existing ones, see also: + // XMLShapeExport::ImpCalcShapeType in xmloff: + // + // OpenFreeHandShape -> OpenBezierShape + // ClosedFreeHandShape -> ClosedBezierShape + // PolyPolygonPathShape -> same as PolyPolygonShape + // PolyLinePathShape -> same as PolyLineShape + + const SdrPathObjType aSdrPathObjType(pSdrPathObj->getSdrPathObjType()); + + switch(aSdrPathObjType) + { + case PathType_Line: + { + return ::rtl::OUString::createFromAscii("com.sun.star.drawing.LineShape"); + } + case PathType_OpenPolygon: + { + return ::rtl::OUString::createFromAscii("com.sun.star.drawing.PolyLineShape"); + } + case PathType_ClosedPolygon: + { + return ::rtl::OUString::createFromAscii("com.sun.star.drawing.PolyPolygonShape"); + break; + } + case PathType_OpenBezier: + { + return ::rtl::OUString::createFromAscii("com.sun.star.drawing.OpenBezierShape"); + break; + } + case PathType_ClosedBezier: + { + return ::rtl::OUString::createFromAscii("com.sun.star.drawing.ClosedBezierShape"); + break; + } + } + + OSL_ENSURE(false, "SvxShapeKind_Path could not be mapped to uno class type (!)"); + } + } + if(getNameForSvxShapeType(aName, mpImpl->meSvxShapeKind)) { return aName; diff --git a/sw/source/ui/ribbar/conpoly.cxx b/sw/source/ui/ribbar/conpoly.cxx index 74dfe052440a..e0be027debd4 100644 --- a/sw/source/ui/ribbar/conpoly.cxx +++ b/sw/source/ui/ribbar/conpoly.cxx @@ -130,7 +130,7 @@ sal_Bool ConstPolygon::MouseButtonUp(const MouseEvent& rMEvt) void ConstPolygon::Activate(const sal_uInt16 nSlotId) { SdrObjectCreationInfo aSdrObjectCreationInfo; - bool bSet(false); + bool bSet(true); switch (nSlotId) { @@ -151,6 +151,7 @@ void ConstPolygon::Activate(const sal_uInt16 nSlotId) break; default: + bSet = false; break; } @@ -162,5 +163,4 @@ void ConstPolygon::Activate(const sal_uInt16 nSlotId) SwDrawBase::Activate(nSlotId); } - - +// eof diff --git a/xmloff/inc/xexptran.hxx b/xmloff/inc/xexptran.hxx index b1ac0307a5b9..b57a84ed21dd 100644 --- a/xmloff/inc/xexptran.hxx +++ b/xmloff/inc/xexptran.hxx @@ -116,82 +116,83 @@ public: class SdXMLImExViewBox { rtl::OUString msString; - sal_Int32 mnX; - sal_Int32 mnY; - sal_Int32 mnW; - sal_Int32 mnH; + double mfX; + double mfY; + double mfW; + double mfH; public: - SdXMLImExViewBox(sal_Int32 nX = 0L, sal_Int32 nY = 0L, sal_Int32 nW = 1000L, sal_Int32 nH = 1000L); + SdXMLImExViewBox(double fX = 0.0, double fY = 0.0, double fW = 1000.0, double fH = 1000.0); SdXMLImExViewBox(const rtl::OUString& rNew, const SvXMLUnitConverter& rConv); - sal_Int32 GetX() const { return mnX; } - sal_Int32 GetY() const { return mnY; } - sal_Int32 GetWidth() const { return mnW; } - sal_Int32 GetHeight() const { return mnH; } + double GetX() const { return mfX; } + double GetY() const { return mfY; } + double GetWidth() const { return mfW; } + double GetHeight() const { return mfH; } const rtl::OUString& GetExportString(); }; ////////////////////////////////////////////////////////////////////////////// - -class SdXMLImExPointsElement -{ - rtl::OUString msString; - com::sun::star::drawing::PointSequenceSequence maPoly; - -public: - SdXMLImExPointsElement(com::sun::star::drawing::PointSequence* pPoints, - const SdXMLImExViewBox& rViewBox, - const com::sun::star::awt::Point& rObjectPos, - const com::sun::star::awt::Size& rObjectSize, - const bool bClosed); - SdXMLImExPointsElement(const rtl::OUString& rNew, - const SdXMLImExViewBox& rViewBox, - const com::sun::star::awt::Point& rObjectPos, - const com::sun::star::awt::Size& rObjectSize, - const SvXMLUnitConverter& rConv, - const bool bClosed); - - const rtl::OUString& GetExportString() const { return msString; } - const com::sun::star::drawing::PointSequenceSequence& GetPointSequenceSequence() const { return maPoly; } -}; - +// +//class SdXMLImExPointsElement +//{ +// rtl::OUString msString; +// com::sun::star::drawing::PointSequenceSequence maPoly; +// +//public: +// SdXMLImExPointsElement(com::sun::star::drawing::PointSequence* pPoints, +// const SdXMLImExViewBox& rViewBox, +// const com::sun::star::awt::Point& rObjectPos, +// const com::sun::star::awt::Size& rObjectSize, +// const bool bClosed); +// SdXMLImExPointsElement(const rtl::OUString& rNew, +// const SdXMLImExViewBox& rViewBox, +// const com::sun::star::awt::Point& rObjectPos, +// const com::sun::star::awt::Size& rObjectSize, +// const SvXMLUnitConverter& rConv, +// const bool bClosed); +// +// const rtl::OUString& GetExportString() const { return msString; } +// const com::sun::star::drawing::PointSequenceSequence& GetPointSequenceSequence() const { return maPoly; } +//}; +// ////////////////////////////////////////////////////////////////////////////// - -class SdXMLImExSvgDElement -{ - rtl::OUString msString; - const SdXMLImExViewBox& mrViewBox; - bool mbIsClosed; - bool mbIsCurve; - - sal_Int32 mnLastX; - sal_Int32 mnLastY; - - com::sun::star::drawing::PointSequenceSequence maPoly; - com::sun::star::drawing::FlagSequenceSequence maFlag; - -public: - SdXMLImExSvgDElement(const SdXMLImExViewBox& rViewBox); - SdXMLImExSvgDElement(const rtl::OUString& rNew, - const SdXMLImExViewBox& rViewBox, - const com::sun::star::awt::Point& rObjectPos, - const com::sun::star::awt::Size& rObjectSize, - const SvXMLUnitConverter& rConv); - - void AddPolygon( - com::sun::star::drawing::PointSequence* pPoints, - com::sun::star::drawing::FlagSequence* pFlags, - const com::sun::star::awt::Point& rObjectPos, - const com::sun::star::awt::Size& rObjectSize, - bool bClosed = false, bool bRelative = true); - - 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; } -}; - +// +//class SdXMLImExSvgDElement +//{ +// rtl::OUString msString; +// const SdXMLImExViewBox& mrViewBox; +// bool mbIsClosed; +// bool mbIsCurve; +// +// sal_Int32 mnLastX; +// sal_Int32 mnLastY; +// +// com::sun::star::drawing::PointSequenceSequence maPoly; +// com::sun::star::drawing::FlagSequenceSequence maFlag; +// +//public: +// SdXMLImExSvgDElement(const SdXMLImExViewBox& rViewBox); +// SdXMLImExSvgDElement(const rtl::OUString& rNew, +// const SdXMLImExViewBox& rViewBox, +// const com::sun::star::awt::Point& rObjectPos, +// const com::sun::star::awt::Size& rObjectSize, +// const SvXMLUnitConverter& rConv); +// +// void AddPolygon( +// com::sun::star::drawing::PointSequence* pPoints, +// com::sun::star::drawing::FlagSequence* pFlags, +// const com::sun::star::awt::Point& rObjectPos, +// const com::sun::star::awt::Size& rObjectSize, +// bool bClosed = false, bool bRelative = true); +// +// 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; } +//}; +// #endif // _XEXPTRANSFORM_HXX +// eof 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; + //} } } } diff --git a/xmloff/source/style/MarkerStyle.cxx b/xmloff/source/style/MarkerStyle.cxx index 9947e86deac0..e7352aa9a04a 100644 --- a/xmloff/source/style/MarkerStyle.cxx +++ b/xmloff/source/style/MarkerStyle.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" + #include "xmloff/MarkerStyle.hxx" #include "xexptran.hxx" #include <xmloff/attrlist.hxx> @@ -35,6 +34,9 @@ #include <rtl/ustrbuf.hxx> #include <rtl/ustring.hxx> #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> using namespace ::com::sun::star; using ::rtl::OUString; @@ -103,50 +105,83 @@ sal_Bool XMLMarkerStyleImport::importXML( if( bHasViewBox && bHasPathData ) { - SdXMLImExSvgDElement aPoints(strPathData, *pViewBox, awt::Point( 0, 0 ), - awt::Size( pViewBox->GetWidth(), pViewBox->GetHeight() ), - rUnitConverter ); + basegfx::B2DPolyPolygon aPolyPolygon; - if(aPoints.IsCurve()) - { - drawing::PolyPolygonBezierCoords aSourcePolyPolygon( - aPoints.GetPointSequenceSequence(), - aPoints.GetFlagSequenceSequence()); - rValue <<= aSourcePolyPolygon; - } - else + if(basegfx::tools::importFromSvgD(aPolyPolygon, strPathData)) { - drawing::PolyPolygonBezierCoords aSourcePolyPolygon; - aSourcePolyPolygon.Coordinates = aPoints.GetPointSequenceSequence(); - aSourcePolyPolygon.Flags.realloc(aSourcePolyPolygon.Coordinates.getLength()); - - // Zeiger auf innere sequences holen - const drawing::PointSequence* pInnerSequence = aSourcePolyPolygon.Coordinates.getConstArray(); - drawing::FlagSequence* pInnerSequenceFlags = aSourcePolyPolygon.Flags.getArray(); - - for(sal_Int32 a(0); a < aSourcePolyPolygon.Coordinates.getLength(); a++) + if(aPolyPolygon.count()) { - pInnerSequenceFlags->realloc(pInnerSequence->getLength()); - drawing::PolygonFlags* pPolyFlags = pInnerSequenceFlags->getArray(); + // TTTT: ViewBox probably not used, but stay with former processing inside of + // SdXMLImExSvgDElement + const basegfx::B2DRange aSourceRange( + pViewBox->GetX(), pViewBox->GetY(), + pViewBox->GetX() + pViewBox->GetWidth(), pViewBox->GetY() + pViewBox->GetHeight()); + const basegfx::B2DRange aTargetRange( + 0.0, 0.0, + pViewBox->GetWidth(), pViewBox->GetHeight()); + + if(!aSourceRange.equal(aTargetRange)) + { + aPolyPolygon.transform( + basegfx::tools::createSourceRangeTargetRangeTransform( + aSourceRange, + aTargetRange)); + } - for(sal_Int32 b(0); b < pInnerSequence->getLength(); b++) - *pPolyFlags++ = drawing::PolygonFlags_NORMAL; + // always use PolyPolygonBezierCoords here + drawing::PolyPolygonBezierCoords aSourcePolyPolygon; - // next run - pInnerSequence++; - pInnerSequenceFlags++; + basegfx::tools::B2DPolyPolygonToUnoPolyPolygonBezierCoords( + aPolyPolygon, + aSourcePolyPolygon); + rValue <<= aSourcePolyPolygon; } - - rValue <<= aSourcePolyPolygon; } + // TTTT + //SdXMLImExSvgDElement aPoints(strPathData, *pViewBox, awt::Point( 0, 0 ), + // awt::Size( pViewBox->GetWidth(), pViewBox->GetHeight() ), + // rUnitConverter ); + // + //if(aPoints.IsCurve()) + //{ + // drawing::PolyPolygonBezierCoords aSourcePolyPolygon( + // aPoints.GetPointSequenceSequence(), + // aPoints.GetFlagSequenceSequence()); + // rValue <<= aSourcePolyPolygon; + //} + //else + //{ + // drawing::PolyPolygonBezierCoords aSourcePolyPolygon; + // aSourcePolyPolygon.Coordinates = aPoints.GetPointSequenceSequence(); + // aSourcePolyPolygon.Flags.realloc(aSourcePolyPolygon.Coordinates.getLength()); + // + // // Zeiger auf innere sequences holen + // const drawing::PointSequence* pInnerSequence = aSourcePolyPolygon.Coordinates.getConstArray(); + // drawing::FlagSequence* pInnerSequenceFlags = aSourcePolyPolygon.Flags.getArray(); + // + // for(sal_Int32 a(0); a < aSourcePolyPolygon.Coordinates.getLength(); a++) + // { + // pInnerSequenceFlags->realloc(pInnerSequence->getLength()); + // drawing::PolygonFlags* pPolyFlags = pInnerSequenceFlags->getArray(); + // + // for(sal_Int32 b(0); b < pInnerSequence->getLength(); b++) + // *pPolyFlags++ = drawing::PolygonFlags_NORMAL; + // + // // next run + // pInnerSequence++; + // pInnerSequenceFlags++; + // } + // + // rValue <<= aSourcePolyPolygon; + //} + if( aDisplayName.getLength() ) { rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_MARKER_ID, rStrName, aDisplayName ); rStrName = aDisplayName; } - } if( pViewBox ) @@ -183,96 +218,111 @@ sal_Bool XMLMarkerStyleExport::exportXML( if(rValue >>= aBezier) { - OUString aStrValue; - OUStringBuffer aOut; - ///////////////// // Name - sal_Bool bEncoded = sal_False; + sal_Bool bEncoded(sal_False); OUString aStrName( rStrName ); - rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, - rExport.EncodeStyleName( aStrName, - &bEncoded ) ); - if( bEncoded ) - rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, - aStrName ); - - ///////////////// - // Viewbox (viewBox="0 0 1500 1000") - sal_Int32 nMinX(0x7fffffff); - sal_Int32 nMaxX(0x80000000); - sal_Int32 nMinY(0x7fffffff); - sal_Int32 nMaxY(0x80000000); - sal_Int32 nOuterCnt(aBezier.Coordinates.getLength()); - drawing::PointSequence* pOuterSequence = aBezier.Coordinates.getArray(); - sal_Int32 a, b; - sal_Bool bClosed(sal_False); - - for (a = 0; a < nOuterCnt; a++) - { - drawing::PointSequence* pSequence = pOuterSequence++; - const awt::Point *pPoints = pSequence->getConstArray(); - sal_Int32 nPointCount(pSequence->getLength()); - if(nPointCount) - { - const awt::Point aStart = pPoints[0]; - const awt::Point aEnd = pPoints[nPointCount - 1]; - - if(aStart.X == aEnd.X && aStart.Y == aEnd.Y) - { - bClosed = sal_True; - } - } - - for (b = 0; b < nPointCount; b++) - { - const awt::Point aPoint = pPoints[b]; + rExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NAME, rExport.EncodeStyleName( aStrName, &bEncoded ) ); - if( aPoint.X < nMinX ) - nMinX = aPoint.X; - - if( aPoint.X > nMaxX ) - nMaxX = aPoint.X; - - if( aPoint.Y < nMinY ) - nMinY = aPoint.Y; - - if( aPoint.Y > nMaxY ) - nMaxY = aPoint.Y; - } + if( bEncoded ) + { + rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, aStrName ); } - sal_Int32 nDifX(nMaxX - nMinX); - sal_Int32 nDifY(nMaxY - nMinY); + const basegfx::B2DPolyPolygon aPolyPolygon( + basegfx::tools::UnoPolyPolygonBezierCoordsToB2DPolyPolygon( + aBezier)); + const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange()); + + ///////////////// + // Viewbox (viewBox="0 0 1500 1000") - SdXMLImExViewBox aViewBox( 0, 0, nDifX, nDifY ); + // TTTT + //sal_Int32 nMinX(0x7fffffff); + //sal_Int32 nMaxX(0x80000000); + //sal_Int32 nMinY(0x7fffffff); + //sal_Int32 nMaxY(0x80000000); + //sal_Int32 nOuterCnt(aBezier.Coordinates.getLength()); + //drawing::PointSequence* pOuterSequence = aBezier.Coordinates.getArray(); + //sal_Int32 a, b; + //sal_Bool bClosed(sal_False); + // + //for (a = 0; a < nOuterCnt; a++) + //{ + // drawing::PointSequence* pSequence = pOuterSequence++; + // const awt::Point *pPoints = pSequence->getConstArray(); + // sal_Int32 nPointCount(pSequence->getLength()); + // + // if(nPointCount) + // { + // const awt::Point aStart = pPoints[0]; + // const awt::Point aEnd = pPoints[nPointCount - 1]; + // + // if(aStart.X == aEnd.X && aStart.Y == aEnd.Y) + // { + // bClosed = sal_True; + // } + // } + // + // for (b = 0; b < nPointCount; b++) + // { + // const awt::Point aPoint = pPoints[b]; + // + // if( aPoint.X < nMinX ) + // nMinX = aPoint.X; + // + // if( aPoint.X > nMaxX ) + // nMaxX = aPoint.X; + // + // if( aPoint.Y < nMinY ) + // nMinY = aPoint.Y; + // + // if( aPoint.Y > nMaxY ) + // nMaxY = aPoint.Y; + // } + //} + // + //sal_Int32 nDifX(nMaxX - nMinX); + //sal_Int32 nDifY(nMaxY - nMinY); + + SdXMLImExViewBox aViewBox( + aPolyPolygonRange.getMinX(), + aPolyPolygonRange.getMinY(), + aPolyPolygonRange.getWidth(), + aPolyPolygonRange.getHeight()); rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() ); ///////////////// // Pathdata - pOuterSequence = aBezier.Coordinates.getArray(); - drawing::FlagSequence* pOuterFlags = aBezier.Flags.getArray(); - SdXMLImExSvgDElement aSvgDElement(aViewBox); - - for (a = 0; a < nOuterCnt; a++) - { - drawing::PointSequence* pSequence = pOuterSequence++; - drawing::FlagSequence* pFlags = pOuterFlags++; - - aSvgDElement.AddPolygon(pSequence, pFlags, - awt::Point( 0, 0 ), - awt::Size( aViewBox.GetWidth(), aViewBox.GetHeight() ), - bClosed); - } + const ::rtl::OUString aPolygonString( + basegfx::tools::exportToSvgD( + aPolyPolygon, + true, // bUseRelativeCoordinates + false)); // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now + + // TTTT + //pOuterSequence = aBezier.Coordinates.getArray(); + //drawing::FlagSequence* pOuterFlags = aBezier.Flags.getArray(); + //SdXMLImExSvgDElement aSvgDElement(aViewBox); + // + //for (a = 0; a < nOuterCnt; a++) + //{ + // drawing::PointSequence* pSequence = pOuterSequence++; + // drawing::FlagSequence* pFlags = pOuterFlags++; + // + // aSvgDElement.AddPolygon(pSequence, pFlags, + // awt::Point( 0, 0 ), + // awt::Size( aViewBox.GetWidth(), aViewBox.GetHeight() ), + // bClosed); + //} // write point array - rExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); + rExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString); ///////////////// // Do Write - SvXMLElementExport rElem( rExport, XML_NAMESPACE_DRAW, XML_MARKER, - sal_True, sal_False ); + SvXMLElementExport rElem( rExport, XML_NAMESPACE_DRAW, XML_MARKER, sal_True, sal_False ); } } diff --git a/xmloff/source/text/XMLTextFrameContext.cxx b/xmloff/source/text/XMLTextFrameContext.cxx index 13bef377b560..9afbe4e06840 100644 --- a/xmloff/source/text/XMLTextFrameContext.cxx +++ b/xmloff/source/text/XMLTextFrameContext.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" + #include <tools/debug.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/text/TextContentAnchorType.hpp> @@ -52,15 +51,16 @@ #include <xmloff/XMLEventsImportContext.hxx> #include "XMLImageMapContext.hxx" #include "XMLTextFrameContext.hxx" - #include "XMLTextListBlockContext.hxx" #include "XMLTextListItemContext.hxx" #include <xmloff/attrlist.hxx> #include <comphelper/stl_types.hxx> - +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> #include <map> - using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -284,36 +284,55 @@ XMLTextFrameContourContext_Impl::XMLTextFrameContourContext_Impl( } } - OUString sContourPolyPolygon( - RTL_CONSTASCII_USTRINGPARAM("ContourPolyPolygon") ); - Reference < XPropertySetInfo > xPropSetInfo = - rPropSet->getPropertySetInfo(); - if( xPropSetInfo->hasPropertyByName( - sContourPolyPolygon ) && - nWidth > 0 && nHeight > 0 && bPixelWidth == bPixelHeight && - (bPath ? sD : sPoints).getLength() ) + OUString sContourPolyPolygon(RTL_CONSTASCII_USTRINGPARAM("ContourPolyPolygon")); + Reference < XPropertySetInfo > xPropSetInfo = rPropSet->getPropertySetInfo(); + + if(xPropSetInfo->hasPropertyByName(sContourPolyPolygon) && nWidth > 0 && nHeight > 0 && bPixelWidth == bPixelHeight && (bPath ? sD : sPoints).getLength()) { - awt::Point aPoint( 0, 0 ); - awt::Size aSize( nWidth, nHeight ); - SdXMLImExViewBox aViewBox( sViewBox, - GetImport().GetMM100UnitConverter()); + const SdXMLImExViewBox aViewBox( sViewBox, GetImport().GetMM100UnitConverter()); + basegfx::B2DPolyPolygon aPolyPolygon; Any aAny; + if( bPath ) { - SdXMLImExSvgDElement aPoints( sD, aViewBox, aPoint, aSize, - GetImport().GetMM100UnitConverter() ); - aAny <<= aPoints.GetPointSequenceSequence(); + basegfx::tools::importFromSvgD( + aPolyPolygon, + sD); } else { - SdXMLImExPointsElement aPoints( sPoints, aViewBox, aPoint, aSize, - GetImport().GetMM100UnitConverter(), true ); - aAny <<= aPoints.GetPointSequenceSequence(); + basegfx::B2DPolygon aPolygon; + + if(basegfx::tools::importFromSvgPoints(aPolygon, sPoints)) + { + aPolyPolygon = basegfx::B2DPolyPolygon(aPolygon); + } } - OUString sIsPixelContour( - RTL_CONSTASCII_USTRINGPARAM("IsPixelContour") ); - xPropSet->setPropertyValue( sContourPolyPolygon, aAny ); + if(aPolyPolygon.count()) + { + const basegfx::B2DRange aSourceRange( + aViewBox.GetX(), aViewBox.GetY(), + aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight()); + const basegfx::B2DRange aTargetRange( + 0.0, 0.0, + nWidth, nHeight); + + if(!aSourceRange.equal(aTargetRange)) + { + aPolyPolygon.transform( + basegfx::tools::createSourceRangeTargetRangeTransform( + aSourceRange, + aTargetRange)); + } + + com::sun::star::drawing::PointSequenceSequence aPointSequenceSequence; + basegfx::tools::B2DPolyPolygonToUnoPointSequenceSequence(aPolyPolygon, aPointSequenceSequence); + aAny <<= aPointSequenceSequence; + xPropSet->setPropertyValue( sContourPolyPolygon, aAny ); + } + + const OUString sIsPixelContour(RTL_CONSTASCII_USTRINGPARAM("IsPixelContour")); if( xPropSetInfo->hasPropertyByName( sIsPixelContour ) ) { @@ -321,8 +340,8 @@ XMLTextFrameContourContext_Impl::XMLTextFrameContourContext_Impl( xPropSet->setPropertyValue( sIsPixelContour, aAny ); } - OUString sIsAutomaticContour( - RTL_CONSTASCII_USTRINGPARAM("IsAutomaticContour") ); + const OUString sIsAutomaticContour(RTL_CONSTASCII_USTRINGPARAM("IsAutomaticContour") ); + if( xPropSetInfo->hasPropertyByName( sIsAutomaticContour ) ) { aAny.setValue( &bAuto, ::getBooleanCppuType() ); diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx index 82068e7fb7ff..6a23dd514f70 100644 --- a/xmloff/source/text/txtparae.cxx +++ b/xmloff/source/text/txtparae.cxx @@ -19,8 +19,6 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" #include "unointerfacetouniqueidentifiermapper.hxx" @@ -32,11 +30,9 @@ #include <svl/svarray.hxx> #include <rtl/ustrbuf.hxx> #include <sal/types.h> - #include <vector> #include <list> #include <hash_map> - #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/container/XEnumeration.hpp> @@ -70,15 +66,12 @@ #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp> #include <com/sun/star/document/XEventsSupplier.hpp> #include <com/sun/star/document/XRedlinesSupplier.hpp> - #include <com/sun/star/text/XBookmarksSupplier.hpp> #include <com/sun/star/text/XFormField.hpp> - #include <com/sun/star/text/XTextSection.hpp> #include <com/sun/star/text/SectionFileLink.hpp> #include <com/sun/star/drawing/XShape.hpp> #include <com/sun/star/text/XTextShapesSupplier.hpp> - #include <com/sun/star/style/XAutoStylesSupplier.hpp> #include <com/sun/star/style/XAutoStyleFamily.hpp> #include <com/sun/star/text/XTextFieldsSupplier.hpp> @@ -112,11 +105,11 @@ #include <xmloff/formlayerexport.hxx> #include "XMLTextCharStyleNamesElementExport.hxx" #include <comphelper/stlunosequence.hxx> - -// --> OD 2008-04-25 #refactorlists# #include <txtlists.hxx> -// <-- #include <com/sun/star/rdf/XMetadatable.hpp> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -2877,34 +2870,46 @@ void XMLTextParagraphExport::exportContour( const Reference < XPropertySetInfo > & rPropSetInfo ) { if( !rPropSetInfo->hasPropertyByName( sContourPolyPolygon ) ) + { return; + } PointSequenceSequence aSourcePolyPolygon; rPropSet->getPropertyValue( sContourPolyPolygon ) >>= aSourcePolyPolygon; + const basegfx::B2DPolyPolygon aPolyPolygon( + basegfx::tools::UnoPointSequenceSequenceToB2DPolyPolygon( + aSourcePolyPolygon)); + const sal_uInt32 nPolygonCount(aPolyPolygon.count()); - if( !aSourcePolyPolygon.getLength() ) - return; - - awt::Point aPoint( 0, 0 ); - awt::Size aSize( 0, 0 ); - sal_Int32 nPolygons = aSourcePolyPolygon.getLength(); - const PointSequence *pPolygons = aSourcePolyPolygon.getConstArray(); - while( nPolygons-- ) + if(!nPolygonCount) { - sal_Int32 nPoints = pPolygons->getLength(); - const awt::Point *pPoints = pPolygons->getConstArray(); - while( nPoints-- ) - { - if( aSize.Width < pPoints->X ) - aSize.Width = pPoints->X; - if( aSize.Height < pPoints->Y ) - aSize.Height = pPoints->Y; - pPoints++; - } - pPolygons++; + return; } - sal_Bool bPixel = sal_False; + const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange()); + +// TTTT: +// awt::Point aPoint( 0, 0 ); +// awt::Size aSize( 0, 0 ); +// sal_Int32 nPolygons = aSourcePolyPolygon.getLength(); +// const PointSequence *pPolygons = aSourcePolyPolygon.getConstArray(); +// while( nPolygons-- ) +// { +// sal_Int32 nPoints = pPolygons->getLength(); +// const awt::Point *pPoints = pPolygons->getConstArray(); +// while( nPoints-- ) +// { +// if( aSize.Width < pPoints->X ) +// aSize.Width = pPoints->X; +// if( aSize.Height < pPoints->Y ) +// aSize.Height = pPoints->Y; +// pPoints++; +// } +// pPolygons++; +// } + + bool bPixel(false); + if( rPropSetInfo->hasPropertyByName( sIsPixelContour ) ) { bPixel = *(sal_Bool *)rPropSet->getPropertyValue( sIsPixelContour ).getValue(); @@ -2912,67 +2917,87 @@ void XMLTextParagraphExport::exportContour( // svg: width OUStringBuffer aStringBuffer( 10 ); - if( bPixel ) - GetExport().GetMM100UnitConverter().convertMeasurePx(aStringBuffer, aSize.Width); + + if(bPixel) + { + GetExport().GetMM100UnitConverter().convertMeasurePx(aStringBuffer, aPolyPolygonRange.getWidth()); + } else - GetExport().GetMM100UnitConverter().convertMeasure(aStringBuffer, aSize.Width); - GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH, - aStringBuffer.makeStringAndClear() ); + { + GetExport().GetMM100UnitConverter().convertMeasure(aStringBuffer, aPolyPolygonRange.getWidth()); + } + + GetExport().AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStringBuffer.makeStringAndClear()); // svg: height - if( bPixel ) - GetExport().GetMM100UnitConverter().convertMeasurePx(aStringBuffer, aSize.Height); + if(bPixel) + { + GetExport().GetMM100UnitConverter().convertMeasurePx(aStringBuffer, aPolyPolygonRange.getHeight()); + } else - GetExport().GetMM100UnitConverter().convertMeasure(aStringBuffer, aSize.Height); - GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT, - aStringBuffer.makeStringAndClear() ); - - // svg:viewbox - SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height); - GetExport().AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, - aViewBox.GetExportString()); + { + GetExport().GetMM100UnitConverter().convertMeasure(aStringBuffer, aPolyPolygonRange.getHeight()); + } - sal_Int32 nOuterCnt( aSourcePolyPolygon.getLength() ); + GetExport().AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStringBuffer.makeStringAndClear()); + // svg:viewbox + SdXMLImExViewBox aViewBox(0.0, 0.0, aPolyPolygonRange.getWidth(), aPolyPolygonRange.getHeight()); + GetExport().AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString()); enum XMLTokenEnum eElem = XML_TOKEN_INVALID; - if( 1L == nOuterCnt ) + + if(1 == nPolygonCount ) { // simple polygon shape, can be written as svg:points sequence - /*const*/ PointSequence* pSequence = - (PointSequence*)aSourcePolyPolygon.getConstArray(); + const ::rtl::OUString aPointString( + basegfx::tools::exportToSvgPoints( + aPolyPolygon.getB2DPolygon(0))); - SdXMLImExPointsElement aPoints( pSequence, aViewBox, aPoint, aSize, true); + // TTTT + //PointSequence* pSequence = (PointSequence*)aSourcePolyPolygon.getConstArray(); + //SdXMLImExPointsElement aPoints( pSequence, aViewBox, aPolyPolygonRange.getMinimum(), aPolyPolygonRange.getRange(), true); // write point array - GetExport().AddAttribute( XML_NAMESPACE_DRAW, XML_POINTS, - aPoints.GetExportString()); + GetExport().AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString); eElem = XML_CONTOUR_POLYGON; } else { // polypolygon, needs to be written as a svg:path sequence - /*const*/ PointSequence* pOuterSequence = - (PointSequence*)aSourcePolyPolygon.getConstArray(); - if(pOuterSequence) - { - // prepare svx:d element export - SdXMLImExSvgDElement aSvgDElement( aViewBox ); - - for(sal_Int32 a(0L); a < nOuterCnt; a++) - { - /*const*/ PointSequence* pSequence = pOuterSequence++; - if(pSequence) - { - aSvgDElement.AddPolygon(pSequence, 0L, aPoint, - aSize, sal_True ); - } - } + const ::rtl::OUString aPolygonString( + basegfx::tools::exportToSvgD( + aPolyPolygon, + true, // bUseRelativeCoordinates + false)); // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now - // write point array - GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_D, - aSvgDElement.GetExportString()); - eElem = XML_CONTOUR_PATH; - } + // write point array + GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_D, aPolygonString); + eElem = XML_CONTOUR_PATH; + + // TTTT + ///*const*/ PointSequence* pOuterSequence = + // (PointSequence*)aSourcePolyPolygon.getConstArray(); + //if(pOuterSequence) + //{ + // // prepare svx:d element export + // SdXMLImExSvgDElement aSvgDElement( aViewBox ); + // + // for(sal_Int32 a(0L); a < nPolygonCount; a++) + // { + // /*const*/ PointSequence* pSequence = pOuterSequence++; + // if(pSequence) + // { + // awt::Point aPoint(aPolyPolygonRange.getMinX(), aPolyPolygonRange.getMinY()); + // awt::Size aSize(aPolyPolygonRange.getWidth(), aPolyPolygonRange.getHeight()); + // aSvgDElement.AddPolygon(pSequence, 0L, aPoint, aSize, sal_True ); + // } + // } + // + // // write point array + // GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_D, + // aSvgDElement.GetExportString()); + // eElem = XML_CONTOUR_PATH; + //} } if( rPropSetInfo->hasPropertyByName( sIsAutomaticContour ) ) |