diff --git a/tools/source/generic/poly2.cxx b/tools/source/generic/poly2.cxx index 535ff9ac1c01..2650960db126 100644 --- a/tools/source/generic/poly2.cxx +++ b/tools/source/generic/poly2.cxx @@ -241,39 +241,62 @@ void PolyPolygon::Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* { DBG_CHKTHIS( PolyPolygon, NULL ); - if( nOptimizeFlags ) + if(nOptimizeFlags && Count()) { - double fArea; - const sal_Bool bEdges = ( nOptimizeFlags & POLY_OPTIMIZE_EDGES ) == POLY_OPTIMIZE_EDGES; - sal_uInt16 nPercent = 0; + // #115630# ImplDrawHatch does not work with beziers included in the polypolygon, take care of that + bool bIsCurve(false); - if( bEdges ) + for(sal_uInt16 a(0); !bIsCurve && a < Count(); a++) { - const Rectangle aBound( GetBoundRect() ); - - fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5; - nPercent = pData ? pData->GetPercentValue() : 50; - nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES; + if((*this)[a].HasFlags()) + { + bIsCurve = true; + } } - // watch for ref counter - if( mpImplPolyPolygon->mnRefCount > 1 ) + if(bIsCurve) { - mpImplPolyPolygon->mnRefCount--; - mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); - } + OSL_ENSURE(false, "Optimize does *not* support curves, falling back to AdaptiveSubdivide()..."); + PolyPolygon aPolyPoly; - // Optimize polygons - for( sal_uInt16 i = 0, nPolyCount = mpImplPolyPolygon->mnCount; i < nPolyCount; i++ ) + AdaptiveSubdivide(aPolyPoly); + aPolyPoly.Optimize(nOptimizeFlags, pData); + *this = aPolyPoly; + } + else { + double fArea; + const sal_Bool bEdges = ( nOptimizeFlags & POLY_OPTIMIZE_EDGES ) == POLY_OPTIMIZE_EDGES; + sal_uInt16 nPercent = 0; + if( bEdges ) { - mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( POLY_OPTIMIZE_NO_SAME ); - Polygon::ImplReduceEdges( *( mpImplPolyPolygon->mpPolyAry[ i ] ), fArea, nPercent ); + const Rectangle aBound( GetBoundRect() ); + + fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5; + nPercent = pData ? pData->GetPercentValue() : 50; + nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES; } - if( nOptimizeFlags ) - mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( nOptimizeFlags, pData ); + // watch for ref counter + if( mpImplPolyPolygon->mnRefCount > 1 ) + { + mpImplPolyPolygon->mnRefCount--; + mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); + } + + // Optimize polygons + for( sal_uInt16 i = 0, nPolyCount = mpImplPolyPolygon->mnCount; i < nPolyCount; i++ ) + { + if( bEdges ) + { + mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( POLY_OPTIMIZE_NO_SAME ); + Polygon::ImplReduceEdges( *( mpImplPolyPolygon->mpPolyAry[ i ] ), fArea, nPercent ); + } + + if( nOptimizeFlags ) + mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( nOptimizeFlags, pData ); + } } } } diff --git a/vcl/source/gdi/outdev4.cxx b/vcl/source/gdi/outdev4.cxx index dba20d33f504..4dd70e638486 100644 --- a/vcl/source/gdi/outdev4.cxx +++ b/vcl/source/gdi/outdev4.cxx @@ -1077,40 +1077,39 @@ void OutputDevice::AddHatchActions( const PolyPolygon& rPolyPoly, const Hatch& r void OutputDevice::ImplDrawHatch( const PolyPolygon& rPolyPoly, const Hatch& rHatch, sal_Bool bMtf ) { - Rectangle aRect( rPolyPoly.GetBoundRect() ); - const long nLogPixelWidth = ImplDevicePixelToLogicWidth( 1 ); - const long nWidth = ImplDevicePixelToLogicWidth( std::max( ImplLogicWidthToDevicePixel( rHatch.GetDistance() ), 3L ) ); - Point* pPtBuffer = new Point[ HATCH_MAXPOINTS ]; - Point aPt1, aPt2, aEndPt1; - Size aInc; - - // Single hatch - aRect.Left() -= nLogPixelWidth; aRect.Top() -= nLogPixelWidth; aRect.Right() += nLogPixelWidth; aRect.Bottom() += nLogPixelWidth; - ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle(), aPt1, aPt2, aInc, aEndPt1 ); - do + if(rPolyPoly.Count()) { - ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf ); - aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height(); - aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height(); - } - while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) ); + // #i115630# ImplDrawHatch does not work with beziers included in the polypolygon, take care of that + bool bIsCurve(false); - if( ( rHatch.GetStyle() == HATCH_DOUBLE ) || ( rHatch.GetStyle() == HATCH_TRIPLE ) ) - { - // Double hatch - ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle() + 900, aPt1, aPt2, aInc, aEndPt1 ); - do + for(sal_uInt16 a(0); !bIsCurve && a < rPolyPoly.Count(); a++) { - ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf ); - aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height(); - aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height(); + if(rPolyPoly[a].HasFlags()) + { + bIsCurve = true; + } } - while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) ); - if( rHatch.GetStyle() == HATCH_TRIPLE ) + if(bIsCurve) { - // Triple hatch - ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle() + 450, aPt1, aPt2, aInc, aEndPt1 ); + OSL_ENSURE(false, "ImplDrawHatch does *not* support curves, falling back to AdaptiveSubdivide()..."); + PolyPolygon aPolyPoly; + + rPolyPoly.AdaptiveSubdivide(aPolyPoly); + ImplDrawHatch(aPolyPoly, rHatch, bMtf); + } + else + { + Rectangle aRect( rPolyPoly.GetBoundRect() ); + const long nLogPixelWidth = ImplDevicePixelToLogicWidth( 1 ); + const long nWidth = ImplDevicePixelToLogicWidth( std::max( ImplLogicWidthToDevicePixel( rHatch.GetDistance() ), 3L ) ); + Point* pPtBuffer = new Point[ HATCH_MAXPOINTS ]; + Point aPt1, aPt2, aEndPt1; + Size aInc; + + // Single hatch + aRect.Left() -= nLogPixelWidth; aRect.Top() -= nLogPixelWidth; aRect.Right() += nLogPixelWidth; aRect.Bottom() += nLogPixelWidth; + ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle(), aPt1, aPt2, aInc, aEndPt1 ); do { ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf ); @@ -1118,10 +1117,36 @@ void OutputDevice::ImplDrawHatch( const PolyPolygon& rPolyPoly, const Hatch& rHa aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height(); } while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) ); + + if( ( rHatch.GetStyle() == HATCH_DOUBLE ) || ( rHatch.GetStyle() == HATCH_TRIPLE ) ) + { + // Double hatch + ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle() + 900, aPt1, aPt2, aInc, aEndPt1 ); + do + { + ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf ); + aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height(); + aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height(); + } + while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) ); + + if( rHatch.GetStyle() == HATCH_TRIPLE ) + { + // Triple hatch + ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle() + 450, aPt1, aPt2, aInc, aEndPt1 ); + do + { + ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf ); + aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height(); + aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height(); + } + while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) ); + } + } + + delete[] pPtBuffer; } } - - delete[] pPtBuffer; } void OutputDevice::ImplCalcHatchValues( const Rectangle& rRect, long nDist, sal_uInt16 nAngle10,