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