summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorRadek Doulik <rodo@novell.com>2011-10-05 16:09:26 +0200
committerRadek Doulik <rodo@novell.com>2011-10-05 17:40:21 +0200
commitfcdc9c4fa0f318f3fe7a9cba3a95f0737fb62ffc (patch)
tree0b08dd36ea08b767587d9d5b6bfcb08471e3ba3a /svx
parent1c0ae973ddabddaf30fe1598127ba2e99a3d5531 (diff)
added ARCANGLETO command implementation, optimization, fixes, debug
- added new ARCANGLETO command needed for PPTX custom shapes import - added added placeholder for unimplemented QUADRATICCURVETO command, skip it's data at least so that we don't break other things for now - cache equations results to optimize custom shapes calculation PPTX import creates such equations that made system busy for long time, this removes that issue - added lot of debug output to help with debugging of complex imported custom shapes
Diffstat (limited to 'svx')
-rw-r--r--svx/inc/svx/EnhancedCustomShape2d.hxx6
-rw-r--r--svx/source/customshapes/EnhancedCustomShape2d.cxx110
-rw-r--r--svx/source/customshapes/EnhancedCustomShapeFunctionParser.cxx24
3 files changed, 129 insertions, 11 deletions
diff --git a/svx/inc/svx/EnhancedCustomShape2d.hxx b/svx/inc/svx/EnhancedCustomShape2d.hxx
index 867aac13fa3c..2aadcf895d13 100644
--- a/svx/inc/svx/EnhancedCustomShape2d.hxx
+++ b/svx/inc/svx/EnhancedCustomShape2d.hxx
@@ -103,9 +103,13 @@ class EnhancedCustomShape2d : public SfxItemSet
/*
*/
+ struct EquationResult {
+ sal_Bool bReady;
+ double fValue;
+ };
com::sun::star::uno::Sequence< rtl::OUString > seqEquations;
std::vector< ::boost::shared_ptr< EnhancedCustomShape::ExpressionNode > > vNodesSharedPtr;
-
+ std::vector< EquationResult > vEquationResults;
com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments;
com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx
index 1d0baff17e5d..b19087f6b474 100644
--- a/svx/source/customshapes/EnhancedCustomShape2d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx
@@ -824,14 +824,18 @@ EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
if ( nLength )
{
vNodesSharedPtr.resize( nLength );
+ vEquationResults.resize( nLength );
for ( i = 0; i < seqEquations.getLength(); i++ )
{
+ vEquationResults[ i ].bReady = sal_False;
try
{
vNodesSharedPtr[ i ] = EnhancedCustomShape::FunctionParser::parseFunction( seqEquations[ i ], *this );
}
catch ( EnhancedCustomShape::ParseError& )
{
+ OSL_TRACE("error: equation number: %d, parser failed ( %s )",
+ i, OUStringToOString( seqEquations[ i ], RTL_TEXTENCODING_ASCII_US ).getStr());
}
}
}
@@ -876,20 +880,49 @@ double EnhancedCustomShape2d::GetAdjustValueAsDouble( const sal_Int32 nIndex ) c
double EnhancedCustomShape2d::GetEquationValueAsDouble( const sal_Int32 nIndex ) const
{
double fNumber = 0.0;
+#if OSL_DEBUG_LEVEL > 1
+ static sal_uInt32 nLevel = 0;
+#endif
if ( nIndex < (sal_Int32)vNodesSharedPtr.size() )
{
- if ( vNodesSharedPtr[ nIndex ].get() )
- try
- {
- fNumber = (*vNodesSharedPtr[ nIndex ])();
- if ( !rtl::math::isFinite( fNumber ) )
- fNumber = 0.0;
- }
- catch ( ... )
- {
- /* sal_Bool bUps = sal_True; */
+ if ( vNodesSharedPtr[ nIndex ].get() ) {
+#if OSL_DEBUG_LEVEL > 1
+ nLevel ++;
+#endif
+ try
+ {
+ if ( vEquationResults[ nIndex ].bReady )
+ fNumber = vEquationResults[ nIndex ].fValue;
+ else {
+ // cast to non const, so that we can optimize by caching
+ // equation results, without changing all the const in the stack
+ struct EquationResult &aResult = ((EnhancedCustomShape2d*)this)->vEquationResults[ nIndex ];
+
+ fNumber = aResult.fValue = (*vNodesSharedPtr[ nIndex ])();
+ aResult.bReady = sal_True;
+
+ if ( !rtl::math::isFinite( fNumber ) )
+ fNumber = 0.0;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE("equation %d (level: %d): %s --> %f (angle: %f)", nIndex,
+ nLevel, OUStringToOString( seqEquations[ nIndex ],
+ RTL_TEXTENCODING_ASCII_US ).getStr(), fNumber, 180.0*fNumber/10800000.0);
+#endif
+ }
+ }
+ catch ( ... )
+ {
+ /* sal_Bool bUps = sal_True; */
+ OSL_TRACE("error: EnhancedCustomShape2d::GetEquationValueAsDouble failed");
+ }
+#if OSL_DEBUG_LEVEL > 1
+ nLevel --;
+#endif
}
+ OSL_TRACE(" ?%d --> %f (angle: %f)", nIndex,
+ fNumber, 180.0*fNumber/10800000.0);
}
+
return fNumber;
}
sal_Int32 EnhancedCustomShape2d::GetAdjustValueAsInteger( const sal_Int32 nIndex, const sal_Int32 nDefault ) const
@@ -1457,6 +1490,7 @@ void EnhancedCustomShape2d::CreateSubPath( sal_uInt16& rSrcPt, sal_uInt16& rSegm
if ( rSrcPt < nCoordSize )
{
const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True ));
+ OSL_TRACE("moveTo: %d,%d", aTempPoint.X(), aTempPoint.Y());
aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
}
}
@@ -1591,11 +1625,19 @@ void EnhancedCustomShape2d::CreateSubPath( sal_uInt16& rSrcPt, sal_uInt16& rSegm
}
break;
+ case QUADRATICCURVETO : // TODO
+ for ( sal_Int32 i(0L); ( i < nPntCount ) && ( rSrcPt + 1 < nCoordSize ); i++ )
+ {
+ rSrcPt += 2;
+ }
+ break;
+
case LINETO :
{
for ( sal_Int32 i(0L); ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ )
{
const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True ));
+ OSL_TRACE("lineTo: %d,%d", aTempPoint.X(), aTempPoint.Y());
aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
}
}
@@ -1638,6 +1680,54 @@ void EnhancedCustomShape2d::CreateSubPath( sal_uInt16& rSrcPt, sal_uInt16& rSegm
}
break;
+ case ARCANGLETO :
+ {
+ double fWR, fHR, fStartAngle, fSwingAngle;
+
+ for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( rSrcPt + 1 < nCoordSize ); i++ )
+ {
+ GetParameter ( fWR, seqCoordinates[ (sal_uInt16)( rSrcPt ) ].First, sal_True, sal_False );
+ GetParameter ( fHR, seqCoordinates[ (sal_uInt16)( rSrcPt ) ].Second, sal_False, sal_True );
+
+ GetParameter ( fStartAngle, seqCoordinates[ (sal_uInt16)( rSrcPt + 1) ].First, sal_False, sal_False );
+ GetParameter ( fSwingAngle, seqCoordinates[ (sal_uInt16)( rSrcPt + 1 ) ].Second, sal_False, sal_False );
+
+ fWR *= fXScale;
+ fHR *= fYScale;
+
+ fStartAngle *= F_PI180;
+ fSwingAngle *= F_PI180;
+
+ OSL_TRACE("ARCANGLETO scale: %f x %f angles: %f, %f", fWR, fHR, fStartAngle, fSwingAngle);
+
+ sal_Bool bClockwise = fSwingAngle >= 0.0;
+
+ if (aNewB2DPolygon.count() > 0)
+ {
+ basegfx::B2DPoint aStartPointB2D( aNewB2DPolygon.getB2DPoint(aNewB2DPolygon.count() - 1 ) );
+ Point aStartPoint( aStartPointB2D.getX(), aStartPointB2D.getY() );
+
+ double fT = atan2((fWR*sin(fStartAngle)), (fHR*cos(fStartAngle)));
+ double fTE = atan2((fWR*sin(fStartAngle + fSwingAngle)), fHR*cos(fStartAngle + fSwingAngle));
+
+ OSL_TRACE("ARCANGLETO angles: %f, %f --> parameters: %f, %f", fStartAngle, fSwingAngle, fT, fTE );
+
+ Rectangle aRect ( Point ( aStartPoint.getX() - fWR*cos(fT) - fWR, aStartPoint.getY() - fHR*sin(fT) - fHR ),
+ Point ( aStartPoint.getX() - fWR*cos(fT) + fWR, aStartPoint.getY() - fHR*sin(fT) + fHR) );
+
+ Point aEndPoint ( aStartPoint.getX() - fWR*(cos(fT) - cos(fTE)), aStartPoint.getY() - fHR*(sin(fT) - sin(fTE)) );
+
+ OSL_TRACE("ARCANGLETO rect: %d, %d x %d, %d start: %d, %d end: %d, %d clockwise: %d",
+ aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom(),
+ aStartPoint.X(), aStartPoint.Y(), aEndPoint.X(), aEndPoint.Y(), bClockwise);
+ aNewB2DPolygon.append(CreateArc( aRect, bClockwise ? aEndPoint : aStartPoint, bClockwise ? aStartPoint : aEndPoint, bClockwise));
+ }
+
+ rSrcPt += 2;
+ }
+ }
+ break;
+
case ELLIPTICALQUADRANTX :
case ELLIPTICALQUADRANTY :
{
diff --git a/svx/source/customshapes/EnhancedCustomShapeFunctionParser.cxx b/svx/source/customshapes/EnhancedCustomShapeFunctionParser.cxx
index 7c71123b740b..b72ed51f8a62 100644
--- a/svx/source/customshapes/EnhancedCustomShapeFunctionParser.cxx
+++ b/svx/source/customshapes/EnhancedCustomShapeFunctionParser.cxx
@@ -163,6 +163,7 @@ public:
}
virtual double operator()() const
{
+ OSL_TRACE(" $%d --> %f (angle: %f)", mnIndex, mrCustoShape.GetAdjustValueAsDouble( mnIndex ), 180.0*mrCustoShape.GetAdjustValueAsDouble( mnIndex )/10800000.0);
return mrCustoShape.GetAdjustValueAsDouble( mnIndex );
}
virtual bool isConstant() const
@@ -253,6 +254,29 @@ public:
}
virtual double operator()() const
{
+#if OSL_DEBUG_LEVEL > 1
+ const char *funcName;
+
+ switch (meFunct) {
+ case ENUM_FUNC_PI : funcName = "pi"; break;
+ case ENUM_FUNC_LEFT : funcName = "left"; break;
+ case ENUM_FUNC_TOP : funcName = "top"; break;
+ case ENUM_FUNC_RIGHT : funcName = "right"; break;
+ case ENUM_FUNC_BOTTOM : funcName = "bottom"; break;
+ case ENUM_FUNC_XSTRETCH : funcName = "xstretch"; break;
+ case ENUM_FUNC_YSTRETCH : funcName = "ystretch"; break;
+ case ENUM_FUNC_HASSTROKE : funcName = "hasstroke"; break;
+ case ENUM_FUNC_HASFILL : funcName = "hasfill"; break;
+ case ENUM_FUNC_WIDTH : funcName = "width"; break;
+ case ENUM_FUNC_HEIGHT : funcName = "height"; break;
+ case ENUM_FUNC_LOGWIDTH : funcName = "logwidth"; break;
+ case ENUM_FUNC_LOGHEIGHT : funcName = "logheight"; break;
+ default: funcName = "???"; break;
+ }
+
+ OSL_TRACE(" %s --> %f (angle: %f)", funcName, getValue( mrCustoShape, meFunct ), 180.0*getValue( mrCustoShape, meFunct )/10800000.0);
+#endif
+
return getValue( mrCustoShape, meFunct );
}
virtual bool isConstant() const