Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */