LibreOffice Module vcl (master)  1
BitmapTools.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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  */
10 
11 #include <vcl/BitmapTools.hxx>
12 
13 #include <sal/log.hxx>
15 #include <comphelper/seqstream.hxx>
16 #include <vcl/canvastools.hxx>
18 
19 #include <com/sun/star/graphic/SvgTools.hpp>
20 #include <com/sun/star/graphic/Primitive2DTools.hpp>
21 
23 
24 #include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp>
25 
26 #include <vcl/dibtools.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/bitmapaccess.hxx>
30 #include <vcl/virdev.hxx>
31 #if ENABLE_CAIRO_CANVAS
32 #include <cairo.h>
33 #endif
34 #include <tools/diagnose_ex.h>
35 #include <tools/fract.hxx>
36 #include <tools/stream.hxx>
37 #include <bitmapwriteaccess.hxx>
38 
39 using namespace css;
40 
43 
44 namespace vcl::bitmap
45 {
46 
47 BitmapEx loadFromName(const OUString& rFileName, const ImageLoadFlags eFlags)
48 {
49  BitmapEx aBitmapEx;
50 
52 
53  ImageTree::get().loadImage(rFileName, aIconTheme, aBitmapEx, true, eFlags);
54 
55  return aBitmapEx;
56 }
57 
58 void loadFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx, double fScalingFactor)
59 {
60  uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
61  const uno::Reference<graphic::XSvgParser> xSvgParser = graphic::SvgTools::create(xContext);
62 
63  std::size_t nSize = rStream.remainingSize();
64  std::vector<sal_Int8> aBuffer(nSize + 1);
65  rStream.ReadBytes(aBuffer.data(), nSize);
66  aBuffer[nSize] = 0;
67 
68  uno::Sequence<sal_Int8> aData(aBuffer.data(), nSize + 1);
69  uno::Reference<io::XInputStream> aInputStream(new comphelper::SequenceInputStream(aData));
70 
71  const Primitive2DSequence aPrimitiveSequence = xSvgParser->getDecomposition(aInputStream, sPath);
72 
73  if (!aPrimitiveSequence.hasElements())
74  return;
75 
76  uno::Sequence<beans::PropertyValue> aViewParameters;
77 
78  geometry::RealRectangle2D aRealRect;
79  basegfx::B2DRange aRange;
80  for (Primitive2DReference const & xReference : aPrimitiveSequence)
81  {
82  if (xReference.is())
83  {
84  aRealRect = xReference->getRange(aViewParameters);
85  aRange.expand(basegfx::B2DRange(aRealRect.X1, aRealRect.Y1, aRealRect.X2, aRealRect.Y2));
86  }
87  }
88 
89  aRealRect.X1 = aRange.getMinX();
90  aRealRect.Y1 = aRange.getMinY();
91  aRealRect.X2 = aRange.getMaxX();
92  aRealRect.Y2 = aRange.getMaxY();
93 
94  double nDPI = 96 * fScalingFactor;
95 
96  const css::uno::Reference<css::graphic::XPrimitive2DRenderer> xPrimitive2DRenderer = css::graphic::Primitive2DTools::create(xContext);
97  const css::uno::Reference<css::rendering::XBitmap> xBitmap(
98  xPrimitive2DRenderer->rasterize(aPrimitiveSequence, aViewParameters, nDPI, nDPI, aRealRect, 256*256));
99 
100  if (xBitmap.is())
101  {
102  const css::uno::Reference<css::rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap, uno::UNO_QUERY_THROW);
103  rBitmapEx = vcl::unotools::bitmapExFromXBitmap(xIntBmp);
104  }
105 
106 }
107 
116 BitmapEx CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, sal_uInt16 nBitCount )
117 {
118  assert(nStride >= (nWidth * nBitCount / 8));
119  assert( nBitCount == 1 || nBitCount == 24 || nBitCount == 32);
120  Bitmap aBmp( Size( nWidth, nHeight ), nBitCount );
121 
122  BitmapScopedWriteAccess pWrite(aBmp);
123  assert(pWrite.get());
124  if( !pWrite )
125  return BitmapEx();
126  std::unique_ptr<AlphaMask> pAlphaMask;
127  AlphaScopedWriteAccess xMaskAcc;
128  if (nBitCount == 32)
129  {
130  pAlphaMask.reset( new AlphaMask( Size(nWidth, nHeight) ) );
131  xMaskAcc = AlphaScopedWriteAccess(*pAlphaMask);
132  }
133  if (nBitCount == 1)
134  {
135  for( long y = 0; y < nHeight; ++y )
136  {
137  Scanline pScanline = pWrite->GetScanline(y);
138  for (long x = 0; x < nWidth; ++x)
139  {
140  sal_uInt8 const *p = pData + y * nStride / 8;
141  int bitIndex = (y * nStride) % 8;
142  pWrite->SetPixelOnData(pScanline, x, BitmapColor((*p >> bitIndex) & 1));
143  }
144  }
145  }
146  else
147  {
148  for( long y = 0; y < nHeight; ++y )
149  {
150  sal_uInt8 const *p = pData + (y * nStride);
151  Scanline pScanline = pWrite->GetScanline(y);
152  for (long x = 0; x < nWidth; ++x)
153  {
154  BitmapColor col(p[0], p[1], p[2]);
155  pWrite->SetPixelOnData(pScanline, x, col);
156  p += nBitCount/8;
157  }
158  if (nBitCount == 32)
159  {
160  p = pData + (y * nStride) + 3;
161  Scanline pMaskScanLine = xMaskAcc->GetScanline(y);
162  for (long x = 0; x < nWidth; ++x)
163  {
164  xMaskAcc->SetPixelOnData(pMaskScanLine, x, BitmapColor(*p));
165  p += 4;
166  }
167  }
168  }
169  }
170  if (nBitCount == 32)
171  return BitmapEx(aBmp, *pAlphaMask);
172  else
173  return BitmapEx(aBmp);
174 }
175 
180 {
181  auto nBitCount = rawBitmap.GetBitCount();
182  assert( nBitCount == 24 || nBitCount == 32);
183  Bitmap aBmp( rawBitmap.maSize, nBitCount );
184 
185  BitmapScopedWriteAccess pWrite(aBmp);
186  assert(pWrite.get());
187  if( !pWrite )
188  return BitmapEx();
189  std::unique_ptr<AlphaMask> pAlphaMask;
190  AlphaScopedWriteAccess xMaskAcc;
191  if (nBitCount == 32)
192  {
193  pAlphaMask.reset( new AlphaMask( rawBitmap.maSize ) );
194  xMaskAcc = AlphaScopedWriteAccess(*pAlphaMask);
195  }
196 
197  auto nHeight = rawBitmap.maSize.getHeight();
198  auto nWidth = rawBitmap.maSize.getWidth();
199  auto nStride = nWidth * nBitCount / 8;
200  for( long y = 0; y < nHeight; ++y )
201  {
202  sal_uInt8 const *p = rawBitmap.mpData.get() + (y * nStride);
203  Scanline pScanline = pWrite->GetScanline(y);
204  for (long x = 0; x < nWidth; ++x)
205  {
206  BitmapColor col(p[0], p[1], p[2]);
207  pWrite->SetPixelOnData(pScanline, x, col);
208  p += nBitCount/8;
209  }
210  if (nBitCount == 32)
211  {
212  p = rawBitmap.mpData.get() + (y * nStride) + 3;
213  Scanline pMaskScanLine = xMaskAcc->GetScanline(y);
214  for (long x = 0; x < nWidth; ++x)
215  {
216  xMaskAcc->SetPixelOnData(pMaskScanLine, x, BitmapColor(*p));
217  p += 4;
218  }
219  }
220  }
221  if (nBitCount == 32)
222  return BitmapEx(aBmp, *pAlphaMask);
223  else
224  return BitmapEx(aBmp);
225 }
226 
227 #if ENABLE_CAIRO_CANVAS
228 BitmapEx* CreateFromCairoSurface(Size aSize, cairo_surface_t * pSurface)
229 {
230  // FIXME: if we could teach VCL/ about cairo handles, life could
231  // be significantly better here perhaps.
232 
233 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
234  cairo_surface_t *pPixels = cairo_surface_create_similar_image(pSurface,
235 #else
236  cairo_surface_t *pPixels = cairo_image_surface_create(
237 #endif
238  CAIRO_FORMAT_ARGB32, aSize.Width(), aSize.Height());
239  cairo_t *pCairo = cairo_create( pPixels );
240  if( !pPixels || !pCairo || cairo_status(pCairo) != CAIRO_STATUS_SUCCESS )
241  return nullptr;
242 
243  // suck ourselves from the X server to this buffer so then we can fiddle with
244  // Alpha to turn it into the ultra-lame vcl required format and then push it
245  // all back again later at vast expense [ urgh ]
246  cairo_set_source_surface( pCairo, pSurface, 0, 0 );
247  cairo_set_operator( pCairo, CAIRO_OPERATOR_SOURCE );
248  cairo_paint( pCairo );
249 
250  ::Bitmap aRGB( aSize, 24 );
251  ::AlphaMask aMask( aSize );
252 
253  BitmapScopedWriteAccess pRGBWrite(aRGB);
254  assert(pRGBWrite);
255  if (!pRGBWrite)
256  return nullptr;
257 
258  AlphaScopedWriteAccess pMaskWrite(aMask);
259  assert(pMaskWrite);
260  if (!pMaskWrite)
261  return nullptr;
262 
263  cairo_surface_flush(pPixels);
264  unsigned char *pSrc = cairo_image_surface_get_data( pPixels );
265  unsigned int nStride = cairo_image_surface_get_stride( pPixels );
267  for( long y = 0; y < aSize.Height(); y++ )
268  {
269  sal_uInt32 *pPix = reinterpret_cast<sal_uInt32 *>(pSrc + nStride * y);
270  for( long x = 0; x < aSize.Width(); x++ )
271  {
272 #if defined OSL_BIGENDIAN
273  sal_uInt8 nB = (*pPix >> 24);
274  sal_uInt8 nG = (*pPix >> 16) & 0xff;
275  sal_uInt8 nR = (*pPix >> 8) & 0xff;
276  sal_uInt8 nAlpha = *pPix & 0xff;
277 #else
278  sal_uInt8 nAlpha = (*pPix >> 24);
279  sal_uInt8 nR = (*pPix >> 16) & 0xff;
280  sal_uInt8 nG = (*pPix >> 8) & 0xff;
281  sal_uInt8 nB = *pPix & 0xff;
282 #endif
283  if( nAlpha != 0 && nAlpha != 255 )
284  {
285  // Cairo uses pre-multiplied alpha - we do not => re-multiply
286  nR = unpremultiply_table[nAlpha][nR];
287  nG = unpremultiply_table[nAlpha][nG];
288  nB = unpremultiply_table[nAlpha][nB];
289  }
290  pRGBWrite->SetPixel( y, x, BitmapColor( nR, nG, nB ) );
291  pMaskWrite->SetPixelIndex( y, x, 255 - nAlpha );
292  pPix++;
293  }
294  }
295 
296  // ignore potential errors above. will get caller a
297  // uniformly white bitmap, but not that there would
298  // be error handling in calling code ...
299  ::BitmapEx *pBitmapEx = new ::BitmapEx( aRGB, aMask );
300 
301  cairo_destroy( pCairo );
302  cairo_surface_destroy( pPixels );
303  return pBitmapEx;
304 }
305 #endif
306 
308  const ::basegfx::B2DHomMatrix& rTransform,
309  ::basegfx::B2DRectangle const & rDestRect,
310  ::basegfx::B2DHomMatrix const & rLocalTransform )
311 {
312  const Size aBmpSize( rBitmap.GetSizePixel() );
313  Bitmap aSrcBitmap( rBitmap.GetBitmap() );
314  Bitmap aSrcAlpha;
315 
316  // differentiate mask and alpha channel (on-off
317  // vs. multi-level transparency)
318  if( rBitmap.IsTransparent() )
319  {
320  if( rBitmap.IsAlpha() )
321  aSrcAlpha = rBitmap.GetAlpha().GetBitmap();
322  else
323  aSrcAlpha = rBitmap.GetMask();
324  }
325 
326  Bitmap::ScopedReadAccess pReadAccess( aSrcBitmap );
327  Bitmap::ScopedReadAccess pAlphaReadAccess( rBitmap.IsTransparent() ?
328  aSrcAlpha.AcquireReadAccess() :
329  nullptr,
330  aSrcAlpha );
331 
332  if( pReadAccess.get() == nullptr ||
333  (pAlphaReadAccess.get() == nullptr && rBitmap.IsTransparent()) )
334  {
335  // TODO(E2): Error handling!
336  ENSURE_OR_THROW( false,
337  "transformBitmap(): could not access source bitmap" );
338  }
339 
340  // mapping table, to translate pAlphaReadAccess' pixel
341  // values into destination alpha values (needed e.g. for
342  // paletted 1-bit masks).
343  sal_uInt8 aAlphaMap[256];
344 
345  if( rBitmap.IsTransparent() )
346  {
347  if( rBitmap.IsAlpha() )
348  {
349  // source already has alpha channel - 1:1 mapping,
350  // i.e. aAlphaMap[0]=0,...,aAlphaMap[255]=255.
351  sal_uInt8 val=0;
352  sal_uInt8* pCur=aAlphaMap;
353  sal_uInt8* const pEnd=&aAlphaMap[256];
354  while(pCur != pEnd)
355  *pCur++ = val++;
356  }
357  else
358  {
359  // mask transparency - determine used palette colors
360  const BitmapColor& rCol0( pAlphaReadAccess->GetPaletteColor( 0 ) );
361  const BitmapColor& rCol1( pAlphaReadAccess->GetPaletteColor( 1 ) );
362 
363  // shortcut for true luminance calculation
364  // (assumes that palette is grey-level)
365  aAlphaMap[0] = rCol0.GetRed();
366  aAlphaMap[1] = rCol1.GetRed();
367  }
368  }
369  // else: mapping table is not used
370 
371  const Size aDestBmpSize( ::basegfx::fround( rDestRect.getWidth() ),
372  ::basegfx::fround( rDestRect.getHeight() ) );
373 
374  if( aDestBmpSize.Width() == 0 || aDestBmpSize.Height() == 0 )
375  return BitmapEx();
376 
377  Bitmap aDstBitmap( aDestBmpSize, aSrcBitmap.GetBitCount(), &pReadAccess->GetPalette() );
378  Bitmap aDstAlpha( AlphaMask( aDestBmpSize ).GetBitmap() );
379 
380  {
381  // just to be on the safe side: let the
382  // ScopedAccessors get destructed before
383  // copy-constructing the resulting bitmap. This will
384  // rule out the possibility that cached accessor data
385  // is not yet written back.
386  BitmapScopedWriteAccess pWriteAccess( aDstBitmap );
387  BitmapScopedWriteAccess pAlphaWriteAccess( aDstAlpha );
388 
389 
390  if( pWriteAccess.get() != nullptr &&
391  pAlphaWriteAccess.get() != nullptr &&
392  rTransform.isInvertible() )
393  {
394  // we're doing inverse mapping here, i.e. mapping
395  // points from the destination bitmap back to the
396  // source
397  ::basegfx::B2DHomMatrix aTransform( rLocalTransform );
398  aTransform.invert();
399 
400  // for the time being, always read as ARGB
401  for( long y=0; y<aDestBmpSize.Height(); ++y )
402  {
403  // differentiate mask and alpha channel (on-off
404  // vs. multi-level transparency)
405  if( rBitmap.IsTransparent() )
406  {
407  Scanline pScan = pWriteAccess->GetScanline( y );
408  Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y );
409  // Handling alpha and mask just the same...
410  for( long x=0; x<aDestBmpSize.Width(); ++x )
411  {
412  ::basegfx::B2DPoint aPoint(x,y);
413  aPoint *= aTransform;
414 
415  const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
416  const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
417  if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
418  nSrcY < 0 || nSrcY >= aBmpSize.Height() )
419  {
420  pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) );
421  }
422  else
423  {
424  const sal_uInt8 cAlphaIdx = pAlphaReadAccess->GetPixelIndex( nSrcY, nSrcX );
425  pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(aAlphaMap[ cAlphaIdx ]) );
426  pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY, nSrcX ) );
427  }
428  }
429  }
430  else
431  {
432  Scanline pScan = pWriteAccess->GetScanline( y );
433  Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y );
434  for( long x=0; x<aDestBmpSize.Width(); ++x )
435  {
436  ::basegfx::B2DPoint aPoint(x,y);
437  aPoint *= aTransform;
438 
439  const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
440  const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
441  if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
442  nSrcY < 0 || nSrcY >= aBmpSize.Height() )
443  {
444  pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) );
445  }
446  else
447  {
448  pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(0) );
449  pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY,
450  nSrcX ) );
451  }
452  }
453  }
454  }
455  }
456  else
457  {
458  // TODO(E2): Error handling!
459  ENSURE_OR_THROW( false,
460  "transformBitmap(): could not access bitmap" );
461  }
462  }
463 
464  return BitmapEx(aDstBitmap, AlphaMask(aDstAlpha));
465 }
466 
467 
468 void DrawAlphaBitmapAndAlphaGradient(BitmapEx & rBitmapEx, bool bFixedTransparence, float fTransparence, AlphaMask & rNewMask)
469 {
470  // mix existing and new alpha mask
471  AlphaMask aOldMask;
472 
473  if(rBitmapEx.IsAlpha())
474  {
475  aOldMask = rBitmapEx.GetAlpha();
476  }
477  else if(TransparentType::Bitmap == rBitmapEx.GetTransparentType())
478  {
479  aOldMask = rBitmapEx.GetMask();
480  }
481  else if(TransparentType::Color == rBitmapEx.GetTransparentType())
482  {
483  aOldMask = rBitmapEx.GetBitmap().CreateMask(rBitmapEx.GetTransparentColor());
484  }
485 
486  {
487  AlphaScopedWriteAccess pOld(aOldMask);
488 
489  assert(pOld && "Got no access to old alpha mask (!)");
490 
491  const double fFactor(1.0 / 255.0);
492 
493  if(bFixedTransparence)
494  {
495  const double fOpNew(1.0 - fTransparence);
496 
497  for(long y(0); y < pOld->Height(); y++)
498  {
499  Scanline pScanline = pOld->GetScanline( y );
500  for(long x(0); x < pOld->Width(); x++)
501  {
502  const double fOpOld(1.0 - (pOld->GetIndexFromData(pScanline, x) * fFactor));
503  const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
504 
505  pOld->SetPixelOnData(pScanline, x, BitmapColor(aCol));
506  }
507  }
508  }
509  else
510  {
511  AlphaMask::ScopedReadAccess pNew(rNewMask);
512 
513  assert(pNew && "Got no access to new alpha mask (!)");
514 
515  assert(pOld->Width() == pNew->Width() && pOld->Height() == pNew->Height() &&
516  "Alpha masks have different sizes (!)");
517 
518  for(long y(0); y < pOld->Height(); y++)
519  {
520  Scanline pScanline = pOld->GetScanline( y );
521  for(long x(0); x < pOld->Width(); x++)
522  {
523  const double fOpOld(1.0 - (pOld->GetIndexFromData(pScanline, x) * fFactor));
524  const double fOpNew(1.0 - (pNew->GetIndexFromData(pScanline, x) * fFactor));
525  const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
526 
527  pOld->SetPixelOnData(pScanline, x, BitmapColor(aCol));
528  }
529  }
530  }
531 
532  }
533 
534  // apply combined bitmap as mask
535  rBitmapEx = BitmapEx(rBitmapEx.GetBitmap(), aOldMask);
536 }
537 
538 
539 void DrawAndClipBitmap(const Point& rPos, const Size& rSize, const BitmapEx& rBitmap, BitmapEx & aBmpEx, basegfx::B2DPolyPolygon const & rClipPath)
540 {
542  MapMode aMapMode( MapUnit::Map100thMM );
543  aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) );
544  const Size aOutputSizePixel( pVDev->LogicToPixel( rSize, aMapMode ) );
545  const Size aSizePixel( rBitmap.GetSizePixel() );
546  if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() )
547  {
548  aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) );
549  aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) );
550  }
551  pVDev->SetMapMode( aMapMode );
552  pVDev->SetOutputSizePixel( aSizePixel );
553  pVDev->SetFillColor( COL_BLACK );
554  const tools::PolyPolygon aClip( rClipPath );
555  pVDev->DrawPolyPolygon( aClip );
556 
557  // #i50672# Extract whole VDev content (to match size of rBitmap)
558  pVDev->EnableMapMode( false );
559  const Bitmap aVDevMask(pVDev->GetBitmap(Point(), aSizePixel));
560 
561  if(aBmpEx.IsTransparent())
562  {
563  // bitmap already uses a Mask or Alpha, we need to blend that with
564  // the new masking in pVDev
565  if(aBmpEx.IsAlpha())
566  {
567  // need to blend in AlphaMask quality (8Bit)
568  AlphaMask fromVDev(aVDevMask);
569  AlphaMask fromBmpEx(aBmpEx.GetAlpha());
570  AlphaMask::ScopedReadAccess pR(fromVDev);
571  AlphaScopedWriteAccess pW(fromBmpEx);
572 
573  if(pR && pW)
574  {
575  const long nWidth(std::min(pR->Width(), pW->Width()));
576  const long nHeight(std::min(pR->Height(), pW->Height()));
577 
578  for(long nY(0); nY < nHeight; nY++)
579  {
580  Scanline pScanlineR = pR->GetScanline( nY );
581  Scanline pScanlineW = pW->GetScanline( nY );
582  for(long nX(0); nX < nWidth; nX++)
583  {
584  const sal_uInt8 nIndR(pR->GetIndexFromData(pScanlineR, nX));
585  const sal_uInt8 nIndW(pW->GetIndexFromData(pScanlineW, nX));
586 
587  // these values represent transparency (0 == no, 255 == fully transparent),
588  // so to blend these we have to multiply the inverse (opacity)
589  // and re-invert the result to transparence
590  const sal_uInt8 nCombined(0x00ff - (((0x00ff - nIndR) * (0x00ff - nIndW)) >> 8));
591 
592  pW->SetPixelOnData(pScanlineW, nX, BitmapColor(nCombined));
593  }
594  }
595  }
596 
597  pR.reset();
598  pW.reset();
599  aBmpEx = BitmapEx(aBmpEx.GetBitmap(), fromBmpEx);
600  }
601  else
602  {
603  // need to blend in Mask quality (1Bit)
604  Bitmap aMask(aVDevMask.CreateMask(COL_WHITE));
605 
606  if ( rBitmap.GetTransparentColor() == COL_WHITE )
607  {
608  aMask.CombineSimple( rBitmap.GetMask(), BmpCombine::Or );
609  }
610  else
611  {
612  aMask.CombineSimple( rBitmap.GetMask(), BmpCombine::And );
613  }
614 
615  aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
616  }
617  }
618  else
619  {
620  // no mask yet, create and add new mask. For better quality, use Alpha,
621  // this allows the drawn mask being processed with AntiAliasing (AAed)
622  aBmpEx = BitmapEx(rBitmap.GetBitmap(), aVDevMask);
623  }
624 }
625 
626 
627 css::uno::Sequence< sal_Int8 > GetMaskDIB(BitmapEx const & aBmpEx)
628 {
629  if ( aBmpEx.IsAlpha() )
630  {
631  SvMemoryStream aMem;
632  WriteDIB(aBmpEx.GetAlpha().GetBitmap(), aMem, false, true);
633  return css::uno::Sequence< sal_Int8 >( static_cast<sal_Int8 const *>(aMem.GetData()), aMem.Tell() );
634  }
635  else if ( aBmpEx.IsTransparent() )
636  {
637  SvMemoryStream aMem;
638  WriteDIB(aBmpEx.GetMask(), aMem, false, true);
639  return css::uno::Sequence< sal_Int8 >( static_cast<sal_Int8 const *>(aMem.GetData()), aMem.Tell() );
640  }
641 
642  return css::uno::Sequence< sal_Int8 >();
643 }
644 
645 static bool readAlpha( BitmapReadAccess const * pAlphaReadAcc, long nY, const long nWidth, unsigned char* data, long nOff )
646 {
647  bool bIsAlpha = false;
648  long nX;
649  int nAlpha;
650  Scanline pReadScan;
651 
652  nOff += 3;
653 
654  switch( pAlphaReadAcc->GetScanlineFormat() )
655  {
657  pReadScan = pAlphaReadAcc->GetScanline( nY );
658  for( nX = 0; nX < nWidth; nX++ )
659  {
660  nAlpha = data[ nOff ] = 255 - ( *pReadScan++ );
661  if( nAlpha != 255 )
662  bIsAlpha = true;
663  nOff += 4;
664  }
665  break;
667  pReadScan = pAlphaReadAcc->GetScanline( nY );
668  for( nX = 0; nX < nWidth; nX++ )
669  {
670  BitmapColor const& rColor(
671  pAlphaReadAcc->GetPaletteColor(*pReadScan));
672  pReadScan++;
673  nAlpha = data[ nOff ] = 255 - rColor.GetIndex();
674  if( nAlpha != 255 )
675  bIsAlpha = true;
676  nOff += 4;
677  }
678  break;
679  default:
680  SAL_INFO( "canvas.cairo", "fallback to GetColor for alpha - slow, format: " << static_cast<int>(pAlphaReadAcc->GetScanlineFormat()) );
681  for( nX = 0; nX < nWidth; nX++ )
682  {
683  nAlpha = data[ nOff ] = 255 - pAlphaReadAcc->GetColor( nY, nX ).GetIndex();
684  if( nAlpha != 255 )
685  bIsAlpha = true;
686  nOff += 4;
687  }
688  }
689 
690  return bIsAlpha;
691 }
692 
693 
694 
699 void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, unsigned char*& data, bool& bHasAlpha, long& rnWidth, long& rnHeight )
700 {
701  AlphaMask aAlpha = aBmpEx.GetAlpha();
702 
703  ::BitmapReadAccess* pBitmapReadAcc = aBitmap.AcquireReadAccess();
704  ::BitmapReadAccess* pAlphaReadAcc = nullptr;
705  const long nWidth = rnWidth = pBitmapReadAcc->Width();
706  const long nHeight = rnHeight = pBitmapReadAcc->Height();
707  long nX, nY;
708  bool bIsAlpha = false;
709 
710  if( aBmpEx.IsTransparent() || aBmpEx.IsAlpha() )
711  pAlphaReadAcc = aAlpha.AcquireReadAccess();
712 
713  data = static_cast<unsigned char*>(malloc( nWidth*nHeight*4 ));
714 
715  long nOff = 0;
716  ::Color aColor;
717  unsigned int nAlpha = 255;
718 
720  for( nY = 0; nY < nHeight; nY++ )
721  {
722  ::Scanline pReadScan;
723 
724  switch( pBitmapReadAcc->GetScanlineFormat() )
725  {
727  pReadScan = pBitmapReadAcc->GetScanline( nY );
728  if( pAlphaReadAcc )
729  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
730  bIsAlpha = true;
731 
732  for( nX = 0; nX < nWidth; nX++ )
733  {
734 #ifdef OSL_BIGENDIAN
735  if( pAlphaReadAcc )
736  nAlpha = data[ nOff++ ];
737  else
738  nAlpha = data[ nOff++ ] = 255;
739 #else
740  if( pAlphaReadAcc )
741  nAlpha = data[ nOff + 3 ];
742  else
743  nAlpha = data[ nOff + 3 ] = 255;
744 #endif
745  aColor = pBitmapReadAcc->GetPaletteColor(*pReadScan++);
746 
747 #ifdef OSL_BIGENDIAN
748  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()];
749  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()];
750  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()];
751 #else
752  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()];
753  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()];
754  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()];
755  nOff++;
756 #endif
757  }
758  break;
760  pReadScan = pBitmapReadAcc->GetScanline( nY );
761  if( pAlphaReadAcc )
762  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
763  bIsAlpha = true;
764 
765  for( nX = 0; nX < nWidth; nX++ )
766  {
767 #ifdef OSL_BIGENDIAN
768  if( pAlphaReadAcc )
769  nAlpha = data[ nOff ];
770  else
771  nAlpha = data[ nOff ] = 255;
772  data[ nOff + 3 ] = premultiply_table[nAlpha][*pReadScan++];
773  data[ nOff + 2 ] = premultiply_table[nAlpha][*pReadScan++];
774  data[ nOff + 1 ] = premultiply_table[nAlpha][*pReadScan++];
775  nOff += 4;
776 #else
777  if( pAlphaReadAcc )
778  nAlpha = data[ nOff + 3 ];
779  else
780  nAlpha = data[ nOff + 3 ] = 255;
781  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
782  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
783  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
784  nOff++;
785 #endif
786  }
787  break;
789  pReadScan = pBitmapReadAcc->GetScanline( nY );
790  if( pAlphaReadAcc )
791  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
792  bIsAlpha = true;
793 
794  for( nX = 0; nX < nWidth; nX++ )
795  {
796 #ifdef OSL_BIGENDIAN
797  if( pAlphaReadAcc )
798  nAlpha = data[ nOff++ ];
799  else
800  nAlpha = data[ nOff++ ] = 255;
801  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
802  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
803  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
804 #else
805  if( pAlphaReadAcc )
806  nAlpha = data[ nOff + 3 ];
807  else
808  nAlpha = data[ nOff + 3 ] = 255;
809  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 2 ]];
810  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 1 ]];
811  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 0 ]];
812  pReadScan += 3;
813  nOff++;
814 #endif
815  }
816  break;
818  pReadScan = pBitmapReadAcc->GetScanline( nY );
819  if( pAlphaReadAcc )
820  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
821  bIsAlpha = true;
822 
823  for( nX = 0; nX < nWidth; nX++ )
824  {
825 #ifdef OSL_BIGENDIAN
826  if( pAlphaReadAcc )
827  nAlpha = data[ nOff++ ];
828  else
829  nAlpha = data[ nOff++ ] = 255;
830  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 2 ]];
831  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 1 ]];
832  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 0 ]];
833  pReadScan += 4;
834 #else
835  if( pAlphaReadAcc )
836  nAlpha = data[ nOff + 3 ];
837  else
838  nAlpha = data[ nOff + 3 ] = 255;
839  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
840  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
841  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
842  pReadScan++;
843  nOff++;
844 #endif
845  }
846  break;
848  pReadScan = pBitmapReadAcc->GetScanline( nY );
849  if( pAlphaReadAcc )
850  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
851  bIsAlpha = true;
852 
853  for( nX = 0; nX < nWidth; nX++ )
854  {
855 #ifdef OSL_BIGENDIAN
856  if( pAlphaReadAcc )
857  nAlpha = data[ nOff ++ ];
858  else
859  nAlpha = data[ nOff ++ ] = 255;
860  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
861  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
862  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
863  pReadScan++;
864 #else
865  if( pAlphaReadAcc )
866  nAlpha = data[ nOff + 3 ];
867  else
868  nAlpha = data[ nOff + 3 ] = 255;
869  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 2 ]];
870  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 1 ]];
871  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 0 ]];
872  pReadScan += 4;
873  nOff++;
874 #endif
875  }
876  break;
877  default:
878  SAL_INFO( "canvas.cairo", "fallback to GetColor - slow, format: " << static_cast<int>(pBitmapReadAcc->GetScanlineFormat()) );
879 
880  if( pAlphaReadAcc )
881  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
882  bIsAlpha = true;
883 
884  for( nX = 0; nX < nWidth; nX++ )
885  {
886  aColor = pBitmapReadAcc->GetColor( nY, nX );
887 
888  // cairo need premultiplied color values
889  // TODO(rodo) handle endianness
890 #ifdef OSL_BIGENDIAN
891  if( pAlphaReadAcc )
892  nAlpha = data[ nOff++ ];
893  else
894  nAlpha = data[ nOff++ ] = 255;
895  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()];
896  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()];
897  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()];
898 #else
899  if( pAlphaReadAcc )
900  nAlpha = data[ nOff + 3 ];
901  else
902  nAlpha = data[ nOff + 3 ] = 255;
903  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()];
904  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()];
905  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()];
906  nOff ++;
907 #endif
908  }
909  }
910  }
911 
912  ::Bitmap::ReleaseAccess( pBitmapReadAcc );
913  if( pAlphaReadAcc )
914  aAlpha.ReleaseAccess( pAlphaReadAcc );
915 
916  bHasAlpha = bIsAlpha;
917 
918 }
919 
920  uno::Sequence< sal_Int8 > CanvasExtractBitmapData(BitmapEx const & rBitmapEx, const geometry::IntegerRectangle2D& rect)
921  {
922  Bitmap aBitmap( rBitmapEx.GetBitmap() );
923  Bitmap aAlpha( rBitmapEx.GetAlpha().GetBitmap() );
924 
925  Bitmap::ScopedReadAccess pReadAccess( aBitmap );
926  Bitmap::ScopedReadAccess pAlphaReadAccess( aAlpha.IsEmpty() ?
927  nullptr : aAlpha.AcquireReadAccess(),
928  aAlpha );
929 
930  assert( pReadAccess );
931 
932  // TODO(F1): Support more formats.
933  const Size aBmpSize( aBitmap.GetSizePixel() );
934 
935  // for the time being, always return as BGRA
936  uno::Sequence< sal_Int8 > aRes( 4*aBmpSize.Width()*aBmpSize.Height() );
937  sal_Int8* pRes = aRes.getArray();
938 
939  int nCurrPos(0);
940  for( long y=rect.Y1;
941  y<aBmpSize.Height() && y<rect.Y2;
942  ++y )
943  {
944  if( pAlphaReadAccess.get() != nullptr )
945  {
946  Scanline pScanlineReadAlpha = pAlphaReadAccess->GetScanline( y );
947  for( long x=rect.X1;
948  x<aBmpSize.Width() && x<rect.X2;
949  ++x )
950  {
951  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetRed();
952  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetGreen();
953  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetBlue();
954  pRes[ nCurrPos++ ] = pAlphaReadAccess->GetIndexFromData( pScanlineReadAlpha, x );
955  }
956  }
957  else
958  {
959  for( long x=rect.X1;
960  x<aBmpSize.Width() && x<rect.X2;
961  ++x )
962  {
963  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetRed();
964  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetGreen();
965  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetBlue();
966  pRes[ nCurrPos++ ] = sal_uInt8(255);
967  }
968  }
969  }
970  return aRes;
971  }
972 
973  BitmapEx createHistorical8x8FromArray(std::array<sal_uInt8,64> const & pArray, Color aColorPix, Color aColorBack)
974  {
975  BitmapPalette aPalette(2);
976 
977  aPalette[0] = BitmapColor(aColorBack);
978  aPalette[1] = BitmapColor(aColorPix);
979 
980  Bitmap aBitmap(Size(8, 8), 1, &aPalette);
982 
983  for(sal_uInt16 a(0); a < 8; a++)
984  {
985  for(sal_uInt16 b(0); b < 8; b++)
986  {
987  if(pArray[(a * 8) + b])
988  {
989  pContent->SetPixelIndex(a, b, 1);
990  }
991  else
992  {
993  pContent->SetPixelIndex(a, b, 0);
994  }
995  }
996  }
997 
998  return BitmapEx(aBitmap);
999  }
1000 
1001  bool isHistorical8x8(const BitmapEx& rBitmapEx, Color& o_rBack, Color& o_rFront)
1002  {
1003  bool bRet(false);
1004 
1005  if(!rBitmapEx.IsTransparent())
1006  {
1007  Bitmap aBitmap(rBitmapEx.GetBitmap());
1008 
1009  if(8 == aBitmap.GetSizePixel().Width() && 8 == aBitmap.GetSizePixel().Height())
1010  {
1011  if(2 == aBitmap.GetColorCount())
1012  {
1013  BitmapReadAccess* pRead = aBitmap.AcquireReadAccess();
1014 
1015  if(pRead)
1016  {
1017  if(pRead->HasPalette() && 2 == pRead->GetPaletteEntryCount())
1018  {
1019  const BitmapPalette& rPalette = pRead->GetPalette();
1020 
1021  // #i123564# background and foreground were exchanged; of course
1022  // rPalette[0] is the background color
1023  o_rFront = rPalette[1];
1024  o_rBack = rPalette[0];
1025 
1026  bRet = true;
1027  }
1028 
1029  Bitmap::ReleaseAccess(pRead);
1030  }
1031  }
1032  }
1033  }
1034 
1035  return bRet;
1036  }
1037 
1039  {
1040  return (a == 0) ? 0 : (c * 255 + a / 2) / a;
1041  }
1042 
1044  {
1045  return (c * a + 127) / 255;
1046  }
1047 
1049  {
1050  static bool inited;
1051  static sal_uInt8 unpremultiply_table[256][256];
1052 
1053  if (!inited)
1054  {
1055  for (int a = 0; a < 256; ++a)
1056  for (int c = 0; c < 256; ++c)
1057  unpremultiply_table[a][c] = unpremultiply(c, a);
1058  inited = true;
1059  }
1060 
1061  return unpremultiply_table;
1062  }
1063 
1065  {
1066  static bool inited;
1067  static sal_uInt8 premultiply_table[256][256];
1068 
1069  if (!inited)
1070  {
1071  for (int a = 0; a < 256; ++a)
1072  for (int c = 0; c < 256; ++c)
1073  premultiply_table[a][c] = premultiply(c, a);
1074  inited = true;
1075  }
1076 
1077  return premultiply_table;
1078  }
1079 
1080 bool convertBitmap32To24Plus8(BitmapEx const & rInput, BitmapEx & rResult)
1081 {
1082  Bitmap aBitmap(rInput.GetBitmap());
1083  if (aBitmap.GetBitCount() != 32)
1084  return false;
1085 
1086  Size aSize = aBitmap.GetSizePixel();
1087  Bitmap aResultBitmap(aSize, 24);
1088  AlphaMask aResultAlpha(aSize);
1089  {
1090  BitmapScopedWriteAccess pResultBitmapAccess(aResultBitmap);
1091  AlphaScopedWriteAccess pResultAlphaAccess(aResultAlpha);
1092 
1093  Bitmap::ScopedReadAccess pReadAccess(aBitmap);
1094 
1095  for (long nY = 0; nY < aSize.Height(); ++nY)
1096  {
1097  Scanline aResultScan = pResultBitmapAccess->GetScanline(nY);
1098  Scanline aResultScanAlpha = pResultAlphaAccess->GetScanline(nY);
1099 
1100  Scanline aReadScan = pReadAccess->GetScanline(nY);
1101 
1102  for (long nX = 0; nX < aSize.Width(); ++nX)
1103  {
1104  const BitmapColor aColor = pReadAccess->GetPixelFromData(aReadScan, nX);
1105  BitmapColor aResultColor(aColor.GetRed(), aColor.GetGreen(), aColor.GetBlue());
1106  BitmapColor aResultColorAlpha(aColor.GetAlpha(), aColor.GetAlpha(), aColor.GetAlpha());
1107 
1108  pResultBitmapAccess->SetPixelOnData(aResultScan, nX, aResultColor);
1109  pResultAlphaAccess->SetPixelOnData(aResultScanAlpha, nX, aResultColorAlpha);
1110  }
1111  }
1112  }
1113  if (rInput.IsTransparent())
1114  rResult = BitmapEx(aResultBitmap, rInput.GetAlpha());
1115  else
1116  rResult = BitmapEx(aResultBitmap, aResultAlpha);
1117  return true;
1118 }
1119 
1120 } // end vcl::bitmap
1121 
1122 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long Width() const
void loadFromSvg(SvStream &rStream, const OUString &sPath, BitmapEx &rBitmapEx, double fScalingFactor)
Definition: BitmapTools.cxx:58
sal_uInt8 premultiply(sal_uInt8 c, sal_uInt8 a)
Bitmap GetMask() const
Definition: bitmapex.cxx:258
ImageLoadFlags
Definition: ImageTree.hxx:31
sal_uInt8 GetIndex() const
Definition: BitmapColor.hxx:61
void expand(const B2DTuple &rTuple)
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
sal_uInt8 GetRed() const
double getHeight() const
Scanline GetScanline(long nY) const
OUString DetermineIconTheme() const
Determine which icon theme should be used.
const char aData[]
sal_uInt8 GetAlpha() const
Definition: BitmapColor.hxx:71
void DrawAlphaBitmapAndAlphaGradient(BitmapEx &rBitmapEx, bool bFixedTransparence, float fTransparence, AlphaMask &rNewMask)
long Height() const
signed char sal_Int8
sal_uInt8 unpremultiply(sal_uInt8 c, sal_uInt8 a)
Bitmap const & GetBitmap() const
Definition: alpha.cxx:70
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:714
double getX() const
lookup_table get_unpremultiply_table()
sal_uInt8(* lookup_table)[256]
Definition: BitmapTools.hxx:31
static bool readAlpha(BitmapReadAccess const *pAlphaReadAcc, long nY, const long nWidth, unsigned char *data, long nOff)
double getY() const
B2DVector getRange() const
BitmapReadAccess * AcquireReadAccess()
long Width() const
::BitmapEx bitmapExFromXBitmap(const uno::Reference< rendering::XIntegerReadOnlyBitmap > &xInputBitmap)
float x
double getMaxX() const
void CanvasCairoExtractBitmapData(BitmapEx const &aBmpEx, Bitmap &aBitmap, unsigned char *&data, bool &bHasAlpha, long &rnWidth, long &rnHeight)
static VCL_DLLPUBLIC ImageTree & get()
Definition: ImageTree.cxx:16
bool IsAlpha() const
Definition: bitmapex.cxx:226
bool CombineSimple(const Bitmap &rMask, BmpCombine eCombine)
Perform boolean operations with another bitmap.
double getWidth() const
void DrawAndClipBitmap(const Point &rPos, const Size &rSize, const BitmapEx &rBitmap, BitmapEx &aBmpEx, basegfx::B2DPolyPolygon const &rClipPath)
void SetPixelOnData(sal_uInt8 *pData, long nX, const BitmapColor &rBitmapColor)
sal_uInt64 remainingSize()
double getMaxY() const
sal_uInt8 GetBlue() const
B2IRange fround(const B2DRange &rRange)
float y
css::uno::Sequence< Primitive2DReference > Primitive2DSequence
BitmapEx CreateFromData(RawBitmap &&rawBitmap)
Copy block of image data into the bitmap.
VCL_DLLPUBLIC bool loadImage(OUString const &name, OUString const &style, BitmapEx &bitmap, bool localized, const ImageLoadFlags eFlags=ImageLoadFlags::NONE)
Definition: ImageTree.cxx:45
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
void SetScaleX(const Fraction &rScaleX)
Definition: mapmod.cxx:108
bool HasPalette() const
uno_Any a
ScanlineFormat GetScanlineFormat() const
void SetOrigin(const Point &rOrigin)
Definition: mapmod.cxx:102
::rtl::Reference< Content > pContent
TransparentType GetTransparentType() const
Definition: bitmapex.hxx:73
void SetScaleY(const Fraction &rScaleY)
Definition: mapmod.cxx:115
bool isHistorical8x8(const BitmapEx &rBitmapEx, Color &o_rBack, Color &o_rFront)
css::uno::Sequence< sal_Int8 > GetMaskDIB(BitmapEx const &aBmpEx)
static void ReleaseAccess(BitmapInfoAccess *pAccess)
struct _cairo cairo_t
Definition: svpgdi.hxx:70
uno::Sequence< sal_Int8 > CanvasExtractBitmapData(BitmapEx const &rBitmapEx, const geometry::IntegerRectangle2D &rect)
bool IsTransparent() const
Definition: bitmapex.cxx:221
Intended to be used to feed into CreateFromData to create a BitmapEx.
Definition: BitmapTools.hxx:42
short nBitCount
BitmapEx CanvasTransformBitmap(const BitmapEx &rBitmap, const ::basegfx::B2DHomMatrix &rTransform,::basegfx::B2DRectangle const &rDestRect,::basegfx::B2DHomMatrix const &rLocalTransform)
BitmapColor GetPixel(long nY, long nX) const
sal_uInt16 GetPaletteEntryCount() const
void ReleaseAccess(BitmapReadAccess *pAccess)
Definition: alpha.cxx:141
std::size_t ReadBytes(void *pData, std::size_t nSize)
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: bitmapex.cxx:236
sal_uInt8 GetGreen() const
BitmapEx createHistorical8x8FromArray(std::array< sal_uInt8, 64 > const &pArray, Color aColorPix, Color aColorBack)
const Color & GetTransparentColor() const
Definition: bitmapex.hxx:92
#define ENSURE_OR_THROW(c, m)
lookup_table get_premultiply_table()
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
std::unique_ptr< char[]> aBuffer
double getMinY() const
AlphaMask GetAlpha() const
Definition: bitmapex.cxx:268
long Height() const
unsigned char sal_uInt8
BitmapColor GetColor(long nY, long nX) const
const BitmapPalette & GetPalette() const
#define SAL_INFO(area, stream)
bool convertBitmap32To24Plus8(BitmapEx const &rInput, BitmapEx &rResult)
BitmapWriteAccess * AcquireWriteAccess()
sal_uInt64 Tell() const
void * p
Reference< XComponentContext > getProcessComponentContext()
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
BitmapColor GetPixelFromData(const sal_uInt8 *pData, long nX) const
vcl::ScopedBitmapAccess< BitmapWriteAccess, AlphaMask,&AlphaMask::AcquireAlphaWriteAccess > AlphaScopedWriteAccess
BitmapEx loadFromName(const OUString &rFileName, const ImageLoadFlags eFlags)
Definition: BitmapTools.cxx:47
double getMinX() const
const BitmapColor & GetPaletteColor(sal_uInt16 nColor) const
bool WriteDIB(const Bitmap &rSource, SvStream &rOStm, bool bCompressed, bool bFileHeader)
Definition: dibtools.cxx:1855
const Size & GetSizePixel() const
Definition: bitmapex.hxx:83
struct _cairo_surface cairo_surface_t
Definition: svpgdi.hxx:71
Bitmap CreateMask(const Color &rTransColor, sal_uInt8 nTol=0) const
Create on-off mask from bitmap.
const void * GetData()
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, long nX) const