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 .
20 #ifndef INCLUDED_CANVAS_CANVASTOOLS_HXX
21 #define INCLUDED_CANVAS_CANVASTOOLS_HXX
23 #include <rtl/math.hxx>
24 #include <com/sun/star/uno/Reference.hxx>
25 #include <com/sun/star/uno/Sequence.hxx>
26 #include <com/sun/star/uno/RuntimeException.hpp>
27 #include <com/sun/star/lang/IllegalArgumentException.hpp>
28 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
29 #include <osl/diagnose.h>
30 #include <rtl/ustring.hxx>
37 #include <canvas/canvastoolsdllapi.h>
48 namespace com
{ namespace sun
{ namespace star
{ namespace geometry
52 struct AffineMatrix2D
;
56 namespace com
{ namespace sun
{ namespace star
{ namespace rendering
60 struct IntegerBitmapLayout
;
63 class XIntegerBitmapColorSpace
;
67 namespace com
{ namespace sun
{ namespace star
{ namespace awt
80 /** Compute the next highest power of 2 of a 32-bit value
82 Code devised by Sean Anderson, in good ole HAKMEM
85 @return 1 << (lg(x - 1) + 1)
87 inline sal_uInt32
nextPow2( sal_uInt32 x
)
101 * Count the number of 1-bits of an n-bit value
105 /** Round given floating point value down to next integer
107 inline sal_Int32
roundDown( const double& rVal
)
109 return static_cast< sal_Int32
>( floor( rVal
) );
112 /** Round given floating point value up to next integer
114 inline sal_Int32
roundUp( const double& rVal
)
116 return static_cast< sal_Int32
>( ceil( rVal
) );
119 /** Create a RealSize2D with both coordinate values set to +infinity
121 CANVASTOOLS_DLLPUBLIC
css::geometry::RealSize2D
createInfiniteSize2D();
124 // View- and RenderState utilities
127 CANVASTOOLS_DLLPUBLIC
css::rendering::RenderState
&
128 initRenderState( css::rendering::RenderState
& renderState
);
130 CANVASTOOLS_DLLPUBLIC
css::rendering::ViewState
&
131 initViewState( css::rendering::ViewState
& viewState
);
133 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
&
134 getViewStateTransform( ::basegfx::B2DHomMatrix
& transform
,
135 const css::rendering::ViewState
& viewState
);
137 CANVASTOOLS_DLLPUBLIC
css::rendering::ViewState
&
138 setViewStateTransform( css::rendering::ViewState
& viewState
,
139 const ::basegfx::B2DHomMatrix
& transform
);
141 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
&
142 getRenderStateTransform( ::basegfx::B2DHomMatrix
& transform
,
143 const css::rendering::RenderState
& renderState
);
145 CANVASTOOLS_DLLPUBLIC
css::rendering::RenderState
&
146 setRenderStateTransform( css::rendering::RenderState
& renderState
,
147 const ::basegfx::B2DHomMatrix
& transform
);
149 CANVASTOOLS_DLLPUBLIC
css::rendering::RenderState
&
150 appendToRenderState( css::rendering::RenderState
& renderState
,
151 const ::basegfx::B2DHomMatrix
& transform
);
153 CANVASTOOLS_DLLPUBLIC
css::rendering::RenderState
&
154 prependToRenderState( css::rendering::RenderState
& renderState
,
155 const ::basegfx::B2DHomMatrix
& transform
);
157 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
&
158 mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix
& transform
,
159 const css::rendering::ViewState
& viewState
,
160 const css::rendering::RenderState
& renderState
);
166 CANVASTOOLS_DLLPUBLIC
css::geometry::AffineMatrix2D
&
167 setIdentityAffineMatrix2D( css::geometry::AffineMatrix2D
& matrix
);
169 CANVASTOOLS_DLLPUBLIC
css::geometry::Matrix2D
&
170 setIdentityMatrix2D( css::geometry::Matrix2D
& matrix
);
176 /** Calc the bounding rectangle of a transformed rectangle.
178 The method applies the given transformation to the
179 specified input rectangle, and returns the bounding box of
180 the resulting output area.
188 @param i_Transformation
189 Transformation to apply to the input rectangle
191 @return a reference to the resulting rectangle
193 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DRange
& calcTransformedRectBounds( ::basegfx::B2DRange
& o_Rect
,
194 const ::basegfx::B2DRange
& i_Rect
,
195 const ::basegfx::B2DHomMatrix
& i_Transformation
);
197 /** Calc a transform that maps the upper, left corner of a
198 rectangle to the origin.
200 The method is a specialized version of
201 calcRectToRectTransform() (Removed now), mapping the input rectangle's
202 the upper, left corner to the origin, and leaving the size
206 Output parameter, to receive the resulting transformation
210 Input parameter, specifies the original source
211 rectangle. The resulting transformation will exactly map
212 the source rectangle's upper, left corner to the origin.
214 @param i_transformation
215 The original transformation matrix. This is changed with
216 translations (if necessary), to exactly map the source
217 rectangle to the origin.
219 @return a reference to the resulting transformation matrix
221 @see calcRectToRectTransform()
222 @see calcTransformedRectBounds()
224 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
& calcRectToOriginTransform( ::basegfx::B2DHomMatrix
& o_transform
,
225 const ::basegfx::B2DRange
& i_srcRect
,
226 const ::basegfx::B2DHomMatrix
& i_transformation
);
228 /** Check whether a given rectangle is within another
229 transformed rectangle.
231 This method checks for polygonal containedness, i.e. the
232 transformed rectangle is not represented as an axis-aligned
233 rectangle anymore (like calcTransformedRectBounds()), but
234 polygonal. Thus, the insideness test is based on tight
237 @param rContainedRect
238 This rectangle is checked, whether it is fully within the
239 transformed rTransformRect.
241 @param rTransformRect
242 This rectangle is transformed, and then checked whether it
243 fully contains rContainedRect.
245 @param rTransformation
246 This transformation is applied to rTransformRect
248 CANVASTOOLS_DLLPUBLIC
bool isInside( const ::basegfx::B2DRange
& rContainedRect
,
249 const ::basegfx::B2DRange
& rTransformRect
,
250 const ::basegfx::B2DHomMatrix
& rTransformation
);
252 /** Clip a scroll to the given bound rect
254 @param io_rSourceArea
255 Source area to scroll. The resulting clipped source area
259 Destination point of the scroll (upper, left corner of
260 rSourceArea after the scroll). The new, resulting
261 destination point is returned therein.q
263 @param o_ClippedAreas
264 Vector of rectangles in the <em>destination</em> area
265 coordinate system, which are clipped away from the source
266 area, and thus need extra updates (i.e. they are not
267 correctly copy from the scroll operation, since there was
268 no information about them in the source).
271 Bounds to clip against.
273 @return false, if the resulting scroll area is empty
275 CANVASTOOLS_DLLPUBLIC
bool clipScrollArea( ::basegfx::B2IRange
& io_rSourceArea
,
276 ::basegfx::B2IPoint
& io_rDestPoint
,
277 ::std::vector
< ::basegfx::B2IRange
>& o_ClippedAreas
,
278 const ::basegfx::B2IRange
& rBounds
);
280 /** Clip a blit between two differently surfaces.
282 This method clips source and dest rect for a clip between
283 two differently clipped surfaces, such that the resulting
284 blit rects are fully within both clip areas.
286 @param io_rSourceArea
287 Source area of the blit. Returned therein is the computed
291 Dest area of the blit. Returned therein is the computed
295 Clip bounds of the source surface
298 Clip bounds of the dest surface
300 @return false, if the resulting blit is empty, i.e. fully
303 CANVASTOOLS_DLLPUBLIC ::basegfx::B2IRange
spritePixelAreaFromB2DRange( const ::basegfx::B2DRange
& rRange
);
305 /** Retrieve various internal properties of the actual canvas implementation.
307 This method retrieves a bunch of internal, implementation-
308 and platform-dependent values from the canvas
309 implementation. Among them are for example operating
310 system window handles. The actual layout and content of
311 the returned sequence is dependent on the component
312 implementation, undocumented and subject to change.
315 Input parameter, the canvas representation for which the device information
319 Output parameter, the sequence of Anys that hold the device parameters. Layout is as described above
321 @return A reference to the resulting sequence of parameters
323 CANVASTOOLS_DLLPUBLIC
css::uno::Sequence
< css::uno::Any
>& getDeviceInfo(
324 const css::uno::Reference
< css::rendering::XCanvas
>& i_rxCanvas
,
325 css::uno::Sequence
< css::uno::Any
>& o_rxParams
);
327 /** Return a color space for a default RGBA integer format
329 Use this method for dead-simple bitmap implementations,
330 that map all their formats to 8888 RGBA color.
332 CANVASTOOLS_DLLPUBLIC
css::uno::Reference
< css::rendering::XIntegerBitmapColorSpace
> getStdColorSpace();
334 /** Return a color space for a default RGB integer format
336 Use this method for dead-simple bitmap implementations,
337 that map all their formats to 8888 RGB color (the last byte
340 CANVASTOOLS_DLLPUBLIC
css::uno::Reference
< css::rendering::XIntegerBitmapColorSpace
> getStdColorSpaceWithoutAlpha();
342 /** Return a memory layout for a default RGBA integer format
344 Use this method for dead-simple bitmap implementations,
345 that map all their formats to 8888 RGBA color.
347 CANVASTOOLS_DLLPUBLIC
css::rendering::IntegerBitmapLayout
getStdMemoryLayout(
348 const css::geometry::IntegerSize2D
& rBitmapSize
);
350 /// Convert standard 8888 RGBA color to vcl color
351 CANVASTOOLS_DLLPUBLIC ::Color
stdIntSequenceToColor( const css::uno::Sequence
<sal_Int8
>& rColor
);
353 /// Convert standard 8888 RGBA color to vcl color
354 CANVASTOOLS_DLLPUBLIC
css::uno::Sequence
<sal_Int8
> colorToStdIntSequence( const ::Color
& rColor
);
356 // Modelled closely after boost::numeric_cast, only that we
357 // issue some trace output here and throw a RuntimeException
359 /** Cast numeric value into another (numeric) data type
361 Apart from converting the numeric value, this template
362 also checks if any overflow, underflow, or sign
363 information is lost (if yes, it throws an
364 uno::RuntimeException.
366 template< typename Target
, typename Source
> inline Target
numeric_cast( Source arg
)
368 // typedefs abbreviating respective trait classes
369 typedef ::std::numeric_limits
< Source
> SourceLimits
;
370 typedef ::std::numeric_limits
< Target
> TargetLimits
;
375 if( ( arg
<0 && !TargetLimits::is_signed
) || // losing the sign here
376 ( SourceLimits::is_signed
&& arg
<TargetLimits::min()) || // underflow will happen
377 ( arg
>TargetLimits::max() ) ) // overflow will happen
379 # if OSL_DEBUG_LEVEL > 2
380 OSL_TRACE("numeric_cast detected data loss");
382 throw css::uno::RuntimeException(
383 "numeric_cast detected data loss",
387 return static_cast<Target
>(arg
);
390 CANVASTOOLS_DLLPUBLIC
css::awt::Rectangle
getAbsoluteWindowRect(
391 const css::awt::Rectangle
& rRect
,
392 const css::uno::Reference
< css::awt::XWindow2
>& xWin
);
394 /** Retrieve for small bound marks around each corner of the given rectangle
396 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DPolyPolygon
getBoundMarksPolyPolygon( const ::basegfx::B2DRange
& rRange
);
398 /** Calculate number of gradient "strips" to generate (takes
399 into account device resolution)
402 Maximal integer difference between all color stops, needed
403 for smooth gradient color differences
405 CANVASTOOLS_DLLPUBLIC
int calcGradientStepCount( ::basegfx::B2DHomMatrix
& rTotalTransform
,
406 const css::rendering::ViewState
& viewState
,
407 const css::rendering::RenderState
& renderState
,
408 const css::rendering::Texture
& texture
,
411 /** A very simplistic map for ASCII strings and arbitrary value
414 This class internally references a constant, static array of
415 sorted MapEntries, and performs a binary search to look up
416 values for a given query string. Note that this map is static,
417 i.e. not meant to be extended at runtime.
420 The value type this map should store, associated with an ASCII
423 template< typename ValueType
> class ValueMap
432 /** Create a ValueMap for the given array of MapEntries.
435 Pointer to a <em>static</em> array of MapEntries. Must
436 live longer than this object! Make absolutely sure that
437 the string entries passed via pMap are ASCII-only -
438 everything else might not yield correct string
439 comparisons, and thus will result in undefined behaviour.
442 Number of entries for pMap
444 @param bCaseSensitive
445 Whether the map query should be performed case sensitive
446 or not. When bCaseSensitive is false, all MapEntry strings
449 ValueMap( const MapEntry
* pMap
,
450 ::std::size_t nEntries
,
451 bool bCaseSensitive
) :
453 mnEntries( nEntries
),
454 mbCaseSensitive( bCaseSensitive
)
457 // Ensure that map entries are sorted (and all lowercase, if this
458 // map is case insensitive)
459 const OString
aStr( pMap
->maKey
);
460 if( !mbCaseSensitive
&&
461 aStr
!= aStr
.toAsciiLowerCase() )
463 OSL_TRACE("ValueMap::ValueMap(): Key %s is not lowercase",
465 OSL_FAIL( "ValueMap::ValueMap(): Key is not lowercase" );
470 for( ::std::size_t i
=0; i
<mnEntries
-1; ++i
, ++pMap
)
472 if( !mapComparator(pMap
[0], pMap
[1]) &&
473 mapComparator(pMap
[1], pMap
[0]) )
475 OSL_TRACE("ValueMap::ValueMap(): Map is not sorted, keys %s and %s are wrong",
478 OSL_FAIL( "ValueMap::ValueMap(): Map is not sorted" );
481 const OString
aStr2( pMap
[1].maKey
);
482 if( !mbCaseSensitive
&&
483 aStr2
!= aStr2
.toAsciiLowerCase() )
485 OSL_TRACE("ValueMap::ValueMap(): Key %s is not lowercase",
487 OSL_FAIL( "ValueMap::ValueMap(): Key is not lowercase" );
494 /** Lookup a value for the given query string
497 The string to lookup. If the map was created with the case
498 insensitive flag, the lookup is performed
499 case-insensitive, otherwise, case-sensitive.
502 Output parameter, which receives the value associated with
503 the query string. If no value was found, the referenced
504 object is kept unmodified.
506 @return true, if a matching entry was found.
508 bool lookup( const OUString
& rName
,
509 ValueType
& o_rResult
) const
511 // rName is required to contain only ASCII characters.
512 // TODO(Q1): Enforce this at upper layers
513 OString
aKey( OUStringToOString( mbCaseSensitive
? rName
: rName
.toAsciiLowerCase(),
514 RTL_TEXTENCODING_ASCII_US
) );
515 MapEntry aSearchKey
=
521 const MapEntry
* pRes
;
522 const MapEntry
* pEnd
= mpMap
+mnEntries
;
523 if( (pRes
=::std::lower_bound( mpMap
,
526 &mapComparator
)) != pEnd
)
528 // place to _insert before_ found - is it equal to
530 if( strcmp( pRes
->maKey
, aSearchKey
.maKey
) == 0 )
532 // yep, correct entry found
533 o_rResult
= pRes
->maValue
;
543 static bool mapComparator( const MapEntry
& rLHS
,
544 const MapEntry
& rRHS
)
546 return strcmp( rLHS
.maKey
,
550 const MapEntry
* mpMap
;
551 ::std::size_t mnEntries
;
552 bool mbCaseSensitive
;
555 CANVASTOOLS_DLLPUBLIC
void clipOutDev(const css::rendering::ViewState
& viewState
,
556 const css::rendering::RenderState
& renderState
,
557 OutputDevice
& rOutDev
,
558 OutputDevice
* p2ndOutDev
=nullptr);
562 #endif /* INCLUDED_CANVAS_CANVASTOOLS_HXX */
564 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */