20#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 );
76 if( rPolyPoly.
Count() )
82 aPolyPoly.
Optimize( PolyOptimizeFlags::NO_SAME );
105 aPolyPoly.
Optimize( PolyOptimizeFlags::NO_SAME | PolyOptimizeFlags::CLOSE );
107 if( aPolyPoly.
Count() )
127 nVertSteps = std::numeric_limits<tools::Long>::max();
129 nVertSteps = nVertSteps / rInc.
Height();
136 nHorzSteps = std::numeric_limits<tools::Long>::max();
138 nHorzSteps = nHorzSteps / rInc.
Width();
140 auto nSteps = std::max(nVertSteps, nHorzSteps);
143 SAL_WARN(
"vcl.gdi",
"skipping slow hatch with " << nSteps <<
" steps");
153 if(!rPolyPoly.
Count())
157 bool bIsCurve(
false);
159 for(sal_uInt16
a(0); !bIsCurve &&
a < rPolyPoly.
Count();
a++)
161 if(rPolyPoly[
a].HasFlags())
169 OSL_ENSURE(
false,
"DrawHatch does *not* support curves, falling back to AdaptiveSubdivide()...");
181 Point aPt1, aPt2, aEndPt1;
191 SAL_WARN(
"vcl.gdi",
"invalid increment");
200 while( ( aPt1.
X() <= aEndPt1.
X() ) && ( aPt1.
Y() <= aEndPt1.
Y() ) );
203 if( ( rHatch.
GetStyle() == HatchStyle::Double ) || ( rHatch.
GetStyle() == HatchStyle::Triple ) )
216 while( ( aPt1.
X() <= aEndPt1.
X() ) && ( aPt1.
Y() <= aEndPt1.
Y() ) );
218 if( rHatch.
GetStyle() == HatchStyle::Triple )
231 while( ( aPt1.
X() <= aEndPt1.
X() ) && ( aPt1.
Y() <= aEndPt1.
Y() ) );
241 Degree10 nAngle = nAngle10 % 1800_deg10;
244 if( nAngle > 900_deg10 )
245 nAngle -= 1800_deg10;
249 if( 0_deg10 == nAngle )
251 rInc =
Size( 0, nDist );
256 if( aRef.
Y() <= rRect.
Top() )
257 nOffset = ( ( rRect.
Top() - aRef.
Y() ) % nDist );
259 nOffset = ( nDist - ( ( aRef.
Y() - rRect.
Top() ) % nDist ) );
264 else if( 900_deg10 == nAngle )
266 rInc =
Size( nDist, 0 );
271 if( aRef.
X() <= rRect.
Left() )
272 nOffset = ( rRect.
Left() - aRef.
X() ) % nDist;
274 nOffset = nDist - ( ( aRef.
X() - rRect.
Left() ) % nDist );
279 else if( nAngle >=
Degree10(-450) && nAngle <= 450_deg10 )
281 const double fAngle = std::abs(
toRadians(nAngle) );
282 const double fTan = tan( fAngle );
286 nDist =
FRound( nDist / cos( fAngle ) );
287 rInc =
Size( 0, nDist );
289 if( nAngle > 0_deg10 )
294 nPY =
FRound( aRef.
Y() - ( ( rPt1.
X() - aRef.
X() ) * fTan ) );
301 nPY =
FRound( aRef.
Y() + ( ( rPt1.
X() - aRef.
X() ) * fTan ) );
304 if( nPY <= rPt1.
Y() )
305 nOffset = ( rPt1.
Y() - nPY ) % nDist;
307 nOffset = nDist - ( ( nPY - rPt1.
Y() ) % nDist );
314 const double fAngle = std::abs(
toRadians(nAngle) );
315 const double fTan = tan( fAngle );
319 nDist =
FRound( nDist / sin( fAngle ) );
320 rInc =
Size( nDist, 0 );
322 if( nAngle > 0_deg10 )
327 nPX =
FRound( aRef.
X() - ( (
static_cast<double>(rPt1.
Y()) - aRef.
Y()) / fTan ) );
334 nPX =
FRound( aRef.
X() + ( (
static_cast<double>(rPt1.
Y()) - aRef.
Y()) / fTan ) );
337 if( nPX <= rPt1.
X() )
338 nOffset = ( rPt1.
X() - nPX ) % nDist;
340 nOffset = nDist - ( ( nPX - rPt1.
X() ) % nDist );
348 Point* pPtBuffer,
bool bMtf )
355 for(
tools::Long nPoly = 0, nPolyCount = rPolyPoly.
Count(); nPoly < nPolyCount; nPoly++ )
357 const tools::Polygon& rPoly = rPolyPoly[
static_cast<sal_uInt16
>(nPoly) ];
365 aCurSegment.
SetEnd( rPoly[
static_cast<sal_uInt16
>(
i %
nCount ) ] );
370 if( ( fabs( fX - aCurSegment.
GetStart().
X() ) <= 0.0000001 ) &&
371 ( fabs( fY - aCurSegment.
GetStart().
Y() ) <= 0.0000001 ) )
373 const tools::Line aPrevSegment( rPoly[
static_cast<sal_uInt16
>( (
i > 1 ) ? (
i - 2 ) : (
nCount - 1 ) ) ], aCurSegment.
GetStart() );
377 if( ( fPrevDistance <= 0.0 && fCurDistance > 0.0 ) ||
378 ( fPrevDistance > 0.0 && fCurDistance < 0.0 ) )
383 else if( ( fabs( fX - aCurSegment.
GetEnd().
X() ) <= 0.0000001 ) &&
384 ( fabs( fY - aCurSegment.
GetEnd().
Y() ) <= 0.0000001 ) )
401 SAL_WARN(
"vcl.gdi",
"too many hatch points");
Degree10 GetAngle() const
void SetColor(const Color &rColor)
HatchStyle GetStyle() const
tools::Long GetDistance() const
const Color & GetColor() const
void SetDistance(tools::Long nDistance)
virtual void InitClipRegion()
SAL_DLLPRIVATE void DrawHatchLine(const tools::Line &rLine, const tools::PolyPolygon &rPolyPoly, Point *pPtBuffer, bool bMtf)
void EnableMapMode(bool bEnable=true)
SAL_DLLPRIVATE bool is_double_buffered_window() const
SAL_DLLPRIVATE void InitLineColor()
virtual void DrawHatchLine_DrawLine(const Point &rStartPoint, const Point &rEndPoint)
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
void DrawHatch(const tools::PolyPolygon &rPolyPoly, const Hatch &rHatch)
const Point & GetRefPoint() const
void AddHatchActions(const tools::PolyPolygon &rPolyPoly, const Hatch &rHatch, GDIMetaFile &rMtf)
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
SalGraphics * mpGraphics
Graphics context to draw on.
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicWidth(tools::Long nWidth) const
Convert device pixels to a width in logical units.
bool IsDeviceOutputNecessary() const
SAL_DLLPRIVATE void CalcHatchValues(const tools::Rectangle &rRect, tools::Long nDist, Degree10 nAngle10, Point &rPt1, Point &rPt2, Size &rInc, Point &rEndPt1)
VclPtr< VirtualDevice > mpAlphaVDev
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
DrawModeFlags GetDrawMode() const
const AllSettings & GetSettings() const
constexpr tools::Long Y() const
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
void DrawLine(tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2, const OutputDevice &rOutDev)
constexpr tools::Long Height() const
constexpr tools::Long Width() const
tools::Long FRound(double fVal)
#define SAL_WARN(area, stream)
std::enable_if< std::is_signed< T >::value, bool >::type checked_sub(T a, T b, T &result)
Color GetHatchColor(Color const &rColor, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
static int HatchCmpFnc(const void *p1, const void *p2)
static bool HasSaneNSteps(const Point &rPt1, const Point &rEndPt1, const Size &rInc)