LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / canvas / source / tools / canvastools.cxx
blobf6182ae9b7b33706087094f22f4a8a36e9880371
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <limits>
24 #include <basegfx/matrix/b2dhommatrix.hxx>
25 #include <basegfx/matrix/b2dhommatrixtools.hxx>
26 #include <basegfx/numeric/ftools.hxx>
27 #include <basegfx/point/b2dpoint.hxx>
28 #include <basegfx/point/b2ipoint.hxx>
29 #include <basegfx/polygon/b2dpolygon.hxx>
30 #include <basegfx/polygon/b2dpolygontools.hxx>
31 #include <basegfx/range/b2drange.hxx>
32 #include <basegfx/range/b2drectangle.hxx>
33 #include <basegfx/range/b2irange.hxx>
34 #include <basegfx/utils/canvastools.hxx>
35 #include <basegfx/vector/b2ivector.hxx>
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>
53 #include <cppuhelper/implbase.hxx>
54 #include <sal/log.hxx>
55 #include <toolkit/helper/vclunohelper.hxx>
56 #include <tools/diagnose_ex.h>
57 #include <vcl/canvastools.hxx>
58 #include <vcl/window.hxx>
60 #include <canvas/canvastools.hxx>
63 using namespace ::com::sun::star;
65 namespace canvas::tools
67 geometry::RealSize2D createInfiniteSize2D()
69 return geometry::RealSize2D(
70 std::numeric_limits<double>::infinity(),
71 std::numeric_limits<double>::infinity() );
74 rendering::RenderState& initRenderState( rendering::RenderState& renderState )
76 // setup identity transform
77 setIdentityAffineMatrix2D( renderState.AffineTransform );
78 renderState.Clip.clear();
79 renderState.DeviceColor = uno::Sequence< double >();
80 renderState.CompositeOperation = rendering::CompositeOperation::OVER;
82 return renderState;
85 rendering::ViewState& initViewState( rendering::ViewState& viewState )
87 // setup identity transform
88 setIdentityAffineMatrix2D( viewState.AffineTransform );
89 viewState.Clip.clear();
91 return viewState;
94 ::basegfx::B2DHomMatrix& getViewStateTransform( ::basegfx::B2DHomMatrix& transform,
95 const rendering::ViewState& viewState )
97 return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, viewState.AffineTransform );
100 rendering::ViewState& setViewStateTransform( rendering::ViewState& viewState,
101 const ::basegfx::B2DHomMatrix& transform )
103 ::basegfx::unotools::affineMatrixFromHomMatrix( viewState.AffineTransform, transform );
105 return viewState;
108 ::basegfx::B2DHomMatrix& getRenderStateTransform( ::basegfx::B2DHomMatrix& transform,
109 const rendering::RenderState& renderState )
111 return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, renderState.AffineTransform );
114 rendering::RenderState& setRenderStateTransform( rendering::RenderState& renderState,
115 const ::basegfx::B2DHomMatrix& transform )
117 ::basegfx::unotools::affineMatrixFromHomMatrix( renderState.AffineTransform, transform );
119 return renderState;
122 rendering::RenderState& appendToRenderState( rendering::RenderState& renderState,
123 const ::basegfx::B2DHomMatrix& rTransform )
125 ::basegfx::B2DHomMatrix transform;
127 getRenderStateTransform( transform, renderState );
128 return setRenderStateTransform( renderState, transform * rTransform );
131 rendering::RenderState& prependToRenderState( rendering::RenderState& renderState,
132 const ::basegfx::B2DHomMatrix& rTransform )
134 ::basegfx::B2DHomMatrix transform;
136 getRenderStateTransform( transform, renderState );
137 return setRenderStateTransform( renderState, rTransform * transform );
140 ::basegfx::B2DHomMatrix& mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix& combinedTransform,
141 const rendering::ViewState& viewState,
142 const rendering::RenderState& renderState )
144 ::basegfx::B2DHomMatrix viewTransform;
146 ::basegfx::unotools::homMatrixFromAffineMatrix( combinedTransform, renderState.AffineTransform );
147 ::basegfx::unotools::homMatrixFromAffineMatrix( viewTransform, viewState.AffineTransform );
149 // this statement performs combinedTransform = viewTransform * combinedTransform
150 combinedTransform *= viewTransform;
152 return combinedTransform;
155 geometry::AffineMatrix2D& setIdentityAffineMatrix2D( geometry::AffineMatrix2D& matrix )
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;
164 return matrix;
167 geometry::Matrix2D& setIdentityMatrix2D( geometry::Matrix2D& matrix )
169 matrix.m00 = 1.0;
170 matrix.m01 = 0.0;
171 matrix.m10 = 0.0;
172 matrix.m11 = 1.0;
174 return matrix;
177 namespace
179 class StandardColorSpace : public cppu::WeakImplHelper< css::rendering::XIntegerBitmapColorSpace >
181 private:
182 uno::Sequence< sal_Int8 > maComponentTags;
183 uno::Sequence< sal_Int32 > maBitCounts;
185 virtual ::sal_Int8 SAL_CALL getType( ) override
187 return rendering::ColorSpaceType::RGB;
189 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) override
191 return maComponentTags;
193 virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) override
195 return rendering::RenderingIntent::PERCEPTUAL;
197 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) override
199 return uno::Sequence< beans::PropertyValue >();
201 virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
202 const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
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);
210 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) override
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);
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 )
222 *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
223 pIn += 4;
225 return aRes;
227 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) override
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);
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 )
240 *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
241 pIn += 4;
243 return aRes;
245 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) override
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);
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 )
257 *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
258 pIn += 4;
260 return aRes;
262 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
264 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
265 const std::size_t nLen( rgbColor.getLength() );
267 uno::Sequence< double > aRes(nLen*4);
268 double* pColors=aRes.getArray();
269 for( std::size_t i=0; i<nLen; ++i )
271 *pColors++ = pIn->Red;
272 *pColors++ = pIn->Green;
273 *pColors++ = pIn->Blue;
274 *pColors++ = 1.0;
275 ++pIn;
277 return aRes;
279 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
281 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
282 const std::size_t nLen( rgbColor.getLength() );
284 uno::Sequence< double > aRes(nLen*4);
285 double* pColors=aRes.getArray();
286 for( std::size_t i=0; i<nLen; ++i )
288 *pColors++ = pIn->Red;
289 *pColors++ = pIn->Green;
290 *pColors++ = pIn->Blue;
291 *pColors++ = pIn->Alpha;
292 ++pIn;
294 return aRes;
296 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
298 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
299 const std::size_t nLen( rgbColor.getLength() );
301 uno::Sequence< double > aRes(nLen*4);
302 double* pColors=aRes.getArray();
303 for( std::size_t i=0; i<nLen; ++i )
305 *pColors++ = pIn->Red/pIn->Alpha;
306 *pColors++ = pIn->Green/pIn->Alpha;
307 *pColors++ = pIn->Blue/pIn->Alpha;
308 *pColors++ = pIn->Alpha;
309 ++pIn;
311 return aRes;
314 // XIntegerBitmapColorSpace
315 virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) override
317 return 32;
319 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) override
321 return maBitCounts;
323 virtual ::sal_Int8 SAL_CALL getEndianness( ) override
325 return util::Endianness::LITTLE;
327 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
328 const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
330 if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
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);
338 uno::Sequence<double> aRes(nLen);
339 double* pOut( aRes.getArray() );
340 for( std::size_t i=0; i<nLen; i+=4 )
342 *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
343 *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
344 *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
345 *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
347 return aRes;
349 else
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);
358 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
359 const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) override
361 if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
363 // it's us, so simply pass-through the data
364 return deviceColor;
366 else
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);
375 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
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);
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 )
387 *pOut++ = rendering::RGBColor(
388 vcl::unotools::toDoubleColor(pIn[0]),
389 vcl::unotools::toDoubleColor(pIn[1]),
390 vcl::unotools::toDoubleColor(pIn[2]));
391 pIn += 4;
393 return aRes;
396 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
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);
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 )
408 *pOut++ = rendering::ARGBColor(
409 vcl::unotools::toDoubleColor(pIn[3]),
410 vcl::unotools::toDoubleColor(pIn[0]),
411 vcl::unotools::toDoubleColor(pIn[1]),
412 vcl::unotools::toDoubleColor(pIn[2]));
413 pIn += 4;
415 return aRes;
418 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
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);
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 )
430 const sal_Int8 nAlpha( pIn[3] );
431 *pOut++ = rendering::ARGBColor(
432 vcl::unotools::toDoubleColor(nAlpha),
433 vcl::unotools::toDoubleColor(nAlpha*pIn[0]),
434 vcl::unotools::toDoubleColor(nAlpha*pIn[1]),
435 vcl::unotools::toDoubleColor(nAlpha*pIn[2]));
436 pIn += 4;
438 return aRes;
441 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
443 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
444 const std::size_t nLen( rgbColor.getLength() );
446 uno::Sequence< sal_Int8 > aRes(nLen*4);
447 sal_Int8* pColors=aRes.getArray();
448 for( std::size_t i=0; i<nLen; ++i )
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;
456 return aRes;
459 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
461 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
462 const std::size_t nLen( rgbColor.getLength() );
464 uno::Sequence< sal_Int8 > aRes(nLen*4);
465 sal_Int8* pColors=aRes.getArray();
466 for( std::size_t i=0; i<nLen; ++i )
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;
474 return aRes;
477 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
479 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
480 const std::size_t nLen( rgbColor.getLength() );
482 uno::Sequence< sal_Int8 > aRes(nLen*4);
483 sal_Int8* pColors=aRes.getArray();
484 for( std::size_t i=0; i<nLen; ++i )
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;
492 return aRes;
495 public:
496 StandardColorSpace() :
497 maComponentTags(4),
498 maBitCounts(4)
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;
507 pBitCounts[0] =
508 pBitCounts[1] =
509 pBitCounts[2] =
510 pBitCounts[3] = 8;
514 class StandardNoAlphaColorSpace : public cppu::WeakImplHelper< css::rendering::XIntegerBitmapColorSpace >
516 private:
517 uno::Sequence< sal_Int8 > maComponentTags;
518 uno::Sequence< sal_Int32 > maBitCounts;
520 virtual ::sal_Int8 SAL_CALL getType( ) override
522 return rendering::ColorSpaceType::RGB;
524 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) override
526 return maComponentTags;
528 virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) override
530 return rendering::RenderingIntent::PERCEPTUAL;
532 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) override
534 return uno::Sequence< beans::PropertyValue >();
536 virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
537 const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
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);
545 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) override
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);
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 )
557 *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
558 pIn += 4;
560 return aRes;
562 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) override
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);
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 )
574 *pOut++ = rendering::ARGBColor(1.0,pIn[0],pIn[1],pIn[2]);
575 pIn += 4;
577 return aRes;
579 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) override
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);
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 )
591 *pOut++ = rendering::ARGBColor(1.0,pIn[0],pIn[1],pIn[2]);
592 pIn += 4;
594 return aRes;
596 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
598 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
599 const std::size_t nLen( rgbColor.getLength() );
601 uno::Sequence< double > aRes(nLen*4);
602 double* pColors=aRes.getArray();
603 for( std::size_t i=0; i<nLen; ++i )
605 *pColors++ = pIn->Red;
606 *pColors++ = pIn->Green;
607 *pColors++ = pIn->Blue;
608 *pColors++ = 1.0; // the value does not matter
609 ++pIn;
611 return aRes;
613 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
615 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
616 const std::size_t nLen( rgbColor.getLength() );
618 uno::Sequence< double > aRes(nLen*4);
619 double* pColors=aRes.getArray();
620 for( std::size_t i=0; i<nLen; ++i )
622 *pColors++ = pIn->Red;
623 *pColors++ = pIn->Green;
624 *pColors++ = pIn->Blue;
625 *pColors++ = 1.0; // the value does not matter
626 ++pIn;
628 return aRes;
630 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
632 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
633 const std::size_t nLen( rgbColor.getLength() );
635 uno::Sequence< double > aRes(nLen*4);
636 double* pColors=aRes.getArray();
637 for( std::size_t i=0; i<nLen; ++i )
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;
645 return aRes;
648 // XIntegerBitmapColorSpace
649 virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) override
651 return 32;
653 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) override
655 return maBitCounts;
657 virtual ::sal_Int8 SAL_CALL getEndianness( ) override
659 return util::Endianness::LITTLE;
661 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
662 const uno::Reference< rendering::XColorSpace >& targetColorSpace ) override
664 if( dynamic_cast<StandardNoAlphaColorSpace*>(targetColorSpace.get()) )
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);
672 uno::Sequence<double> aRes(nLen);
673 double* pOut( aRes.getArray() );
674 for( std::size_t i=0; i<nLen; i+=4 )
676 *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
677 *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
678 *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
679 *pOut++ = 1.0; pIn++;
681 return aRes;
683 else
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);
692 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
693 const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) override
695 if( dynamic_cast<StandardNoAlphaColorSpace*>(targetColorSpace.get()) )
697 // it's us, so simply pass-through the data
698 return deviceColor;
700 else
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);
709 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
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);
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 )
721 *pOut++ = rendering::RGBColor(
722 vcl::unotools::toDoubleColor(pIn[0]),
723 vcl::unotools::toDoubleColor(pIn[1]),
724 vcl::unotools::toDoubleColor(pIn[2]));
725 pIn += 4;
727 return aRes;
730 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
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);
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 )
742 *pOut++ = rendering::ARGBColor(
743 1.0,
744 vcl::unotools::toDoubleColor(pIn[0]),
745 vcl::unotools::toDoubleColor(pIn[1]),
746 vcl::unotools::toDoubleColor(pIn[2]));
747 pIn += 4;
749 return aRes;
752 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) override
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);
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 )
764 *pOut++ = rendering::ARGBColor(
765 1.0,
766 vcl::unotools::toDoubleColor(pIn[0]),
767 vcl::unotools::toDoubleColor(pIn[1]),
768 vcl::unotools::toDoubleColor(pIn[2]));
769 pIn += 4;
771 return aRes;
774 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) override
776 const rendering::RGBColor* pIn( rgbColor.getConstArray() );
777 const std::size_t nLen( rgbColor.getLength() );
779 uno::Sequence< sal_Int8 > aRes(nLen*4);
780 sal_Int8* pColors=aRes.getArray();
781 for( std::size_t i=0; i<nLen; ++i )
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;
789 return aRes;
792 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
794 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
795 const std::size_t nLen( rgbColor.getLength() );
797 uno::Sequence< sal_Int8 > aRes(nLen*4);
798 sal_Int8* pColors=aRes.getArray();
799 for( std::size_t i=0; i<nLen; ++i )
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;
807 return aRes;
810 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) override
812 const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
813 const std::size_t nLen( rgbColor.getLength() );
815 uno::Sequence< sal_Int8 > aRes(nLen*4);
816 sal_Int8* pColors=aRes.getArray();
817 for( std::size_t i=0; i<nLen; ++i )
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;
825 return aRes;
828 public:
829 StandardNoAlphaColorSpace() :
830 maComponentTags(3),
831 maBitCounts(3)
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;
839 pBitCounts[0] =
840 pBitCounts[1] =
841 pBitCounts[2] = 8;
847 uno::Reference<rendering::XIntegerBitmapColorSpace> const & getStdColorSpace()
849 static uno::Reference<rendering::XIntegerBitmapColorSpace> SPACE = new StandardColorSpace();
850 return SPACE;
853 uno::Reference<rendering::XIntegerBitmapColorSpace> const & getStdColorSpaceWithoutAlpha()
855 static uno::Reference<rendering::XIntegerBitmapColorSpace> SPACE = new StandardNoAlphaColorSpace();
856 return SPACE;
859 rendering::IntegerBitmapLayout getStdMemoryLayout( const geometry::IntegerSize2D& rBmpSize )
861 rendering::IntegerBitmapLayout aLayout;
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;
871 return aLayout;
874 uno::Sequence<sal_Int8> colorToStdIntSequence( const ::Color& rColor )
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;
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.
894 ::basegfx::B2DHomMatrix& calcRectToOriginTransform( ::basegfx::B2DHomMatrix& o_transform,
895 const ::basegfx::B2DRange& i_srcRect,
896 const ::basegfx::B2DHomMatrix& i_transformation )
898 if( i_srcRect.isEmpty() )
900 o_transform = i_transformation;
901 return o_transform;
904 // transform by given transformation
905 ::basegfx::B2DRectangle aTransformedRect;
907 calcTransformedRectBounds( aTransformedRect,
908 i_srcRect,
909 i_transformation );
911 // now move resulting left,top point of bounds to (0,0)
912 const basegfx::B2DHomMatrix aCorrectedTransform(basegfx::utils::createTranslateB2DHomMatrix(
913 -aTransformedRect.getMinX(), -aTransformedRect.getMinY()));
915 // prepend to original transformation
916 o_transform = aCorrectedTransform * i_transformation;
918 return o_transform;
921 ::basegfx::B2DRange& calcTransformedRectBounds( ::basegfx::B2DRange& outRect,
922 const ::basegfx::B2DRange& inRect,
923 const ::basegfx::B2DHomMatrix& transformation )
925 outRect.reset();
927 if( inRect.isEmpty() )
928 return outRect;
930 // transform all four extremal points of the rectangle,
931 // take bounding rect of those.
933 // transform left-top point
934 outRect.expand( transformation * inRect.getMinimum() );
936 // transform bottom-right point
937 outRect.expand( transformation * inRect.getMaximum() );
939 ::basegfx::B2DPoint aPoint;
941 // transform top-right point
942 aPoint.setX( inRect.getMaxX() );
943 aPoint.setY( inRect.getMinY() );
945 aPoint *= transformation;
946 outRect.expand( aPoint );
948 // transform bottom-left point
949 aPoint.setX( inRect.getMinX() );
950 aPoint.setY( inRect.getMaxY() );
952 aPoint *= transformation;
953 outRect.expand( aPoint );
955 // over and out.
956 return outRect;
959 bool isInside( const ::basegfx::B2DRange& rContainedRect,
960 const ::basegfx::B2DRange& rTransformRect,
961 const ::basegfx::B2DHomMatrix& rTransformation )
963 if( rContainedRect.isEmpty() || rTransformRect.isEmpty() )
964 return false;
966 ::basegfx::B2DPolygon aPoly(
967 ::basegfx::utils::createPolygonFromRect( rTransformRect ) );
968 aPoly.transform( rTransformation );
970 return ::basegfx::utils::isInside( aPoly,
971 ::basegfx::utils::createPolygonFromRect(
972 rContainedRect ),
973 true );
976 namespace
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 )
984 const ::basegfx::B2IPoint aSourceTopLeft(
985 io_rSourceArea.getMinimum() );
987 ::basegfx::B2IRange aLocalSourceArea( io_rSourceArea );
989 // clip source area (which must be inside rSourceBounds)
990 aLocalSourceArea.intersect( rSourceBounds );
992 if( aLocalSourceArea.isEmpty() )
993 return false;
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 );
1002 ::basegfx::B2IRange aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
1003 io_rDestPoint + aLowerRightOffset );
1005 // clip dest area (which must be inside rDestBounds)
1006 aLocalDestArea.intersect( rDestBounds );
1008 if( aLocalDestArea.isEmpty() )
1009 return false;
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 );
1018 io_rSourceArea = ::basegfx::B2IRange( aSourceTopLeft + aDestUpperLeftOffset,
1019 aSourceTopLeft + aDestLowerRightOffset );
1020 io_rDestPoint = aLocalDestArea.getMinimum();
1022 if( o_pDestArea )
1023 *o_pDestArea = aLocalDestArea;
1025 return true;
1029 bool clipScrollArea( ::basegfx::B2IRange& io_rSourceArea,
1030 ::basegfx::B2IPoint& io_rDestPoint,
1031 std::vector< ::basegfx::B2IRange >& o_ClippedAreas,
1032 const ::basegfx::B2IRange& rBounds )
1034 ::basegfx::B2IRange aResultingDestArea;
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 );
1048 // clip to rBounds
1049 if( !clipAreaImpl( &aResultingDestArea,
1050 io_rSourceArea,
1051 io_rDestPoint,
1052 rBounds,
1053 rBounds ) )
1054 return false;
1056 // finally, compute all areas clipped off the total
1057 // destination area.
1058 ::basegfx::computeSetDifference( o_ClippedAreas,
1059 aInputDestArea,
1060 aResultingDestArea );
1062 return true;
1065 ::basegfx::B2IRange spritePixelAreaFromB2DRange( const ::basegfx::B2DRange& rRange )
1067 if( rRange.isEmpty() )
1068 return ::basegfx::B2IRange();
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() ) ) );
1078 uno::Sequence< uno::Any >& getDeviceInfo( const uno::Reference< rendering::XCanvas >& i_rxCanvas,
1079 uno::Sequence< uno::Any >& o_rxParams )
1081 o_rxParams.realloc( 0 );
1083 if( i_rxCanvas.is() )
1087 uno::Reference< rendering::XGraphicDevice > xDevice( i_rxCanvas->getDevice(),
1088 uno::UNO_SET_THROW );
1090 uno::Reference< lang::XServiceInfo > xServiceInfo( xDevice,
1091 uno::UNO_QUERY_THROW );
1092 uno::Reference< beans::XPropertySet > xPropSet( xDevice,
1093 uno::UNO_QUERY_THROW );
1095 o_rxParams = { uno::Any(xServiceInfo->getImplementationName()),
1096 xPropSet->getPropertyValue( "DeviceHandle" ) };
1098 catch( const uno::Exception& )
1100 // ignore, but return empty sequence
1104 return o_rxParams;
1107 awt::Rectangle getAbsoluteWindowRect( const awt::Rectangle& rRect,
1108 const uno::Reference< awt::XWindow2 >& xWin )
1110 awt::Rectangle aRetVal( rRect );
1112 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWin);
1113 if( pWindow )
1115 ::Point aPoint( aRetVal.X,
1116 aRetVal.Y );
1118 aPoint = pWindow->OutputToScreenPixel( aPoint );
1120 aRetVal.X = aPoint.X();
1121 aRetVal.Y = aPoint.Y();
1124 return aRetVal;
1127 ::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange )
1129 ::basegfx::B2DPolyPolygon aPolyPoly;
1130 ::basegfx::B2DPolygon aPoly;
1132 const double nX0( rRange.getMinX() );
1133 const double nY0( rRange.getMinY() );
1134 const double nX1( rRange.getMaxX() );
1135 const double nY1( rRange.getMaxY() );
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();
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();
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();
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 );
1169 return aPolyPoly;
1172 int calcGradientStepCount( ::basegfx::B2DHomMatrix& rTotalTransform,
1173 const rendering::ViewState& viewState,
1174 const rendering::RenderState& renderState,
1175 const rendering::Texture& texture,
1176 int nColorSteps )
1178 // calculate overall texture transformation (directly from
1179 // texture to device space).
1180 ::basegfx::B2DHomMatrix aMatrix;
1182 rTotalTransform.identity();
1183 ::basegfx::unotools::homMatrixFromAffineMatrix( rTotalTransform,
1184 texture.AffineTransform );
1185 ::canvas::tools::mergeViewAndRenderTransform(aMatrix,
1186 viewState,
1187 renderState);
1188 rTotalTransform *= aMatrix; // prepend total view/render transformation
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 );
1197 aLeftTop *= rTotalTransform;
1198 aLeftBottom *= rTotalTransform;
1199 aRightTop *= rTotalTransform;
1200 aRightBottom*= rTotalTransform;
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 ) );
1209 // typical number for pixel of the same color (strip size)
1210 const int nStripSize( nGradientSize < 50 ? 2 : 4 );
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 ) );
1220 void clipOutDev(const rendering::ViewState& viewState,
1221 const rendering::RenderState& renderState,
1222 OutputDevice& rOutDev,
1223 OutputDevice* p2ndOutDev)
1225 // accumulate non-empty clips into one region
1226 vcl::Region aClipRegion(true);
1228 if( viewState.Clip.is() )
1230 ::basegfx::B2DPolyPolygon aClipPoly(
1231 ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(viewState.Clip) );
1233 if( aClipPoly.count() )
1235 // setup non-empty clipping
1236 ::basegfx::B2DHomMatrix aMatrix;
1237 aClipPoly.transform(
1238 ::basegfx::unotools::homMatrixFromAffineMatrix( aMatrix,
1239 viewState.AffineTransform ) );
1241 aClipRegion = vcl::Region::GetRegionFromPolyPolygon( ::tools::PolyPolygon( aClipPoly ) );
1243 else
1245 // clip polygon is empty
1246 aClipRegion.SetEmpty();
1250 if( renderState.Clip.is() )
1252 ::basegfx::B2DPolyPolygon aClipPoly(
1253 ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(renderState.Clip) );
1255 ::basegfx::B2DHomMatrix aMatrix;
1256 aClipPoly.transform(
1257 ::canvas::tools::mergeViewAndRenderTransform( aMatrix,
1258 viewState,
1259 renderState ) );
1261 if( aClipPoly.count() )
1263 // setup non-empty clipping
1264 vcl::Region aRegion = vcl::Region::GetRegionFromPolyPolygon( ::tools::PolyPolygon( aClipPoly ) );
1265 aClipRegion.Intersect( aRegion );
1267 else
1269 // clip polygon is empty
1270 aClipRegion.SetEmpty();
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() )
1282 rOutDev.SetClipRegion();
1284 if( p2ndOutDev )
1285 p2ndOutDev->SetClipRegion();
1287 else
1289 rOutDev.SetClipRegion( aClipRegion );
1291 if( p2ndOutDev )
1292 p2ndOutDev->SetClipRegion( aClipRegion );
1296 void extractExtraFontProperties(const uno::Sequence<beans::PropertyValue>& rExtraFontProperties,
1297 sal_uInt32 &rEmphasisMark)
1299 for(const beans::PropertyValue& rPropVal : rExtraFontProperties)
1301 if (rPropVal.Name == "EmphasisMark")
1302 rPropVal.Value >>= rEmphasisMark;
1306 } // namespace
1308 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */