1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
31 #include <rtl/logfile.hxx>
32 #include <cppuhelper/compbase1.hxx>
34 #include <com/sun/star/geometry/RealSize2D.hpp>
35 #include <com/sun/star/geometry/RealPoint2D.hpp>
36 #include <com/sun/star/geometry/RealRectangle2D.hpp>
37 #include <com/sun/star/geometry/IntegerSize2D.hpp>
38 #include <com/sun/star/geometry/IntegerPoint2D.hpp>
39 #include <com/sun/star/geometry/IntegerRectangle2D.hpp>
40 #include <com/sun/star/geometry/RealBezierSegment2D.hpp>
42 #include <com/sun/star/rendering/ColorSpaceType.hpp>
43 #include <com/sun/star/rendering/RenderingIntent.hpp>
44 #include <com/sun/star/rendering/XGraphicDevice.hpp>
45 #include <com/sun/star/rendering/XBitmap.hpp>
46 #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
47 #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
48 #include <com/sun/star/rendering/XIntegerBitmap.hpp>
49 #include <com/sun/star/rendering/ColorComponentTag.hpp>
51 #include <basegfx/matrix/b2dhommatrix.hxx>
52 #include <basegfx/vector/b2dsize.hxx>
53 #include <basegfx/point/b2dpoint.hxx>
54 #include <basegfx/range/b2drectangle.hxx>
55 #include <basegfx/vector/b2isize.hxx>
56 #include <basegfx/point/b2ipoint.hxx>
57 #include <basegfx/range/b2irectangle.hxx>
60 #include <basegfx/polygon/b2dpolygon.hxx>
61 #include <basegfx/tools/canvastools.hxx>
62 #include <basegfx/polygon/b2dpolypolygon.hxx>
64 #include <tools/poly.hxx>
65 #include <tools/diagnose_ex.h>
68 #include <vcl/salbtype.hxx>
69 #include <vcl/bmpacc.hxx>
70 #include <vcl/bitmapex.hxx>
72 #include <vcl/canvasbitmap.hxx>
73 #include <vcl/canvastools.hxx>
77 using namespace ::com::sun::star
;
83 // #i79917# removed helpers bezierSequenceFromPolygon and
84 // pointSequenceFromPolygon here
85 // Also all helpers using tools Polygon and PolyPolygon will get mapped to the
86 // B2DPolygon helpers for these cases, see comments with the same TaskID below.
87 // TODO: Remove those wrapped methods
89 //---------------------------------------------------------------------------------------
91 uno::Reference
< rendering::XPolyPolygon2D
> xPolyPolygonFromPolygon( const uno::Reference
< rendering::XGraphicDevice
>& xGraphicDevice
,
92 const ::Polygon
& inputPolygon
)
94 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::xPolyPolygonFromPolygon()" );
96 // #i79917# map to basegfx
97 const basegfx::B2DPolygon
aB2DPolygon(inputPolygon
.getB2DPolygon());
98 return basegfx::unotools::xPolyPolygonFromB2DPolygon(xGraphicDevice
, aB2DPolygon
);
101 //---------------------------------------------------------------------------------------
103 uno::Reference
< rendering::XPolyPolygon2D
> xPolyPolygonFromPolyPolygon( const uno::Reference
< rendering::XGraphicDevice
>& xGraphicDevice
,
104 const ::PolyPolygon
& inputPolyPolygon
)
106 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::xPolyPolygonFromPolyPolygon()" );
108 // #i79917# map to basegfx
109 const basegfx::B2DPolyPolygon
aB2DPolyPolygon(inputPolyPolygon
.getB2DPolyPolygon());
110 return basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(xGraphicDevice
, aB2DPolyPolygon
);
113 //---------------------------------------------------------------------------------------
115 ::Polygon
polygonFromPoint2DSequence( const uno::Sequence
< geometry::RealPoint2D
>& points
)
117 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::polygonFromPoint2DSequence()" );
119 const USHORT
nCurrSize( sal::static_int_cast
<USHORT
>(points
.getLength()) );
121 ::Polygon
aPoly( nCurrSize
);
124 for( nCurrPoint
=0; nCurrPoint
<nCurrSize
; ++nCurrPoint
)
125 aPoly
[nCurrPoint
] = pointFromRealPoint2D( points
[nCurrPoint
] );
130 //---------------------------------------------------------------------------------------
132 ::PolyPolygon
polyPolygonFromPoint2DSequenceSequence( const uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> >& points
)
134 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::polyPolygonFromPoint2DSequenceSequence()" );
139 for( nCurrPoly
=0; nCurrPoly
<points
.getLength(); ++nCurrPoly
)
141 aRes
.Insert( polygonFromPoint2DSequence( points
[nCurrPoly
] ) );
147 //---------------------------------------------------------------------------------------
149 ::Polygon
polygonFromBezier2DSequence( const uno::Sequence
< geometry::RealBezierSegment2D
>& curves
)
151 // #i79917# map to basegfx
152 const basegfx::B2DPolygon
aB2DPolygon(basegfx::unotools::polygonFromBezier2DSequence(curves
));
153 return ::Polygon(aB2DPolygon
);
156 //---------------------------------------------------------------------------------------
158 ::PolyPolygon
polyPolygonFromBezier2DSequenceSequence( const uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> >& curves
)
160 // #i79917# map to basegfx
161 const basegfx::B2DPolyPolygon
aB2DPolyPolygon(basegfx::unotools::polyPolygonFromBezier2DSequenceSequence(curves
));
162 return ::PolyPolygon(aB2DPolyPolygon
);
165 //---------------------------------------------------------------------------------------
167 uno::Reference
< rendering::XBitmap
> xBitmapFromBitmap( const uno::Reference
< rendering::XGraphicDevice
>& /*xGraphicDevice*/,
168 const ::Bitmap
& inputBitmap
)
170 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::xBitmapFromBitmap()" );
172 return new vcl::unotools::VclCanvasBitmap( BitmapEx( inputBitmap
) );
175 //---------------------------------------------------------------------------------------
177 uno::Reference
< rendering::XBitmap
> xBitmapFromBitmapEx( const uno::Reference
< rendering::XGraphicDevice
>& /*xGraphicDevice*/,
178 const ::BitmapEx
& inputBitmap
)
180 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::xBitmapFromBitmapEx()" );
182 return new vcl::unotools::VclCanvasBitmap( inputBitmap
);
185 //---------------------------------------------------------------------------------------
187 const uno::Sequence
< sal_Int8
> getTunnelIdentifier( TunnelIdentifierType eType
)
189 static std::hash_map
< int, uno::Sequence
< sal_Int8
> > aIds
;
190 std::hash_map
< int, uno::Sequence
< sal_Int8
> >::iterator it
=
192 if( it
== aIds
.end() )
194 uno::Sequence
< sal_Int8
> aNewId( 16 );
195 rtl_createUuid( (sal_uInt8
*)aNewId
.getArray(), NULL
, sal_True
);
196 aIds
[ eType
] = aNewId
;
197 it
= aIds
.find( eType
);
202 //---------------------------------------------------------------------------------------
206 inline bool operator==( const rendering::IntegerBitmapLayout
& rLHS
,
207 const rendering::IntegerBitmapLayout
& rRHS
)
210 rLHS
.ScanLineBytes
== rRHS
.ScanLineBytes
&&
211 rLHS
.ScanLineStride
== rRHS
.ScanLineStride
&&
212 rLHS
.PlaneStride
== rRHS
.PlaneStride
&&
213 rLHS
.ColorSpace
== rRHS
.ColorSpace
&&
214 rLHS
.Palette
== rRHS
.Palette
&&
215 rLHS
.IsMsbFirst
== rRHS
.IsMsbFirst
;
218 bool readBmp( sal_Int32 nWidth
,
220 const rendering::IntegerBitmapLayout
& rLayout
,
221 const uno::Reference
< rendering::XIntegerReadOnlyBitmap
>& xInputBitmap
,
222 ScopedBitmapWriteAccess
& rWriteAcc
,
223 ScopedBitmapWriteAccess
& rAlphaAcc
)
225 rendering::IntegerBitmapLayout aCurrLayout
;
226 geometry::IntegerRectangle2D aRect
;
227 uno::Sequence
<sal_Int8
> aPixelData
;
228 uno::Sequence
<rendering::RGBColor
> aRGBColors
;
229 uno::Sequence
<rendering::ARGBColor
> aARGBColors
;
231 for( aRect
.Y1
=0; aRect
.Y1
<nHeight
; ++aRect
.Y1
)
233 aRect
.X1
= 0; aRect
.X2
= nWidth
; aRect
.Y2
= aRect
.Y1
+1;
236 aPixelData
= xInputBitmap
->getData(aCurrLayout
,aRect
);
238 catch( rendering::VolatileContentDestroyedException
& )
240 // re-read bmp from the start
243 if( !(aCurrLayout
== rLayout
) )
244 return false; // re-read bmp from the start
246 if( rAlphaAcc
.get() )
249 aARGBColors
= rLayout
.ColorSpace
->convertIntegerToARGB(aPixelData
);
251 if( rWriteAcc
->HasPalette() )
253 for( sal_Int32 x
=0; x
<nWidth
; ++x
)
255 const rendering::ARGBColor
& rColor
=aARGBColors
[x
];
256 rWriteAcc
->SetPixel( aRect
.Y1
, x
,
257 (BYTE
)rWriteAcc
->GetBestPaletteIndex(
258 BitmapColor( toByteColor(rColor
.Red
),
259 toByteColor(rColor
.Green
),
260 toByteColor(rColor
.Blue
))) );
261 rAlphaAcc
->SetPixel( aRect
.Y1
, x
,
262 BitmapColor( 255 - toByteColor(rColor
.Alpha
) ));
267 for( sal_Int32 x
=0; x
<nWidth
; ++x
)
269 const rendering::ARGBColor
& rColor
=aARGBColors
[x
];
270 rWriteAcc
->SetPixel( aRect
.Y1
, x
,
271 BitmapColor( toByteColor(rColor
.Red
),
272 toByteColor(rColor
.Green
),
273 toByteColor(rColor
.Blue
) ));
274 rAlphaAcc
->SetPixel( aRect
.Y1
, x
,
275 BitmapColor( 255 - toByteColor(rColor
.Alpha
) ));
282 aRGBColors
= rLayout
.ColorSpace
->convertIntegerToRGB(aPixelData
);
283 if( rWriteAcc
->HasPalette() )
285 for( sal_Int32 x
=0; x
<nWidth
; ++x
)
287 const rendering::RGBColor
& rColor
=aRGBColors
[x
];
288 rWriteAcc
->SetPixel( aRect
.Y1
, x
,
289 (BYTE
)rWriteAcc
->GetBestPaletteIndex(
290 BitmapColor( toByteColor(rColor
.Red
),
291 toByteColor(rColor
.Green
),
292 toByteColor(rColor
.Blue
))) );
297 for( sal_Int32 x
=0; x
<nWidth
; ++x
)
299 const rendering::RGBColor
& rColor
=aRGBColors
[x
];
300 rWriteAcc
->SetPixel( aRect
.Y1
, x
,
301 BitmapColor( toByteColor(rColor
.Red
),
302 toByteColor(rColor
.Green
),
303 toByteColor(rColor
.Blue
) ));
313 ::BitmapEx VCL_DLLPUBLIC
bitmapExFromXBitmap( const uno::Reference
< rendering::XIntegerReadOnlyBitmap
>& xInputBitmap
)
315 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::bitmapExFromXBitmap()" );
317 if( !xInputBitmap
.is() )
320 // tunnel directly for known implementation
321 // ----------------------------------------------------------------
322 VclCanvasBitmap
* pImplBitmap
= dynamic_cast<VclCanvasBitmap
*>(xInputBitmap
.get());
324 return pImplBitmap
->getBitmapEx();
326 // retrieve data via UNO interface
327 // ----------------------------------------------------------------
329 // volatile bitmaps are a bit more complicated to read
331 uno::Reference
<rendering::XVolatileBitmap
> xVolatileBitmap(
332 xInputBitmap
, uno::UNO_QUERY
);
334 // loop a few times, until successfully read (for XVolatileBitmap)
335 for( int i
=0; i
<10; ++i
)
338 sal_Int32 nAlphaDepth
=0;
339 const rendering::IntegerBitmapLayout
aLayout(
340 xInputBitmap
->getMemoryLayout());
342 OSL_ENSURE(aLayout
.ColorSpace
.is(),
343 "Cannot convert image without color space!");
344 if( !aLayout
.ColorSpace
.is() )
347 nDepth
= aLayout
.ColorSpace
->getBitsPerPixel();
349 if( xInputBitmap
->hasAlpha() )
351 // determine alpha channel depth
352 const uno::Sequence
<sal_Int8
> aTags(
353 aLayout
.ColorSpace
->getComponentTags() );
354 const uno::Sequence
<sal_Int32
> aDepths(
355 aLayout
.ColorSpace
->getComponentBitCounts() );
356 const sal_Int8
* pStart(aTags
.getConstArray());
357 const sal_Size
nLen(aTags
.getLength());
358 const sal_Int8
* pEnd(pStart
+nLen
);
360 const std::ptrdiff_t nAlphaIndex
=
361 std::find(pStart
,pEnd
,
362 rendering::ColorComponentTag::ALPHA
) - pStart
;
364 if( nAlphaIndex
< sal::static_int_cast
<std::ptrdiff_t>(nLen
) )
366 nAlphaDepth
= aLayout
.ColorSpace
->getComponentBitCounts()[nAlphaIndex
] > 1 ? 8 : 1;
367 nDepth
-= nAlphaDepth
;
371 BitmapPalette aPalette
;
372 if( aLayout
.Palette
.is() )
374 uno::Reference
< rendering::XColorSpace
> xPaletteColorSpace(
375 aLayout
.Palette
->getColorSpace());
376 ENSURE_OR_THROW(xPaletteColorSpace
.is(),
377 "Palette without color space");
379 const sal_Int32
nEntryCount( aLayout
.Palette
->getNumberOfEntries() );
380 if( nEntryCount
<= 256 )
382 if( nEntryCount
<= 2 )
387 const USHORT
nPaletteEntries(
388 sal::static_int_cast
<USHORT
>(
389 std::min(sal_Int32(255), nEntryCount
)));
391 // copy palette entries
392 aPalette
.SetEntryCount(nPaletteEntries
);
393 uno::Reference
<rendering::XBitmapPalette
> xPalette( aLayout
.Palette
);
394 uno::Reference
<rendering::XColorSpace
> xPalColorSpace( xPalette
->getColorSpace() );
396 uno::Sequence
<double> aPaletteEntry
;
397 for( USHORT j
=0; j
<nPaletteEntries
; ++j
)
399 if( !xPalette
->getIndex(aPaletteEntry
,j
) &&
404 uno::Sequence
<rendering::RGBColor
> aColors
=xPalColorSpace
->convertToRGB(aPaletteEntry
);
405 ENSURE_OR_THROW(aColors
.getLength() == 1,
406 "Palette returned more or less than one entry");
407 const rendering::RGBColor
& rColor
=aColors
[0];
408 aPalette
[j
] = BitmapColor(toByteColor(rColor
.Red
),
409 toByteColor(rColor
.Green
),
410 toByteColor(rColor
.Blue
));
415 const ::Size
aPixelSize(
416 sizeFromIntegerSize2D(xInputBitmap
->getSize()));
418 // normalize bitcount
420 ( nDepth
<= 1 ) ? 1 :
421 ( nDepth
<= 4 ) ? 4 :
422 ( nDepth
<= 8 ) ? 8 : 24;
424 ::Bitmap
aBitmap( aPixelSize
,
425 sal::static_int_cast
<USHORT
>(nDepth
),
426 aLayout
.Palette
.is() ? &aPalette
: NULL
);
429 aAlpha
= ::Bitmap( aPixelSize
,
430 sal::static_int_cast
<USHORT
>(nAlphaDepth
),
431 &::Bitmap::GetGreyPalette(
432 sal::static_int_cast
<USHORT
>(1L << nAlphaDepth
)) );
434 { // limit scoped access
435 ScopedBitmapWriteAccess
pWriteAccess( aBitmap
.AcquireWriteAccess(),
437 ScopedBitmapWriteAccess
pAlphaWriteAccess( nAlphaDepth
? aAlpha
.AcquireWriteAccess() : NULL
,
440 ENSURE_OR_THROW(pWriteAccess
.get() != NULL
,
441 "Cannot get write access to bitmap");
443 const sal_Int32
nWidth(aPixelSize
.Width());
444 const sal_Int32
nHeight(aPixelSize
.Height());
446 if( !readBmp(nWidth
,nHeight
,aLayout
,xInputBitmap
,
447 pWriteAccess
,pAlphaWriteAccess
) )
449 } // limit scoped access
452 return ::BitmapEx( aBitmap
,
453 AlphaMask( aAlpha
) );
455 return ::BitmapEx( aBitmap
);
458 // failed to read data 10 times - bail out
462 //---------------------------------------------------------------------------------------
464 geometry::RealSize2D
size2DFromSize( const Size
& rSize
)
466 return geometry::RealSize2D( rSize
.Width(),
470 geometry::RealPoint2D
point2DFromPoint( const Point
& rPoint
)
472 return geometry::RealPoint2D( rPoint
.X(),
476 geometry::RealRectangle2D
rectangle2DFromRectangle( const Rectangle
& rRect
)
478 return geometry::RealRectangle2D( rRect
.Left(), rRect
.Top(),
479 rRect
.Right(), rRect
.Bottom() );
482 Size
sizeFromRealSize2D( const geometry::RealSize2D
& rSize
)
484 return Size( static_cast<long>(rSize
.Width
+ .5),
485 static_cast<long>(rSize
.Height
+ .5) );
488 Point
pointFromRealPoint2D( const geometry::RealPoint2D
& rPoint
)
490 return Point( static_cast<long>(rPoint
.X
+ .5),
491 static_cast<long>(rPoint
.Y
+ .5) );
494 Rectangle
rectangleFromRealRectangle2D( const geometry::RealRectangle2D
& rRect
)
496 return Rectangle( static_cast<long>(rRect
.X1
+ .5),
497 static_cast<long>(rRect
.Y1
+ .5),
498 static_cast<long>(rRect
.X2
+ .5),
499 static_cast<long>(rRect
.Y2
+ .5) );
502 ::Size
sizeFromB2DSize( const ::basegfx::B2DVector
& rVec
)
504 return ::Size( FRound( rVec
.getX() ),
505 FRound( rVec
.getY() ) );
508 ::Point
pointFromB2DPoint( const ::basegfx::B2DPoint
& rPoint
)
510 return ::Point( FRound( rPoint
.getX() ),
511 FRound( rPoint
.getY() ) );
514 ::Rectangle
rectangleFromB2DRectangle( const ::basegfx::B2DRange
& rRect
)
516 return ::Rectangle( FRound( rRect
.getMinX() ),
517 FRound( rRect
.getMinY() ),
518 FRound( rRect
.getMaxX() ),
519 FRound( rRect
.getMaxY() ) );
522 Size
sizeFromB2ISize( const ::basegfx::B2IVector
& rVec
)
524 return ::Size( rVec
.getX(),
528 Point
pointFromB2IPoint( const ::basegfx::B2IPoint
& rPoint
)
530 return ::Point( rPoint
.getX(),
534 Rectangle
rectangleFromB2IRectangle( const ::basegfx::B2IRange
& rRect
)
536 return ::Rectangle( rRect
.getMinX(),
542 ::basegfx::B2DVector
b2DSizeFromSize( const ::Size
& rSize
)
544 return ::basegfx::B2DVector( rSize
.Width(),
548 ::basegfx::B2DPoint
b2DPointFromPoint( const ::Point
& rPoint
)
550 return ::basegfx::B2DPoint( rPoint
.X(),
554 ::basegfx::B2DRange
b2DRectangleFromRectangle( const ::Rectangle
& rRect
)
556 return ::basegfx::B2DRange( rRect
.Left(),
562 basegfx::B2IVector
b2ISizeFromSize( const Size
& rSize
)
564 return ::basegfx::B2IVector( rSize
.Width(),
568 basegfx::B2IPoint
b2IPointFromPoint( const Point
& rPoint
)
570 return ::basegfx::B2IPoint( rPoint
.X(),
574 basegfx::B2IRange
b2IRectangleFromRectangle( const Rectangle
& rRect
)
576 return ::basegfx::B2IRange( rRect
.Left(),
582 geometry::IntegerSize2D
integerSize2DFromSize( const Size
& rSize
)
584 return geometry::IntegerSize2D( rSize
.Width(),
588 geometry::IntegerPoint2D
integerPoint2DFromPoint( const Point
& rPoint
)
590 return geometry::IntegerPoint2D( rPoint
.X(),
594 geometry::IntegerRectangle2D
integerRectangle2DFromRectangle( const Rectangle
& rRectangle
)
596 return geometry::IntegerRectangle2D( rRectangle
.Left(), rRectangle
.Top(),
597 rRectangle
.Right(), rRectangle
.Bottom() );
600 Size
sizeFromIntegerSize2D( const geometry::IntegerSize2D
& rSize
)
602 return Size( rSize
.Width
,
606 Point
pointFromIntegerPoint2D( const geometry::IntegerPoint2D
& rPoint
)
608 return Point( rPoint
.X
,
612 Rectangle
rectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D
& rRectangle
)
614 return Rectangle( rRectangle
.X1
, rRectangle
.Y1
,
615 rRectangle
.X2
, rRectangle
.Y2
);
620 class StandardColorSpace
: public cppu::WeakImplHelper1
< com::sun::star::rendering::XColorSpace
>
623 uno::Sequence
< sal_Int8
> m_aComponentTags
;
625 virtual ::sal_Int8 SAL_CALL
getType( ) throw (uno::RuntimeException
)
627 return rendering::ColorSpaceType::RGB
;
629 virtual uno::Sequence
< ::sal_Int8
> SAL_CALL
getComponentTags( ) throw (uno::RuntimeException
)
631 return m_aComponentTags
;
633 virtual ::sal_Int8 SAL_CALL
getRenderingIntent( ) throw (uno::RuntimeException
)
635 return rendering::RenderingIntent::PERCEPTUAL
;
637 virtual uno::Sequence
< beans::PropertyValue
> SAL_CALL
getProperties( ) throw (uno::RuntimeException
)
639 return uno::Sequence
< beans::PropertyValue
>();
641 virtual uno::Sequence
< double > SAL_CALL
convertColorSpace( const uno::Sequence
< double >& deviceColor
,
642 const uno::Reference
< rendering::XColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,
643 uno::RuntimeException
)
645 // TODO(P3): if we know anything about target
646 // colorspace, this can be greatly sped up
647 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
648 convertToARGB(deviceColor
));
649 return targetColorSpace
->convertFromARGB(aIntermediate
);
651 virtual uno::Sequence
< rendering::RGBColor
> SAL_CALL
convertToRGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
653 const double* pIn( deviceColor
.getConstArray() );
654 const sal_Size
nLen( deviceColor
.getLength() );
655 ENSURE_ARG_OR_THROW2(nLen
%4==0,
656 "number of channels no multiple of 4",
657 static_cast<rendering::XColorSpace
*>(this), 0);
659 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/4);
660 rendering::RGBColor
* pOut( aRes
.getArray() );
661 for( sal_Size i
=0; i
<nLen
; i
+=4 )
663 *pOut
++ = rendering::RGBColor(pIn
[0],pIn
[1],pIn
[2]);
668 virtual uno::Sequence
< rendering::ARGBColor
> SAL_CALL
convertToARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
670 const double* pIn( deviceColor
.getConstArray() );
671 const sal_Size
nLen( deviceColor
.getLength() );
672 ENSURE_ARG_OR_THROW2(nLen
%4==0,
673 "number of channels no multiple of 4",
674 static_cast<rendering::XColorSpace
*>(this), 0);
676 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/4);
677 rendering::ARGBColor
* pOut( aRes
.getArray() );
678 for( sal_Size i
=0; i
<nLen
; i
+=4 )
680 *pOut
++ = rendering::ARGBColor(pIn
[3],pIn
[0],pIn
[1],pIn
[2]);
685 virtual uno::Sequence
< rendering::ARGBColor
> SAL_CALL
convertToPARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
687 const double* pIn( deviceColor
.getConstArray() );
688 const sal_Size
nLen( deviceColor
.getLength() );
689 ENSURE_ARG_OR_THROW2(nLen
%4==0,
690 "number of channels no multiple of 4",
691 static_cast<rendering::XColorSpace
*>(this), 0);
693 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/4);
694 rendering::ARGBColor
* pOut( aRes
.getArray() );
695 for( sal_Size i
=0; i
<nLen
; i
+=4 )
697 *pOut
++ = rendering::ARGBColor(pIn
[3],pIn
[3]*pIn
[0],pIn
[3]*pIn
[1],pIn
[3]*pIn
[2]);
702 virtual uno::Sequence
< double > SAL_CALL
convertFromRGB( const uno::Sequence
< rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
704 const rendering::RGBColor
* pIn( rgbColor
.getConstArray() );
705 const sal_Size
nLen( rgbColor
.getLength() );
707 uno::Sequence
< double > aRes(nLen
*4);
708 double* pColors
=aRes
.getArray();
709 for( sal_Size i
=0; i
<nLen
; ++i
)
711 *pColors
++ = pIn
->Red
;
712 *pColors
++ = pIn
->Green
;
713 *pColors
++ = pIn
->Blue
;
719 virtual uno::Sequence
< double > SAL_CALL
convertFromARGB( const uno::Sequence
< rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
721 const rendering::ARGBColor
* pIn( rgbColor
.getConstArray() );
722 const sal_Size
nLen( rgbColor
.getLength() );
724 uno::Sequence
< double > aRes(nLen
*4);
725 double* pColors
=aRes
.getArray();
726 for( sal_Size i
=0; i
<nLen
; ++i
)
728 *pColors
++ = pIn
->Red
;
729 *pColors
++ = pIn
->Green
;
730 *pColors
++ = pIn
->Blue
;
731 *pColors
++ = pIn
->Alpha
;
736 virtual uno::Sequence
< double > SAL_CALL
convertFromPARGB( const uno::Sequence
< rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
738 const rendering::ARGBColor
* pIn( rgbColor
.getConstArray() );
739 const sal_Size
nLen( rgbColor
.getLength() );
741 uno::Sequence
< double > aRes(nLen
*4);
742 double* pColors
=aRes
.getArray();
743 for( sal_Size i
=0; i
<nLen
; ++i
)
745 *pColors
++ = pIn
->Red
/pIn
->Alpha
;
746 *pColors
++ = pIn
->Green
/pIn
->Alpha
;
747 *pColors
++ = pIn
->Blue
/pIn
->Alpha
;
748 *pColors
++ = pIn
->Alpha
;
755 StandardColorSpace() : m_aComponentTags(4)
757 sal_Int8
* pTags
= m_aComponentTags
.getArray();
758 pTags
[0] = rendering::ColorComponentTag::RGB_RED
;
759 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
760 pTags
[2] = rendering::ColorComponentTag::RGB_BLUE
;
761 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
766 uno::Reference
<rendering::XColorSpace
> VCL_DLLPUBLIC
createStandardColorSpace()
768 return new StandardColorSpace();
771 //---------------------------------------------------------------------------------------
773 uno::Sequence
< double > colorToStdColorSpaceSequence( const Color
& rColor
)
775 uno::Sequence
< double > aRet(4);
776 double* pRet
= aRet
.getArray();
778 pRet
[0] = toDoubleColor(rColor
.GetRed());
779 pRet
[1] = toDoubleColor(rColor
.GetGreen());
780 pRet
[2] = toDoubleColor(rColor
.GetBlue());
782 // VCL's notion of alpha is different from the rest of the world's
783 pRet
[3] = 1.0 - toDoubleColor(rColor
.GetTransparency());
788 Color
stdColorSpaceSequenceToColor( const uno::Sequence
< double >& rColor
)
790 ENSURE_ARG_OR_THROW( rColor
.getLength() == 4,
791 "color must have 4 channels" );
795 aColor
.SetRed ( toByteColor(rColor
[0]) );
796 aColor
.SetGreen( toByteColor(rColor
[1]) );
797 aColor
.SetBlue ( toByteColor(rColor
[2]) );
798 // VCL's notion of alpha is different from the rest of the world's
799 aColor
.SetTransparency( 255 - toByteColor(rColor
[3]) );
804 uno::Sequence
< double > VCL_DLLPUBLIC
colorToDoubleSequence(
806 const uno::Reference
< rendering::XColorSpace
>& xColorSpace
)
808 uno::Sequence
<rendering::ARGBColor
> aSeq(1);
809 aSeq
[0] = rendering::ARGBColor(
810 1.0-toDoubleColor(rColor
.GetTransparency()),
811 toDoubleColor(rColor
.GetRed()),
812 toDoubleColor(rColor
.GetGreen()),
813 toDoubleColor(rColor
.GetBlue()) );
815 return xColorSpace
->convertFromARGB(aSeq
);
818 Color VCL_DLLPUBLIC
doubleSequenceToColor(
819 const uno::Sequence
< double > rColor
,
820 const uno::Reference
< rendering::XColorSpace
>& xColorSpace
)
822 const rendering::ARGBColor
& rARGBColor(
823 xColorSpace
->convertToARGB(rColor
)[0]);
825 return Color( 255-toByteColor(rARGBColor
.Alpha
),
826 toByteColor(rARGBColor
.Red
),
827 toByteColor(rARGBColor
.Green
),
828 toByteColor(rARGBColor
.Blue
) );
831 //---------------------------------------------------------------------------------------
833 } // namespace vcltools
835 } // namespace canvas