diff options
author | Radek Doulik <rodo@novell.com> | 2011-10-05 16:09:26 +0200 |
---|---|---|
committer | Radek Doulik <rodo@novell.com> | 2011-10-05 17:40:21 +0200 |
commit | fcdc9c4fa0f318f3fe7a9cba3a95f0737fb62ffc (patch) | |
tree | 0b08dd36ea08b767587d9d5b6bfcb08471e3ba3a /svx | |
parent | 1c0ae973ddabddaf30fe1598127ba2e99a3d5531 (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.hxx | 6 | ||||
-rw-r--r-- | svx/source/customshapes/EnhancedCustomShape2d.cxx | 110 | ||||
-rw-r--r-- | svx/source/customshapes/EnhancedCustomShapeFunctionParser.cxx | 24 |
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 |