LibreOffice Module vcl (master)  1
canvastools.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  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <com/sun/star/geometry/RealSize2D.hpp>
21 #include <com/sun/star/geometry/IntegerSize2D.hpp>
22 #include <com/sun/star/geometry/IntegerPoint2D.hpp>
23 #include <com/sun/star/geometry/IntegerRectangle2D.hpp>
24 
25 #include <com/sun/star/rendering/ColorSpaceType.hpp>
26 #include <com/sun/star/rendering/RenderingIntent.hpp>
27 #include <com/sun/star/rendering/VolatileContentDestroyedException.hpp>
28 #include <com/sun/star/rendering/XBitmap.hpp>
29 #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
30 #include <com/sun/star/rendering/ColorComponentTag.hpp>
31 
36 
37 #include <sal/log.hxx>
38 #include <tools/helpers.hxx>
39 #include <tools/diagnose_ex.h>
40 
41 #include <vcl/bitmapex.hxx>
42 
43 #include <canvasbitmap.hxx>
44 #include <vcl/canvastools.hxx>
45 #include <bitmapwriteaccess.hxx>
46 
47 using namespace ::com::sun::star;
48 
49 namespace vcl
50 {
51  namespace unotools
52  {
53  uno::Reference< rendering::XBitmap > xBitmapFromBitmapEx(const ::BitmapEx& inputBitmap )
54  {
55  SAL_INFO( "vcl.helper", "vcl::unotools::xBitmapFromBitmapEx()" );
56 
57  return new vcl::unotools::VclCanvasBitmap( inputBitmap );
58  }
59 
60  namespace
61  {
62  bool equalsLayout( const rendering::IntegerBitmapLayout& rLHS,
63  const rendering::IntegerBitmapLayout& rRHS )
64  {
65  return
66  rLHS.ScanLineBytes == rRHS.ScanLineBytes &&
67  rLHS.ScanLineStride == rRHS.ScanLineStride &&
68  rLHS.PlaneStride == rRHS.PlaneStride &&
69  rLHS.ColorSpace == rRHS.ColorSpace &&
70  rLHS.Palette == rRHS.Palette &&
71  rLHS.IsMsbFirst == rRHS.IsMsbFirst;
72  }
73  bool readBmp( sal_Int32 nWidth,
74  sal_Int32 nHeight,
75  const rendering::IntegerBitmapLayout& rLayout,
76  const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap,
77  BitmapScopedWriteAccess& rWriteAcc,
78  BitmapScopedWriteAccess& rAlphaAcc )
79  {
80  rendering::IntegerBitmapLayout aCurrLayout;
81  geometry::IntegerRectangle2D aRect;
82  uno::Sequence<sal_Int8> aPixelData;
83  uno::Sequence<rendering::RGBColor> aRGBColors;
84  uno::Sequence<rendering::ARGBColor> aARGBColors;
85 
86  for( aRect.Y1=0; aRect.Y1<nHeight; ++aRect.Y1 )
87  {
88  aRect.X1 = 0; aRect.X2 = nWidth; aRect.Y2 = aRect.Y1+1;
89  try
90  {
91  aPixelData = xInputBitmap->getData(aCurrLayout,aRect);
92  }
93  catch( rendering::VolatileContentDestroyedException& )
94  {
95  // re-read bmp from the start
96  return false;
97  }
98  if( !equalsLayout(aCurrLayout, rLayout) )
99  return false; // re-read bmp from the start
100 
101  Scanline pScanline = rWriteAcc->GetScanline( aRect.Y1 );
102  if( rAlphaAcc.get() )
103  {
104  Scanline pScanlineAlpha = rAlphaAcc->GetScanline( aRect.Y1 );
105  // read ARGB color
106  aARGBColors = rLayout.ColorSpace->convertIntegerToARGB(aPixelData);
107 
108  if( rWriteAcc->HasPalette() )
109  {
110  for( sal_Int32 x=0; x<nWidth; ++x )
111  {
112  const rendering::ARGBColor& rColor=aARGBColors[x];
113  rWriteAcc->SetPixelOnData( pScanline, x,
114  BitmapColor(static_cast<sal_uInt8>(rWriteAcc->GetBestPaletteIndex(
115  BitmapColor( toByteColor(rColor.Red),
116  toByteColor(rColor.Green),
117  toByteColor(rColor.Blue))))) );
118  rAlphaAcc->SetPixelOnData( pScanlineAlpha, x,
119  BitmapColor( 255 - toByteColor(rColor.Alpha) ));
120  }
121  }
122  else
123  {
124  for( sal_Int32 x=0; x<nWidth; ++x )
125  {
126  const rendering::ARGBColor& rColor=aARGBColors[x];
127  rWriteAcc->SetPixelOnData( pScanline, x,
128  BitmapColor( toByteColor(rColor.Red),
129  toByteColor(rColor.Green),
130  toByteColor(rColor.Blue) ));
131  rAlphaAcc->SetPixelOnData( pScanlineAlpha, x,
132  BitmapColor( 255 - toByteColor(rColor.Alpha) ));
133  }
134  }
135  }
136  else
137  {
138  // read RGB color
139  aRGBColors = rLayout.ColorSpace->convertIntegerToRGB(aPixelData);
140  if( rWriteAcc->HasPalette() )
141  {
142  for( sal_Int32 x=0; x<nWidth; ++x )
143  {
144  const rendering::RGBColor& rColor=aRGBColors[x];
145  rWriteAcc->SetPixelOnData( pScanline, x,
146  BitmapColor(static_cast<sal_uInt8>(rWriteAcc->GetBestPaletteIndex(
147  BitmapColor( toByteColor(rColor.Red),
148  toByteColor(rColor.Green),
149  toByteColor(rColor.Blue))))) );
150  }
151  }
152  else
153  {
154  for( sal_Int32 x=0; x<nWidth; ++x )
155  {
156  const rendering::RGBColor& rColor=aRGBColors[x];
157  rWriteAcc->SetPixelOnData( pScanline, x,
158  BitmapColor( toByteColor(rColor.Red),
159  toByteColor(rColor.Green),
160  toByteColor(rColor.Blue) ));
161  }
162  }
163  }
164  }
165 
166  return true;
167  }
168  }
169 
170  ::BitmapEx bitmapExFromXBitmap( const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap )
171  {
172  SAL_INFO( "vcl.helper", "vcl::unotools::bitmapExFromXBitmap()" );
173 
174  if( !xInputBitmap.is() )
175  return ::BitmapEx();
176 
177  // tunnel directly for known implementation
178  VclCanvasBitmap* pImplBitmap = dynamic_cast<VclCanvasBitmap*>(xInputBitmap.get());
179  if( pImplBitmap )
180  return pImplBitmap->getBitmapEx();
181 
182  // retrieve data via UNO interface
183 
184  // volatile bitmaps are a bit more complicated to read
185  // from...
186 
187  // loop a few times, until successfully read (for XVolatileBitmap)
188  for( int i=0; i<10; ++i )
189  {
190  sal_Int32 nDepth=0;
191  sal_Int32 nAlphaDepth=0;
192  const rendering::IntegerBitmapLayout aLayout(
193  xInputBitmap->getMemoryLayout());
194 
195  OSL_ENSURE(aLayout.ColorSpace.is(),
196  "Cannot convert image without color space!");
197  if( !aLayout.ColorSpace.is() )
198  return ::BitmapEx();
199 
200  nDepth = aLayout.ColorSpace->getBitsPerPixel();
201 
202  if( xInputBitmap->hasAlpha() )
203  {
204  // determine alpha channel depth
205  const uno::Sequence<sal_Int8> aTags(
206  aLayout.ColorSpace->getComponentTags() );
207  const sal_Int8* pStart(aTags.getConstArray());
208  const std::size_t nLen(aTags.getLength());
209  const sal_Int8* pEnd(pStart+nLen);
210 
211  const std::ptrdiff_t nAlphaIndex =
212  std::find(pStart,pEnd,
213  rendering::ColorComponentTag::ALPHA) - pStart;
214 
215  if( nAlphaIndex < sal::static_int_cast<std::ptrdiff_t>(nLen) )
216  {
217  nAlphaDepth = aLayout.ColorSpace->getComponentBitCounts()[nAlphaIndex] > 1 ? 8 : 1;
218  nDepth -= nAlphaDepth;
219  }
220  }
221 
222  BitmapPalette aPalette;
223  if( aLayout.Palette.is() )
224  {
225  uno::Reference< rendering::XColorSpace > xPaletteColorSpace(
226  aLayout.Palette->getColorSpace());
227  ENSURE_OR_THROW(xPaletteColorSpace.is(),
228  "Palette without color space");
229 
230  const sal_Int32 nEntryCount( aLayout.Palette->getNumberOfEntries() );
231  if( nEntryCount <= 256 )
232  {
233  if( nEntryCount <= 2 )
234  nDepth = 1;
235  else
236  nDepth = 8;
237 
238  const sal_uInt16 nPaletteEntries(
239  sal::static_int_cast<sal_uInt16>(
240  std::min(sal_Int32(255), nEntryCount)));
241 
242  // copy palette entries
243  aPalette.SetEntryCount(nPaletteEntries);
244  uno::Reference<rendering::XBitmapPalette> xPalette( aLayout.Palette );
245  uno::Reference<rendering::XColorSpace> xPalColorSpace( xPalette->getColorSpace() );
246 
247  uno::Sequence<double> aPaletteEntry;
248  for( sal_uInt16 j=0; j<nPaletteEntries; ++j )
249  {
250  if( !xPalette->getIndex(aPaletteEntry,j) &&
251  nAlphaDepth == 0 )
252  {
253  nAlphaDepth = 1;
254  }
255  uno::Sequence<rendering::RGBColor> aColors=xPalColorSpace->convertToRGB(aPaletteEntry);
256  ENSURE_OR_THROW(aColors.getLength() == 1,
257  "Palette returned more or less than one entry");
258  const rendering::RGBColor& rColor=aColors[0];
259  aPalette[j] = BitmapColor(toByteColor(rColor.Red),
260  toByteColor(rColor.Green),
261  toByteColor(rColor.Blue));
262  }
263  }
264  }
265 
266  const ::Size aPixelSize(
267  sizeFromIntegerSize2D(xInputBitmap->getSize()));
268 
269  // normalize bitcount
270  nDepth =
271  ( nDepth <= 1 ) ? 1 :
272  ( nDepth <= 4 ) ? 4 :
273  ( nDepth <= 8 ) ? 8 : 24;
274 
275  ::Bitmap aBitmap( aPixelSize,
276  sal::static_int_cast<sal_uInt16>(nDepth),
277  aLayout.Palette.is() ? &aPalette : nullptr );
278  ::Bitmap aAlpha;
279  if( nAlphaDepth )
280  aAlpha = ::Bitmap( aPixelSize,
281  sal::static_int_cast<sal_uInt16>(nAlphaDepth),
283  sal::static_int_cast<sal_uInt16>(1 << nAlphaDepth)) );
284 
285  { // limit scoped access
286  BitmapScopedWriteAccess pWriteAccess( aBitmap );
287  BitmapScopedWriteAccess pAlphaWriteAccess( nAlphaDepth ? aAlpha.AcquireWriteAccess() : nullptr,
288  aAlpha );
289 
290  ENSURE_OR_THROW(pWriteAccess.get() != nullptr,
291  "Cannot get write access to bitmap");
292 
293  const sal_Int32 nWidth(aPixelSize.Width());
294  const sal_Int32 nHeight(aPixelSize.Height());
295 
296  if( !readBmp(nWidth,nHeight,aLayout,xInputBitmap,
297  pWriteAccess,pAlphaWriteAccess) )
298  continue;
299  } // limit scoped access
300 
301  if( nAlphaDepth )
302  return ::BitmapEx( aBitmap,
303  AlphaMask( aAlpha ) );
304  else
305  return ::BitmapEx( aBitmap );
306  }
307 
308  // failed to read data 10 times - bail out
309  return ::BitmapEx();
310  }
311 
312  geometry::RealSize2D size2DFromSize( const Size& rSize )
313  {
314  return geometry::RealSize2D( rSize.Width(),
315  rSize.Height() );
316  }
317 
318  Size sizeFromRealSize2D( const geometry::RealSize2D& rSize )
319  {
320  return Size( static_cast<long>(rSize.Width + .5),
321  static_cast<long>(rSize.Height + .5) );
322  }
323 
325  {
326  return ::Size( FRound( rVec.getX() ),
327  FRound( rVec.getY() ) );
328  }
329 
331  {
332  return pointFromB2IPoint(basegfx::fround(rPoint));
333  }
334 
336  {
338  }
339 
341  {
342  return ::Point( rPoint.getX(),
343  rPoint.getY() );
344  }
345 
347  {
348  return basegfx::B2IPoint(rPoint.X(), rPoint.Y());
349  }
350 
352  {
353  return ::tools::Rectangle( rRect.getMinX(),
354  rRect.getMinY(),
355  rRect.getMaxX(),
356  rRect.getMaxY() );
357  }
358 
360  {
361  // although B2IRange internally has separate height/width emptiness, it doesn't
362  // expose any API to let us set them separately, so just do the best we can.
363  if (rRect.IsWidthEmpty() && rRect.IsHeightEmpty())
364  return basegfx::B2IRange( basegfx::B2ITuple( rRect.Left(), rRect.Top() ) );
365  return basegfx::B2IRange( rRect.Left(),
366  rRect.Top(),
367  rRect.IsWidthEmpty() ? rRect.Left() : rRect.Right(),
368  rRect.IsHeightEmpty() ? rRect.Top() : rRect.Bottom() );
369  }
370 
371  basegfx::B2DVector b2DSizeFromSize( const ::Size& rSize )
372  {
373  return basegfx::B2DVector( rSize.Width(),
374  rSize.Height() );
375  }
376 
377  basegfx::B2DPoint b2DPointFromPoint( const ::Point& rPoint )
378  {
379  return basegfx::B2DPoint( rPoint.X(),
380  rPoint.Y() );
381  }
382 
383  basegfx::B2DRange b2DRectangleFromRectangle( const ::tools::Rectangle& rRect )
384  {
385  // although B2DRange internally has separate height/width emptiness, it doesn't
386  // expose any API to let us set them separately, so just do the best we can.
387  if (rRect.IsWidthEmpty() && rRect.IsHeightEmpty())
388  return basegfx::B2DRange( basegfx::B2DTuple( rRect.Left(), rRect.Top() ) );
389  return basegfx::B2DRectangle( rRect.Left(),
390  rRect.Top(),
391  rRect.IsWidthEmpty() ? rRect.Left() : rRect.Right(),
392  rRect.IsHeightEmpty() ? rRect.Top() : rRect.Bottom() );
393  }
394 
395  geometry::IntegerSize2D integerSize2DFromSize( const Size& rSize )
396  {
397  return geometry::IntegerSize2D( rSize.Width(),
398  rSize.Height() );
399  }
400 
401  Size sizeFromIntegerSize2D( const geometry::IntegerSize2D& rSize )
402  {
403  return Size( rSize.Width,
404  rSize.Height );
405  }
406 
407  Point pointFromIntegerPoint2D( const geometry::IntegerPoint2D& rPoint )
408  {
409  return Point( rPoint.X,
410  rPoint.Y );
411  }
412 
413  tools::Rectangle rectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D& rRectangle )
414  {
415  return tools::Rectangle( rRectangle.X1, rRectangle.Y1,
416  rRectangle.X2, rRectangle.Y2 );
417  }
418 
419  namespace
420  {
421  class StandardColorSpace : public cppu::WeakImplHelper< css::rendering::XColorSpace >
422  {
423  private:
424  uno::Sequence< sal_Int8 > m_aComponentTags;
425 
426  virtual ::sal_Int8 SAL_CALL getType( ) override
427  {
428  return rendering::ColorSpaceType::RGB;
429  }
430  virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) override
431  {
432  return m_aComponentTags;
433  }
434  virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) override
435  {
436  return rendering::RenderingIntent::PERCEPTUAL;
437  }
438  virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) override
439  {
440  return uno::Sequence< beans::PropertyValue >();
441  }
442  virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
443  const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
444  {
445  // TODO(P3): if we know anything about target
446  // colorspace, this can be greatly sped up
447  uno::Sequence<rendering::ARGBColor> aIntermediate(
448  convertToARGB(deviceColor));
449  return targetColorSpace->convertFromARGB(aIntermediate);
450  }
451  virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) override
452  {
453  const double* pIn( deviceColor.getConstArray() );
454  const std::size_t nLen( deviceColor.getLength() );
455  ENSURE_ARG_OR_THROW2(nLen%4==0,
456  "number of channels no multiple of 4",
457  static_cast<rendering::XColorSpace*>(this), 0);
458 
459  uno::Sequence< rendering::RGBColor > aRes(nLen/4);
460  rendering::RGBColor* pOut( aRes.getArray() );
461  for( std::size_t i=0; i<nLen; i+=4 )
462  {
463  *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
464  pIn += 4;
465  }
466  return aRes;
467  }
468  virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) override
469  {
470  const double* pIn( deviceColor.getConstArray() );
471  const std::size_t nLen( deviceColor.getLength() );
472  ENSURE_ARG_OR_THROW2(nLen%4==0,
473  "number of channels no multiple of 4",
474  static_cast<rendering::XColorSpace*>(this), 0);
475 
476  uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
477  rendering::ARGBColor* pOut( aRes.getArray() );
478  for( std::size_t i=0; i<nLen; i+=4 )
479  {
480  *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
481  pIn += 4;
482  }
483  return aRes;
484  }
485  virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) override
486  {
487  const double* pIn( deviceColor.getConstArray() );
488  const std::size_t nLen( deviceColor.getLength() );
489  ENSURE_ARG_OR_THROW2(nLen%4==0,
490  "number of channels no multiple of 4",
491  static_cast<rendering::XColorSpace*>(this), 0);
492 
493  uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
494  rendering::ARGBColor* pOut( aRes.getArray() );
495  for( std::size_t i=0; i<nLen; i+=4 )
496  {
497  *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
498  pIn += 4;
499  }
500  return aRes;
501  }
502  virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
503  {
504  const std::size_t nLen( rgbColor.getLength() );
505 
506  uno::Sequence< double > aRes(nLen*4);
507  double* pColors=aRes.getArray();
508  for( const auto& rIn : rgbColor )
509  {
510  *pColors++ = rIn.Red;
511  *pColors++ = rIn.Green;
512  *pColors++ = rIn.Blue;
513  *pColors++ = 1.0;
514  }
515  return aRes;
516  }
517  virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
518  {
519  const std::size_t nLen( rgbColor.getLength() );
520 
521  uno::Sequence< double > aRes(nLen*4);
522  double* pColors=aRes.getArray();
523  for( const auto& rIn : rgbColor )
524  {
525  *pColors++ = rIn.Red;
526  *pColors++ = rIn.Green;
527  *pColors++ = rIn.Blue;
528  *pColors++ = rIn.Alpha;
529  }
530  return aRes;
531  }
532  virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
533  {
534  const std::size_t nLen( rgbColor.getLength() );
535 
536  uno::Sequence< double > aRes(nLen*4);
537  double* pColors=aRes.getArray();
538  for( const auto& rIn : rgbColor )
539  {
540  *pColors++ = rIn.Red/rIn.Alpha;
541  *pColors++ = rIn.Green/rIn.Alpha;
542  *pColors++ = rIn.Blue/rIn.Alpha;
543  *pColors++ = rIn.Alpha;
544  }
545  return aRes;
546  }
547 
548  public:
549  StandardColorSpace() : m_aComponentTags(4)
550  {
551  sal_Int8* pTags = m_aComponentTags.getArray();
552  pTags[0] = rendering::ColorComponentTag::RGB_RED;
553  pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
554  pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
555  pTags[3] = rendering::ColorComponentTag::ALPHA;
556  }
557  };
558  }
559 
560  uno::Reference<rendering::XColorSpace> createStandardColorSpace()
561  {
562  return new StandardColorSpace();
563  }
564 
565  uno::Sequence< double > colorToStdColorSpaceSequence( const Color& rColor )
566  {
567  uno::Sequence< double > aRet(4);
568  double* pRet = aRet.getArray();
569 
570  pRet[0] = toDoubleColor(rColor.GetRed());
571  pRet[1] = toDoubleColor(rColor.GetGreen());
572  pRet[2] = toDoubleColor(rColor.GetBlue());
573 
574  // VCL's notion of alpha is different from the rest of the world's
575  pRet[3] = 1.0 - toDoubleColor(rColor.GetTransparency());
576 
577  return aRet;
578  }
579 
580  Color stdColorSpaceSequenceToColor( const uno::Sequence< double >& rColor )
581  {
582  ENSURE_ARG_OR_THROW( rColor.getLength() == 4,
583  "color must have 4 channels" );
584 
585  Color aColor;
586 
587  aColor.SetRed ( toByteColor(rColor[0]) );
588  aColor.SetGreen( toByteColor(rColor[1]) );
589  aColor.SetBlue ( toByteColor(rColor[2]) );
590  // VCL's notion of alpha is different from the rest of the world's
591  aColor.SetTransparency( 255 - toByteColor(rColor[3]) );
592 
593  return aColor;
594  }
595 
596  uno::Sequence< double > colorToDoubleSequence(
597  const Color& rColor,
598  const uno::Reference< rendering::XColorSpace >& xColorSpace )
599  {
600  uno::Sequence<rendering::ARGBColor> aSeq(1);
601  aSeq[0] = rendering::ARGBColor(
602  1.0-toDoubleColor(rColor.GetTransparency()),
603  toDoubleColor(rColor.GetRed()),
604  toDoubleColor(rColor.GetGreen()),
605  toDoubleColor(rColor.GetBlue()) );
606 
607  return xColorSpace->convertFromARGB(aSeq);
608  }
609 
611  const uno::Sequence< double >& rColor,
612  const uno::Reference< rendering::XColorSpace >& xColorSpace )
613  {
614  const rendering::ARGBColor aARGBColor(
615  xColorSpace->convertToARGB(rColor)[0]);
616 
617  return Color( 255-toByteColor(aARGBColor.Alpha),
618  toByteColor(aARGBColor.Red),
619  toByteColor(aARGBColor.Green),
620  toByteColor(aARGBColor.Blue) );
621  }
622 
623  } // namespace vcltools
624 
625 } // namespace canvas
626 
627 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long Width() const
tools::Rectangle rectangleFromB2IRectangle(const basegfx::B2IRange &rRect)
basegfx::B2DVector b2DSizeFromSize(const ::Size &rSize)
const BitmapEx & getBitmapEx() const
Retrieve contained bitmap. Call me with locked Solar mutex!
bool IsHeightEmpty() const
::tools::Rectangle rectangleFromB2DRectangle(const basegfx::B2DRange &rRect)
sal_uInt8 GetRed() const
long FRound(double fVal)
Scanline GetScanline(long nY) const
void SetEntryCount(sal_uInt16 nCount)
bool getType(BSTR name, Type &type)
long Height() const
signed char sal_Int8
uno::Sequence< double > colorToDoubleSequence(const Color &rColor, const uno::Reference< rendering::XColorSpace > &xColorSpace)
sal_uInt8 GetTransparency() const
double getX() const
sal_Int32 getMinY() const
uno::Reference< rendering::XBitmap > xBitmapFromBitmapEx(const ::BitmapEx &inputBitmap)
Create an XBitmap from VCL BitmapEx.
Definition: canvastools.cxx:53
Point pointFromIntegerPoint2D(const geometry::IntegerPoint2D &rPoint)
double getY() const
sal_uInt16 GetBestPaletteIndex(const BitmapColor &rBitmapColor) const
Definition: bmpacc.cxx:81
Color stdColorSpaceSequenceToColor(const uno::Sequence< double > &rColor)
B2DRange B2DRectangle
::Point pointFromB2DPoint(const basegfx::B2DPoint &rPoint)
::BitmapEx bitmapExFromXBitmap(const uno::Reference< rendering::XIntegerReadOnlyBitmap > &xInputBitmap)
float x
Size sizeFromIntegerSize2D(const geometry::IntegerSize2D &rSize)
long Right() const
sal_Int32 getMaxX() const
geometry::IntegerSize2D integerSize2DFromSize(const Size &rSize)
void SetPixelOnData(sal_uInt8 *pData, long nX, const BitmapColor &rBitmapColor)
long Top() const
basegfx::B2IPoint b2IPointFromPoint(Point const &rPoint)
sal_uInt8 GetBlue() const
B2IRange fround(const B2DRange &rRange)
sal_Int8 toByteColor(double val)
Convert [0,1] double value to [0,255] int.
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
bool HasPalette() const
sal_Int32 getX() const
int i
geometry::RealSize2D size2DFromSize(const Size &rSize)
Color doubleSequenceToColor(const uno::Sequence< double > &rColor, const uno::Reference< rendering::XColorSpace > &xColorSpace)
#define ENSURE_ARG_OR_THROW2(c, m, ifc, arg)
void SetRed(sal_uInt8 nRed)
uno::Sequence< sal_Int8 > m_aComponentTags
long Bottom() const
basegfx::B2IRectangle b2IRectangleFromRectangle(tools::Rectangle const &rRect)
sal_Int32 getMinX() const
::Size sizeFromB2DSize(const basegfx::B2DVector &rVec)
#define ENSURE_ARG_OR_THROW(c, m)
long X() const
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
sal_uInt8 GetGreen() const
#define ENSURE_OR_THROW(c, m)
Size sizeFromRealSize2D(const geometry::RealSize2D &rSize)
uno::Sequence< double > colorToStdColorSpaceSequence(const Color &rColor)
Create a device-specific color sequence from VCL/Tools color.
double toDoubleColor(sal_uInt8 val)
Convert [0,255] int value to [0,1] double value.
uno::Reference< rendering::XColorSpace > createStandardColorSpace()
Create a standard color space suitable for VCL RGB color.
tools::Rectangle rectangleFromIntegerRectangle2D(const geometry::IntegerRectangle2D &rRectangle)
#define SAL_INFO(area, stream)
sal_Int32 getY() const
bool IsWidthEmpty() const
long Left() const
sal_Int32 getMaxY() const
Point pointFromB2IPoint(const basegfx::B2IPoint &rPoint)
basegfx::B2DPoint b2DPointFromPoint(const ::Point &rPoint)
long Y() const
static const BitmapPalette & GetGreyPalette(int nEntries)