LibreOffice Module canvas (master) 1
dx_impltools.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 <sal/config.h>
21
22#include <algorithm>
23#include <memory>
24#include <vector>
25
26
34#include <com/sun/star/geometry/IntegerRectangle2D.hpp>
35#include <com/sun/star/geometry/RealPoint2D.hpp>
36#include <com/sun/star/lang/XServiceInfo.hpp>
37#include <com/sun/star/lang/XUnoTunnel.hpp>
38#include <tools/diagnose_ex.h>
39
41#include <verifyinput.hxx>
42
43#include "dx_canvas.hxx"
44#include "dx_canvasbitmap.hxx"
45#include "dx_canvasfont.hxx"
46#include "dx_impltools.hxx"
48#include "dx_spritecanvas.hxx"
49#include "dx_vcltools.hxx"
50
51
52using namespace ::com::sun::star;
53
54
56{
57 ::basegfx::B2DPolyPolygon polyPolygonFromXPolyPolygon2D( const uno::Reference< rendering::XPolyPolygon2D >& xPoly )
58 {
59 LinePolyPolygon* pPolyImpl = dynamic_cast< LinePolyPolygon* >( xPoly.get() );
60
61 if( pPolyImpl )
62 {
63 return pPolyImpl->getPolyPolygon();
64 }
65 else
66 {
67 const sal_Int32 nPolys( xPoly->getNumberOfPolygons() );
68
69 // not a known implementation object - try data source
70 // interfaces
71 uno::Reference< rendering::XBezierPolyPolygon2D > xBezierPoly(
72 xPoly,
73 uno::UNO_QUERY );
74
75 if( xBezierPoly.is() )
76 {
77 return ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence(
78 xBezierPoly->getBezierSegments( 0,
79 nPolys,
80 0,
81 -1 ) );
82 }
83 else
84 {
85 uno::Reference< rendering::XLinePolyPolygon2D > xLinePoly(
86 xPoly,
87 uno::UNO_QUERY );
88
89 // no implementation class and no data provider
90 // found - contract violation.
91 ENSURE_ARG_OR_THROW( xLinePoly.is(),
92 "VCLCanvas::polyPolygonFromXPolyPolygon2D(): Invalid input "
93 "poly-polygon, cannot retrieve vertex data" );
94
95 return ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence(
96 xLinePoly->getPoints( 0,
97 nPolys,
98 0,
99 -1 ) );
100 }
101 }
102 }
103
104 void setupGraphics( Gdiplus::Graphics& rGraphics )
105 {
106 // setup graphics with (somewhat arbitrary) defaults
107 //rGraphics.SetCompositingQuality( Gdiplus::CompositingQualityHighQuality );
108 rGraphics.SetCompositingQuality( Gdiplus::CompositingQualityHighSpeed );
109 //rGraphics.SetInterpolationMode( Gdiplus::InterpolationModeHighQualityBilinear ); // with prefiltering for shrinks
110 rGraphics.SetInterpolationMode( Gdiplus::InterpolationModeBilinear );
111
112 // #122683# Switched precedence of pixel offset
113 // mode. Seemingly, polygon stroking needs
114 // PixelOffsetModeNone to achieve visually pleasing
115 // results, whereas all other operations (e.g. polygon
116 // fills, bitmaps) look better with PixelOffsetModeHalf.
117 rGraphics.SetPixelOffsetMode( Gdiplus::PixelOffsetModeHalf ); // Pixel center at (0.5, 0.5) etc.
118 //rGraphics.SetPixelOffsetMode( Gdiplus::PixelOffsetModeNone );
119
120 //rGraphics.SetSmoothingMode( Gdiplus::SmoothingModeHighSpeed ); // no line/curve antialiasing
121 //rGraphics.SetSmoothingMode( Gdiplus::SmoothingModeHighQuality );
122 rGraphics.SetSmoothingMode( Gdiplus::SmoothingModeAntiAlias );
123 //rGraphics.SetTextRenderingHint( Gdiplus::TextRenderingHintAntiAlias );
124 rGraphics.SetTextRenderingHint( Gdiplus::TextRenderingHintSystemDefault );
125 rGraphics.SetPageUnit(Gdiplus::UnitPixel);
126 }
127
128 Gdiplus::Graphics* createGraphicsFromHDC(HDC aHDC)
129 {
130 Gdiplus::Graphics* pRet = new Gdiplus::Graphics(aHDC);
131 setupGraphics( *pRet );
132 return pRet;
133 }
134
136 {
137 GraphicsSharedPtr pRet(Gdiplus::Graphics::FromImage(rBitmap.get()));
138 if( pRet )
139 setupGraphics( *pRet );
140 return pRet;
141 }
142
143 void gdiPlusMatrixFromB2DHomMatrix( Gdiplus::Matrix& rGdiplusMatrix, const ::basegfx::B2DHomMatrix& rMatrix )
144 {
145 rGdiplusMatrix.SetElements( static_cast<Gdiplus::REAL>(rMatrix.get(0,0)),
146 static_cast<Gdiplus::REAL>(rMatrix.get(1,0)),
147 static_cast<Gdiplus::REAL>(rMatrix.get(0,1)),
148 static_cast<Gdiplus::REAL>(rMatrix.get(1,1)),
149 static_cast<Gdiplus::REAL>(rMatrix.get(0,2)),
150 static_cast<Gdiplus::REAL>(rMatrix.get(1,2)) );
151 }
152
153 void gdiPlusMatrixFromAffineMatrix2D( Gdiplus::Matrix& rGdiplusMatrix,
154 const geometry::AffineMatrix2D& rMatrix )
155 {
156 rGdiplusMatrix.SetElements( static_cast<Gdiplus::REAL>(rMatrix.m00),
157 static_cast<Gdiplus::REAL>(rMatrix.m10),
158 static_cast<Gdiplus::REAL>(rMatrix.m01),
159 static_cast<Gdiplus::REAL>(rMatrix.m11),
160 static_cast<Gdiplus::REAL>(rMatrix.m02),
161 static_cast<Gdiplus::REAL>(rMatrix.m12) );
162 }
163
164 namespace
165 {
166 // TODO(P2): Check whether this gets inlined. If not, make functor
167 // out of it
168 Gdiplus::PointF implGdiPlusPointFromRealPoint2D( const css::geometry::RealPoint2D& rPoint )
169 {
170 return Gdiplus::PointF( static_cast<Gdiplus::REAL>(rPoint.X),
171 static_cast<Gdiplus::REAL>(rPoint.Y) );
172 }
173
175 std::vector< Gdiplus::PointF >& rPoints,
176 const ::basegfx::B2DPolygon& rPoly,
177 bool bNoLineJoin)
178 {
179 const sal_uInt32 nPoints( rPoly.count() );
180
181 if( nPoints < 2 )
182 return;
183
184 rOutput->StartFigure();
185
186 const bool bClosedPolygon( rPoly.isClosed() );
187
188 if( rPoly.areControlPointsUsed() )
189 {
190 // control points used -> for now, add all
191 // segments as curves to GraphicsPath
192
193 // If the polygon is closed, we need to add the
194 // first point, thus, one more (can't simply
195 // GraphicsPath::CloseFigure() it, since the last
196 // point cannot have any control points for GDI+)
197 rPoints.resize( 3*nPoints + (bClosedPolygon ? 1 : 0) );
198
199 sal_uInt32 nCurrOutput=0;
200 for( sal_uInt32 nCurrPoint=0; nCurrPoint<nPoints; ++nCurrPoint )
201 {
202 const ::basegfx::B2DPoint& rPoint( rPoly.getB2DPoint( nCurrPoint ) );
203 rPoints[nCurrOutput++] = Gdiplus::PointF( static_cast<Gdiplus::REAL>(rPoint.getX()),
204 static_cast<Gdiplus::REAL>(rPoint.getY()) );
205
206 const ::basegfx::B2DPoint& rControlPointA( rPoly.getNextControlPoint( nCurrPoint ) );
207 rPoints[nCurrOutput++] = Gdiplus::PointF( static_cast<Gdiplus::REAL>(rControlPointA.getX()),
208 static_cast<Gdiplus::REAL>(rControlPointA.getY()) );
209
210 const ::basegfx::B2DPoint& rControlPointB( rPoly.getPrevControlPoint( (nCurrPoint + 1) % nPoints) );
211 rPoints[nCurrOutput++] = Gdiplus::PointF( static_cast<Gdiplus::REAL>(rControlPointB.getX()),
212 static_cast<Gdiplus::REAL>(rControlPointB.getY()) );
213 }
214
215 if( bClosedPolygon )
216 {
217 // add first point again (to be able to pass
218 // control points for the last point, see
219 // above)
220 const ::basegfx::B2DPoint& rPoint( rPoly.getB2DPoint(0) );
221 rPoints[nCurrOutput++] = Gdiplus::PointF( static_cast<Gdiplus::REAL>(rPoint.getX()),
222 static_cast<Gdiplus::REAL>(rPoint.getY()) );
223
224 if(bNoLineJoin && nCurrOutput > 7)
225 {
226 for(sal_uInt32 a(3); a < nCurrOutput; a+=3)
227 {
228 rOutput->StartFigure();
229 rOutput->AddBezier(rPoints[a - 3], rPoints[a - 2], rPoints[a - 1], rPoints[a]);
230 }
231 }
232 else
233 {
234 rOutput->AddBeziers( rPoints.data(), nCurrOutput );
235 }
236 }
237 else
238 {
239 // GraphicsPath expects 3(n-1)+1 points (i.e. the
240 // last point must not have any trailing control
241 // points after it).
242 // Therefore, simply don't pass the last two
243 // points here.
244 if( nCurrOutput > 3 )
245 {
246 if(bNoLineJoin && nCurrOutput > 7)
247 {
248 for(sal_uInt32 a(3); a < nCurrOutput; a+=3)
249 {
250 rOutput->StartFigure();
251 rOutput->AddBezier(rPoints[a - 3], rPoints[a - 2], rPoints[a - 1], rPoints[a]);
252 }
253 }
254 else
255 {
256 rOutput->AddBeziers( rPoints.data(), nCurrOutput-2 );
257 }
258 }
259 }
260 }
261 else
262 {
263 // no control points -> no curves, simply add
264 // straight lines to GraphicsPath
265 rPoints.resize( nPoints );
266
267 for( sal_uInt32 nCurrPoint=0; nCurrPoint<nPoints; ++nCurrPoint )
268 {
269 const ::basegfx::B2DPoint& rPoint( rPoly.getB2DPoint( nCurrPoint ) );
270 rPoints[nCurrPoint] = Gdiplus::PointF( static_cast<Gdiplus::REAL>(rPoint.getX()),
271 static_cast<Gdiplus::REAL>(rPoint.getY()) );
272 }
273
274 if(bNoLineJoin && nPoints > 2)
275 {
276 for(sal_uInt32 a(1); a < nPoints; a++)
277 {
278 rOutput->StartFigure();
279 rOutput->AddLine(rPoints[a - 1], rPoints[a]);
280 }
281
282 if(bClosedPolygon)
283 {
284 rOutput->StartFigure();
285 rOutput->AddLine(rPoints[nPoints - 1], rPoints[0]);
286 }
287 }
288 else
289 {
290 rOutput->AddLines( rPoints.data(), nPoints );
291 }
292 }
293
294 if( bClosedPolygon && !bNoLineJoin )
295 rOutput->CloseFigure();
296 }
297 }
298
299 Gdiplus::Rect gdiPlusRectFromIntegerRectangle2D( const geometry::IntegerRectangle2D& rRect )
300 {
301 return Gdiplus::Rect( rRect.X1,
302 rRect.Y1,
303 rRect.X2 - rRect.X1,
304 rRect.Y2 - rRect.Y1 );
305 }
306
307 Gdiplus::RectF gdiPlusRectFFromRectangle2D( const geometry::RealRectangle2D& rRect )
308 {
309 return Gdiplus::RectF( static_cast<Gdiplus::REAL>(rRect.X1),
310 static_cast<Gdiplus::REAL>(rRect.Y1),
311 static_cast<Gdiplus::REAL>(rRect.X2 - rRect.X1),
312 static_cast<Gdiplus::REAL>(rRect.Y2 - rRect.Y1) );
313 }
314
315 RECT gdiRectFromB2IRect( const ::basegfx::B2IRange& rRect )
316 {
317 RECT aRect = {rRect.getMinX(),
318 rRect.getMinY(),
319 rRect.getMaxX(),
320 rRect.getMaxY()};
321
322 return aRect;
323 }
324
325 geometry::RealPoint2D realPoint2DFromGdiPlusPointF( const Gdiplus::PointF& rPoint )
326 {
327 return geometry::RealPoint2D( rPoint.X, rPoint.Y );
328 }
329
330 geometry::RealRectangle2D realRectangle2DFromGdiPlusRectF( const Gdiplus::RectF& rRect )
331 {
332 return geometry::RealRectangle2D( rRect.X, rRect.Y,
333 rRect.X + rRect.Width,
334 rRect.Y + rRect.Height );
335 }
336
337 ::basegfx::B2DPoint b2dPointFromGdiPlusPointF( const Gdiplus::PointF& rPoint )
338 {
339 return ::basegfx::B2DPoint( rPoint.X, rPoint.Y );
340 }
341
342 ::basegfx::B2DRange b2dRangeFromGdiPlusRectF( const Gdiplus::RectF& rRect )
343 {
344 return ::basegfx::B2DRange( rRect.X, rRect.Y,
345 rRect.X + rRect.Width,
346 rRect.Y + rRect.Height );
347 }
348
349 uno::Sequence< sal_Int8 > argbToIntSequence( Gdiplus::ARGB rColor )
350 {
351 // TODO(F1): handle color space conversions, when defined on canvas/graphicDevice
352 return
353 {
354 static_cast<sal_Int8>((rColor >> 16) & 0xFF), // red
355 static_cast<sal_Int8>((rColor >> 8) & 0xFF), // green
356 static_cast<sal_Int8>(rColor & 0xFF), // blue
357 static_cast<sal_Int8>((rColor >> 24) & 0xFF) // alpha
358 };
359 }
360
361 Gdiplus::ARGB sequenceToArgb( const uno::Sequence< sal_Int8 >& rColor )
362 {
363 ENSURE_OR_THROW( rColor.getLength() > 2,
364 "sequenceToArgb: need at least three channels" );
365
366 // TODO(F1): handle color space conversions, when defined on canvas/graphicDevice
367 Gdiplus::ARGB aColor;
368
369 aColor = (static_cast<sal_uInt8>(rColor[0]) << 16) | (static_cast<sal_uInt8>(rColor[1]) << 8) | static_cast<sal_uInt8>(rColor[2]);
370
371 if( rColor.getLength() > 3 )
372 aColor |= static_cast<sal_uInt8>(rColor[3]) << 24;
373
374 return aColor;
375 }
376
377 Gdiplus::ARGB sequenceToArgb( const uno::Sequence< double >& rColor )
378 {
379 ENSURE_OR_THROW( rColor.getLength() > 2,
380 "sequenceToColor: need at least three channels" );
381
382 // TODO(F1): handle color space conversions, when defined on canvas/graphicDevice
383 Gdiplus::ARGB aColor;
384
385 ::canvas::tools::verifyRange(rColor[0],0.0,1.0);
386 ::canvas::tools::verifyRange(rColor[1],0.0,1.0);
387 ::canvas::tools::verifyRange(rColor[2],0.0,1.0);
388
389 aColor =
390 (static_cast<sal_uInt8>( ::basegfx::fround( 255*rColor[0] ) ) << 16) |
391 (static_cast<sal_uInt8>( ::basegfx::fround( 255*rColor[1] ) ) << 8) |
392 static_cast<sal_uInt8>( ::basegfx::fround( 255*rColor[2] ) );
393
394 if( rColor.getLength() > 3 )
395 {
396 ::canvas::tools::verifyRange(rColor[3],0.0,1.0);
397 aColor |= static_cast<sal_uInt8>( ::basegfx::fround( 255*rColor[3] ) ) << 24;
398 }
399
400 return aColor;
401 }
402
403 GraphicsPathSharedPtr graphicsPathFromRealPoint2DSequence( const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >& points )
404 {
405 GraphicsPathSharedPtr pRes = std::make_shared<Gdiplus::GraphicsPath>();
406 std::vector< Gdiplus::PointF > aPoints;
407
408 for( uno::Sequence< geometry::RealPoint2D > const & seqPoints : points )
409 {
410 const sal_Int32 nCurrSize( seqPoints.getLength() );
411 if( nCurrSize )
412 {
413 aPoints.resize( nCurrSize );
414
415 // TODO(F1): Closed/open polygons
416
417 // convert from RealPoint2D array to Gdiplus::PointF array
418 std::transform( seqPoints.getConstArray(),
419 seqPoints.getConstArray()+nCurrSize,
420 aPoints.begin(),
421 implGdiPlusPointFromRealPoint2D );
422
423 pRes->AddLines( aPoints.data(), nCurrSize );
424 }
425 }
426
427 return pRes;
428 }
429
430 GraphicsPathSharedPtr graphicsPathFromB2DPolygon( const ::basegfx::B2DPolygon& rPoly, bool bNoLineJoin )
431 {
432 GraphicsPathSharedPtr pRes = std::make_shared<Gdiplus::GraphicsPath>();
433 std::vector< Gdiplus::PointF > aPoints;
434
435 graphicsPathFromB2DPolygon( pRes, aPoints, rPoly, bNoLineJoin );
436
437 return pRes;
438 }
439
440 GraphicsPathSharedPtr graphicsPathFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly, bool bNoLineJoin )
441 {
442 GraphicsPathSharedPtr pRes = std::make_shared<Gdiplus::GraphicsPath>();
443 std::vector< Gdiplus::PointF > aPoints;
444
445 const sal_uInt32 nPolies( rPoly.count() );
446 for( sal_uInt32 nCurrPoly=0; nCurrPoly<nPolies; ++nCurrPoly )
447 {
449 aPoints,
450 rPoly.getB2DPolygon( nCurrPoly ),
451 bNoLineJoin);
452 }
453
454 return pRes;
455 }
456
457 GraphicsPathSharedPtr graphicsPathFromXPolyPolygon2D( const uno::Reference< rendering::XPolyPolygon2D >& xPoly, bool bNoLineJoin )
458 {
459 LinePolyPolygon* pPolyImpl = dynamic_cast< LinePolyPolygon* >( xPoly.get() );
460
461 if( pPolyImpl )
462 {
463 return pPolyImpl->getGraphicsPath( bNoLineJoin );
464 }
465 else
466 {
468 polyPolygonFromXPolyPolygon2D( xPoly ), bNoLineJoin );
469 }
470 }
471
472 bool drawGdiPlusBitmap( const GraphicsSharedPtr& rGraphics,
473 const BitmapSharedPtr& rBitmap )
474 {
475 Gdiplus::PointF aPoint;
476 return (Gdiplus::Ok == rGraphics->DrawImage( rBitmap.get(),
477 aPoint ) );
478 }
479
480 bool drawDIBits( const std::shared_ptr<Gdiplus::Graphics>& rGraphics,
481 const BITMAPINFO& rBI,
482 const void* pBits )
483 {
484 BitmapSharedPtr pBitmap(
485 Gdiplus::Bitmap::FromBITMAPINFO( &rBI,
486 const_cast<void*>(pBits) ) );
487
488 return drawGdiPlusBitmap( rGraphics,
489 pBitmap );
490 }
491
492 bool drawRGBABits( const std::shared_ptr<Gdiplus::Graphics>& rGraphics,
493 const RawRGBABitmap& rRawRGBAData )
494 {
495 BitmapSharedPtr pBitmap = std::make_shared<Gdiplus::Bitmap>( rRawRGBAData.mnWidth,
496 rRawRGBAData.mnHeight,
497 PixelFormat32bppARGB );
498
499 Gdiplus::BitmapData aBmpData;
500 aBmpData.Width = rRawRGBAData.mnWidth;
501 aBmpData.Height = rRawRGBAData.mnHeight;
502 aBmpData.Stride = 4*aBmpData.Width; // bottom-up format
503 aBmpData.PixelFormat = PixelFormat32bppARGB;
504 aBmpData.Scan0 = const_cast<sal_uInt8*>(rRawRGBAData.maBitmapData.data());
505
506 const Gdiplus::Rect aRect( 0,0,aBmpData.Width,aBmpData.Height );
507 if( Gdiplus::Ok != pBitmap->LockBits( &aRect,
508 Gdiplus::ImageLockModeWrite | Gdiplus::ImageLockModeUserInputBuf,
509 PixelFormat32bppARGB,
510 &aBmpData ) )
511 {
512 return false;
513 }
514
515 // commit data to bitmap
516 pBitmap->UnlockBits( &aBmpData );
517
518 return drawGdiPlusBitmap( rGraphics,
519 pBitmap );
520 }
521
522 BitmapSharedPtr bitmapFromXBitmap( const uno::Reference< rendering::XBitmap >& xBitmap )
523 {
524 BitmapProvider* pBitmapProvider = dynamic_cast< BitmapProvider* >(xBitmap.get());
525
526 if( pBitmapProvider )
527 {
528 IBitmapSharedPtr pBitmap( pBitmapProvider->getBitmap() );
529 return pBitmap->getBitmap();
530 }
531 else
532 {
533 // not a native CanvasBitmap, extract VCL bitmap and
534 // render into GDI+ bitmap of similar size
535 // =================================================
536
537 const geometry::IntegerSize2D aBmpSize( xBitmap->getSize() );
538 BitmapSharedPtr pBitmap;
539
540 if( xBitmap->hasAlpha() )
541 {
542 // TODO(P2): At least for the alpha bitmap case, it
543 // would be possible to generate the corresponding
544 // bitmap directly
545 pBitmap = std::make_shared<Gdiplus::Bitmap>( aBmpSize.Width,
546 aBmpSize.Height,
547 PixelFormat32bppARGB );
548 }
549 else
550 {
551 // TODO(F2): Might be wise to create bitmap compatible
552 // to the VCL bitmap. Also, check whether the VCL
553 // bitmap's system handles can be used to create the
554 // GDI+ bitmap (currently, it does not seem so).
555 pBitmap = std::make_shared<Gdiplus::Bitmap>( aBmpSize.Width,
556 aBmpSize.Height,
557 PixelFormat24bppRGB );
558 }
559
561 tools::setupGraphics(*pGraphics);
563 pGraphics,
564 xBitmap) )
565 {
566 pBitmap.reset();
567 }
568
569 return pBitmap;
570 }
571 }
572
573 CanvasFont::ImplRef canvasFontFromXFont( const uno::Reference< rendering::XCanvasFont >& xFont )
574 {
575 CanvasFont* pCanvasFont = dynamic_cast< CanvasFont* >(xFont.get());
576
577 ENSURE_ARG_OR_THROW( pCanvasFont,
578 "canvasFontFromXFont(): Invalid XFont (or incompatible font for this XCanvas)" );
579
580 return CanvasFont::ImplRef( pCanvasFont );
581 }
582
583 void setModulateImageAttributes( Gdiplus::ImageAttributes& o_rAttr,
584 double nRedModulation,
585 double nGreenModulation,
586 double nBlueModulation,
587 double nAlphaModulation )
588 {
589 // This gets rather verbose, but we have to setup a color
590 // transformation matrix, in order to incorporate the global
591 // alpha value mfAlpha into the bitmap rendering.
592 Gdiplus::ColorMatrix aColorMatrix;
593
594 aColorMatrix.m[0][0] = static_cast<Gdiplus::REAL>(nRedModulation);
595 aColorMatrix.m[0][1] = 0.0;
596 aColorMatrix.m[0][2] = 0.0;
597 aColorMatrix.m[0][3] = 0.0;
598 aColorMatrix.m[0][4] = 0.0;
599
600 aColorMatrix.m[1][0] = 0.0;
601 aColorMatrix.m[1][1] = static_cast<Gdiplus::REAL>(nGreenModulation);
602 aColorMatrix.m[1][2] = 0.0;
603 aColorMatrix.m[1][3] = 0.0;
604 aColorMatrix.m[1][4] = 0.0;
605
606 aColorMatrix.m[2][0] = 0.0;
607 aColorMatrix.m[2][1] = 0.0;
608 aColorMatrix.m[2][2] = static_cast<Gdiplus::REAL>(nBlueModulation);
609 aColorMatrix.m[2][3] = 0.0;
610 aColorMatrix.m[2][4] = 0.0;
611
612 aColorMatrix.m[3][0] = 0.0;
613 aColorMatrix.m[3][1] = 0.0;
614 aColorMatrix.m[3][2] = 0.0;
615 aColorMatrix.m[3][3] = static_cast<Gdiplus::REAL>(nAlphaModulation);
616 aColorMatrix.m[3][4] = 0.0;
617
618 aColorMatrix.m[4][0] = 0.0;
619 aColorMatrix.m[4][1] = 0.0;
620 aColorMatrix.m[4][2] = 0.0;
621 aColorMatrix.m[4][3] = 0.0;
622 aColorMatrix.m[4][4] = 1.0;
623
624 o_rAttr.SetColorMatrix( &aColorMatrix );
625 }
626
627} // namespace dxcanvas::tools
628
629/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SAL_DLLPRIVATE B2DPolyPolygon getPolyPolygon() const
rtl::Reference< CanvasFont > ImplRef
GraphicsPathSharedPtr getGraphicsPath(bool bNoLineJoin=false) const
#define ENSURE_OR_THROW(c, m)
#define ENSURE_ARG_OR_THROW(c, m)
Gdiplus::BitmapData aBmpData
uno_Any a
void verifyRange(NumType arg, NumType lowerBound, NumType upperBound)
Range checker, which throws css::lang::IllegalArgument exception, when range is violated.
geometry::RealRectangle2D realRectangle2DFromGdiPlusRectF(const Gdiplus::RectF &rRect)
GraphicsSharedPtr createGraphicsFromBitmap(const BitmapSharedPtr &rBitmap)
RECT gdiRectFromB2IRect(const ::basegfx::B2IRange &rRect)
void setupGraphics(Gdiplus::Graphics &rGraphics)
bool drawDIBits(const std::shared_ptr< Gdiplus::Graphics > &rGraphics, const BITMAPINFO &rBI, const void *pBits)
GraphicsPathSharedPtr graphicsPathFromXPolyPolygon2D(const uno::Reference< rendering::XPolyPolygon2D > &xPoly, bool bNoLineJoin)
bool drawVCLBitmapFromXBitmap(const std::shared_ptr< Gdiplus::Graphics > &rGraphics, const uno::Reference< rendering::XBitmap > &xBitmap)
GraphicsPathSharedPtr graphicsPathFromB2DPolyPolygon(const ::basegfx::B2DPolyPolygon &rPoly, bool bNoLineJoin)
CanvasFont::ImplRef canvasFontFromXFont(const uno::Reference< rendering::XCanvasFont > &xFont)
BitmapSharedPtr bitmapFromXBitmap(const uno::Reference< rendering::XBitmap > &xBitmap)
::basegfx::B2DRange b2dRangeFromGdiPlusRectF(const Gdiplus::RectF &rRect)
geometry::RealPoint2D realPoint2DFromGdiPlusPointF(const Gdiplus::PointF &rPoint)
Gdiplus::RectF gdiPlusRectFFromRectangle2D(const geometry::RealRectangle2D &rRect)
GraphicsPathSharedPtr graphicsPathFromRealPoint2DSequence(const uno::Sequence< uno::Sequence< geometry::RealPoint2D > > &points)
Gdiplus::Rect gdiPlusRectFromIntegerRectangle2D(const geometry::IntegerRectangle2D &rRect)
uno::Sequence< sal_Int8 > argbToIntSequence(Gdiplus::ARGB rColor)
void gdiPlusMatrixFromB2DHomMatrix(Gdiplus::Matrix &rGdiplusMatrix, const ::basegfx::B2DHomMatrix &rMatrix)
::basegfx::B2DPolyPolygon polyPolygonFromXPolyPolygon2D(const uno::Reference< rendering::XPolyPolygon2D > &xPoly)
bool drawRGBABits(const std::shared_ptr< Gdiplus::Graphics > &rGraphics, const RawRGBABitmap &rRawRGBAData)
GraphicsPathSharedPtr graphicsPathFromB2DPolygon(const ::basegfx::B2DPolygon &rPoly, bool bNoLineJoin)
Gdiplus::ARGB sequenceToArgb(const uno::Sequence< sal_Int8 > &rColor)
::basegfx::B2DPoint b2dPointFromGdiPlusPointF(const Gdiplus::PointF &rPoint)
void setModulateImageAttributes(Gdiplus::ImageAttributes &o_rAttr, double nRedModulation, double nGreenModulation, double nBlueModulation, double nAlphaModulation)
bool drawGdiPlusBitmap(const GraphicsSharedPtr &rGraphics, const BitmapSharedPtr &rBitmap)
void gdiPlusMatrixFromAffineMatrix2D(Gdiplus::Matrix &rGdiplusMatrix, const geometry::AffineMatrix2D &rMatrix)
Gdiplus::Graphics * createGraphicsFromHDC(HDC aHDC)
std::shared_ptr< Gdiplus::Graphics > GraphicsSharedPtr
Definition: dx_winstuff.hxx:58
std::shared_ptr< IBitmap > IBitmapSharedPtr
Definition: dx_ibitmap.hxx:58
std::shared_ptr< Gdiplus::GraphicsPath > GraphicsPathSharedPtr
Definition: dx_winstuff.hxx:59
std::shared_ptr< Gdiplus::Bitmap > BitmapSharedPtr
Definition: dx_winstuff.hxx:60
virtual IBitmapSharedPtr getBitmap() const =0
Raw RGBA bitmap data, contiguous in memory.
Definition: dx_vcltools.hxx:35
std::vector< sal_uInt8 > maBitmapData
Definition: dx_vcltools.hxx:38
unsigned char sal_uInt8
signed char sal_Int8