23 #include <osl/diagnose.h>
37 #define HATCH_MAXPOINTS 1024
48 return ( nX1 > nX2 ? 1 : nX1 == nX2 ? nY1 > nY2 ? 1: nY1 == nY2 ? 0 : -1 : -1 );
57 Hatch aHatch( rHatch );
71 const sal_uInt8 cLum = aColor.GetLuminance();
72 aColor =
Color( cLum, cLum, cLum );
97 if( rPolyPoly.
Count() )
101 bool bOldMap =
mbMap;
103 aPolyPoly.
Optimize( PolyOptimizeFlags::NO_SAME );
126 aPolyPoly.
Optimize( PolyOptimizeFlags::NO_SAME | PolyOptimizeFlags::CLOSE );
128 if( aPolyPoly.
Count() )
145 if(!rPolyPoly.
Count())
149 bool bIsCurve(
false);
151 for(sal_uInt16
a(0); !bIsCurve &&
a < rPolyPoly.
Count();
a++)
153 if(rPolyPoly[
a].HasFlags())
161 OSL_ENSURE(
false,
"DrawHatch does *not* support curves, falling back to AdaptiveSubdivide()...");
173 Point aPt1, aPt2, aEndPt1;
177 aRect.AdjustLeft( -nLogPixelWidth ); aRect.AdjustTop( -nLogPixelWidth ); aRect.AdjustRight(nLogPixelWidth ); aRect.AdjustBottom(nLogPixelWidth );
182 aPt1.AdjustX(aInc.Width() ); aPt1.AdjustY(aInc.Height() );
183 aPt2.AdjustX(aInc.Width() ); aPt2.AdjustY(aInc.Height() );
185 while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) );
187 if( ( rHatch.
GetStyle() == HatchStyle::Double ) || ( rHatch.
GetStyle() == HatchStyle::Triple ) )
194 aPt1.AdjustX(aInc.Width() ); aPt1.AdjustY(aInc.Height() );
195 aPt2.AdjustX(aInc.Width() ); aPt2.AdjustY(aInc.Height() );
197 while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) );
199 if( rHatch.
GetStyle() == HatchStyle::Triple )
206 aPt1.AdjustX(aInc.Width() ); aPt1.AdjustY(aInc.Height() );
207 aPt2.AdjustX(aInc.Width() ); aPt2.AdjustY(aInc.Height() );
209 while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) );
216 Point& rPt1, Point& rPt2,
Size& rInc, Point& rEndPt1 )
219 Degree10 nAngle = nAngle10 % 1800_deg10;
222 if( nAngle > 900_deg10 )
223 nAngle -= 1800_deg10;
227 if( 0_deg10 == nAngle )
229 rInc =
Size( 0, nDist );
234 if( aRef.Y() <= rRect.
Top() )
235 nOffset = ( ( rRect.
Top() - aRef.Y() ) % nDist );
237 nOffset = ( nDist - ( ( aRef.Y() - rRect.
Top() ) % nDist ) );
239 rPt1.AdjustY( -nOffset );
240 rPt2.AdjustY( -nOffset );
242 else if( 900_deg10 == nAngle )
244 rInc =
Size( nDist, 0 );
249 if( aRef.X() <= rRect.
Left() )
250 nOffset = ( rRect.
Left() - aRef.X() ) % nDist;
252 nOffset = nDist - ( ( aRef.X() - rRect.
Left() ) % nDist );
254 rPt1.AdjustX( -nOffset );
255 rPt2.AdjustX( -nOffset );
257 else if( nAngle >=
Degree10(-450) && nAngle <= 450_deg10 )
259 const double fAngle =
F_PI1800 * std::abs( nAngle.
get() );
260 const double fTan = tan( fAngle );
264 nDist =
FRound( nDist / cos( fAngle ) );
265 rInc =
Size( 0, nDist );
267 if( nAngle > 0_deg10 )
272 nPY =
FRound( aRef.Y() - ( ( rPt1.X() - aRef.X() ) * fTan ) );
279 nPY =
FRound( aRef.Y() + ( ( rPt1.X() - aRef.X() ) * fTan ) );
282 if( nPY <= rPt1.Y() )
283 nOffset = ( rPt1.Y() - nPY ) % nDist;
285 nOffset = nDist - ( ( nPY - rPt1.Y() ) % nDist );
287 rPt1.AdjustY( -nOffset );
288 rPt2.AdjustY( -nOffset );
292 const double fAngle =
F_PI1800 * std::abs( nAngle.
get() );
293 const double fTan = tan( fAngle );
297 nDist =
FRound( nDist / sin( fAngle ) );
298 rInc =
Size( nDist, 0 );
300 if( nAngle > 0_deg10 )
305 nPX =
FRound( aRef.X() - ( ( rPt1.Y() - aRef.Y() ) / fTan ) );
312 nPX =
FRound( aRef.X() + ( ( rPt1.Y() - aRef.Y() ) / fTan ) );
315 if( nPX <= rPt1.X() )
316 nOffset = ( rPt1.X() - nPX ) % nDist;
318 nOffset = nDist - ( ( nPX - rPt1.X() ) % nDist );
320 rPt1.AdjustX( -nOffset );
321 rPt2.AdjustX( -nOffset );
326 Point* pPtBuffer,
bool bMtf )
333 for(
tools::Long nPoly = 0, nPolyCount = rPolyPoly.
Count(); nPoly < nPolyCount; nPoly++ )
335 const tools::Polygon& rPoly = rPolyPoly[
static_cast<sal_uInt16
>(nPoly) ];
343 aCurSegment.
SetEnd( rPoly[ static_cast<sal_uInt16>(
i %
nCount ) ] );
348 if( ( fabs( fX - aCurSegment.
GetStart().X() ) <= 0.0000001 ) &&
349 ( fabs( fY - aCurSegment.
GetStart().Y() ) <= 0.0000001 ) )
351 const tools::Line aPrevSegment( rPoly[ static_cast<sal_uInt16>( (
i > 1 ) ? (
i - 2 ) : ( nCount - 1 ) ) ], aCurSegment.
GetStart() );
352 const double fPrevDistance = rLine.
GetDistance( aPrevSegment.GetStart() );
355 if( ( fPrevDistance <= 0.0 && fCurDistance > 0.0 ) ||
356 ( fPrevDistance > 0.0 && fCurDistance < 0.0 ) )
361 else if( ( fabs( fX - aCurSegment.
GetEnd().X() ) <= 0.0000001 ) &&
362 ( fabs( fY - aCurSegment.
GetEnd().Y() ) <= 0.0000001 ) )
364 const tools::Line aNextSegment( aCurSegment.
GetEnd(), rPoly[
static_cast<sal_uInt16
>( (
i + 1 ) % nCount ) ] );
366 if( ( fabs( rLine.
GetDistance( aNextSegment.GetEnd() ) ) <= 0.0000001 ) &&
void SetDistance(tools::Long nDistance)
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
void DrawLine(tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2, const OutputDevice &rOutDev)
const Point & GetRefPoint() const
SAL_DLLPRIVATE void CalcHatchValues(const tools::Rectangle &rRect, tools::Long nDist, Degree10 nAngle10, Point &rPt1, Point &rPt2, Size &rInc, Point &rEndPt1)
const StyleSettings & GetStyleSettings() const
SAL_DLLPRIVATE bool is_double_buffered_window() const
void EnableMapMode(bool bEnable=true)
SAL_DLLPRIVATE void InitLineColor()
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
HatchStyle GetStyle() const
static int HatchCmpFnc(const void *p1, const void *p2)
SalGraphics * mpGraphics
Graphics context to draw on.
UNDERLYING_TYPE get() const
tools::Long FRound(double fVal)
SAL_DLLPRIVATE void DrawHatchLine(const tools::Line &rLine, const tools::PolyPolygon &rPolyPoly, Point *pPtBuffer, bool bMtf)
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
const Color & GetColor() const
const Color & GetFontColor() const
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
const AllSettings & GetSettings() const
void DrawHatch(const tools::PolyPolygon &rPolyPoly, const Hatch &rHatch)
virtual void DrawHatchLine_DrawLine(const Point &rStartPoint, const Point &rEndPoint)
Point LogicToPixel(const Point &rLogicPt) const
VclPtr< VirtualDevice > mpAlphaVDev
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
virtual void InitClipRegion()
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
void AddHatchActions(const tools::PolyPolygon &rPolyPoly, const Hatch &rHatch, GDIMetaFile &rMtf)
tools::Long GetDistance() const
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
Degree10 GetAngle() const
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicWidth(tools::Long nWidth) const
Convert device pixels to a width in logical units.
bool IsDeviceOutputNecessary() const
void Push(PushFlags nFlags=PushFlags::ALL)
void SetColor(const Color &rColor)