Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/tools/source/generic/poly2.cxx
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
#include <sal/log.hxx>
21
#include <osl/diagnose.h>
22
#include <poly.h>
23
#include <tools/poly.hxx>
24
#include <tools/debug.hxx>
25
#include <tools/stream.hxx>
26
#include <tools/vcompat.hxx>
27
#include <tools/gen.hxx>
28
#include <basegfx/polygon/b2dpolypolygon.hxx>
29
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
30
#include <basegfx/polygon/b2dpolygonclipper.hxx>
31
32
namespace tools {
33
34
PolyPolygon::PolyPolygon( sal_uInt16 nInitSize )
35
904k
    : mpImplPolyPolygon( ImplPolyPolygon( nInitSize ) )
36
904k
{
37
904k
}
38
39
PolyPolygon::PolyPolygon( const tools::Polygon& rPoly )
40
26.9k
    : mpImplPolyPolygon( rPoly )
41
26.9k
{
42
26.9k
}
43
PolyPolygon::PolyPolygon( const tools::Rectangle& rRect )
44
0
    : mpImplPolyPolygon( tools::Polygon(rRect) )
45
0
{
46
0
}
47
48
PolyPolygon::PolyPolygon( const tools::PolyPolygon& rPolyPoly )
49
804k
    : mpImplPolyPolygon( rPolyPoly.mpImplPolyPolygon )
50
804k
{
51
804k
}
52
53
PolyPolygon::PolyPolygon( tools::PolyPolygon&& rPolyPoly ) noexcept
54
81.5k
    : mpImplPolyPolygon( std::move(rPolyPoly.mpImplPolyPolygon) )
55
81.5k
{
56
81.5k
}
57
58
PolyPolygon::~PolyPolygon()
59
2.14M
{
60
2.14M
}
61
62
void PolyPolygon::Insert( const tools::Polygon& rPoly, sal_uInt16 nPos )
63
664k
{
64
664k
    assert ( mpImplPolyPolygon->mvPolyAry.size() < MAX_POLYGONS );
65
66
664k
    if ( nPos > mpImplPolyPolygon->mvPolyAry.size() )
67
664k
        nPos = mpImplPolyPolygon->mvPolyAry.size();
68
69
664k
    mpImplPolyPolygon->mvPolyAry.insert(mpImplPolyPolygon->mvPolyAry.begin() + nPos, rPoly);
70
664k
}
71
72
void PolyPolygon::Remove( sal_uInt16 nPos )
73
8.99k
{
74
8.99k
    assert(nPos < Count() && "PolyPolygon::Remove(): nPos >= nSize");
75
76
8.99k
    mpImplPolyPolygon->mvPolyAry.erase(mpImplPolyPolygon->mvPolyAry.begin() + nPos);
77
8.99k
}
78
79
void PolyPolygon::Replace( const tools::Polygon& rPoly, sal_uInt16 nPos )
80
2.83M
{
81
2.83M
    assert(nPos < Count() && "PolyPolygon::Replace(): nPos >= nSize");
82
83
2.83M
    mpImplPolyPolygon->mvPolyAry[nPos] = rPoly;
84
2.83M
}
85
86
const tools::Polygon& PolyPolygon::GetObject( sal_uInt16 nPos ) const
87
6.37M
{
88
6.37M
    assert(nPos < Count() && "PolyPolygon::GetObject(): nPos >= nSize");
89
90
6.37M
    return mpImplPolyPolygon->mvPolyAry[nPos];
91
6.37M
}
92
93
bool PolyPolygon::IsRect() const
94
26.0k
{
95
26.0k
    bool bIsRect = false;
96
26.0k
    if ( Count() == 1 )
97
20.3k
        bIsRect = mpImplPolyPolygon->mvPolyAry[ 0 ].IsRect();
98
26.0k
    return bIsRect;
99
26.0k
}
100
101
void PolyPolygon::Clear()
102
1.43M
{
103
1.43M
    mpImplPolyPolygon->mvPolyAry.clear();
104
1.43M
}
105
106
void PolyPolygon::Optimize( PolyOptimizeFlags nOptimizeFlags )
107
1.29k
{
108
1.29k
    if(!(bool(nOptimizeFlags) && Count()))
109
0
        return;
110
111
    // #115630# ImplDrawHatch does not work with beziers included in the polypolygon, take care of that
112
1.29k
    bool bIsCurve(false);
113
114
2.72k
    for(sal_uInt16 a(0); !bIsCurve && a < Count(); a++)
115
1.42k
    {
116
1.42k
        if((*this)[a].HasFlags())
117
0
        {
118
0
            bIsCurve = true;
119
0
        }
120
1.42k
    }
121
122
1.29k
    if(bIsCurve)
123
0
    {
124
0
        OSL_ENSURE(false, "Optimize does *not* support curves, falling back to AdaptiveSubdivide()...");
125
0
        tools::PolyPolygon aPolyPoly;
126
127
0
        AdaptiveSubdivide(aPolyPoly);
128
0
        aPolyPoly.Optimize(nOptimizeFlags);
129
0
        *this = std::move(aPolyPoly);
130
0
    }
131
1.29k
    else
132
1.29k
    {
133
1.29k
        double      fArea;
134
1.29k
        const bool  bEdges = ( nOptimizeFlags & PolyOptimizeFlags::EDGES ) == PolyOptimizeFlags::EDGES;
135
1.29k
        sal_uInt16      nPercent = 0;
136
137
1.29k
        if( bEdges )
138
0
        {
139
0
            const tools::Rectangle aBound( GetBoundRect() );
140
141
0
            fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5;
142
0
            nPercent = 50;
143
0
            nOptimizeFlags &= ~PolyOptimizeFlags::EDGES;
144
0
        }
145
146
        // Optimize polygons
147
2.72k
        for( sal_uInt16 i = 0, nPolyCount = mpImplPolyPolygon->mvPolyAry.size(); i < nPolyCount; i++ )
148
1.42k
        {
149
1.42k
            if( bEdges )
150
0
            {
151
0
                mpImplPolyPolygon->mvPolyAry[ i ].Optimize( PolyOptimizeFlags::NO_SAME );
152
0
                tools::Polygon::ImplReduceEdges( mpImplPolyPolygon->mvPolyAry[ i ], fArea, nPercent );
153
0
            }
154
155
1.42k
            if( bool(nOptimizeFlags) )
156
1.42k
                mpImplPolyPolygon->mvPolyAry[ i ].Optimize( nOptimizeFlags );
157
1.42k
        }
158
1.29k
    }
159
1.29k
}
160
161
void PolyPolygon::AdaptiveSubdivide( tools::PolyPolygon& rResult ) const
162
4.02k
{
163
4.02k
    rResult.Clear();
164
165
4.02k
    tools::Polygon aPolygon;
166
167
12.5k
    for( size_t i = 0; i < mpImplPolyPolygon->mvPolyAry.size(); i++ )
168
8.54k
    {
169
8.54k
        mpImplPolyPolygon->mvPolyAry[ i ].AdaptiveSubdivide( aPolygon, 1.0 );
170
8.54k
        rResult.Insert( aPolygon );
171
8.54k
    }
172
4.02k
}
173
174
tools::PolyPolygon PolyPolygon::SubdivideBezier( const tools::PolyPolygon& rPolyPoly )
175
3.46k
{
176
3.46k
    sal_uInt16 i, nPolys = rPolyPoly.Count();
177
3.46k
    tools::PolyPolygon aPolyPoly( nPolys );
178
10.4k
    for( i=0; i<nPolys; ++i )
179
6.93k
        aPolyPoly.Insert( tools::Polygon::SubdivideBezier( rPolyPoly.GetObject(i) ) );
180
181
3.46k
    return aPolyPoly;
182
3.46k
}
183
184
185
void PolyPolygon::GetIntersection( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult ) const
186
0
{
187
0
    ImplDoOperation( rPolyPoly, rResult, PolyClipOp::INTERSECT );
188
0
}
189
190
void PolyPolygon::GetUnion( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult ) const
191
0
{
192
0
    ImplDoOperation( rPolyPoly, rResult, PolyClipOp::UNION );
193
0
}
194
195
void PolyPolygon::ImplDoOperation( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult, PolyClipOp nOperation ) const
196
0
{
197
    // Convert to B2DPolyPolygon, temporarily. It might be
198
    // advantageous in the future, to have a tools::PolyPolygon adaptor that
199
    // just simulates a B2DPolyPolygon here...
200
0
    basegfx::B2DPolyPolygon aMergePolyPolygonA( getB2DPolyPolygon() );
201
0
    basegfx::B2DPolyPolygon aMergePolyPolygonB( rPolyPoly.getB2DPolyPolygon() );
202
203
    // normalize the two polypolygons before. Force properly oriented
204
    // polygons.
205
0
    aMergePolyPolygonA = basegfx::utils::prepareForPolygonOperation( aMergePolyPolygonA );
206
0
    aMergePolyPolygonB = basegfx::utils::prepareForPolygonOperation( aMergePolyPolygonB );
207
208
0
    switch( nOperation )
209
0
    {
210
        // All code extracted from svx/source/svdraw/svedtv2.cxx
211
212
0
        case PolyClipOp::UNION:
213
0
        {
214
            // merge A and B (OR)
215
0
            aMergePolyPolygonA = basegfx::utils::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
216
0
            break;
217
0
        }
218
219
0
        default:
220
0
        case PolyClipOp::INTERSECT:
221
0
        {
222
            // cut poly 1 against polys 2..n (AND)
223
0
            aMergePolyPolygonA = basegfx::utils::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB);
224
0
            break;
225
0
        }
226
0
    }
227
228
0
    rResult = tools::PolyPolygon( aMergePolyPolygonA );
229
0
}
230
231
sal_uInt16 PolyPolygon::Count() const
232
12.7M
{
233
12.7M
    return mpImplPolyPolygon->mvPolyAry.size();
234
12.7M
}
235
236
void PolyPolygon::Move( tools::Long nHorzMove, tools::Long nVertMove )
237
390k
{
238
    // Required for DrawEngine
239
390k
    if( nHorzMove || nVertMove )
240
389k
    {
241
        // move points
242
389k
        sal_uInt16 nPolyCount = mpImplPolyPolygon->mvPolyAry.size();
243
2.15M
        for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
244
1.76M
            mpImplPolyPolygon->mvPolyAry[i].Move( nHorzMove, nVertMove );
245
389k
    }
246
390k
}
247
248
void PolyPolygon::Translate( const Point& rTrans )
249
0
{
250
    // move points
251
0
    for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mvPolyAry.size(); i < nCount; i++ )
252
0
        mpImplPolyPolygon->mvPolyAry[ i ].Translate( rTrans );
253
0
}
254
255
void PolyPolygon::Scale( double fScaleX, double fScaleY )
256
112
{
257
    // Move points
258
112
    for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mvPolyAry.size(); i < nCount; i++ )
259
0
        mpImplPolyPolygon->mvPolyAry[ i ].Scale( fScaleX, fScaleY );
260
112
}
261
262
void PolyPolygon::Rotate( const Point& rCenter, Degree10 nAngle10 )
263
0
{
264
0
    nAngle10 %= 3600_deg10;
265
266
0
    if( nAngle10 )
267
0
    {
268
0
        const double fAngle = toRadians(nAngle10);
269
0
        Rotate( rCenter, sin( fAngle ), cos( fAngle ) );
270
0
    }
271
0
}
272
273
void PolyPolygon::Rotate( const Point& rCenter, double fSin, double fCos )
274
0
{
275
    // move points
276
0
    for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mvPolyAry.size(); i < nCount; i++ )
277
0
        mpImplPolyPolygon->mvPolyAry[ i ].Rotate( rCenter, fSin, fCos );
278
0
}
279
280
void PolyPolygon::Clip( const tools::Rectangle& rRect )
281
7.93k
{
282
7.93k
    sal_uInt16 nPolyCount = mpImplPolyPolygon->mvPolyAry.size();
283
7.93k
    sal_uInt16 i;
284
285
7.93k
    if ( !nPolyCount )
286
14
        return;
287
288
    // If there are bezier curves involved, Polygon::Clip() is broken.
289
    // Use a temporary B2DPolyPolygon for the clipping.
290
27.0k
    for ( i = 0; i < nPolyCount; i++ )
291
19.1k
    {
292
19.1k
        if(mpImplPolyPolygon->mvPolyAry[i].HasFlags())
293
0
        {
294
0
            const basegfx::B2DPolyPolygon aPoly(
295
0
                basegfx::utils::clipPolyPolygonOnRange(
296
0
                    getB2DPolyPolygon(),
297
0
                    basegfx::B2DRange(
298
0
                        rRect.Left(),
299
0
                        rRect.Top(),
300
0
                        rRect.Right() + 1,
301
0
                        rRect.Bottom() + 1),
302
0
                    true,
303
0
                    false));
304
0
            *this = PolyPolygon( aPoly );
305
0
            return;
306
0
        }
307
19.1k
    }
308
309
    // Clip every polygon, deleting the empty ones
310
27.0k
    for ( i = 0; i < nPolyCount; i++ )
311
19.1k
        mpImplPolyPolygon->mvPolyAry[i].Clip( rRect );
312
27.0k
    while ( nPolyCount )
313
19.1k
    {
314
19.1k
        if ( GetObject( nPolyCount-1 ).GetSize() <= 2 )
315
8.99k
            Remove( nPolyCount-1 );
316
19.1k
        nPolyCount--;
317
19.1k
    }
318
7.91k
}
319
320
tools::Rectangle PolyPolygon::GetBoundRect() const
321
53.2k
{
322
53.2k
    tools::Long    nXMin=0, nXMax=0, nYMin=0, nYMax=0;
323
53.2k
    bool    bFirst = true;
324
53.2k
    sal_uInt16  nPolyCount = mpImplPolyPolygon->mvPolyAry.size();
325
326
1.41M
    for ( sal_uInt16 n = 0; n < nPolyCount; n++ )
327
1.35M
    {
328
1.35M
        const tools::Polygon*  pPoly = &mpImplPolyPolygon->mvPolyAry[n];
329
1.35M
        const Point*    pAry = pPoly->GetConstPointAry();
330
1.35M
        sal_uInt16          nPointCount = pPoly->GetSize();
331
332
8.61M
        for ( sal_uInt16 i = 0; i < nPointCount; i++ )
333
7.25M
        {
334
7.25M
            const Point* pPt = &pAry[ i ];
335
336
7.25M
            if ( bFirst )
337
41.9k
            {
338
41.9k
                nXMin = nXMax = pPt->X();
339
41.9k
                nYMin = nYMax = pPt->Y();
340
41.9k
                bFirst = false;
341
41.9k
            }
342
7.21M
            else
343
7.21M
            {
344
7.21M
                if ( pPt->X() < nXMin )
345
24.4k
                    nXMin = pPt->X();
346
7.21M
                if ( pPt->X() > nXMax )
347
52.6k
                    nXMax = pPt->X();
348
7.21M
                if ( pPt->Y() < nYMin )
349
33.0k
                    nYMin = pPt->Y();
350
7.21M
                if ( pPt->Y() > nYMax )
351
29.2k
                    nYMax = pPt->Y();
352
7.21M
            }
353
7.25M
        }
354
1.35M
    }
355
356
53.2k
    if ( !bFirst )
357
41.9k
        return tools::Rectangle( nXMin, nYMin, nXMax, nYMax );
358
11.3k
    else
359
11.3k
        return tools::Rectangle();
360
53.2k
}
361
362
Polygon& PolyPolygon::operator[]( sal_uInt16 nPos )
363
981k
{
364
981k
    assert(nPos < Count() && "PolyPolygon::[](): nPos >= nSize");
365
366
981k
    return mpImplPolyPolygon->mvPolyAry[nPos];
367
981k
}
368
369
PolyPolygon& PolyPolygon::operator=( const tools::PolyPolygon& rPolyPoly )
370
190k
{
371
190k
    mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon;
372
190k
    return *this;
373
190k
}
374
375
PolyPolygon& PolyPolygon::operator=( tools::PolyPolygon&& rPolyPoly ) noexcept
376
18.8k
{
377
18.8k
    mpImplPolyPolygon = std::move(rPolyPoly.mpImplPolyPolygon);
378
18.8k
    return *this;
379
18.8k
}
380
381
bool PolyPolygon::operator==( const tools::PolyPolygon& rPolyPoly ) const
382
2
{
383
2
    return rPolyPoly.mpImplPolyPolygon == mpImplPolyPolygon;
384
2
}
385
386
SvStream& ReadPolyPolygon( SvStream& rIStream, tools::PolyPolygon& rPolyPoly )
387
22.4k
{
388
22.4k
    sal_uInt16 nPolyCount(0);
389
390
    // Read number of polygons
391
22.4k
    rIStream.ReadUInt16( nPolyCount );
392
393
22.4k
    const size_t nMinRecordSize = sizeof(sal_uInt16);
394
22.4k
    const size_t nMaxRecords = rIStream.remainingSize() / nMinRecordSize;
395
22.4k
    if (nPolyCount > nMaxRecords)
396
432
    {
397
432
        SAL_WARN("tools", "Parsing error: " << nMaxRecords <<
398
432
                 " max possible entries, but " << nPolyCount << " claimed, truncating");
399
432
        nPolyCount = nMaxRecords;
400
432
    }
401
402
22.4k
    if( nPolyCount )
403
10.0k
    {
404
10.0k
        rPolyPoly.mpImplPolyPolygon->mvPolyAry.reserve(nPolyCount);
405
406
10.0k
        tools::Polygon aTempPoly;
407
356k
        for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
408
346k
        {
409
346k
            ReadPolygon( rIStream, aTempPoly );
410
346k
            if (aTempPoly.GetSize() == 0)
411
327k
            {
412
327k
                SAL_WARN("tools", "Parsing error: polygon with 0 points, ignoring");
413
327k
                continue;
414
327k
            }
415
19.6k
            rPolyPoly.mpImplPolyPolygon->mvPolyAry.push_back(aTempPoly);
416
19.6k
        }
417
10.0k
    }
418
12.3k
    else
419
12.3k
        rPolyPoly = tools::PolyPolygon();
420
421
22.4k
    return rIStream;
422
22.4k
}
423
424
SvStream& WritePolyPolygon( SvStream& rOStream, const tools::PolyPolygon& rPolyPoly )
425
0
{
426
    // Write number of polygons
427
0
    sal_uInt16 nPolyCount = rPolyPoly.mpImplPolyPolygon->mvPolyAry.size();
428
0
    rOStream.WriteUInt16( nPolyCount );
429
430
    // output polygons
431
0
    for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
432
0
        WritePolygon( rOStream, rPolyPoly.mpImplPolyPolygon->mvPolyAry[i] );
433
434
0
    return rOStream;
435
0
}
436
437
void PolyPolygon::Read( SvStream& rIStream )
438
6.45k
{
439
6.45k
    VersionCompatRead aCompat(rIStream);
440
441
6.45k
    sal_uInt16 nPolyCount(0);
442
443
    // Read number of polygons
444
6.45k
    rIStream.ReadUInt16( nPolyCount );
445
446
6.45k
    const size_t nMinRecordSize = sizeof(sal_uInt16);
447
6.45k
    const size_t nMaxRecords = rIStream.remainingSize() / nMinRecordSize;
448
6.45k
    if (nPolyCount > nMaxRecords)
449
0
    {
450
0
        SAL_WARN("tools", "Parsing error: " << nMaxRecords <<
451
0
                 " max possible entries, but " << nPolyCount << " claimed, truncating");
452
0
        nPolyCount = nMaxRecords;
453
0
    }
454
455
6.45k
    if( nPolyCount )
456
0
    {
457
0
        mpImplPolyPolygon->mvPolyAry.clear();
458
459
0
        for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
460
0
        {
461
0
            tools::Polygon aTempPoly;
462
0
            aTempPoly.ImplRead( rIStream );
463
0
            mpImplPolyPolygon->mvPolyAry.emplace_back( aTempPoly );
464
0
        }
465
0
    }
466
6.45k
    else
467
6.45k
        *this = tools::PolyPolygon();
468
6.45k
}
469
470
void PolyPolygon::Write( SvStream& rOStream ) const
471
16.6k
{
472
16.6k
    VersionCompatWrite aCompat(rOStream, 1);
473
474
    // Write number of polygons
475
16.6k
    sal_uInt16 nPolyCount = mpImplPolyPolygon->mvPolyAry.size();
476
16.6k
    rOStream.WriteUInt16( nPolyCount );
477
478
    // Output polygons
479
24.2k
    for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
480
7.69k
        mpImplPolyPolygon->mvPolyAry[i].ImplWrite( rOStream );
481
16.6k
}
482
483
// convert to basegfx::B2DPolyPolygon and return
484
basegfx::B2DPolyPolygon PolyPolygon::getB2DPolyPolygon() const
485
549k
{
486
549k
    basegfx::B2DPolyPolygon aRetval;
487
488
1.27M
    for(size_t a(0); a < mpImplPolyPolygon->mvPolyAry.size(); a++)
489
724k
    {
490
724k
        tools::Polygon const & rCandidate = mpImplPolyPolygon->mvPolyAry[a];
491
724k
        aRetval.append(rCandidate.getB2DPolygon());
492
724k
    }
493
494
549k
    return aRetval;
495
549k
}
496
497
// constructor to convert from basegfx::B2DPolyPolygon
498
PolyPolygon::PolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon)
499
328k
    : mpImplPolyPolygon(rPolyPolygon)
500
328k
{
501
328k
}
502
503
PolyPolygon::iterator PolyPolygon::begin()
504
0
{
505
0
    return mpImplPolyPolygon->begin();
506
0
}
507
508
PolyPolygon::iterator PolyPolygon::end()
509
0
{
510
0
    return mpImplPolyPolygon->end();
511
0
}
512
513
PolyPolygon::const_iterator PolyPolygon::begin() const
514
5.70k
{
515
5.70k
    return mpImplPolyPolygon->begin();
516
5.70k
}
517
518
PolyPolygon::const_iterator PolyPolygon::end() const
519
5.70k
{
520
5.70k
    return mpImplPolyPolygon->end();
521
5.70k
}
522
523
} /* namespace tools */
524
525
ImplPolyPolygon::ImplPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon)
526
328k
{
527
328k
    const sal_uInt16 nCount(sal_uInt16(rPolyPolygon.count()));
528
328k
    DBG_ASSERT(sal_uInt32(nCount) == rPolyPolygon.count(),
529
328k
        "PolyPolygon::PolyPolygon: Too many sub-polygons in given basegfx::B2DPolyPolygon (!)");
530
531
328k
    if ( nCount )
532
321k
    {
533
321k
        mvPolyAry.resize( nCount );
534
535
650k
        for(sal_uInt16 a(0); a < nCount; a++)
536
328k
        {
537
328k
            const basegfx::B2DPolygon& aCandidate(rPolyPolygon.getB2DPolygon(sal_uInt32(a)));
538
328k
            mvPolyAry[a] = tools::Polygon( aCandidate );
539
328k
        }
540
321k
    }
541
6.85k
    else
542
6.85k
       mvPolyAry.reserve(16);
543
328k
}
544
545
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */