32#include <com/sun/star/rendering/ColorComponentTag.hpp>
33#include <com/sun/star/rendering/ColorSpaceType.hpp>
34#include <com/sun/star/rendering/CompositeOperation.hpp>
35#include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
36#include <com/sun/star/rendering/PathCapType.hpp>
37#include <com/sun/star/rendering/PathJoinType.hpp>
38#include <com/sun/star/rendering/RenderingIntent.hpp>
39#include <com/sun/star/rendering/TexturingMode.hpp>
40#include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp>
41#include <com/sun/star/util/Endianness.hpp>
44#include <rtl/math.hxx>
52#include <parametricpolypolygon.hxx>
59using namespace ::
cairo;
65 mpSurfaceProvider(nullptr),
81 SurfaceProvider& rSurfaceProvider,
82 rendering::XGraphicDevice* pDevice )
103 const uno::Sequence<double>& rColor )
105 if( rColor.getLength() > 3 )
107 cairo_set_source_rgba( pCairo,
113 else if( rColor.getLength() == 3 )
114 cairo_set_source_rgb( pCairo,
121 const rendering::RenderState& renderState,
124 cairo_matrix_t aViewMatrix;
125 cairo_matrix_t aRenderMatrix;
126 cairo_matrix_t aCombinedMatrix;
128 cairo_matrix_init( &aViewMatrix,
129 viewState.AffineTransform.m00, viewState.AffineTransform.m10, viewState.AffineTransform.m01,
130 viewState.AffineTransform.m11, viewState.AffineTransform.m02, viewState.AffineTransform.m12);
131 cairo_matrix_init( &aRenderMatrix,
132 renderState.AffineTransform.m00, renderState.AffineTransform.m10, renderState.AffineTransform.m01,
133 renderState.AffineTransform.m11, renderState.AffineTransform.m02, renderState.AffineTransform.m12);
134 cairo_matrix_multiply( &aCombinedMatrix, &aRenderMatrix, &aViewMatrix);
136 if( viewState.Clip.is() )
138 SAL_INFO(
"canvas.cairo",
"view clip");
142 cairo_set_matrix(
mpCairo.get(), &aViewMatrix );
148 cairo_set_matrix(
mpCairo.get(), &aCombinedMatrix );
150 if( renderState.Clip.is() )
152 SAL_INFO(
"canvas.cairo",
"render clip BEGIN");
155 SAL_INFO(
"canvas.cairo",
"render clip END");
161 cairo_operator_t compositingMode( CAIRO_OPERATOR_OVER );
162 switch( renderState.CompositeOperation )
164 case rendering::CompositeOperation::CLEAR:
165 compositingMode = CAIRO_OPERATOR_CLEAR;
167 case rendering::CompositeOperation::SOURCE:
168 compositingMode = CAIRO_OPERATOR_SOURCE;
170 case rendering::CompositeOperation::DESTINATION:
171 compositingMode = CAIRO_OPERATOR_DEST;
173 case rendering::CompositeOperation::OVER:
174 compositingMode = CAIRO_OPERATOR_OVER;
176 case rendering::CompositeOperation::UNDER:
177 compositingMode = CAIRO_OPERATOR_DEST;
179 case rendering::CompositeOperation::INSIDE:
180 compositingMode = CAIRO_OPERATOR_IN;
182 case rendering::CompositeOperation::INSIDE_REVERSE:
183 compositingMode = CAIRO_OPERATOR_OUT;
185 case rendering::CompositeOperation::OUTSIDE:
186 compositingMode = CAIRO_OPERATOR_DEST_OVER;
188 case rendering::CompositeOperation::OUTSIDE_REVERSE:
189 compositingMode = CAIRO_OPERATOR_DEST_OUT;
191 case rendering::CompositeOperation::ATOP:
192 compositingMode = CAIRO_OPERATOR_ATOP;
194 case rendering::CompositeOperation::ATOP_REVERSE:
195 compositingMode = CAIRO_OPERATOR_DEST_ATOP;
197 case rendering::CompositeOperation::XOR:
198 compositingMode = CAIRO_OPERATOR_XOR;
200 case rendering::CompositeOperation::ADD:
201 compositingMode = CAIRO_OPERATOR_ADD;
203 case rendering::CompositeOperation::SATURATE:
204 compositingMode = CAIRO_OPERATOR_SATURATE;
207 cairo_set_operator(
mpCairo.get(), compositingMode );
219 cairo_identity_matrix(
mpCairo.get() );
224 cairo_set_source_rgba(
mpCairo.get(), 1.0, 1.0, 1.0, 0.0 );
226 cairo_set_source_rgb(
mpCairo.get(), 1.0, 1.0, 1.0 );
227 cairo_set_operator(
mpCairo.get(), CAIRO_OPERATOR_SOURCE );
232 cairo_restore(
mpCairo.get() );
236 const geometry::RealPoint2D& aStartPoint,
237 const geometry::RealPoint2D& aEndPoint,
238 const rendering::ViewState& viewState,
239 const rendering::RenderState& renderState )
246 cairo_set_line_width(
mpCairo.get(), 1 );
248 useStates( viewState, renderState,
true );
250 cairo_move_to(
mpCairo.get(), aStartPoint.X + 0.5, aStartPoint.Y + 0.5 );
251 cairo_line_to(
mpCairo.get(), aEndPoint.X + 0.5, aEndPoint.Y + 0.5 );
254 cairo_restore(
mpCairo.get() );
258 const geometry::RealBezierSegment2D& aBezierSegment,
259 const geometry::RealPoint2D& aEndPoint,
260 const rendering::ViewState& viewState,
261 const rendering::RenderState& renderState )
268 cairo_set_line_width(
mpCairo.get(), 1 );
270 useStates( viewState, renderState,
true );
272 cairo_move_to(
mpCairo.get(), aBezierSegment.Px + 0.5, aBezierSegment.Py + 0.5 );
276 aBezierSegment.C1x + 0.5, aBezierSegment.C1y + 0.5,
277 aBezierSegment.C2x + 0.5, aBezierSegment.C2y + 0.5,
278 aEndPoint.X + 0.5, aEndPoint.Y + 0.5 );
281 cairo_restore(
mpCairo.get() );
301 SurfaceProvider* pSurfaceProvider =
dynamic_cast<SurfaceProvider*
>( xBitmap.get() );
302 if( pSurfaceProvider )
303 return pSurfaceProvider->getSurface();
311 uno::Reference<rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap,
312 uno::UNO_QUERY_THROW);
319 "bitmapExFromXBitmap(): could not extract BitmapEx" );
337 bHasAlpha = xBitmap->hasAlpha();
351 pSurface = rSurfaceProvider->createSurface( aBitmap );
362 pSurface = rSurfaceProvider->getOutputDevice()->CreateSurface(
364 cairo_image_surface_create_for_data(
366 bHasAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
367 nWidth, nHeight, nWidth*4 ),
368 &cairo_surface_destroy) );
370 SAL_INFO(
"canvas.cairo",
"image: " << nWidth <<
" x " << nHeight <<
" alpha: " << bHasAlpha);
377 static void addColorStops( cairo_pattern_t* pPattern,
const uno::Sequence< uno::Sequence< double > >& rColors,
const uno::Sequence< double >& rStops,
bool bReverseStops )
381 OSL_ASSERT( rColors.getLength() == rStops.getLength() );
383 for(
i = 0;
i < rColors.getLength();
i++ )
385 const uno::Sequence< double >& rColor( rColors[
i] );
386 float stop = bReverseStops ? 1 - rStops[
i] : rStops[
i];
387 if( rColor.getLength() == 3 )
388 cairo_pattern_add_color_stop_rgb( pPattern,
stop, rColor[0], rColor[1], rColor[2] );
389 else if( rColor.getLength() == 4 )
391 double alpha = rColor[3];
398 static uno::Sequence<double>
lerp(
const uno::Sequence<double>& rLeft,
const uno::Sequence<double>& rRight,
double fAlpha)
400 if( rLeft.getLength() == 3 )
409 else if( rLeft.getLength() == 4 )
425 cairo_pattern_t* pPattern =
nullptr;
426 const ::canvas::ParametricPolyPolygon::Values aValues = rPolygon.
getValues();
427 double x0, x1, y0, y1, cx, cy, r0, r1;
429 switch( aValues.meType )
431 case ::canvas::ParametricPolyPolygon::GradientType::Linear:
436 pPattern = cairo_pattern_create_linear( x0, y0, x1, y1 );
437 addColorStops( pPattern, aValues.maColors, aValues.maStops,
false );
440 case ::canvas::ParametricPolyPolygon::GradientType::Elliptical:
446 pPattern = cairo_pattern_create_radial( cx, cy, r0, cy, cy, r1 );
447 addColorStops( pPattern, aValues.maColors, aValues.maStops,
true );
458 const uno::Sequence< rendering::Texture >* pTextures,
468 const css::rendering::Texture& aTexture ( (*pTextures)[0] );
469 if( aTexture.Bitmap.is() )
471 unsigned char* data =
nullptr;
472 bool bHasAlpha =
false;
477 cairo_pattern_t* pPattern;
479 cairo_save( pCairo );
481 css::geometry::AffineMatrix2D aTransform( aTexture.AffineTransform );
482 cairo_matrix_t aScaleMatrix, aTextureMatrix, aScaledTextureMatrix;
484 cairo_matrix_init( &aTextureMatrix,
485 aTransform.m00, aTransform.m10, aTransform.m01,
486 aTransform.m11, aTransform.m02, aTransform.m12);
488 geometry::IntegerSize2D aSize = aTexture.Bitmap->getSize();
490 cairo_matrix_init_scale( &aScaleMatrix, 1.0/aSize.Width, 1.0/aSize.Height );
491 cairo_matrix_multiply( &aScaledTextureMatrix, &aTextureMatrix, &aScaleMatrix );
492 cairo_matrix_invert( &aScaledTextureMatrix );
495 pPattern = cairo_pattern_create_for_surface( pSurface->getCairoSurface().get() );
497 if( aTexture.RepeatModeX == rendering::TexturingMode::REPEAT &&
498 aTexture.RepeatModeY == rendering::TexturingMode::REPEAT )
500 cairo_pattern_set_extend( pPattern, CAIRO_EXTEND_REPEAT );
502 else if ( aTexture.RepeatModeX == rendering::TexturingMode::NONE &&
503 aTexture.RepeatModeY == rendering::TexturingMode::NONE )
505 cairo_pattern_set_extend( pPattern, CAIRO_EXTEND_NONE );
507 else if ( aTexture.RepeatModeX == rendering::TexturingMode::CLAMP &&
508 aTexture.RepeatModeY == rendering::TexturingMode::CLAMP )
510 cairo_pattern_set_extend( pPattern, CAIRO_EXTEND_PAD );
516 double x1, y1, x2, y2;
517 cairo_path_extents(pCairo, &x1, &y1, &x2, &y2);
518 aScaledTextureMatrix.x0 -= (x1 * aScaledTextureMatrix.xx);
519 aScaledTextureMatrix.y0 -= (y1 * aScaledTextureMatrix.yy);
521 cairo_pattern_set_matrix( pPattern, &aScaledTextureMatrix );
523 cairo_set_source( pCairo, pPattern );
525 cairo_set_operator( pCairo, CAIRO_OPERATOR_SOURCE );
526 cairo_fill( pCairo );
528 cairo_restore( pCairo );
530 cairo_pattern_destroy( pPattern );
536 else if( aTexture.Gradient.is() )
538 uno::Reference< lang::XServiceInfo > xRef( aTexture.Gradient, uno::UNO_QUERY );
540 SAL_INFO(
"canvas.cairo",
"gradient fill" );
547 SAL_INFO(
"canvas.cairo",
"known implementation" );
550 css::geometry::AffineMatrix2D aTransform( aTexture.AffineTransform );
551 cairo_matrix_t aTextureMatrix;
553 cairo_matrix_init( &aTextureMatrix,
554 aTransform.m00, aTransform.m10, aTransform.m01,
555 aTransform.m11, aTransform.m02, aTransform.m12);
559 cairo_save( pCairo );
560 cairo_clip( pCairo );
568 cairo_transform( pCairo, &aTextureMatrix );
571 const unsigned int nGradientSize(
572 static_cast<unsigned int>(
576 const unsigned int nStripSize( nGradientSize < 50 ? 2 : 4 );
580 const unsigned int nStepCount(
584 nGradientSize / nStripSize,
589 for(
unsigned int i=1;
i<nStepCount; ++
i )
591 const double fT(
i/
double(nStepCount) );
598 cairo_rectangle( pCairo, -1+fT, -1+fT, 2-2*fT, 2-2*fT );
602 cairo_restore( pCairo );
610 SAL_INFO(
"canvas.cairo",
"filling with pattern" );
612 cairo_save( pCairo );
614 cairo_transform( pCairo, &aTextureMatrix );
615 cairo_set_source( pCairo, pPattern );
616 cairo_fill( pCairo );
617 cairo_restore( pCairo );
619 cairo_pattern_destroy( pPattern );
626 cairo_fill( pCairo );
630 cairo_stroke( pCairo );
631 SAL_INFO(
"canvas.cairo",
"stroke");
634 cairo_clip( pCairo );
642 SAL_INFO(
"canvas.cairo",
"clipNULL");
643 cairo_matrix_t aOrigMatrix, aIdentityMatrix;
650 cairo_matrix_init_identity( &aIdentityMatrix );
651 cairo_get_matrix( pCairo, &aOrigMatrix );
652 cairo_set_matrix( pCairo, &aIdentityMatrix );
654 cairo_reset_clip( pCairo );
655 cairo_rectangle( pCairo, 0, 0, 1, 1 );
656 cairo_clip( pCairo );
657 cairo_rectangle( pCairo, 2, 0, 1, 1 );
658 cairo_clip( pCairo );
661 cairo_set_matrix( pCairo, &aOrigMatrix );
667 const uno::Sequence< rendering::Texture >* pTextures,
669 rendering::FillRule eFillrule )
673 "CanvasHelper::fillTexturedPolyPolygon: empty texture sequence");
675 bool bOpToDo =
false;
676 cairo_matrix_t aOrigMatrix, aIdentityMatrix;
677 double nX, nY, nBX, nBY, nAX, nAY, nLastX(0.0), nLastY(0.0);
679 cairo_get_matrix( pCairo, &aOrigMatrix );
680 cairo_matrix_init_identity( &aIdentityMatrix );
681 cairo_set_matrix( pCairo, &aIdentityMatrix );
683 cairo_set_fill_rule( pCairo,
684 eFillrule == rendering::FillRule_EVEN_ODD ?
685 CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING );
687 for( sal_uInt32 nPolygonIndex = 0; nPolygonIndex < aPolyPolygon.count(); nPolygonIndex++ )
689 const ::basegfx::B2DPolygon& aPolygon( aPolyPolygon.getB2DPolygon( nPolygonIndex ) );
690 const sal_uInt32 nPointCount( aPolygon.count() );
693 const sal_uInt32 nExtendedPointCount( nPointCount +
694 int(aPolygon.isClosed() && aPolygon.areControlPointsUsed()) );
698 bool bIsBezier = aPolygon.areControlPointsUsed();
701 for( sal_uInt32 j=0; j < nExtendedPointCount; j++ )
703 aP = aPolygon.getB2DPoint( j % nPointCount );
707 cairo_matrix_transform_point( &aOrigMatrix, &nX, &nY );
709 if (!bIsBezier && aOperation ==
Clip)
715 if( aOperation ==
Stroke )
723 cairo_move_to( pCairo, nX, nY );
724 SAL_INFO(
"canvas.cairo",
"move to " << nX <<
"," << nY );
730 aA = aPolygon.getNextControlPoint( (j-1) % nPointCount );
731 aB = aPolygon.getPrevControlPoint( j % nPointCount );
738 cairo_matrix_transform_point( &aOrigMatrix, &nAX, &nAY );
739 cairo_matrix_transform_point( &aOrigMatrix, &nBX, &nBY );
741 if( aOperation ==
Stroke )
755 nAX = nLastX + ((nBX - nLastX) * 0.0005);
756 nAY = nLastY + ((nBY - nLastY) * 0.0005);
761 nBX = nX + ((nAX - nX) * 0.0005);
762 nBY = nY + ((nAY - nY) * 0.0005);
765 cairo_curve_to( pCairo, nAX, nAY, nBX, nBY, nX, nY );
769 cairo_line_to( pCairo, nX, nY );
770 SAL_INFO(
"canvas.cairo",
"line to " << nX <<
"," << nY );
779 if( aPolygon.isClosed() )
780 cairo_close_path( pCairo );
785 SAL_INFO(
"canvas.cairo",
"empty polygon for op: " << aOperation );
786 if( aOperation ==
Clip )
795 if( aOperation ==
Fill && pTextures )
797 cairo_set_matrix( pCairo, &aOrigMatrix );
798 doOperation( aOperation, pCairo, pTextures, pDevice, aPolyPolygon.getB2DRange() );
799 cairo_set_matrix( pCairo, &aIdentityMatrix );
802 if( bOpToDo && ( aOperation !=
Fill || !pTextures ) )
803 doOperation( aOperation, pCairo, pTextures, pDevice, aPolyPolygon.getB2DRange() );
805 cairo_set_matrix( pCairo, &aOrigMatrix );
807 if( aPolyPolygon.count() == 0 && aOperation ==
Clip )
814 const uno::Sequence< rendering::Texture >* pTextures )
const
816 const ::basegfx::B2DPolyPolygon& rPolyPoly(
817 ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPolyPolygon) );
821 if(bNoLineJoin && aOperation ==
Stroke)
824 for(sal_uInt32
a(0);
a < rPolyPoly.count();
a++)
827 const sal_uInt32 nPointCount(aCandidate.
count());
831 const sal_uInt32 nEdgeCount(aCandidate.
isClosed() ? nPointCount: nPointCount - 1);
836 for(sal_uInt32 b(0); b < nEdgeCount; b++)
838 const sal_uInt32 nNextIndex((b + 1) % nPointCount);
847 xPolyPolygon->getFillRule() );
860 xPolyPolygon->getFillRule() );
865 const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
866 const rendering::ViewState& viewState,
867 const rendering::RenderState& renderState )
869#ifdef CAIRO_CANVAS_PERF_TRACE
870 struct timespec aTimer;
871 mxDevice->startPerfTrace( &aTimer );
878 cairo_set_line_width(
mpCairo.get(), 1 );
880 useStates( viewState, renderState,
true );
883 cairo_restore(
mpCairo.get() );
886 SAL_INFO(
"canvas.cairo",
"CanvasHelper called after it was disposed");
888#ifdef CAIRO_CANVAS_PERF_TRACE
889 mxDevice->stopPerfTrace( &aTimer,
"drawPolyPolygon" );
892 return uno::Reference< rendering::XCachedPrimitive >(
nullptr);
896 const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
897 const rendering::ViewState& viewState,
898 const rendering::RenderState& renderState,
899 const rendering::StrokeAttributes& strokeAttributes )
901#ifdef CAIRO_CANVAS_PERF_TRACE
902 struct timespec aTimer;
903 mxDevice->startPerfTrace( &aTimer );
910 useStates( viewState, renderState,
true );
912 cairo_matrix_t aMatrix;
913 cairo_get_matrix(
mpCairo.get(), &aMatrix );
914 double scaleFactorX = 1;
915 double scaleFactorY = 0;
916 cairo_matrix_transform_distance( &aMatrix, &scaleFactorX, &scaleFactorY );
918 cairo_set_line_width(
mpCairo.get(), strokeAttributes.StrokeWidth * scaleFactor );
920 cairo_set_miter_limit(
mpCairo.get(), strokeAttributes.MiterLimit );
923 switch( strokeAttributes.StartCapType )
925 case rendering::PathCapType::BUTT:
926 cairo_set_line_cap(
mpCairo.get(), CAIRO_LINE_CAP_BUTT );
928 case rendering::PathCapType::ROUND:
929 cairo_set_line_cap(
mpCairo.get(), CAIRO_LINE_CAP_ROUND );
931 case rendering::PathCapType::SQUARE:
932 cairo_set_line_cap(
mpCairo.get(), CAIRO_LINE_CAP_SQUARE );
936 bool bNoLineJoin(
false);
938 switch( strokeAttributes.JoinType )
940 case rendering::PathJoinType::NONE:
943 case rendering::PathJoinType::MITER:
944 cairo_set_line_join(
mpCairo.get(), CAIRO_LINE_JOIN_MITER );
946 case rendering::PathJoinType::ROUND:
947 cairo_set_line_join(
mpCairo.get(), CAIRO_LINE_JOIN_ROUND );
949 case rendering::PathJoinType::BEVEL:
950 cairo_set_line_join(
mpCairo.get(), CAIRO_LINE_JOIN_BEVEL );
957 if (strokeAttributes.DashArray.hasElements() && scaleFactor > 0.0)
960 for (
auto& rDash : aDashArray)
961 rDash *= scaleFactor;
962 cairo_set_dash(
mpCairo.get(), aDashArray.data(), aDashArray.size(), 0);
969 cairo_restore(
mpCairo.get() );
972 SAL_INFO(
"canvas.cairo",
"CanvasHelper called after it was disposed");
974#ifdef CAIRO_CANVAS_PERF_TRACE
975 mxDevice->stopPerfTrace( &aTimer,
"strokePolyPolygon" );
979 return uno::Reference< rendering::XCachedPrimitive >(
nullptr);
983 const uno::Reference< rendering::XPolyPolygon2D >& ,
984 const rendering::ViewState& ,
985 const rendering::RenderState& ,
986 const uno::Sequence< rendering::Texture >& ,
987 const rendering::StrokeAttributes& )
990 return uno::Reference< rendering::XCachedPrimitive >(
nullptr);
994 const uno::Reference< rendering::XPolyPolygon2D >& ,
995 const rendering::ViewState& ,
996 const rendering::RenderState& ,
997 const uno::Sequence< rendering::Texture >& ,
998 const uno::Reference< geometry::XMapping2D >& ,
999 const rendering::StrokeAttributes& )
1002 return uno::Reference< rendering::XCachedPrimitive >(
nullptr);
1006 const uno::Reference< rendering::XPolyPolygon2D >& ,
1007 const rendering::ViewState& ,
1008 const rendering::RenderState& ,
1009 const rendering::StrokeAttributes& )
1012 return uno::Reference< rendering::XPolyPolygon2D >(
nullptr);
1016 const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
1017 const rendering::ViewState& viewState,
1018 const rendering::RenderState& renderState )
1020#ifdef CAIRO_CANVAS_PERF_TRACE
1021 struct timespec aTimer;
1022 mxDevice->startPerfTrace( &aTimer );
1029 useStates( viewState, renderState,
true );
1032 cairo_restore(
mpCairo.get() );
1035 SAL_INFO(
"canvas.cairo",
"CanvasHelper called after it was disposed");
1037#ifdef CAIRO_CANVAS_PERF_TRACE
1038 mxDevice->stopPerfTrace( &aTimer,
"fillPolyPolygon" );
1041 return uno::Reference< rendering::XCachedPrimitive >(
nullptr);
1045 const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
1046 const rendering::ViewState& viewState,
1047 const rendering::RenderState& renderState,
1048 const uno::Sequence< rendering::Texture >& textures )
1054 useStates( viewState, renderState,
true );
1057 cairo_restore(
mpCairo.get() );
1060 return uno::Reference< rendering::XCachedPrimitive >(
nullptr);
1064 const uno::Reference< rendering::XPolyPolygon2D >& ,
1065 const rendering::ViewState& ,
1066 const rendering::RenderState& ,
1067 const uno::Sequence< rendering::Texture >& ,
1068 const uno::Reference< geometry::XMapping2D >& )
1071 return uno::Reference< rendering::XCachedPrimitive >(
nullptr);
1076 const rendering::ViewState& viewState,
1077 const rendering::RenderState& renderState,
1078 const geometry::IntegerSize2D& rSize,
1079 bool bModulateColors,
1083 uno::Reference< rendering::XCachedPrimitive > rv;
1084 geometry::IntegerSize2D aBitmapSize = rSize;
1093 useStates( viewState, renderState,
true );
1095 cairo_matrix_t aMatrix;
1097 cairo_get_matrix(
mpCairo.get(), &aMatrix );
1098 if( ! ::rtl::math::approxEqual( aMatrix.xx, 1 ) &&
1099 ! ::rtl::math::approxEqual( aMatrix.yy, 1 ) &&
1100 ::rtl::math::approxEqual( aMatrix.x0, 0 ) &&
1101 ::rtl::math::approxEqual( aMatrix.y0, 0 ) &&
1105 double dWidth, dHeight;
1109 aBitmapSize.Width =
static_cast<sal_Int32
>( dWidth );
1110 aBitmapSize.Height =
static_cast<sal_Int32
>( dHeight );
1114 bHasAlpha ? CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_COLOR );
1117 cairo_set_operator( pCairo.get(), CAIRO_OPERATOR_SOURCE );
1119 cairo_scale( pCairo.get(), (dWidth+0.5)/rSize.Width, (dHeight+0.5)/rSize.Height );
1120 cairo_set_source_surface( pCairo.get(), pSurface->getCairoSurface().get(), 0, 0 );
1121 cairo_paint( pCairo.get() );
1123 pSurface = pScaledSurface;
1125 aMatrix.xx = aMatrix.yy = 1;
1126 cairo_set_matrix(
mpCairo.get(), &aMatrix );
1134 const_cast< rendering::XCanvas*
>(pCanvas)) );
1139 double x,
y, width, height;
1142 width = aBitmapSize.Width;
1143 height = aBitmapSize.Height;
1144 cairo_matrix_transform_point( &aMatrix, &
x, &
y );
1145 cairo_matrix_transform_distance( &aMatrix, &width, &height );
1152 SAL_INFO(
"canvas.cairo",
"trying to change surface to rgb");
1160 useStates( viewState, renderState,
true );
1162 cairo_set_matrix(
mpCairo.get(), &aMatrix );
1167 cairo_set_source_surface(
mpCairo.get(), pSurface->getCairoSurface().get(), 0, 0 );
1169 ::rtl::math::approxEqual( aMatrix.xx, 1 ) &&
1170 ::rtl::math::approxEqual( aMatrix.yy, 1 ) &&
1171 ::rtl::math::approxEqual( aMatrix.x0, 0 ) &&
1172 ::rtl::math::approxEqual( aMatrix.y0, 0 ) )
1173 cairo_set_operator(
mpCairo.get(), CAIRO_OPERATOR_SOURCE );
1174 cairo_pattern_set_extend( cairo_get_source(
mpCairo.get()), CAIRO_EXTEND_PAD );
1175 cairo_rectangle(
mpCairo.get(), 0, 0, aBitmapSize.Width, aBitmapSize.Height );
1180 double fPixelWidth = rSize.Width;
1181 double fPixelHeight = rSize.Height;
1182 cairo_matrix_transform_distance(&aMatrix, &fPixelWidth, &fPixelHeight);
1183 int nPixelWidth = std::round(fPixelWidth);
1184 int nPixelHeight = std::round(fPixelHeight);
1185 if (std::abs(nPixelWidth) > 0 && std::abs(nPixelHeight) > 0)
1188 if (bModulateColors)
1189 cairo_paint_with_alpha(
mpCairo.get(), renderState.DeviceColor[3]);
1193 if (cairo_status(
mpCairo.get()) != CAIRO_STATUS_SUCCESS)
1195 SAL_WARN(
"canvas.cairo",
"cairo_paint() failed: " << cairo_status_to_string(
1196 cairo_status(
mpCairo.get())));
1200 cairo_restore(
mpCairo.get() );
1203 SAL_INFO(
"canvas.cairo",
"CanvasHelper called after it was disposed");
1209 const uno::Reference< rendering::XBitmap >& xBitmap,
1210 const rendering::ViewState& viewState,
1211 const rendering::RenderState& renderState )
1213#ifdef CAIRO_CANVAS_PERF_TRACE
1214 struct timespec aTimer;
1215 mxDevice->startPerfTrace( &aTimer );
1218 uno::Reference< rendering::XCachedPrimitive > rv;
1219 unsigned char* data =
nullptr;
1220 bool bHasAlpha =
false;
1222 geometry::IntegerSize2D aSize = xBitmap->getSize();
1234#ifdef CAIRO_CANVAS_PERF_TRACE
1235 mxDevice->stopPerfTrace( &aTimer,
"drawBitmap" );
1242 const uno::Reference< rendering::XBitmap >& xBitmap,
1243 const rendering::ViewState& viewState,
1244 const rendering::RenderState& renderState )
1246#ifdef CAIRO_CANVAS_PERF_TRACE
1247 struct timespec aTimer;
1248 mxDevice->startPerfTrace( &aTimer );
1251 uno::Reference< rendering::XCachedPrimitive > rv;
1252 unsigned char* data =
nullptr;
1253 bool bHasAlpha =
false;
1255 geometry::IntegerSize2D aSize = xBitmap->getSize();
1267#ifdef CAIRO_CANVAS_PERF_TRACE
1268 mxDevice->stopPerfTrace( &aTimer,
"drawBitmap" );
1278 return geometry::IntegerSize2D(1, 1);
1280 return ::basegfx::unotools::integerSize2DFromB2ISize(
maSize );
1286#ifdef CAIRO_CANVAS_PERF_TRACE
1287 struct timespec aTimer;
1288 mxDevice->startPerfTrace( &aTimer );
1294 ::canvas::tools::roundUp( newSize.Height ) ),
1298 SAL_INFO(
"canvas.cairo",
"CanvasHelper called after it was disposed");
1300#ifdef CAIRO_CANVAS_PERF_TRACE
1301 mxDevice->stopPerfTrace( &aTimer,
"getScaledBitmap" );
1304 return uno::Reference< rendering::XBitmap >();
1308 const geometry::IntegerRectangle2D& rect )
1312 const sal_Int32 nWidth( rect.X2 - rect.X1 );
1313 const sal_Int32 nHeight( rect.Y2 - rect.Y1 );
1314 const cairo_format_t eFormat(
mbHaveAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24 );
1315 uno::Sequence< sal_Int8 > aRes( 4*nWidth*nHeight );
1317 cairo_surface_t* pImageSurface = cairo_image_surface_create_for_data(
reinterpret_cast<unsigned char *
>(pData),
1319 nWidth, nHeight, 4*nWidth );
1320 cairo_t* pCairo = cairo_create( pImageSurface );
1321 cairo_set_source_surface( pCairo,
mpSurface->getCairoSurface().get(), -rect.X1, -rect.Y1);
1322 cairo_paint( pCairo );
1323 cairo_destroy( pCairo );
1324 cairo_surface_destroy( pImageSurface );
1331 return uno::Sequence< sal_Int8 >();
1335 const geometry::IntegerPoint2D& )
1337 return uno::Sequence< sal_Int8 >();
1342 class CairoColorSpace :
public cppu::WeakImplHelper< css::rendering::XIntegerBitmapColorSpace >
1348 virtual ::sal_Int8 SAL_CALL
getType( )
override
1350 return rendering::ColorSpaceType::RGB;
1352 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( )
override
1356 virtual ::sal_Int8 SAL_CALL getRenderingIntent( )
override
1358 return rendering::RenderingIntent::PERCEPTUAL;
1360 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( )
override
1362 return uno::Sequence< beans::PropertyValue >();
1364 virtual uno::Sequence< double > SAL_CALL convertColorSpace(
const uno::Sequence< double >& deviceColor,
1365 const uno::Reference< rendering::XColorSpace >& targetColorSpace )
override
1369 uno::Sequence<rendering::ARGBColor> aIntermediate(
1370 convertToARGB(deviceColor));
1371 return targetColorSpace->convertFromARGB(aIntermediate);
1373 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB(
const uno::Sequence< double >& deviceColor )
override
1375 const double* pIn( deviceColor.getConstArray() );
1376 const std::size_t nLen( deviceColor.getLength() );
1378 "number of channels no multiple of 4",
1379 static_cast<rendering::XColorSpace*
>(
this), 0);
1381 uno::Sequence< rendering::RGBColor > aRes(nLen/4);
1382 rendering::RGBColor*
pOut( aRes.getArray() );
1383 for( std::size_t i=0;
i<nLen;
i+=4 )
1385 const double fAlpha(pIn[3]);
1387 *
pOut++ = rendering::RGBColor(0.0, 0.0, 0.0);
1389 *
pOut++ = rendering::RGBColor(pIn[2]/fAlpha,pIn[1]/fAlpha,pIn[0]/fAlpha);
1394 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB(
const uno::Sequence< double >& deviceColor )
override
1396 const double* pIn( deviceColor.getConstArray() );
1397 const std::size_t nLen( deviceColor.getLength() );
1399 "number of channels no multiple of 4",
1400 static_cast<rendering::XColorSpace*
>(
this), 0);
1402 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
1403 rendering::ARGBColor*
pOut( aRes.getArray() );
1404 for( std::size_t i=0;
i<nLen;
i+=4 )
1406 const double fAlpha(pIn[3]);
1408 *
pOut++ = rendering::ARGBColor(0.0, 0.0, 0.0, 0.0);
1410 *
pOut++ = rendering::ARGBColor(fAlpha,pIn[2]/fAlpha,pIn[1]/fAlpha,pIn[0]/fAlpha);
1415 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB(
const uno::Sequence< double >& deviceColor )
override
1417 const double* pIn( deviceColor.getConstArray() );
1418 const std::size_t nLen( deviceColor.getLength() );
1420 "number of channels no multiple of 4",
1421 static_cast<rendering::XColorSpace*
>(
this), 0);
1423 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
1424 rendering::ARGBColor*
pOut( aRes.getArray() );
1425 for( std::size_t i=0;
i<nLen;
i+=4 )
1427 *
pOut++ = rendering::ARGBColor(pIn[3],pIn[2],pIn[1],pIn[1]);
1432 virtual uno::Sequence< double > SAL_CALL convertFromRGB(
const uno::Sequence< rendering::RGBColor >& rgbColor )
override
1434 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
1435 const std::size_t nLen( rgbColor.getLength() );
1437 uno::Sequence< double > aRes(nLen*4);
1438 double* pColors=aRes.getArray();
1439 for( std::size_t i=0;
i<nLen; ++
i )
1441 *pColors++ = pIn->Blue;
1442 *pColors++ = pIn->Green;
1443 *pColors++ = pIn->Red;
1449 virtual uno::Sequence< double > SAL_CALL convertFromARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
override
1451 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
1452 const std::size_t nLen( rgbColor.getLength() );
1454 uno::Sequence< double > aRes(nLen*4);
1455 double* pColors=aRes.getArray();
1456 for( std::size_t i=0;
i<nLen; ++
i )
1458 *pColors++ = pIn->Alpha*pIn->Blue;
1459 *pColors++ = pIn->Alpha*pIn->Green;
1460 *pColors++ = pIn->Alpha*pIn->Red;
1461 *pColors++ = pIn->Alpha;
1466 virtual uno::Sequence< double > SAL_CALL convertFromPARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
override
1468 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
1469 const std::size_t nLen( rgbColor.getLength() );
1471 uno::Sequence< double > aRes(nLen*4);
1472 double* pColors=aRes.getArray();
1473 for( std::size_t i=0;
i<nLen; ++
i )
1475 *pColors++ = pIn->Blue;
1476 *pColors++ = pIn->Green;
1477 *pColors++ = pIn->Red;
1478 *pColors++ = pIn->Alpha;
1485 virtual ::sal_Int32 SAL_CALL getBitsPerPixel( )
override
1489 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( )
override
1493 virtual ::sal_Int8 SAL_CALL getEndianness( )
override
1495 return util::Endianness::LITTLE;
1497 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace(
const uno::Sequence< ::sal_Int8 >& deviceColor,
1498 const uno::Reference< rendering::XColorSpace >& targetColorSpace )
override
1500 if(
dynamic_cast<CairoColorSpace*
>(targetColorSpace.get()) )
1502 const sal_Int8* pIn( deviceColor.getConstArray() );
1503 const std::size_t nLen( deviceColor.getLength() );
1505 "number of channels no multiple of 4",
1506 static_cast<rendering::XColorSpace*
>(
this), 0);
1508 uno::Sequence<double> aRes(nLen);
1509 double*
pOut( aRes.getArray() );
1510 for( std::size_t i=0;
i<nLen;
i+=4 )
1523 uno::Sequence<rendering::ARGBColor> aIntermediate(
1524 convertIntegerToARGB(deviceColor));
1525 return targetColorSpace->convertFromARGB(aIntermediate);
1528 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace(
const uno::Sequence< ::sal_Int8 >& deviceColor,
1529 const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace )
override
1531 if(
dynamic_cast<CairoColorSpace*
>(targetColorSpace.get()) )
1540 uno::Sequence<rendering::ARGBColor> aIntermediate(
1541 convertIntegerToARGB(deviceColor));
1542 return targetColorSpace->convertIntegerFromARGB(aIntermediate);
1545 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB(
const uno::Sequence< ::sal_Int8 >& deviceColor )
override
1547 const sal_Int8* pIn( deviceColor.getConstArray() );
1548 const std::size_t nLen( deviceColor.getLength() );
1550 "number of channels no multiple of 4",
1551 static_cast<rendering::XColorSpace*
>(
this), 0);
1553 uno::Sequence< rendering::RGBColor > aRes(nLen/4);
1554 rendering::RGBColor*
pOut( aRes.getArray() );
1555 for( std::size_t i=0;
i<nLen;
i+=4 )
1557 const double fAlpha(
static_cast<sal_uInt8>(pIn[3]));
1559 *
pOut++ = rendering::RGBColor(
1564 *
pOut++ = rendering::RGBColor(0,0,0);
1570 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB(
const uno::Sequence< ::sal_Int8 >& deviceColor )
override
1572 const sal_Int8* pIn( deviceColor.getConstArray() );
1573 const std::size_t nLen( deviceColor.getLength() );
1575 "number of channels no multiple of 4",
1576 static_cast<rendering::XColorSpace*
>(
this), 0);
1578 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
1579 rendering::ARGBColor*
pOut( aRes.getArray() );
1580 for( std::size_t i=0;
i<nLen;
i+=4 )
1582 const double fAlpha(
static_cast<sal_uInt8>(pIn[3]));
1584 *
pOut++ = rendering::ARGBColor(
1590 *
pOut++ = rendering::ARGBColor(0,0,0,0);
1595 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB(
const uno::Sequence< ::sal_Int8 >& deviceColor )
override
1597 const sal_Int8* pIn( deviceColor.getConstArray() );
1598 const std::size_t nLen( deviceColor.getLength() );
1600 "number of channels no multiple of 4",
1601 static_cast<rendering::XColorSpace*
>(
this), 0);
1603 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
1604 rendering::ARGBColor*
pOut( aRes.getArray() );
1605 for( std::size_t i=0;
i<nLen;
i+=4 )
1607 *
pOut++ = rendering::ARGBColor(
1617 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB(
const uno::Sequence< rendering::RGBColor >& rgbColor )
override
1619 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
1620 const std::size_t nLen( rgbColor.getLength() );
1622 uno::Sequence< sal_Int8 > aRes(nLen*4);
1624 for( std::size_t i=0;
i<nLen; ++
i )
1635 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
override
1637 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
1638 const std::size_t nLen( rgbColor.getLength() );
1640 uno::Sequence< sal_Int8 > aRes(nLen*4);
1642 for( std::size_t i=0;
i<nLen; ++
i )
1644 const double fAlpha(pIn->Alpha);
1653 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
override
1655 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
1656 const std::size_t nLen( rgbColor.getLength() );
1658 uno::Sequence< sal_Int8 > aRes(nLen*4);
1660 for( std::size_t i=0;
i<nLen; ++
i )
1678 pTags[0] = rendering::ColorComponentTag::RGB_BLUE;
1679 pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
1680 pTags[2] = rendering::ColorComponentTag::RGB_RED;
1681 pTags[3] = rendering::ColorComponentTag::PREMULTIPLIED_ALPHA;
1690 class CairoNoAlphaColorSpace :
public cppu::WeakImplHelper< css::rendering::XIntegerBitmapColorSpace >
1696 virtual ::sal_Int8 SAL_CALL
getType( )
override
1698 return rendering::ColorSpaceType::RGB;
1700 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( )
override
1704 virtual ::sal_Int8 SAL_CALL getRenderingIntent( )
override
1706 return rendering::RenderingIntent::PERCEPTUAL;
1708 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( )
override
1710 return uno::Sequence< beans::PropertyValue >();
1712 virtual uno::Sequence< double > SAL_CALL convertColorSpace(
const uno::Sequence< double >& deviceColor,
1713 const uno::Reference< rendering::XColorSpace >& targetColorSpace )
override
1717 uno::Sequence<rendering::ARGBColor> aIntermediate(
1718 convertToARGB(deviceColor));
1719 return targetColorSpace->convertFromARGB(aIntermediate);
1721 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB(
const uno::Sequence< double >& deviceColor )
override
1723 const double* pIn( deviceColor.getConstArray() );
1724 const std::size_t nLen( deviceColor.getLength() );
1726 "number of channels no multiple of 4",
1727 static_cast<rendering::XColorSpace*
>(
this), 0);
1729 uno::Sequence< rendering::RGBColor > aRes(nLen/4);
1730 rendering::RGBColor*
pOut( aRes.getArray() );
1731 for( std::size_t i=0;
i<nLen;
i+=4 )
1733 *
pOut++ = rendering::RGBColor(pIn[2], pIn[1], pIn[0]);
1738 uno::Sequence< rendering::ARGBColor > impl_convertToARGB(
const uno::Sequence< double >& deviceColor )
1740 const double* pIn( deviceColor.getConstArray() );
1741 const std::size_t nLen( deviceColor.getLength() );
1743 "number of channels no multiple of 4",
1744 static_cast<rendering::XColorSpace*
>(
this), 0);
1746 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
1747 rendering::ARGBColor*
pOut( aRes.getArray() );
1748 for( std::size_t i=0;
i<nLen;
i+=4 )
1750 *
pOut++ = rendering::ARGBColor(1.0, pIn[2], pIn[1], pIn[0]);
1755 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB(
const uno::Sequence< double >& deviceColor )
override
1757 return impl_convertToARGB( deviceColor );
1759 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB(
const uno::Sequence< double >& deviceColor )
override
1761 return impl_convertToARGB( deviceColor );
1763 virtual uno::Sequence< double > SAL_CALL convertFromRGB(
const uno::Sequence< rendering::RGBColor >& rgbColor )
override
1765 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
1766 const std::size_t nLen( rgbColor.getLength() );
1768 uno::Sequence< double > aRes(nLen*4);
1769 double* pColors=aRes.getArray();
1770 for( std::size_t i=0;
i<nLen; ++
i )
1772 *pColors++ = pIn->Blue;
1773 *pColors++ = pIn->Green;
1774 *pColors++ = pIn->Red;
1780 uno::Sequence< double > impl_convertFromARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
1782 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
1783 const std::size_t nLen( rgbColor.getLength() );
1785 uno::Sequence< double > aRes(nLen*4);
1786 double* pColors=aRes.getArray();
1787 for( std::size_t i=0;
i<nLen; ++
i )
1789 *pColors++ = pIn->Blue;
1790 *pColors++ = pIn->Green;
1791 *pColors++ = pIn->Red;
1797 virtual uno::Sequence< double > SAL_CALL convertFromARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
override
1799 return impl_convertFromARGB( rgbColor );
1801 virtual uno::Sequence< double > SAL_CALL convertFromPARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
override
1803 return impl_convertFromARGB( rgbColor );
1807 virtual ::sal_Int32 SAL_CALL getBitsPerPixel( )
override
1811 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( )
override
1815 virtual ::sal_Int8 SAL_CALL getEndianness( )
override
1817 return util::Endianness::LITTLE;
1819 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace(
const uno::Sequence< ::sal_Int8 >& deviceColor,
1820 const uno::Reference< rendering::XColorSpace >& targetColorSpace )
override
1822 if(
dynamic_cast<CairoColorSpace*
>(targetColorSpace.get()) )
1824 const sal_Int8* pIn( deviceColor.getConstArray() );
1825 const std::size_t nLen( deviceColor.getLength() );
1827 "number of channels no multiple of 4",
1828 static_cast<rendering::XColorSpace*
>(
this), 0);
1830 uno::Sequence<double> aRes(nLen);
1831 double*
pOut( aRes.getArray() );
1832 for( std::size_t i=0;
i<nLen;
i+=4 )
1837 *
pOut++ = 1.0; pIn++;
1845 uno::Sequence<rendering::ARGBColor> aIntermediate(
1846 convertIntegerToARGB(deviceColor));
1847 return targetColorSpace->convertFromARGB(aIntermediate);
1850 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace(
const uno::Sequence< ::sal_Int8 >& deviceColor,
1851 const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace )
override
1853 if(
dynamic_cast<CairoNoAlphaColorSpace*
>(targetColorSpace.get()) )
1862 uno::Sequence<rendering::ARGBColor> aIntermediate(
1863 convertIntegerToARGB(deviceColor));
1864 return targetColorSpace->convertIntegerFromARGB(aIntermediate);
1867 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB(
const uno::Sequence< ::sal_Int8 >& deviceColor )
override
1869 const sal_Int8* pIn( deviceColor.getConstArray() );
1870 const std::size_t nLen( deviceColor.getLength() );
1872 "number of channels no multiple of 4",
1873 static_cast<rendering::XColorSpace*
>(
this), 0);
1875 uno::Sequence< rendering::RGBColor > aRes(nLen/4);
1876 rendering::RGBColor*
pOut( aRes.getArray() );
1877 for( std::size_t i=0;
i<nLen;
i+=4 )
1879 *
pOut++ = rendering::RGBColor( pIn[2], pIn[1], pIn[0] );
1885 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB(
const uno::Sequence< ::sal_Int8 >& deviceColor )
override
1887 return impl_convertIntegerToARGB( deviceColor );
1889 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB(
const uno::Sequence< ::sal_Int8 >& deviceColor )
override
1891 return impl_convertIntegerToARGB( deviceColor );
1893 uno::Sequence< rendering::ARGBColor > impl_convertIntegerToARGB(
const uno::Sequence< ::sal_Int8 >& deviceColor )
1895 const sal_Int8* pIn( deviceColor.getConstArray() );
1896 const std::size_t nLen( deviceColor.getLength() );
1898 "number of channels no multiple of 4",
1899 static_cast<rendering::XColorSpace*
>(
this), 0);
1901 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
1902 rendering::ARGBColor*
pOut( aRes.getArray() );
1903 for( std::size_t i=0;
i<nLen;
i+=4 )
1905 *
pOut++ = rendering::ARGBColor(
1915 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB(
const uno::Sequence< rendering::RGBColor >& rgbColor )
override
1917 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
1918 const std::size_t nLen( rgbColor.getLength() );
1920 uno::Sequence< sal_Int8 > aRes(nLen*4);
1922 for( std::size_t i=0;
i<nLen; ++
i )
1933 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
override
1935 return impl_convertIntegerFromARGB( rgbColor );
1937 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
override
1939 return impl_convertIntegerFromARGB( rgbColor );
1941 uno::Sequence< ::sal_Int8 > impl_convertIntegerFromARGB(
const uno::Sequence< rendering::ARGBColor >& rgbColor )
1943 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
1944 const std::size_t nLen( rgbColor.getLength() );
1946 uno::Sequence< sal_Int8 > aRes(nLen*4);
1948 for( std::size_t i=0;
i<nLen; ++
i )
1960 CairoNoAlphaColorSpace() :
1966 pTags[0] = rendering::ColorComponentTag::RGB_BLUE;
1967 pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
1968 pTags[2] = rendering::ColorComponentTag::RGB_RED;
1976 uno::Reference<rendering::XIntegerBitmapColorSpace>& GetCairoNoAlphaColorSpace()
1978 static uno::Reference<rendering::XIntegerBitmapColorSpace>
SPACE =
new CairoNoAlphaColorSpace();
1982 uno::Reference<rendering::XIntegerBitmapColorSpace>& GetCairoColorSpace()
1984 static uno::Reference<rendering::XIntegerBitmapColorSpace>
SPACE =
new CairoColorSpace();
1993 return rendering::IntegerBitmapLayout();
1995 const geometry::IntegerSize2D aSize(
getSize());
2000 rendering::IntegerBitmapLayout
2003 rendering::IntegerBitmapLayout aLayout;
2005 aLayout.ScanLines = nHeight;
2006 aLayout.ScanLineBytes = nWidth*4;
2007 aLayout.ScanLineStride = aLayout.ScanLineBytes;
2008 aLayout.PlaneStride = 0;
2009 aLayout.ColorSpace =
mbHaveAlpha ? GetCairoColorSpace() : GetCairoNoAlphaColorSpace();
2010 aLayout.Palette.clear();
2011 aLayout.IsMsbFirst =
false;
2018 const rendering::ViewState& viewState,
2019 const rendering::RenderState& renderState )
2021 SAL_INFO(
"canvas.cairo",
"CanvasHelper::repaint");
2031 useStates( viewState, renderState,
true );
2033 cairo_matrix_t aMatrix;
2035 cairo_get_matrix(
mpCairo.get(), &aMatrix );
2036 aMatrix.xx = aMatrix.yy = 1;
2037 cairo_set_matrix(
mpCairo.get(), &aMatrix );
2039 cairo_set_source_surface(
mpCairo.get(), pSurface->getCairoSurface().get(), 0, 0 );
2041 cairo_restore(
mpCairo.get() );
struct _cairo_surface cairo_surface_t
uno::Sequence< sal_Int32 > maBitCounts
uno::Sequence< sal_Int8 > maComponentTags
Bitmap GetBitmap(Color aTransparentReplaceColor) const
void setB2DPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
void setPrevControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const
void setNextControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
basegfx::B2DPoint getPrevControlPoint(sal_uInt32 nIndex) const
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
basegfx::B2DPoint getNextControlPoint(sal_uInt32 nIndex) const
B2DPoint getMaximum() const
B2DPoint getMinimum() const
ResultType lerp(double fAlpha) const
virtual ::cairo::SurfaceSharedPtr getSurface() override
css::uno::Reference< css::rendering::XCachedPrimitive > strokeTextureMappedPolyPolygon(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XPolyPolygon2D > &xPolyPolygon, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState, const css::uno::Sequence< css::rendering::Texture > &textures, const css::uno::Reference< css::geometry::XMapping2D > &xMapping, const css::rendering::StrokeAttributes &strokeAttributes)
void disposing()
Release all references.
void doPolyPolygonPath(const css::uno::Reference< css::rendering::XPolyPolygon2D > &xPolyPolygon, Operation aOperation, bool bNoLineJoin=false, const css::uno::Sequence< css::rendering::Texture > *pTextures=nullptr) const
::cairo::CairoSharedPtr mpCairo
::cairo::SurfaceSharedPtr mpSurface
void drawLine(const css::rendering::XCanvas *pCanvas, const css::geometry::RealPoint2D &aStartPoint, const css::geometry::RealPoint2D &aEndPoint, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState)
css::rendering::IntegerBitmapLayout impl_getMemoryLayout(sal_Int32 nWidth, sal_Int32 nHeight)
void useStates(const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState, bool setColor)
css::uno::Reference< css::rendering::XCachedPrimitive > fillTexturedPolyPolygon(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XPolyPolygon2D > &xPolyPolygon, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState, const css::uno::Sequence< css::rendering::Texture > &textures)
css::uno::Reference< css::rendering::XBitmap > getScaledBitmap(const css::geometry::RealSize2D &newSize, bool beFast)
css::uno::Reference< css::rendering::XCachedPrimitive > fillPolyPolygon(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XPolyPolygon2D > &xPolyPolygon, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState)
css::uno::Reference< css::rendering::XCachedPrimitive > implDrawBitmapSurface(const css::rendering::XCanvas *pCanvas, const ::cairo::SurfaceSharedPtr &pSurface, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState, const css::geometry::IntegerSize2D &rSize, bool bModulateColors, bool bHasAlpha)
void init(const ::basegfx::B2ISize &rSizePixel, SurfaceProvider &rSurfaceProvider, css::rendering::XGraphicDevice *pDevice)
Initialize canvas helper.
bool repaint(const ::cairo::SurfaceSharedPtr &pSurface, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState)
css::geometry::IntegerSize2D getSize() const
SurfaceProvider * mpSurfaceProvider
Surface provider.
css::uno::Reference< css::rendering::XCachedPrimitive > drawPolyPolygon(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XPolyPolygon2D > &xPolyPolygon, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState)
::basegfx::B2ISize maSize
css::rendering::XGraphicDevice * mpDevice
Phyical output device.
css::uno::Reference< css::rendering::XCachedPrimitive > drawBitmapModulated(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XBitmap > &xBitmap, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState)
void drawBezier(const css::rendering::XCanvas *pCanvas, const css::geometry::RealBezierSegment2D &aBezierSegment, const css::geometry::RealPoint2D &aEndPoint, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState)
css::uno::Sequence< sal_Int8 > getData(css::rendering::IntegerBitmapLayout &bitmapLayout, const css::geometry::IntegerRectangle2D &rect)
css::uno::Sequence< sal_Int8 > getPixel(css::rendering::IntegerBitmapLayout &bitmapLayout, const css::geometry::IntegerPoint2D &pos)
VclPtr< VirtualDevice > mpVirtualDevice
css::uno::Reference< css::rendering::XCachedPrimitive > strokeTexturedPolyPolygon(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XPolyPolygon2D > &xPolyPolygon, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState, const css::uno::Sequence< css::rendering::Texture > &textures, const css::rendering::StrokeAttributes &strokeAttributes)
bool mbHaveAlpha
When true, content is able to represent alpha.
css::uno::Reference< css::rendering::XCachedPrimitive > drawBitmap(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XBitmap > &xBitmap, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState)
css::uno::Reference< css::rendering::XCachedPrimitive > fillTextureMappedPolyPolygon(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XPolyPolygon2D > &xPolyPolygon, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState, const css::uno::Sequence< css::rendering::Texture > &textures, const css::uno::Reference< css::geometry::XMapping2D > &xMapping)
void setSize(const ::basegfx::B2ISize &rSize)
css::uno::Reference< css::rendering::XPolyPolygon2D > queryStrokeShapes(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XPolyPolygon2D > &xPolyPolygon, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState, const css::rendering::StrokeAttributes &strokeAttributes)
css::rendering::IntegerBitmapLayout getMemoryLayout()
css::uno::Reference< css::rendering::XCachedPrimitive > strokePolyPolygon(const css::rendering::XCanvas *pCanvas, const css::uno::Reference< css::rendering::XPolyPolygon2D > &xPolyPolygon, const css::rendering::ViewState &viewState, const css::rendering::RenderState &renderState, const css::rendering::StrokeAttributes &strokeAttributes)
void setSurface(const ::cairo::SurfaceSharedPtr &pSurface, bool bHasAlpha)
Values getValues() const
Query all defining values of this object atomically.
#define ENSURE_ARG_OR_THROW2(c, m, ifc, arg)
#define ENSURE_OR_THROW(c, m)
#define ENSURE_ARG_OR_THROW(c, m)
sal::systools::COMReference< IDirect3DDevice9 > mpDevice
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
ValueType lerp(const ValueType &rFrom, const ValueType &rTo, double t)
B2IRange fround(const B2DRange &rRange)
std::shared_ptr< Surface > SurfaceSharedPtr
std::shared_ptr< cairo_t > CairoSharedPtr
std::shared_ptr< cairo_surface_t > CairoSurfaceSharedPtr
::BitmapEx bitmapExFromXBitmap(const uno::Reference< rendering::XBitmap > &xBitmap)
void doPolyPolygonImplementation(const ::basegfx::B2DPolyPolygon &aPolyPolygon, Operation aOperation, cairo_t *pCairo, const uno::Sequence< rendering::Texture > *pTextures, const SurfaceProviderRef &pDevice, rendering::FillRule eFillrule)
static void addColorStops(cairo_pattern_t *pPattern, const uno::Sequence< uno::Sequence< double > > &rColors, const uno::Sequence< double > &rStops, bool bReverseStops)
static void doOperation(Operation aOperation, cairo_t *pCairo, const uno::Sequence< rendering::Texture > *pTextures, const SurfaceProviderRef &pDevice, const basegfx::B2DRange &rBounds)
static SurfaceSharedPtr surfaceFromXBitmap(const uno::Reference< rendering::XBitmap > &xBitmap)
surfaceFromXBitmap Create a surface from XBitmap
static void setColor(cairo_t *pCairo, const uno::Sequence< double > &rColor)
static cairo_pattern_t * patternFromParametricPolyPolygon(::canvas::ParametricPolyPolygon const &rPolygon)
constexpr OUStringLiteral PARAMETRICPOLYPOLYGON_IMPLEMENTATION_NAME
class SAL_LOPLUGIN_ANNOTATE("crosscast") SurfaceProvider typedef ::rtl::Reference< SurfaceProvider > SurfaceProviderRef
Target interface for XCachedPrimitive implementations.
static uno::Sequence< double > lerp(const uno::Sequence< double > &rLeft, const uno::Sequence< double > &rRight, double fAlpha)
static void clipNULL(cairo_t *pCairo)
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
constexpr double alpha[nDetails]
void CanvasCairoExtractBitmapData(BitmapEx const &aBmpEx, Bitmap &aBitmap, unsigned char *&data, bool &bHasAlpha, tools::Long &rnWidth, tools::Long &rnHeight)
bool getType(BSTR name, Type &type)
const css::uno::Sequence< css::uno::Sequence< double > > maColors
Gradient colors.
const GradientType meType
Type of gradient to render (as e.g. linear grads are not represented by maGradientPoly)
const css::uno::Sequence< double > maStops
Gradient color stops.