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>
32 #include <string.h> // for strcmp
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
;
66 bool operator==( const RenderState
& rLHS
,
67 const RenderState
& rRHS
);
69 bool operator==( const ViewState
& rLHS
,
70 const ViewState
& rRHS
);
73 namespace com
{ namespace sun
{ namespace star
{ namespace awt
85 /** Compute the next highest power of 2 of a 32-bit value
87 Code devised by Sean Anderson, in good ole HAKMEM
90 @return 1 << (lg(x - 1) + 1)
92 inline sal_uInt32
nextPow2( sal_uInt32 x
)
106 * Count the number of 1-bits of an n-bit value
110 // mickey's math tricks...
111 inline unsigned int pow2( unsigned int c
) { return 0x1 << c
; }
112 inline unsigned int mask( unsigned int c
) { return ((unsigned int)(-1)) / (pow2(pow2(c
)) + 1); }
113 inline unsigned int count( unsigned int x
, unsigned int c
) { return ((x
) & mask(c
)) + (((x
) >> (pow2(c
))) & mask(c
)); }
115 inline unsigned int bitcount( T c
) {
116 unsigned int nByteIndex
= 0;
117 unsigned int nNumBytes
= sizeof(T
)<<2;
119 c
=count(c
,nByteIndex
++);
124 inline sal_uInt32
bitcount32( sal_uInt32 c
) {
133 /** Round given floating point value down to next integer
135 inline sal_Int32
roundDown( const double& rVal
)
137 return static_cast< sal_Int32
>( floor( rVal
) );
140 /** Round given floating point value up to next integer
142 inline sal_Int32
roundUp( const double& rVal
)
144 return static_cast< sal_Int32
>( ceil( rVal
) );
147 /** Create a RealSize2D with both coordinate values set to +infinity
149 CANVASTOOLS_DLLPUBLIC ::com::sun::star::geometry::RealSize2D
createInfiniteSize2D();
152 // View- and RenderState utilities
153 // ===================================================================
155 CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::RenderState
&
156 initRenderState( ::com::sun::star::rendering::RenderState
& renderState
);
158 CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::ViewState
&
159 initViewState( ::com::sun::star::rendering::ViewState
& viewState
);
161 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
&
162 getViewStateTransform( ::basegfx::B2DHomMatrix
& transform
,
163 const ::com::sun::star::rendering::ViewState
& viewState
);
165 CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::ViewState
&
166 setViewStateTransform( ::com::sun::star::rendering::ViewState
& viewState
,
167 const ::basegfx::B2DHomMatrix
& transform
);
169 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
&
170 getRenderStateTransform( ::basegfx::B2DHomMatrix
& transform
,
171 const ::com::sun::star::rendering::RenderState
& renderState
);
173 CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::RenderState
&
174 setRenderStateTransform( ::com::sun::star::rendering::RenderState
& renderState
,
175 const ::basegfx::B2DHomMatrix
& transform
);
177 CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::RenderState
&
178 appendToRenderState( ::com::sun::star::rendering::RenderState
& renderState
,
179 const ::basegfx::B2DHomMatrix
& transform
);
181 CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::RenderState
&
182 prependToRenderState( ::com::sun::star::rendering::RenderState
& renderState
,
183 const ::basegfx::B2DHomMatrix
& transform
);
185 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
&
186 mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix
& transform
,
187 const ::com::sun::star::rendering::ViewState
& viewState
,
188 const ::com::sun::star::rendering::RenderState
& renderState
);
192 // ===================================================================
194 CANVASTOOLS_DLLPUBLIC ::com::sun::star::geometry::AffineMatrix2D
&
195 setIdentityAffineMatrix2D( ::com::sun::star::geometry::AffineMatrix2D
& matrix
);
197 CANVASTOOLS_DLLPUBLIC ::com::sun::star::geometry::Matrix2D
&
198 setIdentityMatrix2D( ::com::sun::star::geometry::Matrix2D
& matrix
);
202 // ===================================================================
204 /** Calc the bounding rectangle of a transformed rectangle.
206 The method applies the given transformation to the
207 specified input rectangle, and returns the bounding box of
208 the resulting output area.
216 @param i_Transformation
217 Transformation to apply to the input rectangle
219 @return a reference to the resulting rectangle
221 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DRange
& calcTransformedRectBounds( ::basegfx::B2DRange
& o_Rect
,
222 const ::basegfx::B2DRange
& i_Rect
,
223 const ::basegfx::B2DHomMatrix
& i_Transformation
);
225 /** Calc a transform that maps the upper, left corner of a
226 rectangle to the origin.
228 The method is a specialized version of
229 calcRectToRectTransform() (Removed now), mapping the input rectangle's
230 the upper, left corner to the origin, and leaving the size
234 Output parameter, to receive the resulting transformation
238 Input parameter, specifies the original source
239 rectangle. The resulting transformation will exactly map
240 the source rectangle's upper, left corner to the origin.
242 @param i_transformation
243 The original transformation matrix. This is changed with
244 translations (if necessary), to exactly map the source
245 rectangle to the origin.
247 @return a reference to the resulting transformation matrix
249 @see calcRectToRectTransform()
250 @see calcTransformedRectBounds()
252 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
& calcRectToOriginTransform( ::basegfx::B2DHomMatrix
& o_transform
,
253 const ::basegfx::B2DRange
& i_srcRect
,
254 const ::basegfx::B2DHomMatrix
& i_transformation
);
256 /** Check whether a given rectangle is within another
257 transformed rectangle.
259 This method checks for polygonal containedness, i.e. the
260 transformed rectangle is not represented as an axis-alignd
261 rectangle anymore (like calcTransformedRectBounds()), but
262 polygonal. Thus, the insideness test is based on tight
265 @param rContainedRect
266 This rectangle is checked, whether it is fully within the
267 transformed rTransformRect.
269 @param rTransformRect
270 This rectangle is transformed, and then checked whether it
271 fully contains rContainedRect.
273 @param rTransformation
274 This transformation is applied to rTransformRect
276 CANVASTOOLS_DLLPUBLIC
bool isInside( const ::basegfx::B2DRange
& rContainedRect
,
277 const ::basegfx::B2DRange
& rTransformRect
,
278 const ::basegfx::B2DHomMatrix
& rTransformation
);
280 /** Clip a scroll to the given bound rect
282 @param io_rSourceArea
283 Source area to scroll. The resulting clipped source area
287 Destination point of the scroll (upper, left corner of
288 rSourceArea after the scroll). The new, resulting
289 destination point is returned therein.q
291 @param o_ClippedAreas
292 Vector of rectangles in the <em>destination</em> area
293 coordinate system, which are clipped away from the source
294 area, and thus need extra updates (i.e. they are not
295 correctly copy from the scroll operation, since there was
296 no information about them in the source).
299 Bounds to clip against.
301 @return false, if the resulting scroll area is empty
303 CANVASTOOLS_DLLPUBLIC
bool clipScrollArea( ::basegfx::B2IRange
& io_rSourceArea
,
304 ::basegfx::B2IPoint
& io_rDestPoint
,
305 ::std::vector
< ::basegfx::B2IRange
>& o_ClippedAreas
,
306 const ::basegfx::B2IRange
& rBounds
);
308 /** Clip a blit between two differently surfaces.
310 This method clips source and dest rect for a clip between
311 two differently clipped surfaces, such that the resulting
312 blit rects are fully within both clip areas.
314 @param io_rSourceArea
315 Source area of the blit. Returned therein is the computed
319 Dest area of the blit. Returned therein is the computed
323 Clip bounds of the source surface
326 Clip bounds of the dest surface
328 @return false, if the resulting blit is empty, i.e. fully
331 CANVASTOOLS_DLLPUBLIC ::basegfx::B2IRange
spritePixelAreaFromB2DRange( const ::basegfx::B2DRange
& rRange
);
333 /** Retrieve various internal properties of the actual canvas implementation.
335 This method retrieves a bunch of internal, implementation-
336 and platform-dependent values from the canvas
337 implementation. Among them are for example operating
338 system window handles. The actual layout and content of
339 the returned sequence is dependent on the component
340 implementation, undocumented and subject to change.
343 Input parameter, the canvas representation for which the device information
347 Output parameter, the sequence of Anys that hold the device parameters. Layout is as described above
349 @return A reference to the resulting sequence of parameters
351 CANVASTOOLS_DLLPUBLIC ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Any
>& getDeviceInfo(
352 const ::com::sun::star::uno::Reference
< ::com::sun::star::rendering::XCanvas
>& i_rxCanvas
,
353 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Any
>& o_rxParams
);
355 /** Return a color space for a default RGBA integer format
357 Use this method for dead-simple bitmap implementations,
358 that map all their formats to 8888 RGBA color.
360 CANVASTOOLS_DLLPUBLIC ::com::sun::star::uno::Reference
< ::com::sun::star::rendering::XIntegerBitmapColorSpace
> getStdColorSpace();
362 /** Return a color space for a default RGB integer format
364 Use this method for dead-simple bitmap implementations,
365 that map all their formats to 8888 RGB color (the last byte
368 CANVASTOOLS_DLLPUBLIC ::com::sun::star::uno::Reference
< ::com::sun::star::rendering::XIntegerBitmapColorSpace
> getStdColorSpaceWithoutAlpha();
370 /** Return a memory layout for a default RGBA integer format
372 Use this method for dead-simple bitmap implementations,
373 that map all their formats to 8888 RGBA color.
375 CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::IntegerBitmapLayout
getStdMemoryLayout(
376 const ::com::sun::star::geometry::IntegerSize2D
& rBitmapSize
);
378 /// Convert standard 8888 RGBA color to vcl color
379 CANVASTOOLS_DLLPUBLIC ::Color
stdIntSequenceToColor( const ::com::sun::star::uno::Sequence
<sal_Int8
>& rColor
);
381 /// Convert standard 8888 RGBA color to vcl color
382 CANVASTOOLS_DLLPUBLIC ::com::sun::star::uno::Sequence
<sal_Int8
> colorToStdIntSequence( const ::Color
& rColor
);
384 // Modeled closely after boost::numeric_cast, only that we
385 // issue some trace output here and throw a RuntimeException
387 /** Cast numeric value into another (numeric) data type
389 Apart from converting the numeric value, this template
390 also checks if any overflow, underflow, or sign
391 information is lost (if yes, it throws an
392 uno::RuntimeException.
394 template< typename Target
, typename Source
> inline Target
numeric_cast( Source arg
)
396 // typedefs abbreviating respective trait classes
397 typedef ::std::numeric_limits
< Source
> SourceLimits
;
398 typedef ::std::numeric_limits
< Target
> TargetLimits
;
403 if( ( arg
<0 && !TargetLimits::is_signed
) || // loosing the sign here
404 ( SourceLimits::is_signed
&& arg
<TargetLimits::min()) || // underflow will happen
405 ( arg
>TargetLimits::max() ) ) // overflow will happen
407 # if OSL_DEBUG_LEVEL > 2
408 OSL_TRACE("numeric_cast detected data loss");
410 throw ::com::sun::star::uno::RuntimeException(
411 "numeric_cast detected data loss",
415 return static_cast<Target
>(arg
);
418 CANVASTOOLS_DLLPUBLIC ::com::sun::star::awt::Rectangle
getAbsoluteWindowRect(
419 const ::com::sun::star::awt::Rectangle
& rRect
,
420 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow2
>& xWin
);
422 /** Retrieve for small bound marks around each corner of the given rectangle
424 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DPolyPolygon
getBoundMarksPolyPolygon( const ::basegfx::B2DRange
& rRange
);
426 /** Calculate number of gradient "strips" to generate (takes
427 into account device resolution)
430 Maximal integer difference between all color stops, needed
431 for smooth gradient color differences
433 CANVASTOOLS_DLLPUBLIC
int calcGradientStepCount( ::basegfx::B2DHomMatrix
& rTotalTransform
,
434 const ::com::sun::star::rendering::ViewState
& viewState
,
435 const ::com::sun::star::rendering::RenderState
& renderState
,
436 const ::com::sun::star::rendering::Texture
& texture
,
439 /** A very simplistic map for ASCII strings and arbitrary value
442 This class internally references a constant, static array of
443 sorted MapEntries, and performs a binary search to look up
444 values for a given query string. Note that this map is static,
445 i.e. not meant to be extented at runtime.
448 The value type this map should store, associated with an ASCII
451 template< typename ValueType
> class ValueMap
460 /** Create a ValueMap for the given array of MapEntries.
463 Pointer to a <em>static</em> array of MapEntries. Must
464 live longer than this object! Make absolutely sure that
465 the string entries passed via pMap are ASCII-only -
466 everything else might not yield correct string
467 comparisons, and thus will result in undefined behaviour.
470 Number of entries for pMap
472 @param bCaseSensitive
473 Whether the map query should be performed case sensitive
474 or not. When bCaseSensitive is false, all MapEntry strings
477 ValueMap( const MapEntry
* pMap
,
478 ::std::size_t nEntries
,
479 bool bCaseSensitive
) :
481 mnEntries( nEntries
),
482 mbCaseSensitive( bCaseSensitive
)
485 // Ensure that map entries are sorted (and all lowercase, if this
486 // map is case insensitive)
487 const OString
aStr( pMap
->maKey
);
488 if( !mbCaseSensitive
&&
489 aStr
!= aStr
.toAsciiLowerCase() )
491 OSL_TRACE("ValueMap::ValueMap(): Key %s is not lowercase",
493 OSL_FAIL( "ValueMap::ValueMap(): Key is not lowercase" );
498 for( ::std::size_t i
=0; i
<mnEntries
-1; ++i
, ++pMap
)
500 if( !mapComparator(pMap
[0], pMap
[1]) &&
501 mapComparator(pMap
[1], pMap
[0]) )
503 OSL_TRACE("ValueMap::ValueMap(): Map is not sorted, keys %s and %s are wrong",
506 OSL_FAIL( "ValueMap::ValueMap(): Map is not sorted" );
509 const OString
aStr2( pMap
[1].maKey
);
510 if( !mbCaseSensitive
&&
511 aStr2
!= aStr2
.toAsciiLowerCase() )
513 OSL_TRACE("ValueMap::ValueMap(): Key %s is not lowercase",
515 OSL_FAIL( "ValueMap::ValueMap(): Key is not lowercase" );
522 /** Lookup a value for the given query string
525 The string to lookup. If the map was created with the case
526 insensitive flag, the lookup is performed
527 case-insensitive, otherwise, case-sensitive.
530 Output parameter, which receives the value associated with
531 the query string. If no value was found, the referenced
532 object is kept unmodified.
534 @return true, if a matching entry was found.
536 bool lookup( const OUString
& rName
,
537 ValueType
& o_rResult
) const
539 // rName is required to contain only ASCII characters.
540 // TODO(Q1): Enforce this at upper layers
541 OString
aKey( OUStringToOString( mbCaseSensitive
? rName
: rName
.toAsciiLowerCase(),
542 RTL_TEXTENCODING_ASCII_US
) );
543 MapEntry aSearchKey
=
549 const MapEntry
* pRes
;
550 const MapEntry
* pEnd
= mpMap
+mnEntries
;
551 if( (pRes
=::std::lower_bound( mpMap
,
554 &mapComparator
)) != pEnd
)
556 // place to _insert before_ found - is it equal to
558 if( strcmp( pRes
->maKey
, aSearchKey
.maKey
) == 0 )
560 // yep, correct entry found
561 o_rResult
= pRes
->maValue
;
571 static bool mapComparator( const MapEntry
& rLHS
,
572 const MapEntry
& rRHS
)
574 return strcmp( rLHS
.maKey
,
578 const MapEntry
* mpMap
;
579 ::std::size_t mnEntries
;
580 bool mbCaseSensitive
;
585 #endif /* INCLUDED_CANVAS_CANVASTOOLS_HXX */
587 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */