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