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 <com/sun/star/uno/Reference.hxx>
24 #include <com/sun/star/uno/Sequence.hxx>
25 #include <com/sun/star/uno/RuntimeException.hpp>
26 #include <osl/diagnose.h>
27 #include <rtl/ustring.hxx>
28 #include <sal/log.hxx>
35 #include <canvas/canvastoolsdllapi.h>
46 namespace com::sun::star::geometry
50 struct AffineMatrix2D
;
54 namespace com::sun::star::rendering
58 struct IntegerBitmapLayout
;
61 class XIntegerBitmapColorSpace
;
64 namespace com::sun::star::awt
70 namespace com::sun::star::beans
{
81 /** Compute the next highest power of 2 of a 32-bit value
83 Code devised by Sean Anderson, in good ole HAKMEM
86 @return 1 << (lg(x - 1) + 1)
88 inline sal_uInt32
nextPow2( sal_uInt32 x
)
102 * Count the number of 1-bits of a n-bit value
106 /** Round given floating point value down to next integer
108 inline sal_Int32
roundDown( const double& rVal
)
110 return static_cast< sal_Int32
>( floor( rVal
) );
113 /** Round given floating point value up to next integer
115 inline sal_Int32
roundUp( const double& rVal
)
117 return static_cast< sal_Int32
>( ceil( rVal
) );
120 /** Create a RealSize2D with both coordinate values set to +infinity
122 CANVASTOOLS_DLLPUBLIC
css::geometry::RealSize2D
createInfiniteSize2D();
125 // View- and RenderState utilities
128 CANVASTOOLS_DLLPUBLIC
css::rendering::RenderState
&
129 initRenderState( css::rendering::RenderState
& renderState
);
131 CANVASTOOLS_DLLPUBLIC
css::rendering::ViewState
&
132 initViewState( css::rendering::ViewState
& viewState
);
134 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
&
135 getViewStateTransform( ::basegfx::B2DHomMatrix
& transform
,
136 const css::rendering::ViewState
& viewState
);
138 CANVASTOOLS_DLLPUBLIC
css::rendering::ViewState
&
139 setViewStateTransform( css::rendering::ViewState
& viewState
,
140 const ::basegfx::B2DHomMatrix
& transform
);
142 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
&
143 getRenderStateTransform( ::basegfx::B2DHomMatrix
& transform
,
144 const css::rendering::RenderState
& renderState
);
146 CANVASTOOLS_DLLPUBLIC
css::rendering::RenderState
&
147 setRenderStateTransform( css::rendering::RenderState
& renderState
,
148 const ::basegfx::B2DHomMatrix
& transform
);
150 CANVASTOOLS_DLLPUBLIC
css::rendering::RenderState
&
151 appendToRenderState( css::rendering::RenderState
& renderState
,
152 const ::basegfx::B2DHomMatrix
& transform
);
154 CANVASTOOLS_DLLPUBLIC
css::rendering::RenderState
&
155 prependToRenderState( css::rendering::RenderState
& renderState
,
156 const ::basegfx::B2DHomMatrix
& transform
);
158 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
&
159 mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix
& transform
,
160 const css::rendering::ViewState
& viewState
,
161 const css::rendering::RenderState
& renderState
);
167 CANVASTOOLS_DLLPUBLIC
css::geometry::AffineMatrix2D
&
168 setIdentityAffineMatrix2D( css::geometry::AffineMatrix2D
& matrix
);
170 CANVASTOOLS_DLLPUBLIC
css::geometry::Matrix2D
&
171 setIdentityMatrix2D( css::geometry::Matrix2D
& matrix
);
177 /** Calc the bounding rectangle of a transformed rectangle.
179 The method applies the given transformation to the
180 specified input rectangle, and returns the bounding box of
181 the resulting output area.
189 @param i_Transformation
190 Transformation to apply to the input rectangle
192 @return a reference to the resulting rectangle
194 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DRange
& calcTransformedRectBounds( ::basegfx::B2DRange
& o_Rect
,
195 const ::basegfx::B2DRange
& i_Rect
,
196 const ::basegfx::B2DHomMatrix
& i_Transformation
);
198 /** Calc a transform that maps the upper, left corner of a
199 rectangle to the origin.
201 The method is a specialized version of
202 calcRectToRectTransform() (Removed now), mapping the input rectangle's
203 the upper, left corner to the origin, and leaving the size
207 Output parameter, to receive the resulting transformation
211 Input parameter, specifies the original source
212 rectangle. The resulting transformation will exactly map
213 the source rectangle's upper, left corner to the origin.
215 @param i_transformation
216 The original transformation matrix. This is changed with
217 translations (if necessary), to exactly map the source
218 rectangle to the origin.
220 @return a reference to the resulting transformation matrix
222 @see calcRectToRectTransform()
223 @see calcTransformedRectBounds()
225 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix
& calcRectToOriginTransform( ::basegfx::B2DHomMatrix
& o_transform
,
226 const ::basegfx::B2DRange
& i_srcRect
,
227 const ::basegfx::B2DHomMatrix
& i_transformation
);
229 /** Check whether a given rectangle is within another
230 transformed rectangle.
232 This method checks for polygonal containedness, i.e. the
233 transformed rectangle is not represented as an axis-aligned
234 rectangle anymore (like calcTransformedRectBounds()), but
235 polygonal. Thus, the insideness test is based on tight
238 @param rContainedRect
239 This rectangle is checked, whether it is fully within the
240 transformed rTransformRect.
242 @param rTransformRect
243 This rectangle is transformed, and then checked whether it
244 fully contains rContainedRect.
246 @param rTransformation
247 This transformation is applied to rTransformRect
249 CANVASTOOLS_DLLPUBLIC
bool isInside( const ::basegfx::B2DRange
& rContainedRect
,
250 const ::basegfx::B2DRange
& rTransformRect
,
251 const ::basegfx::B2DHomMatrix
& rTransformation
);
253 /** Clip a scroll to the given bound rect
255 @param io_rSourceArea
256 Source area to scroll. The resulting clipped source area
260 Destination point of the scroll (upper, left corner of
261 rSourceArea after the scroll). The new, resulting
262 destination point is returned therein.q
264 @param o_ClippedAreas
265 Vector of rectangles in the <em>destination</em> area
266 coordinate system, which are clipped away from the source
267 area, and thus need extra updates (i.e. they are not
268 correctly copy from the scroll operation, since there was
269 no information about them in the source).
272 Bounds to clip against.
274 @return false, if the resulting scroll area is empty
276 CANVASTOOLS_DLLPUBLIC
bool clipScrollArea( ::basegfx::B2IRange
& io_rSourceArea
,
277 ::basegfx::B2IPoint
& io_rDestPoint
,
278 ::std::vector
< ::basegfx::B2IRange
>& o_ClippedAreas
,
279 const ::basegfx::B2IRange
& rBounds
);
281 /** Clip a blit between two differently surfaces.
283 This method clips source and dest rect for a clip between
284 two differently clipped surfaces, such that the resulting
285 blit rects are fully within both clip areas.
287 @param io_rSourceArea
288 Source area of the blit. Returned therein is the computed
292 Dest area of the blit. Returned therein is the computed
296 Clip bounds of the source surface
299 Clip bounds of the dest surface
301 @return false, if the resulting blit is empty, i.e. fully
304 CANVASTOOLS_DLLPUBLIC ::basegfx::B2IRange
spritePixelAreaFromB2DRange( const ::basegfx::B2DRange
& rRange
);
306 /** Retrieve various internal properties of the actual canvas implementation.
308 This method retrieves a bunch of internal, implementation-
309 and platform-dependent values from the canvas
310 implementation. Among them are for example operating
311 system window handles. The actual layout and content of
312 the returned sequence is dependent on the component
313 implementation, undocumented and subject to change.
316 Input parameter, the canvas representation for which the device information
320 Output parameter, the sequence of Anys that hold the device parameters. Layout is as described above
322 @return A reference to the resulting sequence of parameters
324 CANVASTOOLS_DLLPUBLIC
css::uno::Sequence
< css::uno::Any
>& getDeviceInfo(
325 const css::uno::Reference
< css::rendering::XCanvas
>& i_rxCanvas
,
326 css::uno::Sequence
< css::uno::Any
>& o_rxParams
);
328 /** Return a color space for a default RGBA integer format
330 Use this method for dead-simple bitmap implementations,
331 that map all their formats to 8888 RGBA color.
333 CANVASTOOLS_DLLPUBLIC
css::uno::Reference
< css::rendering::XIntegerBitmapColorSpace
> const & getStdColorSpace();
335 /** Return a color space for a default RGB integer format
337 Use this method for dead-simple bitmap implementations,
338 that map all their formats to 8888 RGB color (the last byte
341 CANVASTOOLS_DLLPUBLIC
css::uno::Reference
< css::rendering::XIntegerBitmapColorSpace
> const & getStdColorSpaceWithoutAlpha();
343 /** Return a memory layout for a default RGBA integer format
345 Use this method for dead-simple bitmap implementations,
346 that map all their formats to 8888 RGBA color.
348 CANVASTOOLS_DLLPUBLIC
css::rendering::IntegerBitmapLayout
getStdMemoryLayout(
349 const css::geometry::IntegerSize2D
& rBitmapSize
);
351 /// Convert standard 8888 RGBA color to vcl color
352 CANVASTOOLS_DLLPUBLIC
css::uno::Sequence
<sal_Int8
> colorToStdIntSequence( const ::Color
& rColor
);
354 // Modelled closely after boost::numeric_cast, only that we
355 // issue some trace output here and throw a RuntimeException
357 /** Cast numeric value into another (numeric) data type
359 Apart from converting the numeric value, this template
360 also checks if any overflow, underflow, or sign
361 information is lost (if yes, it throws an
362 uno::RuntimeException.
364 template< typename Target
, typename Source
> inline Target
numeric_cast( Source arg
)
366 // typedefs abbreviating respective trait classes
367 typedef ::std::numeric_limits
< Source
> SourceLimits
;
368 typedef ::std::numeric_limits
< Target
> TargetLimits
;
373 if( ( arg
<0 && !TargetLimits::is_signed
) || // losing the sign here
374 ( SourceLimits::is_signed
&& arg
<TargetLimits::min()) || // underflow will happen
375 ( arg
>TargetLimits::max() ) ) // overflow will happen
377 # if OSL_DEBUG_LEVEL > 2
378 SAL_WARN("canvas", "numeric_cast detected data loss");
380 throw css::uno::RuntimeException(
381 "numeric_cast detected data loss",
385 return static_cast<Target
>(arg
);
388 CANVASTOOLS_DLLPUBLIC
css::awt::Rectangle
getAbsoluteWindowRect(
389 const css::awt::Rectangle
& rRect
,
390 const css::uno::Reference
< css::awt::XWindow2
>& xWin
);
392 /** Retrieve for small bound marks around each corner of the given rectangle
394 CANVASTOOLS_DLLPUBLIC ::basegfx::B2DPolyPolygon
getBoundMarksPolyPolygon( const ::basegfx::B2DRange
& rRange
);
396 /** Calculate number of gradient "strips" to generate (takes
397 into account device resolution)
400 Maximal integer difference between all color stops, needed
401 for smooth gradient color differences
403 CANVASTOOLS_DLLPUBLIC
int calcGradientStepCount( ::basegfx::B2DHomMatrix
& rTotalTransform
,
404 const css::rendering::ViewState
& viewState
,
405 const css::rendering::RenderState
& renderState
,
406 const css::rendering::Texture
& texture
,
409 /** A very simplistic map for ASCII strings and arbitrary value
412 This class internally references a constant, static array of
413 sorted MapEntries, and performs a binary search to look up
414 values for a given query string. Note that this map is static,
415 i.e. not meant to be extended at runtime.
418 The value type this map should store, associated with an ASCII
421 template< typename ValueType
> class ValueMap
430 /** Create a ValueMap for the given array of MapEntries.
433 Pointer to a <em>static</em> array of MapEntries. Must
434 live longer than this object! Make absolutely sure that
435 the string entries passed via pMap are ASCII-only -
436 everything else might not yield correct string
437 comparisons, and thus will result in undefined behaviour.
440 Number of entries for pMap
442 @param bCaseSensitive
443 Whether the map query should be performed case sensitive
444 or not. When bCaseSensitive is false, all MapEntry strings
447 ValueMap( const MapEntry
* pMap
,
448 ::std::size_t nEntries
,
449 bool bCaseSensitive
) :
451 mnEntries( nEntries
),
452 mbCaseSensitive( bCaseSensitive
)
455 // Ensure that map entries are sorted (and all lowercase, if this
456 // map is case insensitive)
457 const OString
aStr( pMap
->maKey
);
458 if( !mbCaseSensitive
&&
459 aStr
!= aStr
.toAsciiLowerCase() )
461 SAL_WARN("canvas", "ValueMap::ValueMap(): Key is not lowercase " << pMap
->maKey
);
466 for( ::std::size_t i
=0; i
<mnEntries
-1; ++i
, ++pMap
)
468 if( !mapComparator(pMap
[0], pMap
[1]) &&
469 mapComparator(pMap
[1], pMap
[0]) )
471 SAL_WARN("canvas", "ValueMap::ValueMap(): Map is not sorted, keys are wrong, "
472 << pMap
[0].maKey
<< " and " << pMap
[1].maKey
);
473 OSL_FAIL( "ValueMap::ValueMap(): Map is not sorted" );
476 const OString
aStr2( pMap
[1].maKey
);
477 if( !mbCaseSensitive
&&
478 aStr2
!= aStr2
.toAsciiLowerCase() )
480 SAL_WARN("canvas", "ValueMap::ValueMap(): Key is not lowercase" << pMap
[1].maKey
);
487 /** Lookup a value for the given query string
490 The string to lookup. If the map was created with the case
491 insensitive flag, the lookup is performed
492 case-insensitive, otherwise, case-sensitive.
495 Output parameter, which receives the value associated with
496 the query string. If no value was found, the referenced
497 object is kept unmodified.
499 @return true, if a matching entry was found.
501 bool lookup( const OUString
& rName
,
502 ValueType
& o_rResult
) const
504 // rName is required to contain only ASCII characters.
505 // TODO(Q1): Enforce this at upper layers
506 OString
aKey( OUStringToOString( mbCaseSensitive
? rName
: rName
.toAsciiLowerCase(),
507 RTL_TEXTENCODING_ASCII_US
) );
508 MapEntry aSearchKey
=
514 const MapEntry
* pEnd
= mpMap
+mnEntries
;
515 const MapEntry
* pRes
= ::std::lower_bound( mpMap
,
521 // place to _insert before_ found - is it equal to
523 if( strcmp( pRes
->maKey
, aSearchKey
.maKey
) == 0 )
525 // yep, correct entry found
526 o_rResult
= pRes
->maValue
;
536 static bool mapComparator( const MapEntry
& rLHS
,
537 const MapEntry
& rRHS
)
539 return strcmp( rLHS
.maKey
,
543 const MapEntry
* mpMap
;
544 ::std::size_t mnEntries
;
545 bool mbCaseSensitive
;
548 CANVASTOOLS_DLLPUBLIC
void clipOutDev(const css::rendering::ViewState
& viewState
,
549 const css::rendering::RenderState
& renderState
,
550 OutputDevice
& rOutDev
,
551 OutputDevice
* p2ndOutDev
=nullptr);
553 CANVASTOOLS_DLLPUBLIC
void extractExtraFontProperties(const css::uno::Sequence
<css::beans::PropertyValue
>& rExtraFontProperties
,
554 sal_uInt32
& rEmphasisMark
);
558 #endif /* INCLUDED_CANVAS_CANVASTOOLS_HXX */
560 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */