1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
22 #include <com/sun/star/geometry/Matrix2D.hpp>
23 #include <com/sun/star/geometry/RealPoint2D.hpp>
24 #include <com/sun/star/geometry/RealSize2D.hpp>
25 #include <com/sun/star/geometry/IntegerPoint2D.hpp>
26 #include <com/sun/star/geometry/IntegerSize2D.hpp>
27 #include <com/sun/star/geometry/RealRectangle2D.hpp>
28 #include <com/sun/star/geometry/RealBezierSegment2D.hpp>
29 #include <com/sun/star/rendering/RenderState.hpp>
30 #include <com/sun/star/rendering/ViewState.hpp>
31 #include <com/sun/star/rendering/XCanvas.hpp>
32 #include <com/sun/star/rendering/CompositeOperation.hpp>
33 #include <com/sun/star/rendering/TexturingMode.hpp>
34 #include <com/sun/star/util/Endianness.hpp>
35 #include <com/sun/star/rendering/PathCapType.hpp>
36 #include <com/sun/star/rendering/PathJoinType.hpp>
37 #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
38 #include <com/sun/star/rendering/FloatingPointBitmapFormat.hpp>
39 #include <com/sun/star/rendering/FloatingPointBitmapLayout.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <basegfx/matrix/b2dhommatrix.hxx>
44 #include <basegfx/range/b2drange.hxx>
45 #include <basegfx/range/b2irange.hxx>
46 #include <basegfx/range/b2drectangle.hxx>
47 #include <basegfx/point/b2dpoint.hxx>
48 #include <basegfx/tools/canvastools.hxx>
49 #include <basegfx/polygon/b2dpolygon.hxx>
51 #include <canvas/verifyinput.hxx>
52 #include <canvas/canvastools.hxx>
55 using namespace ::com::sun::star
;
61 void verifyInput( const geometry::RealPoint2D
& rPoint
,
63 const uno::Reference
< uno::XInterface
>& xIf
,
66 (void)pStr
; (void)xIf
; (void)nArgPos
;
68 #if OSL_DEBUG_LEVEL > 0
69 if( !::rtl::math::isFinite( rPoint
.X
) )
71 throw lang::IllegalArgumentException(
72 OUString::createFromAscii( pStr
) + ": verifyInput(): point X value contains infinite or NAN",
76 if( !::rtl::math::isFinite( rPoint
.Y
) )
78 throw lang::IllegalArgumentException(
79 OUString::createFromAscii( pStr
) + ": verifyInput(): point X value contains infinite or NAN",
83 if( !::rtl::math::isFinite( rPoint
.X
) ||
84 !::rtl::math::isFinite( rPoint
.Y
) )
86 throw lang::IllegalArgumentException();
91 void verifyInput( const geometry::RealBezierSegment2D
& rSegment
,
93 const uno::Reference
< uno::XInterface
>& xIf
,
96 (void)pStr
; (void)xIf
; (void)nArgPos
;
98 #if OSL_DEBUG_LEVEL > 0
99 if( !::rtl::math::isFinite( rSegment
.Px
) )
101 throw lang::IllegalArgumentException(
102 OUString::createFromAscii( pStr
) +
103 ": verifyInput(): bezier segment's Px value contains infinite or NAN",
107 if( !::rtl::math::isFinite( rSegment
.Py
) )
109 throw lang::IllegalArgumentException(
110 OUString::createFromAscii( pStr
) +
111 ": verifyInput(): bezier segment's Py value contains infinite or NAN",
115 if( !::rtl::math::isFinite( rSegment
.C1x
) )
117 throw lang::IllegalArgumentException(
118 OUString::createFromAscii( pStr
) +
119 ": verifyInput(): bezier segment's C1x value contains infinite or NAN",
123 if( !::rtl::math::isFinite( rSegment
.C1y
) )
125 throw lang::IllegalArgumentException(
126 OUString::createFromAscii( pStr
) +
127 ": verifyInput(): bezier segment's C1y value contains infinite or NAN",
131 if( !::rtl::math::isFinite( rSegment
.C2x
) )
133 throw lang::IllegalArgumentException(
134 OUString::createFromAscii( pStr
) +
135 ": verifyInput(): bezier segment's C2x value contains infinite or NAN",
139 if( !::rtl::math::isFinite( rSegment
.C2y
) )
141 throw lang::IllegalArgumentException(
142 OUString::createFromAscii( pStr
) +
143 ": verifyInput(): bezier segment's C2y value contains infinite or NAN",
147 if( !::rtl::math::isFinite( rSegment
.Px
) ||
148 !::rtl::math::isFinite( rSegment
.Py
) ||
149 !::rtl::math::isFinite( rSegment
.C1x
) ||
150 !::rtl::math::isFinite( rSegment
.C1y
) ||
151 !::rtl::math::isFinite( rSegment
.C2x
) ||
152 !::rtl::math::isFinite( rSegment
.C2y
) )
154 throw lang::IllegalArgumentException();
159 void verifyInput( const geometry::RealRectangle2D
& rRect
,
161 const uno::Reference
< uno::XInterface
>& xIf
,
162 ::sal_Int16 nArgPos
)
164 (void)pStr
; (void)xIf
; (void)nArgPos
;
166 #if OSL_DEBUG_LEVEL > 0
167 if( !::rtl::math::isFinite( rRect
.X1
) )
169 throw lang::IllegalArgumentException(
170 OUString::createFromAscii(pStr
) +
171 ": verifyInput(): rectangle point X1 contains infinite or NAN",
175 if( !::rtl::math::isFinite( rRect
.Y1
) )
177 throw lang::IllegalArgumentException(
178 OUString::createFromAscii(pStr
) +
179 ": verifyInput(): rectangle point Y1 contains infinite or NAN",
183 if( !::rtl::math::isFinite( rRect
.X2
) )
185 throw lang::IllegalArgumentException(
186 OUString::createFromAscii(pStr
) +
187 ": verifyInput(): rectangle point X2 contains infinite or NAN",
191 if( !::rtl::math::isFinite( rRect
.Y2
) )
193 throw lang::IllegalArgumentException(
194 OUString::createFromAscii(pStr
) +
195 ": verifyInput(): rectangle point Y2 contains infinite or NAN",
199 if( !::rtl::math::isFinite( rRect
.X1
) ||
200 !::rtl::math::isFinite( rRect
.Y1
) ||
201 !::rtl::math::isFinite( rRect
.X2
) ||
202 !::rtl::math::isFinite( rRect
.Y2
) )
204 throw lang::IllegalArgumentException();
209 void verifyInput( const geometry::AffineMatrix2D
& matrix
,
211 const uno::Reference
< uno::XInterface
>& xIf
,
212 ::sal_Int16 nArgPos
)
214 (void)pStr
; (void)xIf
; (void)nArgPos
;
216 #if OSL_DEBUG_LEVEL > 0
217 const sal_Int32
nBinaryState(
218 100000 * int(!::rtl::math::isFinite( matrix
.m00
)) +
219 10000 * int(!::rtl::math::isFinite( matrix
.m01
)) +
220 1000 * int(!::rtl::math::isFinite( matrix
.m02
)) +
221 100 * int(!::rtl::math::isFinite( matrix
.m10
)) +
222 10 * int(!::rtl::math::isFinite( matrix
.m11
)) +
223 1 * int(!::rtl::math::isFinite( matrix
.m12
)) );
227 throw lang::IllegalArgumentException(
228 OUString::createFromAscii(pStr
) +
229 ": verifyInput(): AffineMatrix2D contains infinite or NAN value(s) at the following positions (m00-m12): " +
230 OUString::number(nBinaryState
),
234 if( !::rtl::math::isFinite( matrix
.m00
) ||
235 !::rtl::math::isFinite( matrix
.m01
) ||
236 !::rtl::math::isFinite( matrix
.m02
) ||
237 !::rtl::math::isFinite( matrix
.m10
) ||
238 !::rtl::math::isFinite( matrix
.m11
) ||
239 !::rtl::math::isFinite( matrix
.m12
) )
241 throw lang::IllegalArgumentException();
246 void verifyInput( const geometry::Matrix2D
& matrix
,
248 const uno::Reference
< uno::XInterface
>& xIf
,
249 ::sal_Int16 nArgPos
)
251 (void)pStr
; (void)xIf
; (void)nArgPos
;
253 #if OSL_DEBUG_LEVEL > 0
254 const sal_Int32
nBinaryState(
255 1000 * int(!::rtl::math::isFinite( matrix
.m00
)) +
256 100 * int(!::rtl::math::isFinite( matrix
.m01
)) +
257 10 * int(!::rtl::math::isFinite( matrix
.m10
)) +
258 1 * int(!::rtl::math::isFinite( matrix
.m11
)) );
262 throw lang::IllegalArgumentException(
263 OUString::createFromAscii(pStr
) +
264 ": verifyInput(): Matrix2D contains infinite or NAN value(s) at the following positions (m00-m11): " +
265 OUString::number(nBinaryState
),
269 if( !::rtl::math::isFinite( matrix
.m00
) ||
270 !::rtl::math::isFinite( matrix
.m01
) ||
271 !::rtl::math::isFinite( matrix
.m10
) ||
272 !::rtl::math::isFinite( matrix
.m11
) )
274 throw lang::IllegalArgumentException();
279 void verifyInput( const rendering::ViewState
& viewState
,
281 const uno::Reference
< uno::XInterface
>& xIf
,
282 ::sal_Int16 nArgPos
)
284 verifyInput( viewState
.AffineTransform
,
285 pStr
, xIf
, nArgPos
);
288 void verifyInput( const rendering::RenderState
& renderState
,
290 const uno::Reference
< uno::XInterface
>& xIf
,
292 sal_Int32 nMinColorComponents
)
294 verifyInput( renderState
.AffineTransform
,
295 pStr
, xIf
, nArgPos
);
297 if( renderState
.DeviceColor
.getLength() < nMinColorComponents
)
299 #if OSL_DEBUG_LEVEL > 0
300 throw lang::IllegalArgumentException(
301 OUString::createFromAscii(pStr
) +
302 ": verifyInput(): render state's device color has too few components (" +
303 OUString::number(nMinColorComponents
) +
305 OUString::number(renderState
.DeviceColor
.getLength()) +
309 throw lang::IllegalArgumentException();
313 if( renderState
.CompositeOperation
< rendering::CompositeOperation::CLEAR
||
314 renderState
.CompositeOperation
> rendering::CompositeOperation::SATURATE
)
316 #if OSL_DEBUG_LEVEL > 0
317 throw lang::IllegalArgumentException(
318 OUString::createFromAscii(pStr
) +
319 ": verifyInput(): render state's CompositeOperation value out of range (" +
320 OUString::number(sal::static_int_cast
<sal_Int32
>(renderState
.CompositeOperation
)) +
324 throw lang::IllegalArgumentException();
329 void verifyInput( const rendering::Texture
& texture
,
331 const uno::Reference
< uno::XInterface
>& xIf
,
332 ::sal_Int16 nArgPos
)
334 verifyInput( texture
.AffineTransform
,
335 pStr
, xIf
, nArgPos
);
337 if( !::rtl::math::isFinite( texture
.Alpha
) ||
338 texture
.Alpha
< 0.0 ||
339 texture
.Alpha
> 1.0 )
341 #if OSL_DEBUG_LEVEL > 0
342 throw lang::IllegalArgumentException(
343 OUString::createFromAscii(pStr
) +
344 ": verifyInput(): textures' alpha value out of range (is " +
345 OUString::number(texture
.Alpha
) + ")",
348 throw lang::IllegalArgumentException();
352 if( texture
.NumberOfHatchPolygons
< 0 )
354 #if OSL_DEBUG_LEVEL > 0
355 throw lang::IllegalArgumentException(
356 OUString::createFromAscii(pStr
) +
357 ": verifyInput(): textures' NumberOfHatchPolygons is negative",
360 throw lang::IllegalArgumentException();
364 if( texture
.RepeatModeX
< rendering::TexturingMode::NONE
||
365 texture
.RepeatModeX
> rendering::TexturingMode::REPEAT
)
367 #if OSL_DEBUG_LEVEL > 0
368 throw lang::IllegalArgumentException(
369 OUString::createFromAscii(pStr
) +
370 ": verifyInput(): textures' RepeatModeX value is out of range (" +
371 OUString::number(sal::static_int_cast
<sal_Int32
>(texture
.RepeatModeX
)) +
375 throw lang::IllegalArgumentException();
379 if( texture
.RepeatModeY
< rendering::TexturingMode::NONE
||
380 texture
.RepeatModeY
> rendering::TexturingMode::REPEAT
)
382 #if OSL_DEBUG_LEVEL > 0
383 throw lang::IllegalArgumentException(
384 OUString::createFromAscii(pStr
) +
385 ": verifyInput(): textures' RepeatModeY value is out of range (" +
386 OUString::number(sal::static_int_cast
<sal_Int32
>(texture
.RepeatModeY
)) +
390 throw lang::IllegalArgumentException();
397 struct VerifyDashValue
399 VerifyDashValue( const char* pStr
,
400 const uno::Reference
< uno::XInterface
>& xIf
,
401 ::sal_Int16 nArgPos
) :
408 void operator()( const double& rVal
)
410 if( !::rtl::math::isFinite( rVal
) || rVal
< 0.0 )
412 #if OSL_DEBUG_LEVEL > 0
413 throw lang::IllegalArgumentException(
414 OUString::createFromAscii(mpStr
) +
415 ": verifyInput(): one of stroke attributes' DashArray value out of range (is " +
416 OUString::number(rVal
) + ")",
419 throw lang::IllegalArgumentException();
425 const uno::Reference
< uno::XInterface
>& mrIf
;
430 void verifyInput( const rendering::StrokeAttributes
& strokeAttributes
,
432 const uno::Reference
< uno::XInterface
>& xIf
,
433 ::sal_Int16 nArgPos
)
435 if( !::rtl::math::isFinite( strokeAttributes
.StrokeWidth
) ||
436 strokeAttributes
.StrokeWidth
< 0.0 )
438 #if OSL_DEBUG_LEVEL > 0
439 throw lang::IllegalArgumentException(
440 OUString::createFromAscii(pStr
) +
441 ": verifyInput(): stroke attributes' StrokeWidth value out of range (is " +
442 OUString::number(strokeAttributes
.StrokeWidth
) +
446 throw lang::IllegalArgumentException();
450 if( !::rtl::math::isFinite( strokeAttributes
.MiterLimit
) ||
451 strokeAttributes
.MiterLimit
< 0.0 )
453 #if OSL_DEBUG_LEVEL > 0
454 throw lang::IllegalArgumentException(
455 OUString::createFromAscii(pStr
) +
456 ": verifyInput(): stroke attributes' MiterLimit value out of range (is " +
457 OUString::number(strokeAttributes
.MiterLimit
) + ")",
460 throw lang::IllegalArgumentException();
464 ::std::for_each( strokeAttributes
.DashArray
.getConstArray(),
465 strokeAttributes
.DashArray
.getConstArray() + strokeAttributes
.DashArray
.getLength(),
466 VerifyDashValue( pStr
, xIf
, nArgPos
) );
468 ::std::for_each( strokeAttributes
.LineArray
.getConstArray(),
469 strokeAttributes
.LineArray
.getConstArray() + strokeAttributes
.LineArray
.getLength(),
470 VerifyDashValue( pStr
, xIf
, nArgPos
) );
472 if( strokeAttributes
.StartCapType
< rendering::PathCapType::BUTT
||
473 strokeAttributes
.StartCapType
> rendering::PathCapType::SQUARE
)
475 #if OSL_DEBUG_LEVEL > 0
476 throw lang::IllegalArgumentException(
477 OUString::createFromAscii(pStr
) +
478 ": verifyInput(): stroke attributes' StartCapType value is out of range (" +
479 OUString::number(sal::static_int_cast
<sal_Int32
>(strokeAttributes
.StartCapType
)) +
483 throw lang::IllegalArgumentException();
487 if( strokeAttributes
.EndCapType
< rendering::PathCapType::BUTT
||
488 strokeAttributes
.EndCapType
> rendering::PathCapType::SQUARE
)
490 #if OSL_DEBUG_LEVEL > 0
491 throw lang::IllegalArgumentException(
492 OUString::createFromAscii(pStr
) +
493 ": verifyInput(): stroke attributes' StartCapType value is out of range (" +
494 OUString::number(sal::static_int_cast
<sal_Int32
>(strokeAttributes
.EndCapType
)) +
498 throw lang::IllegalArgumentException();
502 if( strokeAttributes
.JoinType
< rendering::PathJoinType::NONE
||
503 strokeAttributes
.JoinType
> rendering::PathJoinType::BEVEL
)
505 #if OSL_DEBUG_LEVEL > 0
506 throw lang::IllegalArgumentException(
507 OUString::createFromAscii(pStr
) +
508 ": verifyInput(): stroke attributes' JoinType value is out of range (" +
509 OUString::number(sal::static_int_cast
<sal_Int32
>(strokeAttributes
.JoinType
)) +
513 throw lang::IllegalArgumentException();
518 void verifyInput( const rendering::IntegerBitmapLayout
& bitmapLayout
,
520 const uno::Reference
< uno::XInterface
>& xIf
,
521 ::sal_Int16 nArgPos
)
523 (void)pStr
; (void)xIf
; (void)nArgPos
;
525 if( bitmapLayout
.ScanLines
< 0 )
527 #if OSL_DEBUG_LEVEL > 0
528 throw lang::IllegalArgumentException(
529 OUString::createFromAscii(pStr
) +
530 ": verifyInput(): bitmap layout's ScanLines is negative",
533 throw lang::IllegalArgumentException();
537 if( bitmapLayout
.ScanLineBytes
< 0 )
539 #if OSL_DEBUG_LEVEL > 0
540 throw lang::IllegalArgumentException(
541 OUString::createFromAscii(pStr
) +
542 ": verifyInput(): bitmap layout's ScanLineBytes is negative",
545 throw lang::IllegalArgumentException();
549 if( !bitmapLayout
.ColorSpace
.is() )
551 #if OSL_DEBUG_LEVEL > 0
552 throw lang::IllegalArgumentException(
553 OUString::createFromAscii(pStr
) +
554 ": verifyInput(): bitmap layout's ColorSpace is invalid",
557 throw lang::IllegalArgumentException();
562 if( bitmapLayout
.ColorSpace
->getBitsPerPixel() < 0 )
564 #if OSL_DEBUG_LEVEL > 0
565 throw lang::IllegalArgumentException(
566 OUString::createFromAscii(pStr
) +
567 ": verifyInput(): bitmap layout's ColorSpace getBitsPerPixel() is negative",
570 throw lang::IllegalArgumentException();
574 if( bitmapLayout
.ColorSpace
->getEndianness() < util::Endianness::LITTLE
||
575 bitmapLayout
.ColorSpace
->getEndianness() > util::Endianness::BIG
)
577 #if OSL_DEBUG_LEVEL > 0
578 throw lang::IllegalArgumentException(
579 OUString::createFromAscii(pStr
) +
580 ": verifyInput(): bitmap layout's ColorSpace getEndianness() value is out of range (" +
581 OUString::number(sal::static_int_cast
<sal_Int32
>(bitmapLayout
.ColorSpace
->getEndianness())) +
585 throw lang::IllegalArgumentException();
591 void verifyInput( const rendering::FontInfo
& /*fontInfo*/,
592 const char* /*pStr*/,
593 const uno::Reference
< uno::XInterface
>& /*xIf*/,
594 ::sal_Int16
/*nArgPos*/ )
596 // TODO(E3): Implement FontDescription checks, once the
597 // Panose stuff is ready.
600 void verifyInput( const rendering::FontRequest
& fontRequest
,
602 const uno::Reference
< uno::XInterface
>& xIf
,
603 ::sal_Int16 nArgPos
)
605 verifyInput( fontRequest
.FontDescription
,
606 pStr
, xIf
, nArgPos
);
608 if( !::rtl::math::isFinite( fontRequest
.CellSize
) )
610 #if OSL_DEBUG_LEVEL > 0
611 throw lang::IllegalArgumentException(
612 OUString::createFromAscii(pStr
) +
613 ": verifyInput(): font request's CellSize value contains infinite or NAN",
616 throw lang::IllegalArgumentException();
620 if( !::rtl::math::isFinite( fontRequest
.ReferenceAdvancement
) )
622 #if OSL_DEBUG_LEVEL > 0
623 throw lang::IllegalArgumentException(
624 OUString::createFromAscii(pStr
) +
625 ": verifyInput(): font request's ReferenceAdvancement value contains infinite or NAN",
628 throw lang::IllegalArgumentException();
632 if( fontRequest
.CellSize
!= 0.0 &&
633 fontRequest
.ReferenceAdvancement
!= 0.0 )
635 #if OSL_DEBUG_LEVEL > 0
636 throw lang::IllegalArgumentException(
637 OUString::createFromAscii(pStr
) +
638 ": verifyInput(): font request's CellSize and ReferenceAdvancement are mutually exclusive, one of them must be 0.0",
641 throw lang::IllegalArgumentException();
646 void verifyIndexRange( const geometry::IntegerRectangle2D
& rect
,
647 const geometry::IntegerSize2D
& size
)
649 const ::basegfx::B2IRange
aRect(
650 ::basegfx::unotools::b2IRectangleFromIntegerRectangle2D(
653 if( aRect
.getMinX() < 0 ||
654 aRect
.getMaxX() > size
.Width
||
655 aRect
.getMinY() < 0 ||
656 aRect
.getMaxY() > size
.Height
)
658 throw ::com::sun::star::lang::IndexOutOfBoundsException();
662 void verifyIndexRange( const geometry::IntegerPoint2D
& pos
,
663 const geometry::IntegerSize2D
& size
)
666 pos
.X
> size
.Width
||
668 pos
.Y
> size
.Height
)
670 throw ::com::sun::star::lang::IndexOutOfBoundsException();
674 void verifyBitmapSize( const geometry::IntegerSize2D
& size
,
676 const uno::Reference
< uno::XInterface
>& xIf
)
678 (void)pStr
; (void)xIf
;
680 if( size
.Width
<= 0 )
682 #if OSL_DEBUG_LEVEL > 0
683 throw lang::IllegalArgumentException(
684 OUString::createFromAscii(pStr
) +
685 ": verifyBitmapSize(): size has 0 or negative width (value: " +
686 OUString::number(size
.Width
) + ")",
689 throw lang::IllegalArgumentException();
693 if( size
.Height
<= 0 )
695 #if OSL_DEBUG_LEVEL > 0
696 throw lang::IllegalArgumentException(
697 OUString::createFromAscii(pStr
) +
698 ": verifyBitmapSize(): size has 0 or negative height (value: " +
699 OUString::number(size
.Height
) +
703 throw lang::IllegalArgumentException();
708 void verifySpriteSize( const geometry::RealSize2D
& size
,
710 const uno::Reference
< uno::XInterface
>& xIf
)
712 (void)pStr
; (void)xIf
;
714 if( size
.Width
<= 0.0 )
716 #if OSL_DEBUG_LEVEL > 0
717 throw lang::IllegalArgumentException(
718 OUString::createFromAscii(pStr
) +
719 ": verifySpriteSize(): size has 0 or negative width (value: " +
720 OUString::number(size
.Width
) + ")",
723 throw lang::IllegalArgumentException();
727 if( size
.Height
<= 0.0 )
729 #if OSL_DEBUG_LEVEL > 0
730 throw lang::IllegalArgumentException(
731 OUString::createFromAscii(pStr
) +
732 ": verifySpriteSize(): size has 0 or negative height (value: " +
733 OUString::number(size
.Height
) + ")",
736 throw lang::IllegalArgumentException();
744 } // namespace canvas
746 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */