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