LibreOffice Module vcl (master) 1
outdev/bitmap.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <config_features.h>
21
22#include <osl/diagnose.h>
23#include <tools/debug.hxx>
24#include <tools/helpers.hxx>
25
26#include <vcl/image.hxx>
27#include <vcl/metaact.hxx>
29#include <vcl/virdev.hxx>
30
32#include <bitmap/bmpfast.hxx>
33#include <drawmode.hxx>
34#include <salbmp.hxx>
35#include <salgdi.hxx>
36
37void OutputDevice::DrawBitmap( const Point& rDestPt, const Bitmap& rBitmap )
38{
40
41 const Size aSizePix( rBitmap.GetSizePixel() );
42 DrawBitmap( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmap, MetaActionType::BMP );
43}
44
45void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize, const Bitmap& rBitmap )
46{
48
49 DrawBitmap( rDestPt, rDestSize, Point(), rBitmap.GetSizePixel(), rBitmap, MetaActionType::BMPSCALE );
50}
51
52void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize,
53 const Point& rSrcPtPixel, const Size& rSrcSizePixel,
54 const Bitmap& rBitmap)
55{
57
58 DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmap, MetaActionType::BMPSCALEPART );
59}
60
61void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize,
62 const Point& rSrcPtPixel, const Size& rSrcSizePixel,
63 const Bitmap& rBitmap, const MetaActionType nAction )
64{
66
67 if( ImplIsRecordLayout() )
68 return;
69
71 {
72 DrawRect( tools::Rectangle( rDestPt, rDestSize ) );
73 return;
74 }
75
76 Bitmap aBmp( rBitmap );
77
80 {
82 {
83 sal_uInt8 cCmpVal;
84
86 cCmpVal = 0;
87 else
88 cCmpVal = 255;
89
90 Color aCol( cCmpVal, cCmpVal, cCmpVal );
92 SetLineColor( aCol );
93 SetFillColor( aCol );
94 DrawRect( tools::Rectangle( rDestPt, rDestSize ) );
95 Pop();
96 return;
97 }
98 else if( !aBmp.IsEmpty() )
99 {
102 }
103 }
104
105 if ( mpMetaFile )
106 {
107 switch( nAction )
108 {
110 mpMetaFile->AddAction( new MetaBmpAction( rDestPt, aBmp ) );
111 break;
112
114 mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
115 break;
116
119 rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, aBmp ) );
120 break;
121
122 default: break;
123 }
124 }
125
127 return;
128
129 if (!mpGraphics && !AcquireGraphics())
130 return;
131 assert(mpGraphics);
132
133 if ( mbInitClipRegion )
135
136 if ( mbOutputClipped )
137 return;
138
139 if( !aBmp.IsEmpty() )
140 {
141 SalTwoRect aPosAry(rSrcPtPixel.X(), rSrcPtPixel.Y(), rSrcSizePixel.Width(), rSrcSizePixel.Height(),
142 ImplLogicXToDevicePixel(rDestPt.X()), ImplLogicYToDevicePixel(rDestPt.Y()),
145
146 if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
147 {
148 const BmpMirrorFlags nMirrFlags = AdjustTwoRect( aPosAry, aBmp.GetSizePixel() );
149
150 if ( nMirrFlags != BmpMirrorFlags::NONE )
151 aBmp.Mirror( nMirrFlags );
152
153 if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
154 {
156 {
157 double nScaleX = aPosAry.mnDestWidth / static_cast<double>(aPosAry.mnSrcWidth);
158 double nScaleY = aPosAry.mnDestHeight / static_cast<double>(aPosAry.mnSrcHeight);
159
160 // If subsampling, use Bitmap::Scale() for subsampling of better quality.
161
162 // but hidpi surfaces like the cairo one have their own scale, so don't downscale
163 // past the surface scaling which can retain the extra detail
164 double fScale(1.0);
166 {
167 nScaleX *= fScale;
168 nScaleY *= fScale;
169 }
170
171 if ( nScaleX < 1.0 || nScaleY < 1.0 )
172 {
173 aBmp.Scale(nScaleX, nScaleY);
174 aPosAry.mnSrcWidth = aPosAry.mnDestWidth * fScale;
175 aPosAry.mnSrcHeight = aPosAry.mnDestHeight * fScale;
176 }
177 }
178
179 mpGraphics->DrawBitmap( aPosAry, *aBmp.ImplGetSalBitmap(), *this );
180 }
181 }
182 }
183
184 if( mpAlphaVDev )
185 {
186 // #i32109#: Make bitmap area opaque
188 }
189}
190
191Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const
192{
193 if ( !mpGraphics && !AcquireGraphics() )
194 return Bitmap();
195
196 assert(mpGraphics);
197
198 tools::Long nX = ImplLogicXToDevicePixel( rSrcPt.X() );
199 tools::Long nY = ImplLogicYToDevicePixel( rSrcPt.Y() );
202 if ( nWidth <= 0 || nHeight <= 0 || nX > (mnOutWidth + mnOutOffX) || nY > (mnOutHeight + mnOutOffY))
203 return Bitmap();
204
205 Bitmap aBmp;
206 tools::Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
207 bool bClipped = false;
208
209 // X-Coordinate outside of draw area?
210 if ( nX < mnOutOffX )
211 {
212 nWidth -= ( mnOutOffX - nX );
213 nX = mnOutOffX;
214 bClipped = true;
215 }
216
217 // Y-Coordinate outside of draw area?
218 if ( nY < mnOutOffY )
219 {
220 nHeight -= ( mnOutOffY - nY );
221 nY = mnOutOffY;
222 bClipped = true;
223 }
224
225 // Width outside of draw area?
226 if ( (nWidth + nX) > (mnOutWidth + mnOutOffX) )
227 {
228 nWidth = mnOutOffX + mnOutWidth - nX;
229 bClipped = true;
230 }
231
232 // Height outside of draw area?
233 if ( (nHeight + nY) > (mnOutHeight + mnOutOffY) )
234 {
235 nHeight = mnOutOffY + mnOutHeight - nY;
236 bClipped = true;
237 }
238
239 if ( bClipped )
240 {
241 // If the visible part has been clipped, we have to create a
242 // Bitmap with the correct size in which we copy the clipped
243 // Bitmap to the correct position.
245
246 if ( aVDev->SetOutputSizePixel( aRect.GetSize() ) )
247 {
248 if ( aVDev->mpGraphics || aVDev->AcquireGraphics() )
249 {
250 if ( (nWidth > 0) && (nHeight > 0) )
251 {
252 SalTwoRect aPosAry(nX, nY, nWidth, nHeight,
253 (aRect.Left() < mnOutOffX) ? (mnOutOffX - aRect.Left()) : 0L,
254 (aRect.Top() < mnOutOffY) ? (mnOutOffY - aRect.Top()) : 0L,
255 nWidth, nHeight);
256 aVDev->mpGraphics->CopyBits(aPosAry, *mpGraphics, *this, *this);
257 }
258 else
259 {
260 OSL_ENSURE(false, "CopyBits with zero or negative width or height");
261 }
262
263 aBmp = aVDev->GetBitmap( Point(), aVDev->GetOutputSizePixel() );
264 }
265 else
266 bClipped = false;
267 }
268 else
269 bClipped = false;
270 }
271
272 if ( !bClipped )
273 {
274 std::shared_ptr<SalBitmap> pSalBmp = mpGraphics->GetBitmap( nX, nY, nWidth, nHeight, *this );
275
276 if( pSalBmp )
277 {
278 aBmp.ImplSetSalBitmap(pSalBmp);
279 }
280 }
281
282 return aBmp;
283}
284
285void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& rAlpha,
286 const Point& rDestPt, const Size& rDestSize,
287 const Point& rSrcPtPixel, const Size& rSrcSizePixel )
288{
289 assert(!is_double_buffered_window());
290
291 Point aOutPt(LogicToPixel(rDestPt));
292 Size aOutSz(LogicToPixel(rDestSize));
294
295 const bool bHMirr = aOutSz.Width() < 0;
296 const bool bVMirr = aOutSz.Height() < 0;
297
298 ClipToPaintRegion(aDstRect);
299
301 if (bHMirr)
302 {
303 aOutSz.setWidth( -aOutSz.Width() );
304 aOutPt.AdjustX( -(aOutSz.Width() - 1) );
305 mirrorFlags |= BmpMirrorFlags::Horizontal;
306 }
307
308 if (bVMirr)
309 {
310 aOutSz.setHeight( -aOutSz.Height() );
311 aOutPt.AdjustY( -(aOutSz.Height() - 1) );
312 mirrorFlags |= BmpMirrorFlags::Vertical;
313 }
314
315 if (aDstRect.Intersection(tools::Rectangle(aOutPt, aOutSz)).IsEmpty())
316 return;
317 if (ImplLogicToDevicePixel(aOutSz).IsEmpty()) // nothing to draw
318 return;
319
320 {
321 Point aRelPt = aOutPt + Point(mnOutOffX, mnOutOffY);
322 SalTwoRect aTR(
323 rSrcPtPixel.X(), rSrcPtPixel.Y(),
324 rSrcSizePixel.Width(), rSrcSizePixel.Height(),
325 aRelPt.X(), aRelPt.Y(),
326 aOutSz.Width(), aOutSz.Height());
327
328 Bitmap bitmap(rBmp);
329 AlphaMask alpha(rAlpha);
330 if(bHMirr || bVMirr)
331 {
332 bitmap.Mirror(mirrorFlags);
333 alpha.Mirror(mirrorFlags);
334 }
335 SalBitmap* pSalSrcBmp = bitmap.ImplGetSalBitmap().get();
336 SalBitmap* pSalAlphaBmp = alpha.ImplGetSalBitmap().get();
337
338 // #i83087# Naturally, system alpha blending (SalGraphics::DrawAlphaBitmap) cannot work
339 // with separate alpha VDev
340
341 // try to blend the alpha bitmap with the alpha virtual device
342 if (mpAlphaVDev)
343 {
344 Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aRelPt, aOutSz ) );
345 if (SalBitmap* pSalAlphaBmp2 = aAlphaBitmap.ImplGetSalBitmap().get())
346 {
347 if (mpGraphics->BlendAlphaBitmap(aTR, *pSalSrcBmp, *pSalAlphaBmp, *pSalAlphaBmp2, *this))
348 {
349 mpAlphaVDev->BlendBitmap(aTR, rAlpha);
350 return;
351 }
352 }
353 }
354 else
355 {
356 if (mpGraphics->DrawAlphaBitmap(aTR, *pSalSrcBmp, *pSalAlphaBmp, *this))
357 return;
358 }
359
360 // we need to make sure Skia never reaches this slow code path
361 // (but do not fail in no-op cases)
364 .Intersection(tools::Rectangle(rSrcPtPixel, rSrcSizePixel)).IsEmpty()
366 }
367
368 tools::Rectangle aBmpRect(Point(), rBmp.GetSizePixel());
369 if (aBmpRect.Intersection(tools::Rectangle(rSrcPtPixel, rSrcSizePixel)).IsEmpty())
370 return;
371
372 Point auxOutPt(LogicToPixel(rDestPt));
373 Size auxOutSz(LogicToPixel(rDestSize));
374
375 // HACK: The function is broken with alpha vdev and mirroring, mirror here.
376 Bitmap bitmap(rBmp);
377 AlphaMask alpha(rAlpha);
378 if(mpAlphaVDev && (bHMirr || bVMirr))
379 {
380 bitmap.Mirror(mirrorFlags);
381 alpha.Mirror(mirrorFlags);
382 auxOutPt = aOutPt;
383 auxOutSz = aOutSz;
384 }
385 DrawDeviceAlphaBitmapSlowPath(bitmap, alpha, aDstRect, aBmpRect, auxOutSz, auxOutPt);
386}
387
388namespace
389{
390
391struct LinearScaleContext
392{
393 std::unique_ptr<sal_Int32[]> mpMapX;
394 std::unique_ptr<sal_Int32[]> mpMapY;
395
396 std::unique_ptr<sal_Int32[]> mpMapXOffset;
397 std::unique_ptr<sal_Int32[]> mpMapYOffset;
398
399 LinearScaleContext(tools::Rectangle const & aDstRect, tools::Rectangle const & aBitmapRect,
400 Size const & aOutSize, tools::Long nOffX, tools::Long nOffY)
401
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()])
406 {
407 const tools::Long nSrcWidth = aBitmapRect.GetWidth();
408 const tools::Long nSrcHeight = aBitmapRect.GetHeight();
409
410 generateSimpleMap(
411 nSrcWidth, aDstRect.GetWidth(), aBitmapRect.Left(),
412 aOutSize.Width(), nOffX, mpMapX.get(), mpMapXOffset.get());
413
414 generateSimpleMap(
415 nSrcHeight, aDstRect.GetHeight(), aBitmapRect.Top(),
416 aOutSize.Height(), nOffY, mpMapY.get(), mpMapYOffset.get());
417 }
418
419private:
420
421 static void generateSimpleMap(tools::Long nSrcDimension, tools::Long nDstDimension, tools::Long nDstLocation,
422 tools::Long nOutDimension, tools::Long nOffset, sal_Int32* pMap, sal_Int32* pMapOffset)
423 {
424
425 const double fReverseScale = (std::abs(nOutDimension) > 1) ? (nSrcDimension - 1) / double(std::abs(nOutDimension) - 1) : 0.0;
426
427 tools::Long nSampleRange = std::max(tools::Long(0), nSrcDimension - 2);
428
429 for (tools::Long i = 0; i < nDstDimension; i++)
430 {
431 double fTemp = std::abs((nOffset + i) * fReverseScale);
432
433 pMap[i] = MinMax(nDstLocation + tools::Long(fTemp), 0, nSampleRange);
434 pMapOffset[i] = static_cast<tools::Long>((fTemp - pMap[i]) * 128.0);
435 }
436 }
437
438public:
439 bool blendBitmap(
440 const BitmapWriteAccess* pDestination,
441 const BitmapReadAccess* pSource,
442 const BitmapReadAccess* pSourceAlpha,
443 const tools::Long nDstWidth,
444 const tools::Long nDstHeight)
445 {
446 if (!pSource || !pSourceAlpha || !pDestination)
447 return false;
448
449 ScanlineFormat nSourceFormat = pSource->GetScanlineFormat();
450 ScanlineFormat nDestinationFormat = pDestination->GetScanlineFormat();
451
452 switch (nSourceFormat)
453 {
456 {
457 if ( (nSourceFormat == ScanlineFormat::N24BitTcBgr && nDestinationFormat == ScanlineFormat::N32BitTcBgra)
458 || (nSourceFormat == ScanlineFormat::N24BitTcRgb && nDestinationFormat == ScanlineFormat::N32BitTcRgba))
459 {
460 blendBitmap24(pDestination, pSource, pSourceAlpha, nDstWidth, nDstHeight);
461 return true;
462 }
463 }
464 break;
465 default: break;
466 }
467 return false;
468 }
469
470 void blendBitmap24(
471 const BitmapWriteAccess* pDestination,
472 const BitmapReadAccess* pSource,
473 const BitmapReadAccess* pSourceAlpha,
474 const tools::Long nDstWidth,
475 const tools::Long nDstHeight)
476 {
477 Scanline pLine0, pLine1;
478 Scanline pLineAlpha0, pLineAlpha1;
479 Scanline pColorSample1, pColorSample2;
480 Scanline pDestScanline;
481
482 tools::Long nColor1Line1, nColor2Line1, nColor3Line1;
483 tools::Long nColor1Line2, nColor2Line2, nColor3Line2;
484 tools::Long nAlphaLine1, nAlphaLine2;
485
486 sal_uInt8 nColor1, nColor2, nColor3, nAlpha;
487
488 for (tools::Long nY = 0; nY < nDstHeight; nY++)
489 {
490 const tools::Long nMapY = mpMapY[nY];
491 const tools::Long nMapFY = mpMapYOffset[nY];
492
493 pLine0 = pSource->GetScanline(nMapY);
494 // tdf#95481 guard nMapY + 1 to be within bounds
495 pLine1 = (nMapY + 1 < pSource->Height()) ? pSource->GetScanline(nMapY + 1) : pLine0;
496
497 pLineAlpha0 = pSourceAlpha->GetScanline(nMapY);
498 // tdf#95481 guard nMapY + 1 to be within bounds
499 pLineAlpha1 = (nMapY + 1 < pSourceAlpha->Height()) ? pSourceAlpha->GetScanline(nMapY + 1) : pLineAlpha0;
500
501 pDestScanline = pDestination->GetScanline(nY);
502
503 for (tools::Long nX = 0; nX < nDstWidth; nX++)
504 {
505 const tools::Long nMapX = mpMapX[nX];
506 const tools::Long nMapFX = mpMapXOffset[nX];
507
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);
511
512 pColorSample1++;
513 pColorSample2++;
514 nColor2Line1 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
515
516 pColorSample1++;
517 pColorSample2++;
518 nColor3Line1 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
519
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);
523
524 pColorSample1++;
525 pColorSample2++;
526 nColor2Line2 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
527
528 pColorSample1++;
529 pColorSample2++;
530 nColor3Line2 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
531
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);
535
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);
539
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;
543
544 nAlpha = (nAlphaLine1 + nMapFY * ((nAlphaLine2 >> 7) - (nAlphaLine1 >> 7))) >> 7;
545
546 *pDestScanline = color::ColorChannelMerge(*pDestScanline, nColor1, nAlpha);
547 pDestScanline++;
548 *pDestScanline = color::ColorChannelMerge(*pDestScanline, nColor2, nAlpha);
549 pDestScanline++;
550 *pDestScanline = color::ColorChannelMerge(*pDestScanline, nColor3, nAlpha);
551 pDestScanline++;
552 pDestScanline++;
553 }
554 }
555 }
556};
557
558struct TradScaleContext
559{
560 std::unique_ptr<sal_Int32[]> mpMapX;
561 std::unique_ptr<sal_Int32[]> mpMapY;
562
563 TradScaleContext(tools::Rectangle const & aDstRect, tools::Rectangle const & aBitmapRect,
564 Size const & aOutSize, tools::Long nOffX, tools::Long nOffY)
565
566 : mpMapX(new sal_Int32[aDstRect.GetWidth()])
567 , mpMapY(new sal_Int32[aDstRect.GetHeight()])
568 {
569 const tools::Long nSrcWidth = aBitmapRect.GetWidth();
570 const tools::Long nSrcHeight = aBitmapRect.GetHeight();
571
572 const bool bHMirr = aOutSize.Width() < 0;
573 const bool bVMirr = aOutSize.Height() < 0;
574
575 generateSimpleMap(
576 nSrcWidth, aDstRect.GetWidth(), aBitmapRect.Left(),
577 aOutSize.Width(), nOffX, bHMirr, mpMapX.get());
578
579 generateSimpleMap(
580 nSrcHeight, aDstRect.GetHeight(), aBitmapRect.Top(),
581 aOutSize.Height(), nOffY, bVMirr, mpMapY.get());
582 }
583
584private:
585
586 static void generateSimpleMap(tools::Long nSrcDimension, tools::Long nDstDimension, tools::Long nDstLocation,
587 tools::Long nOutDimension, tools::Long nOffset, bool bMirror, sal_Int32* pMap)
588 {
589 tools::Long nMirrorOffset = 0;
590
591 if (bMirror)
592 nMirrorOffset = (nDstLocation << 1) + nSrcDimension - 1;
593
594 for (tools::Long i = 0; i < nDstDimension; ++i, ++nOffset)
595 {
596 pMap[i] = nDstLocation + nOffset * nSrcDimension / nOutDimension;
597 if (bMirror)
598 pMap[i] = nMirrorOffset - pMap[i];
599 }
600 }
601};
602
603
604} // end anonymous namespace
605
607 const AlphaMask& rAlpha, tools::Rectangle aDstRect, tools::Rectangle aBmpRect, Size const & aOutSize, Point const & aOutPoint)
608{
609 assert(!is_double_buffered_window());
610
611 VirtualDevice* pOldVDev = mpAlphaVDev;
612
613 const bool bHMirr = aOutSize.Width() < 0;
614 const bool bVMirr = aOutSize.Height() < 0;
615
616 // The scaling in this code path produces really ugly results - it
617 // does the most trivial scaling with no smoothing.
618 GDIMetaFile* pOldMetaFile = mpMetaFile;
619 const bool bOldMap = mbMap;
620
621 mpMetaFile = nullptr; // fdo#55044 reset before GetBitmap!
622 mbMap = false;
623
624 Bitmap aBmp(GetBitmap(aDstRect.TopLeft(), aDstRect.GetSize()));
625
626 // #109044# The generated bitmap need not necessarily be
627 // of aDstRect dimensions, it's internally clipped to
628 // window bounds. Thus, we correct the dest size here,
629 // since we later use it (in nDstWidth/Height) for pixel
630 // access)
631 // #i38887# reading from screen may sometimes fail
632 if (aBmp.ImplGetSalBitmap())
633 {
634 aDstRect.SetSize(aBmp.GetSizePixel());
635 }
636
637 const tools::Long nDstWidth = aDstRect.GetWidth();
638 const tools::Long nDstHeight = aDstRect.GetHeight();
639
640 // calculate offset in original bitmap
641 // in RTL case this is a little more complicated since the contents of the
642 // bitmap is not mirrored (it never is), however the paint region and bmp region
643 // are in mirrored coordinates, so the intersection of (aOutPt,aOutSz) with these
644 // is content wise somewhere else and needs to take mirroring into account
645 const tools::Long nOffX = IsRTLEnabled()
646 ? aOutSize.Width() - aDstRect.GetWidth() - (aDstRect.Left() - aOutPoint.X())
647 : aDstRect.Left() - aOutPoint.X();
648
649 const tools::Long nOffY = aDstRect.Top() - aOutPoint.Y();
650
651 TradScaleContext aTradContext(aDstRect, aBmpRect, aOutSize, nOffX, nOffY);
652
653 Bitmap::ScopedReadAccess pBitmapReadAccess(const_cast<Bitmap&>(rBitmap));
654 AlphaMask::ScopedReadAccess pAlphaReadAccess(const_cast<AlphaMask&>(rAlpha));
655
656 DBG_ASSERT( pAlphaReadAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal,
657 "OutputDevice::ImplDrawAlpha(): non-8bit alpha no longer supported!" );
658
659 // #i38887# reading from screen may sometimes fail
660 if (aBmp.ImplGetSalBitmap())
661 {
662 Bitmap aNewBitmap;
663
664 if (mpAlphaVDev)
665 {
666 aNewBitmap = BlendBitmapWithAlpha(
667 aBmp, pBitmapReadAccess.get(), pAlphaReadAccess.get(),
668 aDstRect,
669 nOffY, nDstHeight,
670 nOffX, nDstWidth,
671 aTradContext.mpMapX.get(), aTradContext.mpMapY.get() );
672 }
673 else
674 {
675 LinearScaleContext aLinearContext(aDstRect, aBmpRect, aOutSize, nOffX, nOffY);
676
677 if (aLinearContext.blendBitmap( BitmapScopedWriteAccess(aBmp).get(), pBitmapReadAccess.get(), pAlphaReadAccess.get(),
678 nDstWidth, nDstHeight))
679 {
680 aNewBitmap = aBmp;
681 }
682 else
683 {
684 aNewBitmap = BlendBitmap(
685 aBmp, pBitmapReadAccess.get(), pAlphaReadAccess.get(),
686 nOffY, nDstHeight,
687 nOffX, nDstWidth,
688 aBmpRect, aOutSize,
689 bHMirr, bVMirr,
690 aTradContext.mpMapX.get(), aTradContext.mpMapY.get() );
691 }
692 }
693
694 // #110958# Disable alpha VDev, we're doing the necessary
695 // stuff explicitly further below
696 if (mpAlphaVDev)
697 mpAlphaVDev = nullptr;
698
699 DrawBitmap(aDstRect.TopLeft(), aNewBitmap);
700
701 // #110958# Enable alpha VDev again
702 mpAlphaVDev = pOldVDev;
703 }
704
705 mbMap = bOldMap;
706 mpMetaFile = pOldMetaFile;
707}
708
710{
711 if( ImplIsRecordLayout() )
712 return false;
713
714 if (!mpGraphics && !AcquireGraphics())
715 return false;
716 assert(mpGraphics);
717
719}
720
721void OutputDevice::DrawImage( const Point& rPos, const Image& rImage, DrawImageFlags nStyle )
722{
723 assert(!is_double_buffered_window());
724
725 DrawImage( rPos, Size(), rImage, nStyle );
726}
727
728void OutputDevice::DrawImage( const Point& rPos, const Size& rSize,
729 const Image& rImage, DrawImageFlags nStyle )
730{
731 assert(!is_double_buffered_window());
732
733 bool bIsSizeValid = !rSize.IsEmpty();
734
735 if (!ImplIsRecordLayout())
736 {
737 Image& rNonConstImage = const_cast<Image&>(rImage);
738 if (bIsSizeValid)
739 rNonConstImage.Draw(this, rPos, nStyle, &rSize);
740 else
741 rNonConstImage.Draw(this, rPos, nStyle);
742 }
743}
744
745namespace
746{
747 // Co = Cs + Cd*(1-As) premultiplied alpha -or-
748 // Co = (AsCs + AdCd*(1-As)) / Ao
749 sal_uInt8 CalcColor( const sal_uInt8 nSourceColor, const sal_uInt8 nSourceAlpha,
750 const sal_uInt8 nDstAlpha, const sal_uInt8 nResAlpha, const sal_uInt8 nDestColor )
751 {
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;
754 return sal_uInt8( c );
755 }
756
757 BitmapColor AlphaBlend( int nX, int nY,
758 const tools::Long nMapX,
759 const tools::Long nMapY,
760 BitmapReadAccess const * pP,
761 BitmapReadAccess const * pA,
762 BitmapReadAccess const * pB,
763 BitmapWriteAccess const * pAlphaW,
764 sal_uInt8& nResAlpha )
765 {
766 BitmapColor aDstCol,aSrcCol;
767 aSrcCol = pP->GetColor( nMapY, nMapX );
768 aDstCol = pB->GetColor( nY, nX );
769
770 const sal_uInt8 nSrcAlpha = pA->GetPixelIndex( nMapY, nMapX );
771 const sal_uInt8 nDstAlpha = pAlphaW->GetPixelIndex( nY, nX );
772
773 // Perform porter-duff compositing 'over' operation
774
775 // Co = Cs + Cd*(1-As)
776 // Ad = As + Ad*(1-As)
777 nResAlpha = static_cast<int>(nSrcAlpha) + static_cast<int>(nDstAlpha) - static_cast<int>(nDstAlpha)*nSrcAlpha/255;
778
779 aDstCol.SetRed( CalcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) );
780 aDstCol.SetBlue( CalcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) );
781 aDstCol.SetGreen( CalcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) );
782
783 return aDstCol;
784 }
785}
786
788 const SalTwoRect& rPosAry,
789 const Bitmap& rBmp )
790{
791 mpGraphics->BlendBitmap( rPosAry, *rBmp.ImplGetSalBitmap(), *this );
792}
793
795 Bitmap& aBmp,
796 BitmapReadAccess const * pP,
797 BitmapReadAccess const * pA,
798 const tools::Rectangle& aDstRect,
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 )
805
806{
807 BitmapColor aDstCol;
808 Bitmap res;
809 int nX, nY;
810 sal_uInt8 nResAlpha;
811
812 SAL_WARN_IF( !mpAlphaVDev, "vcl.gdi", "BlendBitmapWithAlpha(): call me only with valid alpha VirtualDevice!" );
813
814 bool bOldMapMode( mpAlphaVDev->IsMapModeEnabled() );
816
817 Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );
818 BitmapScopedWriteAccess pAlphaW(aAlphaBitmap);
819
820 if( GetBitCount() <= 8 )
821 {
823 BitmapColor aIndex( 0 );
825 BitmapScopedWriteAccess pW(aDither);
826
827 if (pB && pP && pA && pW && pAlphaW)
828 {
829 int nOutY;
830
831 for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
832 {
833 const tools::Long nMapY = pMapY[ nY ];
834 const tools::Long nModY = ( nOutY & 0x0FL ) << 4;
835 int nOutX;
836
837 Scanline pScanline = pW->GetScanline(nY);
838 Scanline pScanlineAlpha = pAlphaW->GetScanline(nY);
839 for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
840 {
841 const tools::Long nMapX = pMapX[ nX ];
842 const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ];
843
844 aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB.get(), pAlphaW.get(), nResAlpha );
845
846 aIndex.SetIndex( static_cast<sal_uInt8>( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16 ] +
847 nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16 ] +
848 nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16 ] ) );
849 pW->SetPixelOnData( pScanline, nX, aIndex );
850
851 aIndex.SetIndex( static_cast<sal_uInt8>( nVCLRLut[ ( nVCLLut[ nResAlpha ] + nD ) >> 16 ] +
852 nVCLGLut[ ( nVCLLut[ nResAlpha ] + nD ) >> 16 ] +
853 nVCLBLut[ ( nVCLLut[ nResAlpha ] + nD ) >> 16 ] ) );
854 pAlphaW->SetPixelOnData( pScanlineAlpha, nX, aIndex );
855 }
856 }
857 }
858 pB.reset();
859 pW.reset();
860 res = aDither;
861 }
862 else
863 {
865 if (pB && pP && pA && pAlphaW)
866 {
867 for( nY = 0; nY < nDstHeight; nY++ )
868 {
869 const tools::Long nMapY = pMapY[ nY ];
870 Scanline pScanlineB = pB->GetScanline(nY);
871 Scanline pScanlineAlpha = pAlphaW->GetScanline(nY);
872
873 for( nX = 0; nX < nDstWidth; nX++ )
874 {
875 const tools::Long nMapX = pMapX[ nX ];
876 aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB.get(), pAlphaW.get(), nResAlpha );
877
878 pB->SetPixelOnData(pScanlineB, nX, pB->GetBestMatchingColor(aDstCol));
879 pAlphaW->SetPixelOnData(pScanlineAlpha, nX, pB->GetBestMatchingColor(Color(nResAlpha, nResAlpha, nResAlpha)));
880 }
881 }
882 }
883 pB.reset();
884 res = aBmp;
885 }
886
887 pAlphaW.reset();
888 mpAlphaVDev->DrawBitmap( aDstRect.TopLeft(), aAlphaBitmap );
889 mpAlphaVDev->EnableMapMode( bOldMapMode );
890
891 return res;
892}
893
895 Bitmap& aBmp,
896 BitmapReadAccess const * pP,
897 BitmapReadAccess const * pA,
898 const sal_Int32 nOffY,
899 const sal_Int32 nDstHeight,
900 const sal_Int32 nOffX,
901 const sal_Int32 nDstWidth,
902 const tools::Rectangle& aBmpRect,
903 const Size& aOutSz,
904 const bool bHMirr,
905 const bool bVMirr,
906 const sal_Int32* pMapX,
907 const sal_Int32* pMapY )
908{
909 BitmapColor aDstCol;
910 Bitmap res;
911 int nX, nY;
912
913 if( GetBitCount() <= 8 )
914 {
916 BitmapColor aIndex( 0 );
918 BitmapScopedWriteAccess pW(aDither);
919
920 if( pB && pP && pA && pW )
921 {
922 int nOutY;
923
924 for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
925 {
926 tools::Long nMapY = pMapY[ nY ];
927 if (bVMirr)
928 {
929 nMapY = aBmpRect.Bottom() - nMapY;
930 }
931 const tools::Long nModY = ( nOutY & 0x0FL ) << 4;
932 int nOutX;
933
934 Scanline pScanline = pW->GetScanline(nY);
935 Scanline pScanlineAlpha = pA->GetScanline(nMapY);
936 for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
937 {
938 tools::Long nMapX = pMapX[ nX ];
939 if (bHMirr)
940 {
941 nMapX = aBmpRect.Right() - nMapX;
942 }
943 const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ];
944
945 aDstCol = pB->GetColor( nY, nX );
946 aDstCol.Merge( pP->GetColor( nMapY, nMapX ), 255 - pA->GetIndexFromData( pScanlineAlpha, nMapX ) );
947 aIndex.SetIndex( static_cast<sal_uInt8>( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16 ] +
948 nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16 ] +
949 nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16 ] ) );
950 pW->SetPixelOnData( pScanline, nX, aIndex );
951 }
952 }
953 }
954
955 pB.reset();
956 pW.reset();
957 res = aDither;
958 }
959 else
960 {
962
963 bool bFastBlend = false;
964 if( pP && pA && pB && !bHMirr && !bVMirr )
965 {
966 SalTwoRect aTR(aBmpRect.Left(), aBmpRect.Top(), aBmpRect.GetWidth(), aBmpRect.GetHeight(),
967 nOffX, nOffY, aOutSz.Width(), aOutSz.Height());
968
969 bFastBlend = ImplFastBitmapBlending( *pB,*pP,*pA, aTR );
970 }
971
972 if( pP && pA && pB && !bFastBlend )
973 {
974 switch( pP->GetScanlineFormat() )
975 {
977 {
978 for( nY = 0; nY < nDstHeight; nY++ )
979 {
980 tools::Long nMapY = pMapY[ nY ];
981 if ( bVMirr )
982 {
983 nMapY = aBmpRect.Bottom() - nMapY;
984 }
985 Scanline pPScan = pP->GetScanline( nMapY );
986 Scanline pAScan = pA->GetScanline( nMapY );
987 Scanline pBScan = pB->GetScanline( nY );
988
989 for( nX = 0; nX < nDstWidth; nX++ )
990 {
991 tools::Long nMapX = pMapX[ nX ];
992
993 if ( bHMirr )
994 {
995 nMapX = aBmpRect.Right() - nMapX;
996 }
997 aDstCol = pB->GetPixelFromData( pBScan, nX );
998 aDstCol.Merge( pP->GetPaletteColor( pPScan[ nMapX ] ), pAScan[ nMapX ] );
999 pB->SetPixelOnData( pBScan, nX, aDstCol );
1000 }
1001 }
1002 }
1003 break;
1004
1005 default:
1006 {
1007
1008 for( nY = 0; nY < nDstHeight; nY++ )
1009 {
1010 tools::Long nMapY = pMapY[ nY ];
1011
1012 if ( bVMirr )
1013 {
1014 nMapY = aBmpRect.Bottom() - nMapY;
1015 }
1016 Scanline pAScan = pA->GetScanline( nMapY );
1017 Scanline pBScan = pB->GetScanline(nY);
1018 for( nX = 0; nX < nDstWidth; nX++ )
1019 {
1020 tools::Long nMapX = pMapX[ nX ];
1021
1022 if ( bHMirr )
1023 {
1024 nMapX = aBmpRect.Right() - nMapX;
1025 }
1026 aDstCol = pB->GetPixelFromData( pBScan, nX );
1027 aDstCol.Merge( pP->GetColor( nMapY, nMapX ), pAScan[ nMapX ] );
1028 pB->SetPixelOnData( pBScan, nX, aDstCol );
1029 }
1030 }
1031 }
1032 break;
1033 }
1034 }
1035
1036 pB.reset();
1037 res = aBmp;
1038 }
1039
1040 return res;
1041}
1042
1043/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
DrawImageFlags
sal_uInt8 * Scanline
Definition: Scanline.hxx:26
ScanlineFormat
Definition: Scanline.hxx:29
bool ImplFastBitmapBlending(BitmapWriteAccess const &rDstWA, const BitmapReadAccess &rSrcRA, const BitmapReadAccess &rMskRA, const SalTwoRect &rTR)
Definition: bmpfast.cxx:668
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 IsEmpty() const
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 GetRed() const
sal_uInt8 GetGreen() const
void SetBlue(sal_uInt8 nBlue)
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:585
Definition: image.hxx:40
void Draw(OutputDevice *pOutDev, const Point &rPos, DrawImageFlags nStyle, const Size *pSize=nullptr)
Definition: Image.cxx:118
virtual void InitClipRegion()
SAL_DLLPRIVATE tools::Long ImplLogicYToDevicePixel(tools::Long nY) const
Convert a logical Y coordinate to a device pixel's Y coordinate.
Definition: map.cxx:271
void EnableMapMode(bool bEnable=true)
Definition: map.cxx:589
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)
Definition: outdev.hxx:209
DrawModeFlags mnDrawMode
Definition: outdev.hxx:220
bool mbOutputClipped
Definition: outdev.hxx:245
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
Definition: map.cxx:334
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)
Definition: outdev.hxx:207
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1110
Size GetOutputSizePixel() const
Definition: outdev.hxx:314
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
Definition: outdev.cxx:708
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:50
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:185
bool mbMap
Definition: outdev.hxx:240
SAL_DLLPRIVATE tools::Long ImplLogicHeightToDevicePixel(tools::Long nHeight) const
Convert a logical height to a height in units of device pixels.
Definition: map.cxx:288
void SetLineColor()
Definition: line.cxx:37
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
Definition: map.cxx:280
bool HasFastDrawTransformedBitmap() const
Return true if DrawTransformedBitmapEx() is fast.
virtual void ClipToPaintRegion(tools::Rectangle &rDstRect)
virtual sal_uInt16 GetBitCount() const
Definition: outdev.cxx:372
tools::Long mnOutWidth
Definition: outdev.hxx:210
SalGraphics * mpGraphics
Graphics context to draw on.
Definition: outdev.hxx:182
void DrawBitmap(const Point &rDestPt, const Bitmap &rBitmap)
bool mbInitClipRegion
Definition: outdev.hxx:252
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...
RasterOp meRasterOp
Definition: outdev.hxx:232
bool IsRTLEnabled() const
Definition: outdev.hxx:1269
void SetFillColor()
Definition: fill.cxx:29
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:879
virtual bool CanSubsampleBitmap() const
Definition: outdev.hxx:1387
virtual Bitmap GetBitmap(const Point &rSrcPt, const Size &rSize) const
bool IsDeviceOutputNecessary() const
Definition: outdev.hxx:481
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:196
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:32
void Pop()
Definition: stack.cxx:91
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.
Definition: map.cxx:262
tools::Long mnOutHeight
Definition: outdev.hxx:211
bool IsMapModeEnabled() const
Definition: outdev.hxx:1551
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)
bool IsEmpty() const
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.
Definition: virdev.cxx:342
constexpr tools::Long GetWidth() const
constexpr tools::Long Top() const
void SetSize(const Size &)
constexpr Point TopLeft() const
constexpr Size GetSize() const
constexpr tools::Long Right() const
constexpr tools::Long GetHeight() const
tools::Rectangle & Intersection(const tools::Rectangle &rRect)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
constexpr bool IsEmpty() const
#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)
BmpMirrorFlags
#define SAL_WARN_IF(condition, area, stream)
MetaActionType
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]
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
BmpMirrorFlags AdjustTwoRect(SalTwoRect &rTwoRect, const Size &rSizePix)
Definition: rect.cxx:340
sal_uIntPtr sal_uLong
tools::Long mnDestWidth
Definition: salgtype.hxx:45
tools::Long mnSrcHeight
Definition: salgtype.hxx:42
tools::Long mnSrcWidth
Definition: salgtype.hxx:41
tools::Long mnDestHeight
Definition: salgtype.hxx:46
unsigned char sal_uInt8