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>
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  auto ePixelFormat =
269  ( nDepth <= 1 ) ? vcl::PixelFormat::N1_BPP :
270  ( nDepth <= 8 ) ? vcl::PixelFormat::N8_BPP :
272  auto eAlphaPixelFormat =
273  ( nAlphaDepth <= 1 ) ? vcl::PixelFormat::N1_BPP :
275 
276  ::Bitmap aBitmap( aPixelSize,
277  ePixelFormat,
278  aLayout.Palette.is() ? &aPalette : nullptr );
279  ::Bitmap aAlpha;
280  if( nAlphaDepth )
281  aAlpha = Bitmap(aPixelSize,
282  eAlphaPixelFormat,
284  sal::static_int_cast<sal_uInt16>(1 << nAlphaDepth)) );
285 
286  { // limit scoped access
287  BitmapScopedWriteAccess pWriteAccess( aBitmap );
288  BitmapScopedWriteAccess pAlphaWriteAccess( nAlphaDepth ? aAlpha.AcquireWriteAccess() : nullptr,
289  aAlpha );
290 
291  ENSURE_OR_THROW(pWriteAccess.get() != nullptr,
292  "Cannot get write access to bitmap");
293 
294  const sal_Int32 nWidth(aPixelSize.Width());
295  const sal_Int32 nHeight(aPixelSize.Height());
296 
297  if( !readBmp(nWidth,nHeight,aLayout,xInputBitmap,
298  pWriteAccess,pAlphaWriteAccess) )
299  continue;
300  } // limit scoped access
301 
302  if( nAlphaDepth )
303  return ::BitmapEx( aBitmap,
304  AlphaMask( aAlpha ) );
305  else
306  return ::BitmapEx( aBitmap );
307  }
308 
309  // failed to read data 10 times - bail out
310  return ::BitmapEx();
311  }
312 
313  geometry::RealSize2D size2DFromSize( const Size& rSize )
314  {
315  return geometry::RealSize2D( rSize.Width(),
316  rSize.Height() );
317  }
318 
319  Size sizeFromRealSize2D( const geometry::RealSize2D& rSize )
320  {
321  return Size( static_cast<tools::Long>(rSize.Width + .5),
322  static_cast<tools::Long>(rSize.Height + .5) );
323  }
324 
326  {
327  return ::Size( FRound( rVec.getX() ),
328  FRound( rVec.getY() ) );
329  }
330 
331  ::Point pointFromB2DPoint( const basegfx::B2DPoint& rPoint )
332  {
333  return pointFromB2IPoint(basegfx::fround(rPoint));
334  }
335 
337  {
339  }
340 
342  {
343  return ::Point( rPoint.getX(),
344  rPoint.getY() );
345  }
346 
348  {
349  return basegfx::B2IPoint(rPoint.X(), rPoint.Y());
350  }
351 
353  {
354  return ::tools::Rectangle( rRect.getMinX(),
355  rRect.getMinY(),
356  rRect.getMaxX(),
357  rRect.getMaxY() );
358  }
359 
361  {
362  // although B2IRange internally has separate height/width emptiness, it doesn't
363  // expose any API to let us set them separately, so just do the best we can.
364  if (rRect.IsWidthEmpty() && rRect.IsHeightEmpty())
365  return basegfx::B2IRange( basegfx::B2ITuple( rRect.Left(), rRect.Top() ) );
366  return basegfx::B2IRange( rRect.Left(),
367  rRect.Top(),
368  rRect.IsWidthEmpty() ? rRect.Left() : rRect.Right(),
369  rRect.IsHeightEmpty() ? rRect.Top() : rRect.Bottom() );
370  }
371 
372  basegfx::B2DVector b2DSizeFromSize( const ::Size& rSize )
373  {
374  return basegfx::B2DVector( rSize.Width(),
375  rSize.Height() );
376  }
377 
378  basegfx::B2DPoint b2DPointFromPoint( const ::Point& rPoint )
379  {
380  return basegfx::B2DPoint( rPoint.X(),
381  rPoint.Y() );
382  }
383 
384  basegfx::B2DRange b2DRectangleFromRectangle( const ::tools::Rectangle& rRect )
385  {
386  // although B2DRange internally has separate height/width emptiness, it doesn't
387  // expose any API to let us set them separately, so just do the best we can.
388  if (rRect.IsWidthEmpty() && rRect.IsHeightEmpty())
389  return basegfx::B2DRange( basegfx::B2DTuple( rRect.Left(), rRect.Top() ) );
390  return basegfx::B2DRectangle( rRect.Left(),
391  rRect.Top(),
392  rRect.IsWidthEmpty() ? rRect.Left() : rRect.Right(),
393  rRect.IsHeightEmpty() ? rRect.Top() : rRect.Bottom() );
394  }
395 
396  geometry::IntegerSize2D integerSize2DFromSize( const Size& rSize )
397  {
398  return geometry::IntegerSize2D( rSize.Width(),
399  rSize.Height() );
400  }
401 
402  Size sizeFromIntegerSize2D( const geometry::IntegerSize2D& rSize )
403  {
404  return Size( rSize.Width,
405  rSize.Height );
406  }
407 
408  Point pointFromIntegerPoint2D( const geometry::IntegerPoint2D& rPoint )
409  {
410  return Point( rPoint.X,
411  rPoint.Y );
412  }
413 
414  tools::Rectangle rectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D& rRectangle )
415  {
416  return tools::Rectangle( rRectangle.X1, rRectangle.Y1,
417  rRectangle.X2, rRectangle.Y2 );
418  }
419 
420  namespace
421  {
422  class StandardColorSpace : public cppu::WeakImplHelper< css::rendering::XColorSpace >
423  {
424  private:
425  uno::Sequence< sal_Int8 > m_aComponentTags;
426 
427  virtual ::sal_Int8 SAL_CALL getType( ) override
428  {
429  return rendering::ColorSpaceType::RGB;
430  }
431  virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) override
432  {
433  return m_aComponentTags;
434  }
435  virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) override
436  {
437  return rendering::RenderingIntent::PERCEPTUAL;
438  }
439  virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) override
440  {
441  return uno::Sequence< beans::PropertyValue >();
442  }
443  virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
444  const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
445  {
446  // TODO(P3): if we know anything about target
447  // colorspace, this can be greatly sped up
448  uno::Sequence<rendering::ARGBColor> aIntermediate(
449  convertToARGB(deviceColor));
450  return targetColorSpace->convertFromARGB(aIntermediate);
451  }
452  virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) override
453  {
454  const double* pIn( deviceColor.getConstArray() );
455  const std::size_t nLen( deviceColor.getLength() );
456  ENSURE_ARG_OR_THROW2(nLen%4==0,
457  "number of channels no multiple of 4",
458  static_cast<rendering::XColorSpace*>(this), 0);
459 
460  uno::Sequence< rendering::RGBColor > aRes(nLen/4);
461  rendering::RGBColor* pOut( aRes.getArray() );
462  for( std::size_t i=0; i<nLen; i+=4 )
463  {
464  *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
465  pIn += 4;
466  }
467  return aRes;
468  }
469  virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) override
470  {
471  const double* pIn( deviceColor.getConstArray() );
472  const std::size_t nLen( deviceColor.getLength() );
473  ENSURE_ARG_OR_THROW2(nLen%4==0,
474  "number of channels no multiple of 4",
475  static_cast<rendering::XColorSpace*>(this), 0);
476 
477  uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
478  rendering::ARGBColor* pOut( aRes.getArray() );
479  for( std::size_t i=0; i<nLen; i+=4 )
480  {
481  *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
482  pIn += 4;
483  }
484  return aRes;
485  }
486  virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) override
487  {
488  const double* pIn( deviceColor.getConstArray() );
489  const std::size_t nLen( deviceColor.getLength() );
490  ENSURE_ARG_OR_THROW2(nLen%4==0,
491  "number of channels no multiple of 4",
492  static_cast<rendering::XColorSpace*>(this), 0);
493 
494  uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
495  rendering::ARGBColor* pOut( aRes.getArray() );
496  for( std::size_t i=0; i<nLen; i+=4 )
497  {
498  *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
499  pIn += 4;
500  }
501  return aRes;
502  }
503  virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
504  {
505  const std::size_t nLen( rgbColor.getLength() );
506 
507  uno::Sequence< double > aRes(nLen*4);
508  double* pColors=aRes.getArray();
509  for( const auto& rIn : rgbColor )
510  {
511  *pColors++ = rIn.Red;
512  *pColors++ = rIn.Green;
513  *pColors++ = rIn.Blue;
514  *pColors++ = 1.0;
515  }
516  return aRes;
517  }
518  virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
519  {
520  const std::size_t nLen( rgbColor.getLength() );
521 
522  uno::Sequence< double > aRes(nLen*4);
523  double* pColors=aRes.getArray();
524  for( const auto& rIn : rgbColor )
525  {
526  *pColors++ = rIn.Red;
527  *pColors++ = rIn.Green;
528  *pColors++ = rIn.Blue;
529  *pColors++ = rIn.Alpha;
530  }
531  return aRes;
532  }
533  virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
534  {
535  const std::size_t nLen( rgbColor.getLength() );
536 
537  uno::Sequence< double > aRes(nLen*4);
538  double* pColors=aRes.getArray();
539  for( const auto& rIn : rgbColor )
540  {
541  *pColors++ = rIn.Red/rIn.Alpha;
542  *pColors++ = rIn.Green/rIn.Alpha;
543  *pColors++ = rIn.Blue/rIn.Alpha;
544  *pColors++ = rIn.Alpha;
545  }
546  return aRes;
547  }
548 
549  public:
550  StandardColorSpace() : m_aComponentTags(4)
551  {
552  sal_Int8* pTags = m_aComponentTags.getArray();
553  pTags[0] = rendering::ColorComponentTag::RGB_RED;
554  pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
555  pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
556  pTags[3] = rendering::ColorComponentTag::ALPHA;
557  }
558  };
559  }
560 
561  uno::Reference<rendering::XColorSpace> createStandardColorSpace()
562  {
563  return new StandardColorSpace();
564  }
565 
566  uno::Sequence< double > colorToStdColorSpaceSequence( const Color& rColor )
567  {
568  uno::Sequence< double > aRet(4);
569  double* pRet = aRet.getArray();
570 
571  pRet[0] = toDoubleColor(rColor.GetRed());
572  pRet[1] = toDoubleColor(rColor.GetGreen());
573  pRet[2] = toDoubleColor(rColor.GetBlue());
574  pRet[3] = toDoubleColor(rColor.GetAlpha());
575 
576  return aRet;
577  }
578 
579  Color stdColorSpaceSequenceToColor( const uno::Sequence< double >& rColor )
580  {
581  ENSURE_ARG_OR_THROW( rColor.getLength() == 4,
582  "color must have 4 channels" );
583 
584  Color aColor;
585 
586  aColor.SetRed ( toByteColor(rColor[0]) );
587  aColor.SetGreen( toByteColor(rColor[1]) );
588  aColor.SetBlue ( toByteColor(rColor[2]) );
589  aColor.SetAlpha( 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  toDoubleColor(rColor.GetAlpha()),
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( ColorAlpha, 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: */
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
sal_uInt8 GetAlpha() const
::tools::Rectangle rectangleFromB2DRectangle(const basegfx::B2DRange &rRect)
sal_uInt8 GetRed() const
void SetEntryCount(sal_uInt16 nCount)
bool getType(BSTR name, Type &type)
signed char sal_Int8
uno::Sequence< double > colorToDoubleSequence(const Color &rColor, const uno::Reference< rendering::XColorSpace > &xColorSpace)
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
This template handles BitmapAccess the RAII way.
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)
sal_Int32 getMaxX() const
tools::Long Left() const
geometry::IntegerSize2D integerSize2DFromSize(const Size &rSize)
tools::Long Bottom() const
oslFileHandle & pOut
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
sal_Int32 getX() const
tools::Long FRound(double fVal)
geometry::RealSize2D size2DFromSize(const Size &rSize)
tools::Long Width() const
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
basegfx::B2IRectangle b2IRectangleFromRectangle(tools::Rectangle const &rRect)
sal_Int32 getMinX() const
::Size sizeFromB2DSize(const basegfx::B2DVector &rVec)
tools::Long Top() const
#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)
tools::Long Height() const
sal_Int32 getY() const
Sequence< sal_Int8 > aSeq
bool IsWidthEmpty() const
sal_Int32 getMaxY() const
Point pointFromB2IPoint(const basegfx::B2IPoint &rPoint)
basegfx::B2DPoint b2DPointFromPoint(const ::Point &rPoint)
tools::Long Right() const
static const BitmapPalette & GetGreyPalette(int nEntries)
ColorAlpha