33#define GRADIENT_DEFAULT_STEPCOUNT 0
56 if ( rPolyPoly.
Count() && rPolyPoly[ 0 ].GetSize() )
136 if( aGradient.
GetStyle() == css::awt::GradientStyle_LINEAR || rGradient.
GetStyle() == css::awt::GradientStyle_AXIAL )
182 if ( !(rPolyPoly.
Count() && rPolyPoly[ 0 ].GetSize()) )
216 else if ( nValue > 0xFF )
236 bool bLinear = (rGradient.
GetStyle() == css::awt::GradientStyle_LINEAR);
260 nStartRed = (nStartRed * nFactor) / 100;
261 nStartGreen = (nStartGreen * nFactor) / 100;
262 nStartBlue = (nStartBlue * nFactor) / 100;
264 nEndRed = (nEndRed * nFactor) / 100;
265 nEndGreen = (nEndGreen * nFactor) / 100;
266 nEndBlue = (nEndBlue * nFactor) / 100;
271 std::swap( nStartRed, nEndRed );
272 std::swap( nStartGreen, nEndGreen );
273 std::swap( nStartBlue, nEndBlue );
285 nRed =
static_cast<sal_uInt8>(nStartRed);
286 nGreen =
static_cast<sal_uInt8>(nStartGreen);
287 nBlue =
static_cast<sal_uInt8>(nStartBlue);
293 aPoly[0] = aBorderRect.
TopLeft();
297 aPoly.
Rotate( aCenter, nAngle );
303 aBorderRect = aMirrorRect;
306 aPoly[0] = aBorderRect.
TopLeft();
310 aPoly.
Rotate( aCenter, nAngle );
320 tools::Long nAbsRedSteps = std::abs( nEndRed - nStartRed );
321 tools::Long nAbsGreenSteps = std::abs( nEndGreen - nStartGreen );
322 tools::Long nAbsBlueSteps = std::abs( nEndBlue - nStartBlue );
323 tools::Long nMaxColorSteps = std::max( nAbsRedSteps , nAbsGreenSteps );
324 nMaxColorSteps = std::max( nMaxColorSteps, nAbsBlueSteps );
325 tools::Long nSteps = std::min( nStepCount, nMaxColorSteps );
331 double fScanInc =
static_cast<double>(aRect.
GetHeight()) /
static_cast<double>(nSteps);
332 double fGradientLine =
static_cast<double>(aRect.
Top());
333 double fMirrorGradientLine =
static_cast<double>(aMirrorRect.
Bottom());
335 const double fStepsMinus1 =
static_cast<double>(nSteps) - 1.0;
344 const double fAlpha =
static_cast<double>(
i) / fStepsMinus1;
345 double fTempColor =
static_cast<double>(nStartRed) * (1.0-fAlpha) +
static_cast<double>(nEndRed) * fAlpha;
347 fTempColor =
static_cast<double>(nStartGreen) * (1.0-fAlpha) +
static_cast<double>(nEndGreen) * fAlpha;
349 fTempColor =
static_cast<double>(nStartBlue) * (1.0-fAlpha) +
static_cast<double>(nEndBlue) * fAlpha;
355 aRect.
SetTop(
static_cast<tools::Long>( fGradientLine +
static_cast<double>(
i) * fScanInc ) );
356 aRect.
SetBottom(
static_cast<tools::Long>( fGradientLine + (
static_cast<double>(
i) + 1.0 ) * fScanInc ) );
361 aPoly.
Rotate( aCenter, nAngle );
367 aMirrorRect.
SetBottom(
static_cast<tools::Long>( fMirrorGradientLine -
static_cast<double>(
i) * fScanInc ) );
368 aMirrorRect.
SetTop(
static_cast<tools::Long>( fMirrorGradientLine - (
static_cast<double>(
i) + 1.0)* fScanInc ) );
369 aPoly[0] = aMirrorRect.
TopLeft();
373 aPoly.
Rotate( aCenter, nAngle );
388 aRect.
SetTop(
static_cast<tools::Long>( fGradientLine +
static_cast<double>(nSteps) * fScanInc ) );
389 aRect.
SetBottom(
static_cast<tools::Long>( fMirrorGradientLine -
static_cast<double>(nSteps) * fScanInc ) );
394 aPoly.
Rotate( aCenter, nAngle );
403 return pOwnerWindow && pOwnerWindow->SupportsDoubleBuffering();
418 std::optional<tools::PolyPolygon> xPolyPoly;
445 if ( nTempSteps > nCalcSteps )
446 nCalcSteps = nTempSteps;
447 nTempSteps = std::abs( nBlueSteps );
448 if ( nTempSteps > nCalcSteps )
449 nCalcSteps = nTempSteps;
450 if ( nCalcSteps < nSteps )
457 double fScanLeft = aRect.
Left();
458 double fScanTop = aRect.
Top();
459 double fScanRight = aRect.
Right();
460 double fScanBottom = aRect.
Bottom();
461 double fScanIncX =
static_cast<double>(aRect.
GetWidth()) /
static_cast<double>(nSteps) * 0.5;
462 double fScanIncY =
static_cast<double>(aRect.
GetHeight()) /
static_cast<double>(nSteps) * 0.5;
467 if( rGradient.
GetStyle() != css::awt::GradientStyle_SQUARE )
469 fScanIncY = std::min( fScanIncY, fScanIncX );
470 fScanIncX = fScanIncY;
473 bool bPaintLastPolygon(
false );
480 xPolyPoly->Insert( aPoly );
481 xPolyPoly->Insert( aPoly );
501 fScanLeft += fScanIncX;
503 fScanTop += fScanIncY;
505 fScanRight -= fScanIncX;
507 fScanBottom -= fScanIncY;
513 if( rGradient.
GetStyle() == css::awt::GradientStyle_RADIAL || rGradient.
GetStyle() == css::awt::GradientStyle_ELLIPTICAL )
518 aPoly.
Rotate( aCenter, nAngle );
521 const tools::Long nStepIndex = ( xPolyPoly ?
i : (
i + 1 ) );
529 bPaintLastPolygon =
true;
531 xPolyPoly->Replace( xPolyPoly->GetObject( 1 ), 0 );
532 xPolyPoly->Replace( aPoly, 1 );
566 if( bPaintLastPolygon )
594 if (rGradient.
GetStyle() == css::awt::GradientStyle_LINEAR || rGradient.
GetStyle() == css::awt::GradientStyle_AXIAL)
604 return nMinRect / nInc;
const StyleSettings & GetStyleSettings() const
sal_uInt8 GetBlue() const
sal_uInt8 GetGreen() const
sal_uInt16 GetStartIntensity() const
Degree10 GetAngle() const
sal_uInt16 GetEndIntensity() const
sal_uInt16 GetBorder() const
const Color & GetEndColor() const
const Color & GetStartColor() const
void SetSteps(sal_uInt16 nSteps)
css::awt::GradientStyle GetStyle() const
sal_uInt16 GetSteps() const
void GetBoundRect(const tools::Rectangle &rRect, tools::Rectangle &rBoundRect, Point &rCenter) const
Size GetOutputSize() const
virtual void InitClipRegion()
SAL_DLLPRIVATE bool is_double_buffered_window() const
void EnableOutput(bool bEnable=true)
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
SAL_DLLPRIVATE void DrawGradientToMetafile(const tools::PolyPolygon &rPolyPoly, const Gradient &rGradient)
SAL_DLLPRIVATE void DrawComplexGradient(const tools::Rectangle &rRect, const Gradient &rGradient, const tools::PolyPolygon *pClipPolyPoly)
SAL_DLLPRIVATE void ImplDrawPolygon(const tools::Polygon &rPoly, const tools::PolyPolygon *pClipPolyPoly=nullptr)
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
SalGraphics * mpGraphics
Graphics context to draw on.
SAL_DLLPRIVATE void ImplDrawPolyPolygon(const tools::PolyPolygon &rPolyPoly, const tools::PolyPolygon *pClipPolyPoly)
SAL_DLLPRIVATE tools::Long GetGradientSteps(Gradient const &rGradient, tools::Rectangle const &rRect)
virtual bool UsePolyPolygonForComplexGradient()=0
virtual void ClipAndDrawGradientMetafile(const Gradient &rGradient, const tools::PolyPolygon &rPolyPoly)
void SetRasterOp(RasterOp eRasterOp)
bool IsDeviceOutputNecessary() const
VclPtr< VirtualDevice > mpAlphaVDev
virtual tools::Long GetGradientStepCount(tools::Long nMinRect)
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
void DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
void DrawPolyPolygon(const tools::PolyPolygon &rPolyPoly)
Render the given poly-polygon.
bool IsOutputEnabled() const
const AllSettings & GetSettings() const
void IntersectClipRegion(const tools::Rectangle &rRect)
SAL_DLLPRIVATE Color GetSingleColorGradientFill()
virtual vcl::Window * GetOwnerWindow() const
Get the vcl::Window that this OutputDevice belongs to, if any.
SAL_DLLPRIVATE void DrawLinearGradient(const tools::Rectangle &rRect, const Gradient &rGradient, const tools::PolyPolygon *pClipPolyPoly)
const Color & GetFillColor() const
virtual void SetLineColor()=0
virtual void SetFillColor()=0
bool DrawGradient(const tools::PolyPolygon &rPolyPoly, const Gradient &rGradient, const OutputDevice &rOutDev)
const Color & GetWindowColor() const
const Color & GetHighlightColor() const
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
constexpr ::Color COL_ALPHA_OPAQUE(0xff, 0xff, 0xff)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
static sal_uInt8 GetGradientColorValue(tools::Long nValue)
#define GRADIENT_DEFAULT_STEPCOUNT