Author: alg Date: Thu Sep 27 13:07:14 2012 New Revision: 1390986 URL: http://svn.apache.org/viewvc?rev=1390986&view=rev Log: #115630# secured OutputDevice::ImplDrawHatch in vcl and PolyPolygon::Optimize in tools to useful fallbacks when working on PolyPolygons (what they do *not* support)
Modified: incubator/ooo/trunk/main/tools/source/generic/poly2.cxx incubator/ooo/trunk/main/vcl/source/gdi/outdev4.cxx Modified: incubator/ooo/trunk/main/tools/source/generic/poly2.cxx URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/tools/source/generic/poly2.cxx?rev=1390986&r1=1390985&r2=1390986&view=diff ============================================================================== --- incubator/ooo/trunk/main/tools/source/generic/poly2.cxx (original) +++ incubator/ooo/trunk/main/tools/source/generic/poly2.cxx Thu Sep 27 13:07:14 2012 @@ -281,40 +281,63 @@ void PolyPolygon::Optimize( sal_uIntPtr { 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 ) - { - const Rectangle aBound( GetBoundRect() ); - - fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5; - nPercent = pData ? pData->GetPercentValue() : 50; - nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES; - } - - // watch for ref counter - if( mpImplPolyPolygon->mnRefCount > 1 ) - { - mpImplPolyPolygon->mnRefCount--; - mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); - } + for(sal_uInt16 a(0); !bIsCurve && a < Count(); a++) + { + if((*this)[a].HasFlags()) + { + bIsCurve = true; + } + } - // 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(bIsCurve) + { + OSL_ENSURE(false, "Optimize does *not* support curves, falling back to AdaptiveSubdivide()..."); + PolyPolygon aPolyPoly; - if( nOptimizeFlags ) - mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( nOptimizeFlags, pData ); - } + 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 ) + { + const Rectangle aBound( GetBoundRect() ); + + fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5; + nPercent = pData ? pData->GetPercentValue() : 50; + nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES; + } + + // 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 ); + } + } } } Modified: incubator/ooo/trunk/main/vcl/source/gdi/outdev4.cxx URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/source/gdi/outdev4.cxx?rev=1390986&r1=1390985&r2=1390986&view=diff ============================================================================== --- incubator/ooo/trunk/main/vcl/source/gdi/outdev4.cxx (original) +++ incubator/ooo/trunk/main/vcl/source/gdi/outdev4.cxx Thu Sep 27 13:07:14 2012 @@ -1170,51 +1170,76 @@ void OutputDevice::AddHatchActions( cons 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( 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 ); - 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_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; + if(rPolyPoly.Count()) + { + // #115630# ImplDrawHatch does not work with beziers included in the polypolygon, take care of that + bool bIsCurve(false); + + for(sal_uInt16 a(0); !bIsCurve && a < rPolyPoly.Count(); a++) + { + if(rPolyPoly[a].HasFlags()) + { + bIsCurve = true; + } + } + + if(bIsCurve) + { + 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( 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 ); + 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_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; + } + } } // -----------------------------------------------------------------------