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