LibreOffice Module canvas (master) 1
canvastools.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <limits>
23
36#include <com/sun/star/awt/Rectangle.hpp>
37#include <com/sun/star/awt/XWindow2.hpp>
38#include <com/sun/star/beans/XPropertySet.hpp>
39#include <com/sun/star/geometry/AffineMatrix2D.hpp>
40#include <com/sun/star/geometry/Matrix2D.hpp>
41#include <com/sun/star/lang/XServiceInfo.hpp>
42#include <com/sun/star/rendering/ColorComponentTag.hpp>
43#include <com/sun/star/rendering/ColorSpaceType.hpp>
44#include <com/sun/star/rendering/CompositeOperation.hpp>
45#include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
46#include <com/sun/star/rendering/RenderState.hpp>
47#include <com/sun/star/rendering/RenderingIntent.hpp>
48#include <com/sun/star/rendering/ViewState.hpp>
49#include <com/sun/star/rendering/XCanvas.hpp>
50#include <com/sun/star/rendering/XColorSpace.hpp>
51#include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp>
52#include <com/sun/star/util/Endianness.hpp>
54#include <sal/log.hxx>
56#include <tools/diagnose_ex.h>
57#include <vcl/canvastools.hxx>
58#include <vcl/window.hxx>
59
61
62
63using namespace ::com::sun::star;
64
65namespace canvas::tools
66{
67 geometry::RealSize2D createInfiniteSize2D()
68 {
69 return geometry::RealSize2D(
70 std::numeric_limits<double>::infinity(),
71 std::numeric_limits<double>::infinity() );
72 }
73
74 rendering::RenderState& initRenderState( rendering::RenderState& renderState )
75 {
76 // setup identity transform
77 setIdentityAffineMatrix2D( renderState.AffineTransform );
78 renderState.Clip.clear();
79 renderState.DeviceColor = uno::Sequence< double >();
80 renderState.CompositeOperation = rendering::CompositeOperation::OVER;
81
82 return renderState;
83 }
84
85 rendering::ViewState& initViewState( rendering::ViewState& viewState )
86 {
87 // setup identity transform
88 setIdentityAffineMatrix2D( viewState.AffineTransform );
89 viewState.Clip.clear();
90
91 return viewState;
92 }
93
95 const rendering::ViewState& viewState )
96 {
97 return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, viewState.AffineTransform );
98 }
99
100 rendering::ViewState& setViewStateTransform( rendering::ViewState& viewState,
101 const ::basegfx::B2DHomMatrix& transform )
102 {
103 ::basegfx::unotools::affineMatrixFromHomMatrix( viewState.AffineTransform, transform );
104
105 return viewState;
106 }
107
109 const rendering::RenderState& renderState )
110 {
111 return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, renderState.AffineTransform );
112 }
113
114 rendering::RenderState& setRenderStateTransform( rendering::RenderState& renderState,
115 const ::basegfx::B2DHomMatrix& transform )
116 {
117 ::basegfx::unotools::affineMatrixFromHomMatrix( renderState.AffineTransform, transform );
118
119 return renderState;
120 }
121
122 rendering::RenderState& appendToRenderState( rendering::RenderState& renderState,
123 const ::basegfx::B2DHomMatrix& rTransform )
124 {
125 ::basegfx::B2DHomMatrix transform;
126
127 getRenderStateTransform( transform, renderState );
128 return setRenderStateTransform( renderState, transform * rTransform );
129 }
130
131 rendering::RenderState& prependToRenderState( rendering::RenderState& renderState,
132 const ::basegfx::B2DHomMatrix& rTransform )
133 {
134 ::basegfx::B2DHomMatrix transform;
135
136 getRenderStateTransform( transform, renderState );
137 return setRenderStateTransform( renderState, rTransform * transform );
138 }
139
141 const rendering::ViewState& viewState,
142 const rendering::RenderState& renderState )
143 {
144 ::basegfx::B2DHomMatrix viewTransform;
145
146 ::basegfx::unotools::homMatrixFromAffineMatrix( combinedTransform, renderState.AffineTransform );
147 ::basegfx::unotools::homMatrixFromAffineMatrix( viewTransform, viewState.AffineTransform );
148
149 // this statement performs combinedTransform = viewTransform * combinedTransform
150 combinedTransform *= viewTransform;
151
152 return combinedTransform;
153 }
154
155 geometry::AffineMatrix2D& setIdentityAffineMatrix2D( geometry::AffineMatrix2D& matrix )
156 {
157 matrix.m00 = 1.0;
158 matrix.m01 = 0.0;
159 matrix.m02 = 0.0;
160 matrix.m10 = 0.0;
161 matrix.m11 = 1.0;
162 matrix.m12 = 0.0;
163
164 return matrix;
165 }
166
167 geometry::Matrix2D& setIdentityMatrix2D( geometry::Matrix2D& matrix )
168 {
169 matrix.m00 = 1.0;
170 matrix.m01 = 0.0;
171 matrix.m10 = 0.0;
172 matrix.m11 = 1.0;
173
174 return matrix;
175 }
176
177 namespace
178 {
179 class StandardColorSpace : public cppu::WeakImplHelper< css::rendering::XIntegerBitmapColorSpace >
180 {
181 private:
182 uno::Sequence< sal_Int8 > maComponentTags;
183 uno::Sequence< sal_Int32 > maBitCounts;
184
185 virtual ::sal_Int8 SAL_CALL getType( ) override
186 {
187 return rendering::ColorSpaceType::RGB;
188 }
189 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) override
190 {
191 return maComponentTags;
192 }
193 virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) override
194 {
195 return rendering::RenderingIntent::PERCEPTUAL;
196 }
197 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) override
198 {
199 return uno::Sequence< beans::PropertyValue >();
200 }
201 virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
202 const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
203 {
204 // TODO(P3): if we know anything about target
205 // colorspace, this can be greatly sped up
206 uno::Sequence<rendering::ARGBColor> aIntermediate(
207 convertToARGB(deviceColor));
208 return targetColorSpace->convertFromARGB(aIntermediate);
209 }
210 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) override
211 {
212 const double* pIn( deviceColor.getConstArray() );
213 const std::size_t nLen( deviceColor.getLength() );
214 ENSURE_ARG_OR_THROW2(nLen%4==0,
215 "number of channels no multiple of 4",
216 static_cast<rendering::XColorSpace*>(this), 0);
217
218 uno::Sequence< rendering::RGBColor > aRes(nLen/4);
219 rendering::RGBColor* pOut( aRes.getArray() );
220 for( std::size_t i=0; i<nLen; i+=4 )
221 {
222 *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
223 pIn += 4;
224 }
225 return aRes;
226 }
227 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) override
228 {
229 SAL_WARN_IF(!deviceColor.hasElements(), "canvas", "empty deviceColor argument");
230 const double* pIn( deviceColor.getConstArray() );
231 const std::size_t nLen( deviceColor.getLength() );
232 ENSURE_ARG_OR_THROW2(nLen%4==0,
233 "number of channels no multiple of 4",
234 static_cast<rendering::XColorSpace*>(this), 0);
235
236 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
237 rendering::ARGBColor* pOut( aRes.getArray() );
238 for( std::size_t i=0; i<nLen; i+=4 )
239 {
240 *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
241 pIn += 4;
242 }
243 return aRes;
244 }
245 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) override
246 {
247 const double* pIn( deviceColor.getConstArray() );
248 const std::size_t nLen( deviceColor.getLength() );
249 ENSURE_ARG_OR_THROW2(nLen%4==0,
250 "number of channels no multiple of 4",
251 static_cast<rendering::XColorSpace*>(this), 0);
252
253 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
254 rendering::ARGBColor* pOut( aRes.getArray() );
255 for( std::size_t i=0; i<nLen; i+=4 )
256 {
257 *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
258 pIn += 4;
259 }
260 return aRes;
261 }
262 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
263 {
264 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
265 const std::size_t nLen( rgbColor.getLength() );
266
267 uno::Sequence< double > aRes(nLen*4);
268 double* pColors=aRes.getArray();
269 for( std::size_t i=0; i<nLen; ++i )
270 {
271 *pColors++ = pIn->Red;
272 *pColors++ = pIn->Green;
273 *pColors++ = pIn->Blue;
274 *pColors++ = 1.0;
275 ++pIn;
276 }
277 return aRes;
278 }
279 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
280 {
281 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
282 const std::size_t nLen( rgbColor.getLength() );
283
284 uno::Sequence< double > aRes(nLen*4);
285 double* pColors=aRes.getArray();
286 for( std::size_t i=0; i<nLen; ++i )
287 {
288 *pColors++ = pIn->Red;
289 *pColors++ = pIn->Green;
290 *pColors++ = pIn->Blue;
291 *pColors++ = pIn->Alpha;
292 ++pIn;
293 }
294 return aRes;
295 }
296 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
297 {
298 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
299 const std::size_t nLen( rgbColor.getLength() );
300
301 uno::Sequence< double > aRes(nLen*4);
302 double* pColors=aRes.getArray();
303 for( std::size_t i=0; i<nLen; ++i )
304 {
305 *pColors++ = pIn->Red/pIn->Alpha;
306 *pColors++ = pIn->Green/pIn->Alpha;
307 *pColors++ = pIn->Blue/pIn->Alpha;
308 *pColors++ = pIn->Alpha;
309 ++pIn;
310 }
311 return aRes;
312 }
313
314 // XIntegerBitmapColorSpace
315 virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) override
316 {
317 return 32;
318 }
319 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) override
320 {
321 return maBitCounts;
322 }
323 virtual ::sal_Int8 SAL_CALL getEndianness( ) override
324 {
325 return util::Endianness::LITTLE;
326 }
327 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
328 const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
329 {
330 if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
331 {
332 const sal_Int8* pIn( deviceColor.getConstArray() );
333 const std::size_t nLen( deviceColor.getLength() );
334 ENSURE_ARG_OR_THROW2(nLen%4==0,
335 "number of channels no multiple of 4",
336 static_cast<rendering::XColorSpace*>(this), 0);
337
338 uno::Sequence<double> aRes(nLen);
339 double* pOut( aRes.getArray() );
340 for( std::size_t i=0; i<nLen; i+=4 )
341 {
346 }
347 return aRes;
348 }
349 else
350 {
351 // TODO(P3): if we know anything about target
352 // colorspace, this can be greatly sped up
353 uno::Sequence<rendering::ARGBColor> aIntermediate(
354 convertIntegerToARGB(deviceColor));
355 return targetColorSpace->convertFromARGB(aIntermediate);
356 }
357 }
358 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
359 const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) override
360 {
361 if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
362 {
363 // it's us, so simply pass-through the data
364 return deviceColor;
365 }
366 else
367 {
368 // TODO(P3): if we know anything about target
369 // colorspace, this can be greatly sped up
370 uno::Sequence<rendering::ARGBColor> aIntermediate(
371 convertIntegerToARGB(deviceColor));
372 return targetColorSpace->convertIntegerFromARGB(aIntermediate);
373 }
374 }
375 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
376 {
377 const sal_Int8* pIn( deviceColor.getConstArray() );
378 const std::size_t nLen( deviceColor.getLength() );
379 ENSURE_ARG_OR_THROW2(nLen%4==0,
380 "number of channels no multiple of 4",
381 static_cast<rendering::XColorSpace*>(this), 0);
382
383 uno::Sequence< rendering::RGBColor > aRes(nLen/4);
384 rendering::RGBColor* pOut( aRes.getArray() );
385 for( std::size_t i=0; i<nLen; i+=4 )
386 {
387 *pOut++ = rendering::RGBColor(
391 pIn += 4;
392 }
393 return aRes;
394 }
395
396 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
397 {
398 const sal_Int8* pIn( deviceColor.getConstArray() );
399 const std::size_t nLen( deviceColor.getLength() );
400 ENSURE_ARG_OR_THROW2(nLen%4==0,
401 "number of channels no multiple of 4",
402 static_cast<rendering::XColorSpace*>(this), 0);
403
404 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
405 rendering::ARGBColor* pOut( aRes.getArray() );
406 for( std::size_t i=0; i<nLen; i+=4 )
407 {
408 *pOut++ = rendering::ARGBColor(
413 pIn += 4;
414 }
415 return aRes;
416 }
417
418 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
419 {
420 const sal_Int8* pIn( deviceColor.getConstArray() );
421 const std::size_t nLen( deviceColor.getLength() );
422 ENSURE_ARG_OR_THROW2(nLen%4==0,
423 "number of channels no multiple of 4",
424 static_cast<rendering::XColorSpace*>(this), 0);
425
426 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
427 rendering::ARGBColor* pOut( aRes.getArray() );
428 for( std::size_t i=0; i<nLen; i+=4 )
429 {
430 const sal_Int8 nAlpha( pIn[3] );
431 *pOut++ = rendering::ARGBColor(
433 vcl::unotools::toDoubleColor(nAlpha*pIn[0]),
434 vcl::unotools::toDoubleColor(nAlpha*pIn[1]),
435 vcl::unotools::toDoubleColor(nAlpha*pIn[2]));
436 pIn += 4;
437 }
438 return aRes;
439 }
440
441 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
442 {
443 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
444 const std::size_t nLen( rgbColor.getLength() );
445
446 uno::Sequence< sal_Int8 > aRes(nLen*4);
447 sal_Int8* pColors=aRes.getArray();
448 for( std::size_t i=0; i<nLen; ++i )
449 {
450 *pColors++ = vcl::unotools::toByteColor(pIn->Red);
451 *pColors++ = vcl::unotools::toByteColor(pIn->Green);
452 *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
453 *pColors++ = 0;
454 ++pIn;
455 }
456 return aRes;
457 }
458
459 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
460 {
461 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
462 const std::size_t nLen( rgbColor.getLength() );
463
464 uno::Sequence< sal_Int8 > aRes(nLen*4);
465 sal_Int8* pColors=aRes.getArray();
466 for( std::size_t i=0; i<nLen; ++i )
467 {
468 *pColors++ = vcl::unotools::toByteColor(pIn->Red);
469 *pColors++ = vcl::unotools::toByteColor(pIn->Green);
470 *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
471 *pColors++ = vcl::unotools::toByteColor(pIn->Alpha);
472 ++pIn;
473 }
474 return aRes;
475 }
476
477 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
478 {
479 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
480 const std::size_t nLen( rgbColor.getLength() );
481
482 uno::Sequence< sal_Int8 > aRes(nLen*4);
483 sal_Int8* pColors=aRes.getArray();
484 for( std::size_t i=0; i<nLen; ++i )
485 {
486 *pColors++ = vcl::unotools::toByteColor(pIn->Red/pIn->Alpha);
487 *pColors++ = vcl::unotools::toByteColor(pIn->Green/pIn->Alpha);
488 *pColors++ = vcl::unotools::toByteColor(pIn->Blue/pIn->Alpha);
489 *pColors++ = vcl::unotools::toByteColor(pIn->Alpha);
490 ++pIn;
491 }
492 return aRes;
493 }
494
495 public:
496 StandardColorSpace() :
498 maBitCounts(4)
499 {
500 sal_Int8* pTags = maComponentTags.getArray();
501 sal_Int32* pBitCounts = maBitCounts.getArray();
502 pTags[0] = rendering::ColorComponentTag::RGB_RED;
503 pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
504 pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
505 pTags[3] = rendering::ColorComponentTag::ALPHA;
506
507 pBitCounts[0] =
508 pBitCounts[1] =
509 pBitCounts[2] =
510 pBitCounts[3] = 8;
511 }
512 };
513
514 class StandardNoAlphaColorSpace : public cppu::WeakImplHelper< css::rendering::XIntegerBitmapColorSpace >
515 {
516 private:
517 uno::Sequence< sal_Int8 > maComponentTags;
518 uno::Sequence< sal_Int32 > maBitCounts;
519
520 virtual ::sal_Int8 SAL_CALL getType( ) override
521 {
522 return rendering::ColorSpaceType::RGB;
523 }
524 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) override
525 {
526 return maComponentTags;
527 }
528 virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) override
529 {
530 return rendering::RenderingIntent::PERCEPTUAL;
531 }
532 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) override
533 {
534 return uno::Sequence< beans::PropertyValue >();
535 }
536 virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
537 const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
538 {
539 // TODO(P3): if we know anything about target
540 // colorspace, this can be greatly sped up
541 uno::Sequence<rendering::ARGBColor> aIntermediate(
542 convertToARGB(deviceColor));
543 return targetColorSpace->convertFromARGB(aIntermediate);
544 }
545 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) override
546 {
547 const double* pIn( deviceColor.getConstArray() );
548 const std::size_t nLen( deviceColor.getLength() );
549 ENSURE_ARG_OR_THROW2(nLen%4==0,
550 "number of channels no multiple of 4",
551 static_cast<rendering::XColorSpace*>(this), 0);
552
553 uno::Sequence< rendering::RGBColor > aRes(nLen/4);
554 rendering::RGBColor* pOut( aRes.getArray() );
555 for( std::size_t i=0; i<nLen; i+=4 )
556 {
557 *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
558 pIn += 4;
559 }
560 return aRes;
561 }
562 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) override
563 {
564 const double* pIn( deviceColor.getConstArray() );
565 const std::size_t nLen( deviceColor.getLength() );
566 ENSURE_ARG_OR_THROW2(nLen%4==0,
567 "number of channels no multiple of 4",
568 static_cast<rendering::XColorSpace*>(this), 0);
569
570 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
571 rendering::ARGBColor* pOut( aRes.getArray() );
572 for( std::size_t i=0; i<nLen; i+=4 )
573 {
574 *pOut++ = rendering::ARGBColor(1.0,pIn[0],pIn[1],pIn[2]);
575 pIn += 4;
576 }
577 return aRes;
578 }
579 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) override
580 {
581 const double* pIn( deviceColor.getConstArray() );
582 const std::size_t nLen( deviceColor.getLength() );
583 ENSURE_ARG_OR_THROW2(nLen%4==0,
584 "number of channels no multiple of 4",
585 static_cast<rendering::XColorSpace*>(this), 0);
586
587 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
588 rendering::ARGBColor* pOut( aRes.getArray() );
589 for( std::size_t i=0; i<nLen; i+=4 )
590 {
591 *pOut++ = rendering::ARGBColor(1.0,pIn[0],pIn[1],pIn[2]);
592 pIn += 4;
593 }
594 return aRes;
595 }
596 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
597 {
598 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
599 const std::size_t nLen( rgbColor.getLength() );
600
601 uno::Sequence< double > aRes(nLen*4);
602 double* pColors=aRes.getArray();
603 for( std::size_t i=0; i<nLen; ++i )
604 {
605 *pColors++ = pIn->Red;
606 *pColors++ = pIn->Green;
607 *pColors++ = pIn->Blue;
608 *pColors++ = 1.0; // the value does not matter
609 ++pIn;
610 }
611 return aRes;
612 }
613 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
614 {
615 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
616 const std::size_t nLen( rgbColor.getLength() );
617
618 uno::Sequence< double > aRes(nLen*4);
619 double* pColors=aRes.getArray();
620 for( std::size_t i=0; i<nLen; ++i )
621 {
622 *pColors++ = pIn->Red;
623 *pColors++ = pIn->Green;
624 *pColors++ = pIn->Blue;
625 *pColors++ = 1.0; // the value does not matter
626 ++pIn;
627 }
628 return aRes;
629 }
630 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
631 {
632 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
633 const std::size_t nLen( rgbColor.getLength() );
634
635 uno::Sequence< double > aRes(nLen*4);
636 double* pColors=aRes.getArray();
637 for( std::size_t i=0; i<nLen; ++i )
638 {
639 *pColors++ = pIn->Red/pIn->Alpha;
640 *pColors++ = pIn->Green/pIn->Alpha;
641 *pColors++ = pIn->Blue/pIn->Alpha;
642 *pColors++ = 1.0; // the value does not matter
643 ++pIn;
644 }
645 return aRes;
646 }
647
648 // XIntegerBitmapColorSpace
649 virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) override
650 {
651 return 32;
652 }
653 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) override
654 {
655 return maBitCounts;
656 }
657 virtual ::sal_Int8 SAL_CALL getEndianness( ) override
658 {
659 return util::Endianness::LITTLE;
660 }
661 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
662 const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
663 {
664 if( dynamic_cast<StandardNoAlphaColorSpace*>(targetColorSpace.get()) )
665 {
666 const sal_Int8* pIn( deviceColor.getConstArray() );
667 const std::size_t nLen( deviceColor.getLength() );
668 ENSURE_ARG_OR_THROW2(nLen%4==0,
669 "number of channels no multiple of 4",
670 static_cast<rendering::XColorSpace*>(this), 0);
671
672 uno::Sequence<double> aRes(nLen);
673 double* pOut( aRes.getArray() );
674 for( std::size_t i=0; i<nLen; i+=4 )
675 {
679 *pOut++ = 1.0; pIn++;
680 }
681 return aRes;
682 }
683 else
684 {
685 // TODO(P3): if we know anything about target
686 // colorspace, this can be greatly sped up
687 uno::Sequence<rendering::ARGBColor> aIntermediate(
688 convertIntegerToARGB(deviceColor));
689 return targetColorSpace->convertFromARGB(aIntermediate);
690 }
691 }
692 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
693 const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) override
694 {
695 if( dynamic_cast<StandardNoAlphaColorSpace*>(targetColorSpace.get()) )
696 {
697 // it's us, so simply pass-through the data
698 return deviceColor;
699 }
700 else
701 {
702 // TODO(P3): if we know anything about target
703 // colorspace, this can be greatly sped up
704 uno::Sequence<rendering::ARGBColor> aIntermediate(
705 convertIntegerToARGB(deviceColor));
706 return targetColorSpace->convertIntegerFromARGB(aIntermediate);
707 }
708 }
709 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
710 {
711 const sal_Int8* pIn( deviceColor.getConstArray() );
712 const std::size_t nLen( deviceColor.getLength() );
713 ENSURE_ARG_OR_THROW2(nLen%4==0,
714 "number of channels no multiple of 4",
715 static_cast<rendering::XColorSpace*>(this), 0);
716
717 uno::Sequence< rendering::RGBColor > aRes(nLen/4);
718 rendering::RGBColor* pOut( aRes.getArray() );
719 for( std::size_t i=0; i<nLen; i+=4 )
720 {
721 *pOut++ = rendering::RGBColor(
725 pIn += 4;
726 }
727 return aRes;
728 }
729
730 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
731 {
732 const sal_Int8* pIn( deviceColor.getConstArray() );
733 const std::size_t nLen( deviceColor.getLength() );
734 ENSURE_ARG_OR_THROW2(nLen%4==0,
735 "number of channels no multiple of 4",
736 static_cast<rendering::XColorSpace*>(this), 0);
737
738 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
739 rendering::ARGBColor* pOut( aRes.getArray() );
740 for( std::size_t i=0; i<nLen; i+=4 )
741 {
742 *pOut++ = rendering::ARGBColor(
743 1.0,
747 pIn += 4;
748 }
749 return aRes;
750 }
751
752 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
753 {
754 const sal_Int8* pIn( deviceColor.getConstArray() );
755 const std::size_t nLen( deviceColor.getLength() );
756 ENSURE_ARG_OR_THROW2(nLen%4==0,
757 "number of channels no multiple of 4",
758 static_cast<rendering::XColorSpace*>(this), 0);
759
760 uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
761 rendering::ARGBColor* pOut( aRes.getArray() );
762 for( std::size_t i=0; i<nLen; i+=4 )
763 {
764 *pOut++ = rendering::ARGBColor(
765 1.0,
769 pIn += 4;
770 }
771 return aRes;
772 }
773
774 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
775 {
776 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
777 const std::size_t nLen( rgbColor.getLength() );
778
779 uno::Sequence< sal_Int8 > aRes(nLen*4);
780 sal_Int8* pColors=aRes.getArray();
781 for( std::size_t i=0; i<nLen; ++i )
782 {
783 *pColors++ = vcl::unotools::toByteColor(pIn->Red);
784 *pColors++ = vcl::unotools::toByteColor(pIn->Green);
785 *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
786 *pColors++ = 1.0;
787 ++pIn;
788 }
789 return aRes;
790 }
791
792 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
793 {
794 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
795 const std::size_t nLen( rgbColor.getLength() );
796
797 uno::Sequence< sal_Int8 > aRes(nLen*4);
798 sal_Int8* pColors=aRes.getArray();
799 for( std::size_t i=0; i<nLen; ++i )
800 {
801 *pColors++ = vcl::unotools::toByteColor(pIn->Red);
802 *pColors++ = vcl::unotools::toByteColor(pIn->Green);
803 *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
804 *pColors++ = -1;
805 ++pIn;
806 }
807 return aRes;
808 }
809
810 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
811 {
812 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
813 const std::size_t nLen( rgbColor.getLength() );
814
815 uno::Sequence< sal_Int8 > aRes(nLen*4);
816 sal_Int8* pColors=aRes.getArray();
817 for( std::size_t i=0; i<nLen; ++i )
818 {
819 *pColors++ = vcl::unotools::toByteColor(pIn->Red/pIn->Alpha);
820 *pColors++ = vcl::unotools::toByteColor(pIn->Green/pIn->Alpha);
821 *pColors++ = vcl::unotools::toByteColor(pIn->Blue/pIn->Alpha);
822 *pColors++ = -1;
823 ++pIn;
824 }
825 return aRes;
826 }
827
828 public:
829 StandardNoAlphaColorSpace() :
831 maBitCounts(3)
832 {
833 sal_Int8* pTags = maComponentTags.getArray();
834 sal_Int32* pBitCounts = maBitCounts.getArray();
835 pTags[0] = rendering::ColorComponentTag::RGB_RED;
836 pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
837 pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
838
839 pBitCounts[0] =
840 pBitCounts[1] =
841 pBitCounts[2] = 8;
842 }
843 };
844
845 }
846
847 uno::Reference<rendering::XIntegerBitmapColorSpace> const & getStdColorSpace()
848 {
849 static uno::Reference<rendering::XIntegerBitmapColorSpace> SPACE = new StandardColorSpace();
850 return SPACE;
851 }
852
853 uno::Reference<rendering::XIntegerBitmapColorSpace> const & getStdColorSpaceWithoutAlpha()
854 {
855 static uno::Reference<rendering::XIntegerBitmapColorSpace> SPACE = new StandardNoAlphaColorSpace();
856 return SPACE;
857 }
858
859 rendering::IntegerBitmapLayout getStdMemoryLayout( const geometry::IntegerSize2D& rBmpSize )
860 {
861 rendering::IntegerBitmapLayout aLayout;
862
863 aLayout.ScanLines = rBmpSize.Height;
864 aLayout.ScanLineBytes = rBmpSize.Width*4;
865 aLayout.ScanLineStride = aLayout.ScanLineBytes;
866 aLayout.PlaneStride = 0;
867 aLayout.ColorSpace = getStdColorSpace();
868 aLayout.Palette.clear();
869 aLayout.IsMsbFirst = false;
870
871 return aLayout;
872 }
873
874 uno::Sequence<sal_Int8> colorToStdIntSequence( const ::Color& rColor )
875 {
876 uno::Sequence<sal_Int8> aRet(4);
877 sal_Int8* pCols( aRet.getArray() );
878#ifdef OSL_BIGENDIAN
879 pCols[0] = rColor.GetRed();
880 pCols[1] = rColor.GetGreen();
881 pCols[2] = rColor.GetBlue();
882 pCols[3] = rColor.GetAlpha();
883#else
884 *reinterpret_cast<sal_Int32*>(pCols) = sal_Int32(rColor);
885#endif
886 return aRet;
887 }
888
889 // Create a corrected view transformation out of the give one,
890 // which ensures that the rectangle given by (0,0) and
891 // rSpriteSize is mapped with its left,top corner to (0,0)
892 // again. This is required to properly render sprite
893 // animations to buffer bitmaps.
895 const ::basegfx::B2DRange& i_srcRect,
896 const ::basegfx::B2DHomMatrix& i_transformation )
897 {
898 if( i_srcRect.isEmpty() )
899 {
900 o_transform = i_transformation;
901 return o_transform;
902 }
903
904 // transform by given transformation
905 ::basegfx::B2DRectangle aTransformedRect;
906
907 calcTransformedRectBounds( aTransformedRect,
908 i_srcRect,
909 i_transformation );
910
911 // now move resulting left,top point of bounds to (0,0)
913 -aTransformedRect.getMinX(), -aTransformedRect.getMinY()));
914
915 // prepend to original transformation
916 o_transform = aCorrectedTransform * i_transformation;
917
918 return o_transform;
919 }
920
922 const ::basegfx::B2DRange& inRect,
923 const ::basegfx::B2DHomMatrix& transformation )
924 {
925 outRect.reset();
926
927 if( inRect.isEmpty() )
928 return outRect;
929
930 // transform all four extremal points of the rectangle,
931 // take bounding rect of those.
932
933 // transform left-top point
934 outRect.expand( transformation * inRect.getMinimum() );
935
936 // transform bottom-right point
937 outRect.expand( transformation * inRect.getMaximum() );
938
939 ::basegfx::B2DPoint aPoint;
940
941 // transform top-right point
942 aPoint.setX( inRect.getMaxX() );
943 aPoint.setY( inRect.getMinY() );
944
945 aPoint *= transformation;
946 outRect.expand( aPoint );
947
948 // transform bottom-left point
949 aPoint.setX( inRect.getMinX() );
950 aPoint.setY( inRect.getMaxY() );
951
952 aPoint *= transformation;
953 outRect.expand( aPoint );
954
955 // over and out.
956 return outRect;
957 }
958
959 bool isInside( const ::basegfx::B2DRange& rContainedRect,
960 const ::basegfx::B2DRange& rTransformRect,
961 const ::basegfx::B2DHomMatrix& rTransformation )
962 {
963 if( rContainedRect.isEmpty() || rTransformRect.isEmpty() )
964 return false;
965
967 ::basegfx::utils::createPolygonFromRect( rTransformRect ) );
968 aPoly.transform( rTransformation );
969
971 ::basegfx::utils::createPolygonFromRect(
972 rContainedRect ),
973 true );
974 }
975
976 namespace
977 {
978 bool clipAreaImpl( ::basegfx::B2IRange* o_pDestArea,
979 ::basegfx::B2IRange& io_rSourceArea,
980 ::basegfx::B2IPoint& io_rDestPoint,
981 const ::basegfx::B2IRange& rSourceBounds,
982 const ::basegfx::B2IRange& rDestBounds )
983 {
984 const ::basegfx::B2IPoint aSourceTopLeft(
985 io_rSourceArea.getMinimum() );
986
987 ::basegfx::B2IRange aLocalSourceArea( io_rSourceArea );
988
989 // clip source area (which must be inside rSourceBounds)
990 aLocalSourceArea.intersect( rSourceBounds );
991
992 if( aLocalSourceArea.isEmpty() )
993 return false;
994
995 // calc relative new source area points (relative to orig
996 // source area)
997 const ::basegfx::B2IVector aUpperLeftOffset(
998 aLocalSourceArea.getMinimum()-aSourceTopLeft );
999 const ::basegfx::B2IVector aLowerRightOffset(
1000 aLocalSourceArea.getMaximum()-aSourceTopLeft );
1001
1002 ::basegfx::B2IRange aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
1003 io_rDestPoint + aLowerRightOffset );
1004
1005 // clip dest area (which must be inside rDestBounds)
1006 aLocalDestArea.intersect( rDestBounds );
1007
1008 if( aLocalDestArea.isEmpty() )
1009 return false;
1010
1011 // calc relative new dest area points (relative to orig
1012 // source area)
1013 const ::basegfx::B2IVector aDestUpperLeftOffset(
1014 aLocalDestArea.getMinimum()-io_rDestPoint );
1015 const ::basegfx::B2IVector aDestLowerRightOffset(
1016 aLocalDestArea.getMaximum()-io_rDestPoint );
1017
1018 io_rSourceArea = ::basegfx::B2IRange( aSourceTopLeft + aDestUpperLeftOffset,
1019 aSourceTopLeft + aDestLowerRightOffset );
1020 io_rDestPoint = aLocalDestArea.getMinimum();
1021
1022 if( o_pDestArea )
1023 *o_pDestArea = aLocalDestArea;
1024
1025 return true;
1026 }
1027 }
1028
1030 ::basegfx::B2IPoint& io_rDestPoint,
1031 std::vector< ::basegfx::B2IRange >& o_ClippedAreas,
1032 const ::basegfx::B2IRange& rBounds )
1033 {
1034 ::basegfx::B2IRange aResultingDestArea;
1035
1036 // compute full destination area (to determine uninitialized
1037 // areas below)
1038 const ::basegfx::B2I64Tuple& rRange( io_rSourceArea.getRange() );
1039 ::basegfx::B2IRange aInputDestArea( io_rDestPoint.getX(),
1040 io_rDestPoint.getY(),
1041 (io_rDestPoint.getX()
1042 + static_cast<sal_Int32>(rRange.getX())),
1043 (io_rDestPoint.getY()
1044 + static_cast<sal_Int32>(rRange.getY())) );
1045 // limit to output area (no point updating outside of it)
1046 aInputDestArea.intersect( rBounds );
1047
1048 // clip to rBounds
1049 if( !clipAreaImpl( &aResultingDestArea,
1050 io_rSourceArea,
1051 io_rDestPoint,
1052 rBounds,
1053 rBounds ) )
1054 return false;
1055
1056 // finally, compute all areas clipped off the total
1057 // destination area.
1058 ::basegfx::computeSetDifference( o_ClippedAreas,
1059 aInputDestArea,
1060 aResultingDestArea );
1061
1062 return true;
1063 }
1064
1065 ::basegfx::B2IRange spritePixelAreaFromB2DRange( const ::basegfx::B2DRange& rRange )
1066 {
1067 if( rRange.isEmpty() )
1068 return ::basegfx::B2IRange();
1069
1070 const ::basegfx::B2IPoint aTopLeft( ::basegfx::fround( rRange.getMinX() ),
1071 ::basegfx::fround( rRange.getMinY() ) );
1072 return ::basegfx::B2IRange( aTopLeft,
1073 aTopLeft + ::basegfx::B2IPoint(
1074 ::basegfx::fround( rRange.getWidth() ),
1075 ::basegfx::fround( rRange.getHeight() ) ) );
1076 }
1077
1078 uno::Sequence< uno::Any >& getDeviceInfo( const uno::Reference< rendering::XCanvas >& i_rxCanvas,
1079 uno::Sequence< uno::Any >& o_rxParams )
1080 {
1081 o_rxParams.realloc( 0 );
1082
1083 if( !i_rxCanvas.is() )
1084 return o_rxParams;
1085
1086 try
1087 {
1088 uno::Reference< rendering::XGraphicDevice > xDevice( i_rxCanvas->getDevice(),
1089 uno::UNO_SET_THROW );
1090
1091 uno::Reference< lang::XServiceInfo > xServiceInfo( xDevice,
1092 uno::UNO_QUERY_THROW );
1093 uno::Reference< beans::XPropertySet > xPropSet( xDevice,
1094 uno::UNO_QUERY_THROW );
1095
1096 o_rxParams = { uno::Any(xServiceInfo->getImplementationName()),
1097 xPropSet->getPropertyValue( "DeviceHandle" ) };
1098 }
1099 catch( const uno::Exception& )
1100 {
1101 // ignore, but return empty sequence
1102 }
1103
1104 return o_rxParams;
1105 }
1106
1107 awt::Rectangle getAbsoluteWindowRect( const awt::Rectangle& rRect,
1108 const uno::Reference< awt::XWindow2 >& xWin )
1109 {
1110 awt::Rectangle aRetVal( rRect );
1111
1113 if( pWindow )
1114 {
1115 ::Point aPoint( aRetVal.X,
1116 aRetVal.Y );
1117
1118 aPoint = pWindow->OutputToScreenPixel( aPoint );
1119
1120 aRetVal.X = aPoint.X();
1121 aRetVal.Y = aPoint.Y();
1122 }
1123
1124 return aRetVal;
1125 }
1126
1127 ::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange )
1128 {
1129 ::basegfx::B2DPolyPolygon aPolyPoly;
1131
1132 const double nX0( rRange.getMinX() );
1133 const double nY0( rRange.getMinY() );
1134 const double nX1( rRange.getMaxX() );
1135 const double nY1( rRange.getMaxY() );
1136
1137 aPoly.append( ::basegfx::B2DPoint( nX0+4,
1138 nY0 ) );
1139 aPoly.append( ::basegfx::B2DPoint( nX0,
1140 nY0 ) );
1141 aPoly.append( ::basegfx::B2DPoint( nX0,
1142 nY0+4 ) );
1143 aPolyPoly.append( aPoly ); aPoly.clear();
1144
1145 aPoly.append( ::basegfx::B2DPoint( nX1-4,
1146 nY0 ) );
1147 aPoly.append( ::basegfx::B2DPoint( nX1,
1148 nY0 ) );
1149 aPoly.append( ::basegfx::B2DPoint( nX1,
1150 nY0+4 ) );
1151 aPolyPoly.append( aPoly ); aPoly.clear();
1152
1153 aPoly.append( ::basegfx::B2DPoint( nX0+4,
1154 nY1 ) );
1155 aPoly.append( ::basegfx::B2DPoint( nX0,
1156 nY1 ) );
1157 aPoly.append( ::basegfx::B2DPoint( nX0,
1158 nY1-4 ) );
1159 aPolyPoly.append( aPoly ); aPoly.clear();
1160
1161 aPoly.append( ::basegfx::B2DPoint( nX1-4,
1162 nY1 ) );
1163 aPoly.append( ::basegfx::B2DPoint( nX1,
1164 nY1 ) );
1165 aPoly.append( ::basegfx::B2DPoint( nX1,
1166 nY1-4 ) );
1167 aPolyPoly.append( aPoly );
1168
1169 return aPolyPoly;
1170 }
1171
1173 const rendering::ViewState& viewState,
1174 const rendering::RenderState& renderState,
1175 const rendering::Texture& texture,
1176 int nColorSteps )
1177 {
1178 // calculate overall texture transformation (directly from
1179 // texture to device space).
1181
1182 rTotalTransform.identity();
1183 ::basegfx::unotools::homMatrixFromAffineMatrix( rTotalTransform,
1184 texture.AffineTransform );
1186 viewState,
1187 renderState);
1188 rTotalTransform *= aMatrix; // prepend total view/render transformation
1189
1190 // determine size of gradient in device coordinate system
1191 // (to e.g. determine sensible number of gradient steps)
1192 ::basegfx::B2DPoint aLeftTop( 0.0, 0.0 );
1193 ::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 );
1194 ::basegfx::B2DPoint aRightTop( 1.0, 0.0 );
1195 ::basegfx::B2DPoint aRightBottom( 1.0, 1.0 );
1196
1197 aLeftTop *= rTotalTransform;
1198 aLeftBottom *= rTotalTransform;
1199 aRightTop *= rTotalTransform;
1200 aRightBottom*= rTotalTransform;
1201
1202 // longest line in gradient bound rect
1203 const int nGradientSize(
1204 static_cast<int>(
1205 std::max(
1206 ::basegfx::B2DVector(aRightBottom-aLeftTop).getLength(),
1207 ::basegfx::B2DVector(aRightTop-aLeftBottom).getLength() ) + 1.0 ) );
1208
1209 // typical number for pixel of the same color (strip size)
1210 const int nStripSize( nGradientSize < 50 ? 2 : 4 );
1211
1212 // use at least three steps, and at utmost the number of color
1213 // steps
1214 return std::max( 3,
1215 std::min(
1216 nGradientSize / nStripSize,
1217 nColorSteps ) );
1218 }
1219
1220 void clipOutDev(const rendering::ViewState& viewState,
1221 const rendering::RenderState& renderState,
1222 OutputDevice& rOutDev,
1223 OutputDevice* p2ndOutDev)
1224 {
1225 // accumulate non-empty clips into one region
1226 vcl::Region aClipRegion(true);
1227
1228 if( viewState.Clip.is() )
1229 {
1230 ::basegfx::B2DPolyPolygon aClipPoly(
1231 ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(viewState.Clip) );
1232
1233 if( aClipPoly.count() )
1234 {
1235 // setup non-empty clipping
1237 aClipPoly.transform(
1238 ::basegfx::unotools::homMatrixFromAffineMatrix( aMatrix,
1239 viewState.AffineTransform ) );
1240
1241 aClipRegion = vcl::Region::GetRegionFromPolyPolygon( ::tools::PolyPolygon( aClipPoly ) );
1242 }
1243 else
1244 {
1245 // clip polygon is empty
1246 aClipRegion.SetEmpty();
1247 }
1248 }
1249
1250 if( renderState.Clip.is() )
1251 {
1252 ::basegfx::B2DPolyPolygon aClipPoly(
1253 ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(renderState.Clip) );
1254
1256 aClipPoly.transform(
1258 viewState,
1259 renderState ) );
1260
1261 if( aClipPoly.count() )
1262 {
1263 // setup non-empty clipping
1265 aClipRegion.Intersect( aRegion );
1266 }
1267 else
1268 {
1269 // clip polygon is empty
1270 aClipRegion.SetEmpty();
1271 }
1272 }
1273
1274 // setup accumulated clip region. Note that setting an
1275 // empty clip region denotes "clip everything" on the
1276 // OutputDevice (which is why we translate that into
1277 // SetClipRegion() here). When both view and render clip
1278 // are empty, aClipRegion remains default-constructed,
1279 // i.e. empty, too.
1280 if( aClipRegion.IsNull() )
1281 {
1282 rOutDev.SetClipRegion();
1283
1284 if( p2ndOutDev )
1285 p2ndOutDev->SetClipRegion();
1286 }
1287 else
1288 {
1289 rOutDev.SetClipRegion( aClipRegion );
1290
1291 if( p2ndOutDev )
1292 p2ndOutDev->SetClipRegion( aClipRegion );
1293 }
1294 }
1295
1296 void extractExtraFontProperties(const uno::Sequence<beans::PropertyValue>& rExtraFontProperties,
1297 sal_uInt32 &rEmphasisMark)
1298 {
1299 for(const beans::PropertyValue& rPropVal : rExtraFontProperties)
1300 {
1301 if (rPropVal.Name == "EmphasisMark")
1302 rPropVal.Value >>= rEmphasisMark;
1303 }
1304 }
1305
1306} // namespace
1307
1308/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
uno::Sequence< sal_Int32 > maBitCounts
uno::Sequence< sal_Int8 > maComponentTags
void SetClipRegion()
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
void transform(const basegfx::B2DHomMatrix &rMatrix)
sal_uInt32 count() const
void transform(const basegfx::B2DHomMatrix &rMatrix)
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
B2IPoint getMinimum() const
B2I64Tuple getRange() const
TYPE getMinX() const
TYPE getMinY() const
void expand(const Tuple2D< TYPE > &rTuple)
void intersect(const Range2D &rRange)
TYPE getX() const
void setY(TYPE fY)
TYPE getY() const
void setX(TYPE fX)
bool IsNull() const
void Intersect(const tools::Rectangle &rRegion)
static vcl::Region GetRegionFromPolyPolygon(const tools::PolyPolygon &rPolyPoly)
void SetEmpty()
#define SPACE
#define ENSURE_ARG_OR_THROW2(c, m, ifc, arg)
#define max(a, b)
Definition: dx_winstuff.hxx:43
#define SAL_WARN_IF(condition, area, stream)
double getLength(const B2DPolygon &rCandidate)
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
uno::Reference< rendering::XIntegerBitmapColorSpace > const & getStdColorSpaceWithoutAlpha()
Return a color space for a default RGB integer format.
::basegfx::B2DHomMatrix & mergeViewAndRenderTransform(::basegfx::B2DHomMatrix &combinedTransform, const rendering::ViewState &viewState, const rendering::RenderState &renderState)
bool isInside(const ::basegfx::B2DRange &rContainedRect, const ::basegfx::B2DRange &rTransformRect, const ::basegfx::B2DHomMatrix &rTransformation)
Check whether a given rectangle is within another transformed rectangle.
::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon(const ::basegfx::B2DRange &rRange)
Retrieve for small bound marks around each corner of the given rectangle.
rendering::IntegerBitmapLayout getStdMemoryLayout(const geometry::IntegerSize2D &rBmpSize)
rendering::ViewState & setViewStateTransform(rendering::ViewState &viewState, const ::basegfx::B2DHomMatrix &transform)
rendering::RenderState & setRenderStateTransform(rendering::RenderState &renderState, const ::basegfx::B2DHomMatrix &transform)
rendering::RenderState & appendToRenderState(rendering::RenderState &renderState, const ::basegfx::B2DHomMatrix &rTransform)
uno::Sequence< sal_Int8 > colorToStdIntSequence(const ::Color &rColor)
Convert standard 8888 RGBA color to vcl color.
geometry::Matrix2D & setIdentityMatrix2D(geometry::Matrix2D &matrix)
::basegfx::B2DHomMatrix & calcRectToOriginTransform(::basegfx::B2DHomMatrix &o_transform, const ::basegfx::B2DRange &i_srcRect, const ::basegfx::B2DHomMatrix &i_transformation)
Calc a transform that maps the upper, left corner of a rectangle to the origin.
rendering::RenderState & prependToRenderState(rendering::RenderState &renderState, const ::basegfx::B2DHomMatrix &rTransform)
::basegfx::B2DRange & calcTransformedRectBounds(::basegfx::B2DRange &outRect, const ::basegfx::B2DRange &inRect, const ::basegfx::B2DHomMatrix &transformation)
Calc the bounding rectangle of a transformed rectangle.
::basegfx::B2IRange spritePixelAreaFromB2DRange(const ::basegfx::B2DRange &rRange)
Clip a blit between two differently surfaces.
geometry::AffineMatrix2D & setIdentityAffineMatrix2D(geometry::AffineMatrix2D &matrix)
geometry::RealSize2D createInfiniteSize2D()
Create a RealSize2D with both coordinate values set to +infinity.
Definition: canvastools.cxx:67
awt::Rectangle getAbsoluteWindowRect(const awt::Rectangle &rRect, const uno::Reference< awt::XWindow2 > &xWin)
bool clipScrollArea(::basegfx::B2IRange &io_rSourceArea, ::basegfx::B2IPoint &io_rDestPoint, std::vector< ::basegfx::B2IRange > &o_ClippedAreas, const ::basegfx::B2IRange &rBounds)
uno::Reference< rendering::XIntegerBitmapColorSpace > const & getStdColorSpace()
Return a color space for a default RGBA integer format.
rendering::RenderState & initRenderState(rendering::RenderState &renderState)
Definition: canvastools.cxx:74
::basegfx::B2DHomMatrix & getViewStateTransform(::basegfx::B2DHomMatrix &transform, const rendering::ViewState &viewState)
Definition: canvastools.cxx:94
rendering::ViewState & initViewState(rendering::ViewState &viewState)
Definition: canvastools.cxx:85
::basegfx::B2DHomMatrix & getRenderStateTransform(::basegfx::B2DHomMatrix &transform, const rendering::RenderState &renderState)
int calcGradientStepCount(::basegfx::B2DHomMatrix &rTotalTransform, const rendering::ViewState &viewState, const rendering::RenderState &renderState, const rendering::Texture &texture, int nColorSteps)
void clipOutDev(const rendering::ViewState &viewState, const rendering::RenderState &renderState, OutputDevice &rOutDev, OutputDevice *p2ndOutDev)
uno::Sequence< uno::Any > & getDeviceInfo(const uno::Reference< rendering::XCanvas > &i_rxCanvas, uno::Sequence< uno::Any > &o_rxParams)
void extractExtraFontProperties(const uno::Sequence< beans::PropertyValue > &rExtraFontProperties, sal_uInt32 &rEmphasisMark)
int i
sal_Int8 toByteColor(double val)
double toDoubleColor(sal_uInt8 val)
bool getType(BSTR name, Type &type)
signed char sal_Int8
oslFileHandle & pOut