20#include <config_features.h>
22#include <osl/diagnose.h>
53 const Point& rSrcPtPixel,
const Size& rSrcSizePixel,
62 const Point& rSrcPtPixel,
const Size& rSrcSizePixel,
90 Color aCol( cCmpVal, cCmpVal, cCmpVal );
119 rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, aBmp ) );
151 aBmp.
Mirror( nMirrFlags );
171 if ( nScaleX < 1.0 || nScaleY < 1.0 )
173 aBmp.
Scale(nScaleX, nScaleY);
207 bool bClipped =
false;
246 if ( aVDev->SetOutputSizePixel( aRect.
GetSize() ) )
248 if ( aVDev->mpGraphics || aVDev->AcquireGraphics() )
250 if ( (nWidth > 0) && (nHeight > 0) )
256 aVDev->mpGraphics->CopyBits(aPosAry, *
mpGraphics, *
this, *
this);
260 OSL_ENSURE(
false,
"CopyBits with zero or negative width or height");
263 aBmp = aVDev->GetBitmap(
Point(), aVDev->GetOutputSizePixel() );
274 std::shared_ptr<SalBitmap> pSalBmp =
mpGraphics->
GetBitmap( nX, nY, nWidth, nHeight, *
this );
286 const Point& rDestPt,
const Size& rDestSize,
287 const Point& rSrcPtPixel,
const Size& rSrcSizePixel )
295 const bool bHMirr = aOutSz.
Width() < 0;
296 const bool bVMirr = aOutSz.
Height() < 0;
323 rSrcPtPixel.
X(), rSrcPtPixel.
Y(),
325 aRelPt.
X(), aRelPt.
Y(),
332 bitmap.
Mirror(mirrorFlags);
333 alpha.Mirror(mirrorFlags);
380 bitmap.
Mirror(mirrorFlags);
381 alpha.Mirror(mirrorFlags);
391struct LinearScaleContext
393 std::unique_ptr<sal_Int32[]> mpMapX;
394 std::unique_ptr<sal_Int32[]> mpMapY;
396 std::unique_ptr<sal_Int32[]> mpMapXOffset;
397 std::unique_ptr<sal_Int32[]> mpMapYOffset;
402 : mpMapX(new sal_Int32[aDstRect.GetWidth()])
403 , mpMapY(new sal_Int32[aDstRect.GetHeight()])
404 , mpMapXOffset(new sal_Int32[aDstRect.GetWidth()])
405 , mpMapYOffset(new sal_Int32[aDstRect.GetHeight()])
412 aOutSize.
Width(), nOffX, mpMapX.get(), mpMapXOffset.get());
416 aOutSize.
Height(), nOffY, mpMapY.get(), mpMapYOffset.get());
425 const double fReverseScale = (std::abs(nOutDimension) > 1) ? (nSrcDimension - 1) / double(std::abs(nOutDimension) - 1) : 0.0;
431 double fTemp = std::abs((nOffset + i) * fReverseScale);
434 pMapOffset[
i] =
static_cast<tools::Long>((fTemp - pMap[
i]) * 128.0);
446 if (!pSource || !pSourceAlpha || !pDestination)
452 switch (nSourceFormat)
460 blendBitmap24(pDestination, pSource, pSourceAlpha, nDstWidth, nDstHeight);
479 Scanline pColorSample1, pColorSample2;
482 tools::Long nColor1Line1, nColor2Line1, nColor3Line1;
483 tools::Long nColor1Line2, nColor2Line2, nColor3Line2;
486 sal_uInt8 nColor1, nColor2, nColor3, nAlpha;
495 pLine1 = (nMapY + 1 < pSource->
Height()) ? pSource->
GetScanline(nMapY + 1) : pLine0;
499 pLineAlpha1 = (nMapY + 1 < pSourceAlpha->
Height()) ? pSourceAlpha->
GetScanline(nMapY + 1) : pLineAlpha0;
508 pColorSample1 = pLine0 + 3 * nMapX;
509 pColorSample2 = (nMapX + 1 < pSource->
Width()) ? pColorSample1 + 3 : pColorSample1;
510 nColor1Line1 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
514 nColor2Line1 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
518 nColor3Line1 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
520 pColorSample1 = pLine1 + 3 * nMapX;
521 pColorSample2 = (nMapX + 1 < pSource->
Width()) ? pColorSample1 + 3 : pColorSample1;
522 nColor1Line2 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
526 nColor2Line2 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
530 nColor3Line2 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
532 pColorSample1 = pLineAlpha0 + nMapX;
533 pColorSample2 = (nMapX + 1 < pSourceAlpha->
Width()) ? pColorSample1 + 1 : pColorSample1;
534 nAlphaLine1 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
536 pColorSample1 = pLineAlpha1 + nMapX;
537 pColorSample2 = (nMapX + 1 < pSourceAlpha->
Width()) ? pColorSample1 + 1 : pColorSample1;
538 nAlphaLine2 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
540 nColor1 = (nColor1Line1 + nMapFY * ((nColor1Line2 >> 7) - (nColor1Line1 >> 7))) >> 7;
541 nColor2 = (nColor2Line1 + nMapFY * ((nColor2Line2 >> 7) - (nColor2Line1 >> 7))) >> 7;
542 nColor3 = (nColor3Line1 + nMapFY * ((nColor3Line2 >> 7) - (nColor3Line1 >> 7))) >> 7;
544 nAlpha = (nAlphaLine1 + nMapFY * ((nAlphaLine2 >> 7) - (nAlphaLine1 >> 7))) >> 7;
558struct TradScaleContext
560 std::unique_ptr<sal_Int32[]> mpMapX;
561 std::unique_ptr<sal_Int32[]> mpMapY;
566 : mpMapX(new sal_Int32[aDstRect.GetWidth()])
567 , mpMapY(new sal_Int32[aDstRect.GetHeight()])
572 const bool bHMirr = aOutSize.
Width() < 0;
573 const bool bVMirr = aOutSize.
Height() < 0;
577 aOutSize.
Width(), nOffX, bHMirr, mpMapX.get());
581 aOutSize.
Height(), nOffY, bVMirr, mpMapY.get());
592 nMirrorOffset = (nDstLocation << 1) + nSrcDimension - 1;
596 pMap[
i] = nDstLocation + nOffset * nSrcDimension / nOutDimension;
598 pMap[
i] = nMirrorOffset - pMap[
i];
613 const bool bHMirr = aOutSize.
Width() < 0;
614 const bool bVMirr = aOutSize.
Height() < 0;
619 const bool bOldMap =
mbMap;
647 : aDstRect.
Left() - aOutPoint.
X();
651 TradScaleContext aTradContext(aDstRect, aBmpRect, aOutSize, nOffX, nOffY);
657 "OutputDevice::ImplDrawAlpha(): non-8bit alpha no longer supported!" );
667 aBmp, pBitmapReadAccess.
get(), pAlphaReadAccess.
get(),
671 aTradContext.mpMapX.get(), aTradContext.mpMapY.get() );
675 LinearScaleContext aLinearContext(aDstRect, aBmpRect, aOutSize, nOffX, nOffY);
678 nDstWidth, nDstHeight))
685 aBmp, pBitmapReadAccess.
get(), pAlphaReadAccess.
get(),
690 aTradContext.mpMapX.get(), aTradContext.mpMapY.get() );
733 bool bIsSizeValid = !rSize.
IsEmpty();
737 Image& rNonConstImage =
const_cast<Image&
>(rImage);
739 rNonConstImage.
Draw(
this, rPos, nStyle, &rSize);
741 rNonConstImage.
Draw(
this, rPos, nStyle);
752 int c = nResAlpha ? (
static_cast<int>(nSourceAlpha)*nSourceColor +
static_cast<int>(nDstAlpha)*nDestColor -
753 static_cast<int>(nDstAlpha)*nDestColor*nSourceAlpha/255 ) /
static_cast<int>(nResAlpha) : 0;
767 aSrcCol = pP->
GetColor( nMapY, nMapX );
777 nResAlpha =
static_cast<int>(nSrcAlpha) +
static_cast<int>(nDstAlpha) -
static_cast<int>(nDstAlpha)*nSrcAlpha/255;
779 aDstCol.
SetRed( CalcColor( aSrcCol.
GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.
GetRed() ) );
780 aDstCol.
SetBlue( CalcColor( aSrcCol.
GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.
GetBlue() ) );
799 const sal_Int32 nOffY,
800 const sal_Int32 nDstHeight,
801 const sal_Int32 nOffX,
802 const sal_Int32 nDstWidth,
803 const sal_Int32* pMapX,
804 const sal_Int32* pMapY )
812 SAL_WARN_IF( !
mpAlphaVDev,
"vcl.gdi",
"BlendBitmapWithAlpha(): call me only with valid alpha VirtualDevice!" );
827 if (pB && pP && pA && pW && pAlphaW)
831 for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
837 Scanline pScanline = pW->GetScanline(nY);
838 Scanline pScanlineAlpha = pAlphaW->GetScanline(nY);
839 for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
844 aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB.
get(), pAlphaW.
get(), nResAlpha );
849 pW->SetPixelOnData( pScanline, nX,
aIndex );
854 pAlphaW->SetPixelOnData( pScanlineAlpha, nX,
aIndex );
865 if (pB && pP && pA && pAlphaW)
867 for( nY = 0; nY < nDstHeight; nY++ )
870 Scanline pScanlineB = pB->GetScanline(nY);
871 Scanline pScanlineAlpha = pAlphaW->GetScanline(nY);
873 for( nX = 0; nX < nDstWidth; nX++ )
876 aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB.
get(), pAlphaW.
get(), nResAlpha );
878 pB->SetPixelOnData(pScanlineB, nX, pB->GetBestMatchingColor(aDstCol));
879 pAlphaW->SetPixelOnData(pScanlineAlpha, nX, pB->GetBestMatchingColor(
Color(nResAlpha, nResAlpha, nResAlpha)));
898 const sal_Int32 nOffY,
899 const sal_Int32 nDstHeight,
900 const sal_Int32 nOffX,
901 const sal_Int32 nDstWidth,
906 const sal_Int32* pMapX,
907 const sal_Int32* pMapY )
920 if( pB && pP && pA && pW )
924 for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
929 nMapY = aBmpRect.
Bottom() - nMapY;
934 Scanline pScanline = pW->GetScanline(nY);
936 for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
941 nMapX = aBmpRect.
Right() - nMapX;
950 pW->SetPixelOnData( pScanline, nX,
aIndex );
963 bool bFastBlend =
false;
964 if( pP && pA && pB && !bHMirr && !bVMirr )
972 if( pP && pA && pB && !bFastBlend )
978 for( nY = 0; nY < nDstHeight; nY++ )
983 nMapY = aBmpRect.
Bottom() - nMapY;
987 Scanline pBScan = pB->GetScanline( nY );
989 for( nX = 0; nX < nDstWidth; nX++ )
995 nMapX = aBmpRect.
Right() - nMapX;
997 aDstCol = pB->GetPixelFromData( pBScan, nX );
999 pB->SetPixelOnData( pBScan, nX, aDstCol );
1008 for( nY = 0; nY < nDstHeight; nY++ )
1014 nMapY = aBmpRect.
Bottom() - nMapY;
1017 Scanline pBScan = pB->GetScanline(nY);
1018 for( nX = 0; nX < nDstWidth; nX++ )
1024 nMapX = aBmpRect.
Right() - nMapX;
1026 aDstCol = pB->GetPixelFromData( pBScan, nX );
1027 aDstCol.
Merge( pP->
GetColor( nMapY, nMapX ), pAScan[ nMapX ] );
1028 pB->SetPixelOnData( pBScan, nX, aDstCol );
bool ImplFastBitmapBlending(BitmapWriteAccess const &rDstWA, const BitmapReadAccess &rSrcRA, const BitmapReadAccess &rMskRA, const SalTwoRect &rTR)
tools::Long Height() const
tools::Long Width() const
ScanlineFormat GetScanlineFormat() const
const BitmapColor & GetPaletteColor(sal_uInt16 nColor) const
sal_uInt8 GetPixelIndex(tools::Long nY, tools::Long nX) const
BitmapColor GetColor(tools::Long nY, tools::Long nX) const
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, tools::Long nX) const
Scanline GetScanline(tools::Long nY) const
const std::shared_ptr< SalBitmap > & ImplGetSalBitmap() const
SAL_DLLPRIVATE void ImplSetSalBitmap(const std::shared_ptr< SalBitmap > &xImpBmp)
bool Convert(BmpConversion eConversion)
Convert bitmap format.
Size GetSizePixel() const
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
bool Mirror(BmpMirrorFlags nMirrorFlags)
Mirror the bitmap.
sal_uInt8 GetBlue() const
void SetGreen(sal_uInt8 nGreen)
void SetRed(sal_uInt8 nRed)
void Merge(const Color &rMergeColor, sal_uInt8 cTransparency)
sal_uInt8 GetGreen() const
void SetBlue(sal_uInt8 nBlue)
void Draw(OutputDevice *pOutDev, const Point &rPos, DrawImageFlags nStyle, const Size *pSize=nullptr)
virtual void InitClipRegion()
SAL_DLLPRIVATE tools::Long ImplLogicYToDevicePixel(tools::Long nY) const
Convert a logical Y coordinate to a device pixel's Y coordinate.
void EnableMapMode(bool bEnable=true)
SAL_DLLPRIVATE Bitmap BlendBitmapWithAlpha(Bitmap &aBmp, BitmapReadAccess const *pP, BitmapReadAccess const *pA, const tools::Rectangle &aDstRect, const sal_Int32 nOffY, const sal_Int32 nDstHeight, const sal_Int32 nOffX, const sal_Int32 nDstWidth, const sal_Int32 *pMapX, const sal_Int32 *pMapY)
SAL_DLLPRIVATE bool is_double_buffered_window() const
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames)
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 DrawDeviceAlphaBitmap(const Bitmap &rBmp, const AlphaMask &rAlpha, const Point &rDestPt, const Size &rDestSize, const Point &rSrcPtPixel, const Size &rSrcSizePixel)
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
tools::Long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames)
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Size GetOutputSizePixel() const
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
void DrawRect(const tools::Rectangle &rRect)
SAL_DLLPRIVATE tools::Long ImplLogicHeightToDevicePixel(tools::Long nHeight) const
Convert a logical height to a height in units of device pixels.
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
bool HasFastDrawTransformedBitmap() const
Return true if DrawTransformedBitmapEx() is fast.
virtual void ClipToPaintRegion(tools::Rectangle &rDstRect)
virtual sal_uInt16 GetBitCount() const
SalGraphics * mpGraphics
Graphics context to draw on.
void DrawBitmap(const Point &rDestPt, const Bitmap &rBitmap)
void DrawImage(const Point &rPos, const Image &rImage, DrawImageFlags nStyle=DrawImageFlags::NONE)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool IsRTLEnabled() const
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
virtual bool CanSubsampleBitmap() const
virtual Bitmap GetBitmap(const Point &rSrcPt, const Size &rSize) const
bool IsDeviceOutputNecessary() const
VclPtr< VirtualDevice > mpAlphaVDev
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
SAL_DLLPRIVATE void DrawDeviceAlphaBitmapSlowPath(const Bitmap &rBitmap, const AlphaMask &rAlpha, tools::Rectangle aDstRect, tools::Rectangle aBmpRect, Size const &aOutSz, Point const &aOutPt)
SAL_DLLPRIVATE tools::Long ImplLogicXToDevicePixel(tools::Long nX) const
Convert a logical X coordinate to a device pixel's X coordinate.
bool IsMapModeEnabled() const
SAL_DLLPRIVATE void BlendBitmap(const SalTwoRect &rPosAry, const Bitmap &rBmp)
constexpr tools::Long Y() const
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
std::shared_ptr< SalBitmap > GetBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice &rOutDev)
bool BlendAlphaBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalSrcBitmap, const SalBitmap &rSalMaskBitmap, const SalBitmap &rSalAlphaBitmap, const OutputDevice &rOutDev)
bool HasFastDrawTransformedBitmap() const
void DrawBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalBitmap, const OutputDevice &rOutDev)
virtual bool ShouldDownscaleIconsAtSurface(double *pScaleOut) const
bool BlendBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalBitmap, const OutputDevice &rOutDev)
bool DrawAlphaBitmap(const SalTwoRect &, const SalBitmap &rSourceBitmap, const SalBitmap &rAlphaBitmap, const OutputDevice &rOutDev)
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
SAL_DLLPRIVATE void ImplFillOpaqueRectangle(const tools::Rectangle &rRect)
Used for alpha VDev, to set areas to opaque.
#define DBG_ASSERT(sCon, aError)
std::deque< AttacherIndex_Impl > aIndex
const sal_uLong nVCLLut[256]
const sal_uLong nVCLBLut[6]
const sal_uLong nVCLGLut[6]
const sal_uLong nVCLRLut[6]
const sal_uLong nVCLDitherLut[256]
std::enable_if< std::is_signed< T >::value||std::is_floating_point< T >::value, long >::type MinMax(T nVal, tools::Long nMin, tools::Long nMax)
#define SAL_WARN_IF(condition, area, stream)
VCL_DLLPUBLIC bool isAlphaMaskBlendingEnabled()
VCL_DLLPUBLIC bool isVCLSkiaEnabled()
constexpr sal_uInt8 ColorChannelMerge(sal_uInt8 nDst, sal_uInt8 nSrc, sal_uInt8 nSrcTrans)
constexpr double alpha[nDetails]
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
BmpMirrorFlags AdjustTwoRect(SalTwoRect &rTwoRect, const Size &rSizePix)