/src/libreoffice/include/canvas/canvastools.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <com/sun/star/uno/Reference.hxx> |
23 | | #include <com/sun/star/uno/Sequence.hxx> |
24 | | #include <com/sun/star/uno/RuntimeException.hpp> |
25 | | #include <rtl/ustring.hxx> |
26 | | #include <sal/log.hxx> |
27 | | |
28 | | #include <math.h> |
29 | | #include <string.h> |
30 | | #include <vector> |
31 | | #include <limits> |
32 | | |
33 | | #include <canvas/canvastoolsdllapi.h> |
34 | | |
35 | | namespace basegfx |
36 | | { |
37 | | class B2DHomMatrix; |
38 | | class B2DRange; |
39 | | class B2IRange; |
40 | | class B2IPoint; |
41 | | class B2DPolyPolygon; |
42 | | } |
43 | | |
44 | | namespace com::sun::star::geometry |
45 | | { |
46 | | struct RealSize2D; |
47 | | struct IntegerSize2D; |
48 | | struct AffineMatrix2D; |
49 | | struct Matrix2D; |
50 | | } |
51 | | |
52 | | namespace com::sun::star::rendering |
53 | | { |
54 | | struct RenderState; |
55 | | struct ViewState; |
56 | | struct IntegerBitmapLayout; |
57 | | class XCanvas; |
58 | | struct Texture; |
59 | | class XIntegerBitmapColorSpace; |
60 | | } |
61 | | |
62 | | namespace com::sun::star::awt |
63 | | { |
64 | | struct Rectangle; |
65 | | class XWindow2; |
66 | | } |
67 | | |
68 | | namespace com::sun::star::beans { |
69 | | struct PropertyValue; |
70 | | } |
71 | | |
72 | | class Color; |
73 | | class OutputDevice; |
74 | | |
75 | | namespace canvastools |
76 | | { |
77 | | /** Compute the next highest power of 2 of a 32-bit value |
78 | | |
79 | | Code devised by Sean Anderson, in good ole HAKMEM |
80 | | tradition. |
81 | | |
82 | | @return 1 << (lg(x - 1) + 1) |
83 | | */ |
84 | | inline sal_uInt32 nextPow2( sal_uInt32 x ) |
85 | 0 | { |
86 | 0 | --x; |
87 | 0 | x |= x >> 1; |
88 | 0 | x |= x >> 2; |
89 | 0 | x |= x >> 4; |
90 | 0 | x |= x >> 8; |
91 | 0 | x |= x >> 16; |
92 | 0 |
|
93 | 0 | return ++x; |
94 | 0 | } |
95 | | |
96 | | /** |
97 | | * |
98 | | * Count the number of 1-bits of a n-bit value |
99 | | * |
100 | | */ |
101 | | |
102 | | /** Round given floating point value down to next integer |
103 | | */ |
104 | | inline sal_Int32 roundDown( const double& rVal ) |
105 | 0 | { |
106 | 0 | return static_cast< sal_Int32 >( floor( rVal ) ); |
107 | 0 | } |
108 | | |
109 | | /** Round given floating point value up to next integer |
110 | | */ |
111 | | inline sal_Int32 roundUp( const double& rVal ) |
112 | 0 | { |
113 | 0 | return static_cast< sal_Int32 >( ceil( rVal ) ); |
114 | 0 | } |
115 | | |
116 | | /** Create a RealSize2D with both coordinate values set to +infinity |
117 | | */ |
118 | | CANVASTOOLS_DLLPUBLIC css::geometry::RealSize2D createInfiniteSize2D(); |
119 | | |
120 | | |
121 | | // View- and RenderState utilities |
122 | | |
123 | | |
124 | | CANVASTOOLS_DLLPUBLIC css::rendering::RenderState& |
125 | | initRenderState( css::rendering::RenderState& renderState ); |
126 | | |
127 | | CANVASTOOLS_DLLPUBLIC css::rendering::ViewState& |
128 | | initViewState( css::rendering::ViewState& viewState ); |
129 | | |
130 | | CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix |
131 | | getViewStateTransform( const css::rendering::ViewState& viewState ); |
132 | | |
133 | | CANVASTOOLS_DLLPUBLIC css::rendering::ViewState& |
134 | | setViewStateTransform( css::rendering::ViewState& viewState, |
135 | | const ::basegfx::B2DHomMatrix& transform ); |
136 | | |
137 | | CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix |
138 | | getRenderStateTransform( const css::rendering::RenderState& renderState ); |
139 | | |
140 | | CANVASTOOLS_DLLPUBLIC css::rendering::RenderState& |
141 | | setRenderStateTransform( css::rendering::RenderState& renderState, |
142 | | const ::basegfx::B2DHomMatrix& transform ); |
143 | | |
144 | | CANVASTOOLS_DLLPUBLIC css::rendering::RenderState& |
145 | | appendToRenderState( css::rendering::RenderState& renderState, |
146 | | const ::basegfx::B2DHomMatrix& transform ); |
147 | | |
148 | | CANVASTOOLS_DLLPUBLIC css::rendering::RenderState& |
149 | | prependToRenderState( css::rendering::RenderState& renderState, |
150 | | const ::basegfx::B2DHomMatrix& transform ); |
151 | | |
152 | | CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix& |
153 | | mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix& transform, |
154 | | const css::rendering::ViewState& viewState, |
155 | | const css::rendering::RenderState& renderState ); |
156 | | |
157 | | |
158 | | // Matrix utilities |
159 | | |
160 | | |
161 | | CANVASTOOLS_DLLPUBLIC css::geometry::AffineMatrix2D& |
162 | | setIdentityAffineMatrix2D( css::geometry::AffineMatrix2D& matrix ); |
163 | | |
164 | | CANVASTOOLS_DLLPUBLIC css::geometry::Matrix2D& |
165 | | setIdentityMatrix2D( css::geometry::Matrix2D& matrix ); |
166 | | |
167 | | |
168 | | // Special utilities |
169 | | |
170 | | |
171 | | /** Calc the bounding rectangle of a transformed rectangle. |
172 | | |
173 | | The method applies the given transformation to the |
174 | | specified input rectangle, and returns the bounding box of |
175 | | the resulting output area. |
176 | | |
177 | | @param i_Rect |
178 | | Input rectangle |
179 | | |
180 | | @param i_Transformation |
181 | | Transformation to apply to the input rectangle |
182 | | |
183 | | @return the resulting rectangle |
184 | | */ |
185 | | CANVASTOOLS_DLLPUBLIC ::basegfx::B2DRange calcTransformedRectBounds( |
186 | | const ::basegfx::B2DRange& i_Rect, |
187 | | const ::basegfx::B2DHomMatrix& i_Transformation ); |
188 | | |
189 | | /** Calc a transform that maps the upper, left corner of a |
190 | | rectangle to the origin. |
191 | | |
192 | | The method is a specialized version of |
193 | | calcRectToRectTransform() (Removed now), mapping the input rectangle's |
194 | | the upper, left corner to the origin, and leaving the size |
195 | | untouched. |
196 | | |
197 | | @param i_srcRect |
198 | | Input parameter, specifies the original source |
199 | | rectangle. The resulting transformation will exactly map |
200 | | the source rectangle's upper, left corner to the origin. |
201 | | |
202 | | @param i_transformation |
203 | | The original transformation matrix. This is changed with |
204 | | translations (if necessary), to exactly map the source |
205 | | rectangle to the origin. |
206 | | |
207 | | @return the resulting transformation matrix |
208 | | |
209 | | @see calcRectToRectTransform() |
210 | | @see calcTransformedRectBounds() |
211 | | */ |
212 | | CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix calcRectToOriginTransform( |
213 | | const ::basegfx::B2DRange& i_srcRect, |
214 | | const ::basegfx::B2DHomMatrix& i_transformation ); |
215 | | |
216 | | /** Check whether a given rectangle is within another |
217 | | transformed rectangle. |
218 | | |
219 | | This method checks for polygonal containedness, i.e. the |
220 | | transformed rectangle is not represented as an axis-aligned |
221 | | rectangle anymore (like calcTransformedRectBounds()), but |
222 | | polygonal. Thus, the insideness test is based on tight |
223 | | bounds. |
224 | | |
225 | | @param rContainedRect |
226 | | This rectangle is checked, whether it is fully within the |
227 | | transformed rTransformRect. |
228 | | |
229 | | @param rTransformRect |
230 | | This rectangle is transformed, and then checked whether it |
231 | | fully contains rContainedRect. |
232 | | |
233 | | @param rTransformation |
234 | | This transformation is applied to rTransformRect |
235 | | */ |
236 | | CANVASTOOLS_DLLPUBLIC bool isInside( const ::basegfx::B2DRange& rContainedRect, |
237 | | const ::basegfx::B2DRange& rTransformRect, |
238 | | const ::basegfx::B2DHomMatrix& rTransformation ); |
239 | | |
240 | | /** Clip a scroll to the given bound rect |
241 | | |
242 | | @param io_rSourceArea |
243 | | Source area to scroll. The resulting clipped source area |
244 | | is returned therein. |
245 | | |
246 | | @param io_rDestPoint |
247 | | Destination point of the scroll (upper, left corner of |
248 | | rSourceArea after the scroll). The new, resulting |
249 | | destination point is returned therein.q |
250 | | |
251 | | @param o_ClippedAreas |
252 | | Vector of rectangles in the <em>destination</em> area |
253 | | coordinate system, which are clipped away from the source |
254 | | area, and thus need extra updates (i.e. they are not |
255 | | correctly copy from the scroll operation, since there was |
256 | | no information about them in the source). |
257 | | |
258 | | @param rBounds |
259 | | Bounds to clip against. |
260 | | |
261 | | @return false, if the resulting scroll area is empty |
262 | | */ |
263 | | CANVASTOOLS_DLLPUBLIC bool clipScrollArea( ::basegfx::B2IRange& io_rSourceArea, |
264 | | ::basegfx::B2IPoint& io_rDestPoint, |
265 | | ::std::vector< ::basegfx::B2IRange >& o_ClippedAreas, |
266 | | const ::basegfx::B2IRange& rBounds ); |
267 | | |
268 | | /** Clip a blit between two differently surfaces. |
269 | | |
270 | | This method clips source and dest rect for a clip between |
271 | | two differently clipped surfaces, such that the resulting |
272 | | blit rects are fully within both clip areas. |
273 | | |
274 | | @param io_rSourceArea |
275 | | Source area of the blit. Returned therein is the computed |
276 | | clipped source area. |
277 | | |
278 | | @param io_rDestPoint |
279 | | Dest area of the blit. Returned therein is the computed |
280 | | clipped dest area. |
281 | | |
282 | | @param rSourceBounds |
283 | | Clip bounds of the source surface |
284 | | |
285 | | @param rDestBounds |
286 | | Clip bounds of the dest surface |
287 | | |
288 | | @return false, if the resulting blit is empty, i.e. fully |
289 | | clipped away. |
290 | | */ |
291 | | CANVASTOOLS_DLLPUBLIC ::basegfx::B2IRange spritePixelAreaFromB2DRange( const ::basegfx::B2DRange& rRange ); |
292 | | |
293 | | /** Retrieve various internal properties of the actual canvas implementation. |
294 | | |
295 | | This method retrieves a bunch of internal, implementation- |
296 | | and platform-dependent values from the canvas |
297 | | implementation. Among them are for example operating |
298 | | system window handles. The actual layout and content of |
299 | | the returned sequence is dependent on the component |
300 | | implementation, undocumented and subject to change. |
301 | | |
302 | | @param i_rxCanvas |
303 | | Input parameter, the canvas representation for which the device information |
304 | | is to be retrieved |
305 | | |
306 | | @param o_rxParams |
307 | | Output parameter, the sequence of Anys that hold the device parameters. Layout is as described above |
308 | | |
309 | | @return A reference to the resulting sequence of parameters |
310 | | */ |
311 | | CANVASTOOLS_DLLPUBLIC css::uno::Sequence< css::uno::Any >& getDeviceInfo( |
312 | | const css::uno::Reference< css::rendering::XCanvas >& i_rxCanvas, |
313 | | css::uno::Sequence< css::uno::Any >& o_rxParams ); |
314 | | |
315 | | /** Return a color space for a default RGBA integer format |
316 | | |
317 | | Use this method for dead-simple bitmap implementations, |
318 | | that map all their formats to 8888 RGBA color. |
319 | | */ |
320 | | CANVASTOOLS_DLLPUBLIC css::uno::Reference< css::rendering::XIntegerBitmapColorSpace> const & getStdColorSpace(); |
321 | | |
322 | | /** Return a color space for a default RGB integer format |
323 | | |
324 | | Use this method for dead-simple bitmap implementations, |
325 | | that map all their formats to 8888 RGB color (the last byte |
326 | | is unused). |
327 | | */ |
328 | | CANVASTOOLS_DLLPUBLIC css::uno::Reference< css::rendering::XIntegerBitmapColorSpace> const & getStdColorSpaceWithoutAlpha(); |
329 | | |
330 | | /** Return a memory layout for a default RGBA integer format |
331 | | |
332 | | Use this method for dead-simple bitmap implementations, |
333 | | that map all their formats to 8888 RGBA color. |
334 | | */ |
335 | | CANVASTOOLS_DLLPUBLIC css::rendering::IntegerBitmapLayout getStdMemoryLayout( |
336 | | const css::geometry::IntegerSize2D& rBitmapSize ); |
337 | | |
338 | | /// Convert standard 8888 RGBA color to vcl color |
339 | | CANVASTOOLS_DLLPUBLIC css::uno::Sequence<sal_Int8> colorToStdIntSequence( const ::Color& rColor ); |
340 | | |
341 | | // Modelled closely after boost::numeric_cast, only that we |
342 | | // issue some trace output here and throw a RuntimeException |
343 | | |
344 | | /** Cast numeric value into another (numeric) data type |
345 | | |
346 | | Apart from converting the numeric value, this template |
347 | | also checks if any overflow, underflow, or sign |
348 | | information is lost (if yes, it throws an |
349 | | uno::RuntimeException. |
350 | | */ |
351 | | template< typename Target, typename Source > inline Target numeric_cast( Source arg ) |
352 | 0 | { |
353 | | // typedefs abbreviating respective trait classes |
354 | 0 | typedef ::std::numeric_limits< Source > SourceLimits; |
355 | 0 | typedef ::std::numeric_limits< Target > TargetLimits; |
356 | |
|
357 | 0 | #undef min |
358 | 0 | #undef max |
359 | |
|
360 | 0 | if( ( arg<0 && !TargetLimits::is_signed) || // losing the sign here |
361 | 0 | ( SourceLimits::is_signed && arg<TargetLimits::min()) || // underflow will happen |
362 | 0 | ( arg>TargetLimits::max() ) ) // overflow will happen |
363 | 0 | { |
364 | | # if OSL_DEBUG_LEVEL > 2 |
365 | | SAL_WARN("canvas", "numeric_cast detected data loss"); |
366 | | #endif |
367 | 0 | throw css::uno::RuntimeException( |
368 | 0 | u"numeric_cast detected data loss"_ustr, |
369 | 0 | nullptr ); |
370 | 0 | } |
371 | | |
372 | 0 | return static_cast<Target>(arg); |
373 | 0 | } Unexecuted instantiation: unsigned short canvastools::numeric_cast<unsigned short, int>(int) Unexecuted instantiation: signed char canvastools::numeric_cast<signed char, int>(int) |
374 | | |
375 | | CANVASTOOLS_DLLPUBLIC css::awt::Rectangle getAbsoluteWindowRect( |
376 | | const css::awt::Rectangle& rRect, |
377 | | const css::uno::Reference< css::awt::XWindow2 >& xWin ); |
378 | | |
379 | | /** Retrieve for small bound marks around each corner of the given rectangle |
380 | | */ |
381 | | CANVASTOOLS_DLLPUBLIC ::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange ); |
382 | | |
383 | | /** Calculate number of gradient "strips" to generate (takes |
384 | | into account device resolution) |
385 | | |
386 | | @param nColorSteps |
387 | | Maximal integer difference between all color stops, needed |
388 | | for smooth gradient color differences |
389 | | */ |
390 | | CANVASTOOLS_DLLPUBLIC int calcGradientStepCount( ::basegfx::B2DHomMatrix& rTotalTransform, |
391 | | const css::rendering::ViewState& viewState, |
392 | | const css::rendering::RenderState& renderState, |
393 | | const css::rendering::Texture& texture, |
394 | | int nColorSteps ); |
395 | | |
396 | | /** A very simplistic map for ASCII strings and arbitrary value |
397 | | types. |
398 | | |
399 | | This class internally references a constant, static array of |
400 | | sorted MapEntries, and performs a binary search to look up |
401 | | values for a given query string. Note that this map is static, |
402 | | i.e. not meant to be extended at runtime. |
403 | | |
404 | | @tpl ValueType |
405 | | The value type this map should store, associated with an ASCII |
406 | | string. |
407 | | */ |
408 | | template< typename ValueType > class ValueMap |
409 | | { |
410 | | public: |
411 | | struct MapEntry |
412 | | { |
413 | | const char* maKey; |
414 | | ValueType maValue; |
415 | | }; |
416 | | |
417 | | /** Create a ValueMap for the given array of MapEntries. |
418 | | |
419 | | @param pMap |
420 | | Pointer to a <em>static</em> array of MapEntries. Must |
421 | | live longer than this object! Make absolutely sure that |
422 | | the string entries passed via pMap are ASCII-only - |
423 | | everything else might not yield correct string |
424 | | comparisons, and thus will result in undefined behaviour. |
425 | | |
426 | | @param nEntries |
427 | | Number of entries for pMap |
428 | | |
429 | | @param bCaseSensitive |
430 | | Whether the map query should be performed case sensitive |
431 | | or not. When bCaseSensitive is false, all MapEntry strings |
432 | | must be lowercase! |
433 | | */ |
434 | | ValueMap( const MapEntry* pMap, |
435 | | ::std::size_t nEntries, |
436 | | bool bCaseSensitive ) : |
437 | 0 | mpMap( pMap ), |
438 | 0 | mnEntries( nEntries ), |
439 | 0 | mbCaseSensitive( bCaseSensitive ) |
440 | 0 | { |
441 | | #ifdef DBG_UTIL |
442 | | // Ensure that map entries are sorted (and all lowercase, if this |
443 | | // map is case insensitive) |
444 | | const OString aStr( pMap->maKey ); |
445 | | if( !mbCaseSensitive && |
446 | | aStr != aStr.toAsciiLowerCase() ) |
447 | | { |
448 | | SAL_WARN("canvas", "ValueMap::ValueMap(): Key is not lowercase " << pMap->maKey); |
449 | | } |
450 | | |
451 | | if( mnEntries <= 1 ) |
452 | | return; |
453 | | |
454 | | for( ::std::size_t i=0; i<mnEntries-1; ++i, ++pMap ) |
455 | | { |
456 | | if( !mapComparator(pMap[0], pMap[1]) && |
457 | | mapComparator(pMap[1], pMap[0]) ) |
458 | | { |
459 | | SAL_WARN("canvas", "ValueMap::ValueMap(): Map is not sorted, keys are wrong, " |
460 | | << pMap[0].maKey << " and " << pMap[1].maKey); |
461 | | SAL_WARN("canvas", "ValueMap::ValueMap(): Map is not sorted" ); |
462 | | } |
463 | | |
464 | | const OString aStr2( pMap[1].maKey ); |
465 | | if( !mbCaseSensitive && |
466 | | aStr2 != aStr2.toAsciiLowerCase() ) |
467 | | { |
468 | | SAL_WARN("canvas", "ValueMap::ValueMap(): Key is not lowercase" << pMap[1].maKey); |
469 | | } |
470 | | } |
471 | | #endif |
472 | 0 | } |
473 | | |
474 | | /** Lookup a value for the given query string |
475 | | |
476 | | @param rName |
477 | | The string to lookup. If the map was created with the case |
478 | | insensitive flag, the lookup is performed |
479 | | case-insensitive, otherwise, case-sensitive. |
480 | | |
481 | | @param o_rResult |
482 | | Output parameter, which receives the value associated with |
483 | | the query string. If no value was found, the referenced |
484 | | object is kept unmodified. |
485 | | |
486 | | @return true, if a matching entry was found. |
487 | | */ |
488 | | bool lookup( const OUString& rName, |
489 | | ValueType& o_rResult ) const |
490 | 0 | { |
491 | | // rName is required to contain only ASCII characters. |
492 | | // TODO(Q1): Enforce this at upper layers |
493 | 0 | OString aKey( OUStringToOString( mbCaseSensitive ? rName : rName.toAsciiLowerCase(), |
494 | 0 | RTL_TEXTENCODING_ASCII_US ) ); |
495 | 0 | MapEntry aSearchKey = |
496 | 0 | { |
497 | 0 | aKey.getStr(), |
498 | 0 | ValueType() |
499 | 0 | }; |
500 | |
|
501 | 0 | const MapEntry* pEnd = mpMap+mnEntries; |
502 | 0 | const MapEntry* pRes = ::std::lower_bound( mpMap, |
503 | 0 | pEnd, |
504 | 0 | aSearchKey, |
505 | 0 | &mapComparator ); |
506 | 0 | if( pRes != pEnd ) |
507 | 0 | { |
508 | | // place to _insert before_ found - is it equal to |
509 | | // the search key? |
510 | 0 | if( strcmp( pRes->maKey, aSearchKey.maKey ) == 0 ) |
511 | 0 | { |
512 | | // yep, correct entry found |
513 | 0 | o_rResult = pRes->maValue; |
514 | 0 | return true; |
515 | 0 | } |
516 | 0 | } |
517 | | |
518 | | // not found |
519 | 0 | return false; |
520 | 0 | } |
521 | | |
522 | | private: |
523 | | static bool mapComparator( const MapEntry& rLHS, |
524 | | const MapEntry& rRHS ) |
525 | 0 | { |
526 | 0 | return strcmp( rLHS.maKey, |
527 | 0 | rRHS.maKey ) < 0; |
528 | 0 | } |
529 | | |
530 | | const MapEntry* mpMap; |
531 | | ::std::size_t mnEntries; |
532 | | bool mbCaseSensitive; |
533 | | }; |
534 | | |
535 | | CANVASTOOLS_DLLPUBLIC void clipOutDev(const css::rendering::ViewState& viewState, |
536 | | const css::rendering::RenderState& renderState, |
537 | | OutputDevice& rOutDev); |
538 | | |
539 | | CANVASTOOLS_DLLPUBLIC void extractExtraFontProperties(const css::uno::Sequence<css::beans::PropertyValue>& rExtraFontProperties, |
540 | | sal_uInt32& rEmphasisMark); |
541 | | } |
542 | | |
543 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |