LCOV - code coverage report
Current view: top level - basegfx/source/polygon - b2dpolypolygontools.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 311 0.0 %
Date: 2014-04-14 Functions: 0 29 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <basegfx/polygon/b2dpolypolygontools.hxx>
      21             : #include <osl/diagnose.h>
      22             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      23             : #include <basegfx/polygon/b2dpolygon.hxx>
      24             : #include <basegfx/polygon/b2dpolygontools.hxx>
      25             : #include <basegfx/numeric/ftools.hxx>
      26             : #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
      27             : #include <numeric>
      28             : 
      29             : 
      30             : 
      31             : namespace basegfx
      32             : {
      33             :     namespace tools
      34             :     {
      35           0 :         B2DPolyPolygon correctOrientations(const B2DPolyPolygon& rCandidate)
      36             :         {
      37           0 :             B2DPolyPolygon aRetval(rCandidate);
      38           0 :             const sal_uInt32 nCount(aRetval.count());
      39             : 
      40           0 :             for(sal_uInt32 a(0L); a < nCount; a++)
      41             :             {
      42           0 :                 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
      43           0 :                 const B2VectorOrientation aOrientation(tools::getOrientation(aCandidate));
      44           0 :                 sal_uInt32 nDepth(0L);
      45             : 
      46           0 :                 for(sal_uInt32 b(0L); b < nCount; b++)
      47             :                 {
      48           0 :                     if(b != a)
      49             :                     {
      50           0 :                         const B2DPolygon aCompare(rCandidate.getB2DPolygon(b));
      51             : 
      52           0 :                         if(tools::isInside(aCompare, aCandidate, true))
      53             :                         {
      54           0 :                             nDepth++;
      55           0 :                         }
      56             :                     }
      57             :                 }
      58             : 
      59           0 :                 const bool bShallBeHole(1L == (nDepth & 0x00000001));
      60           0 :                 const bool bIsHole(ORIENTATION_NEGATIVE == aOrientation);
      61             : 
      62           0 :                 if(bShallBeHole != bIsHole && ORIENTATION_NEUTRAL != aOrientation)
      63             :                 {
      64           0 :                     B2DPolygon aFlipped(aCandidate);
      65           0 :                     aFlipped.flip();
      66           0 :                     aRetval.setB2DPolygon(a, aFlipped);
      67             :                 }
      68           0 :             }
      69             : 
      70           0 :             return aRetval;
      71             :         }
      72             : 
      73           0 :         B2DPolyPolygon correctOutmostPolygon(const B2DPolyPolygon& rCandidate)
      74             :         {
      75           0 :             const sal_uInt32 nCount(rCandidate.count());
      76             : 
      77           0 :             if(nCount > 1L)
      78             :             {
      79           0 :                 for(sal_uInt32 a(0L); a < nCount; a++)
      80             :                 {
      81           0 :                     const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
      82           0 :                     sal_uInt32 nDepth(0L);
      83             : 
      84           0 :                     for(sal_uInt32 b(0L); b < nCount; b++)
      85             :                     {
      86           0 :                         if(b != a)
      87             :                         {
      88           0 :                             const B2DPolygon aCompare(rCandidate.getB2DPolygon(b));
      89             : 
      90           0 :                             if(tools::isInside(aCompare, aCandidate, true))
      91             :                             {
      92           0 :                                 nDepth++;
      93           0 :                             }
      94             :                         }
      95             :                     }
      96             : 
      97           0 :                     if(!nDepth)
      98             :                     {
      99           0 :                         B2DPolyPolygon aRetval(rCandidate);
     100             : 
     101           0 :                         if(a != 0L)
     102             :                         {
     103             :                             // exchange polygon a and polygon 0L
     104           0 :                             aRetval.setB2DPolygon(0L, aCandidate);
     105           0 :                             aRetval.setB2DPolygon(a, rCandidate.getB2DPolygon(0L));
     106             :                         }
     107             : 
     108             :                         // exit
     109           0 :                         return aRetval;
     110             :                     }
     111           0 :                 }
     112             :             }
     113             : 
     114           0 :             return rCandidate;
     115             :         }
     116             : 
     117           0 :         B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound)
     118             :         {
     119           0 :             if(rCandidate.areControlPointsUsed())
     120             :             {
     121           0 :                 const sal_uInt32 nPolygonCount(rCandidate.count());
     122           0 :                 B2DPolyPolygon aRetval;
     123             : 
     124           0 :                 for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     125             :                 {
     126           0 :                     const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     127             : 
     128           0 :                     if(aCandidate.areControlPointsUsed())
     129             :                     {
     130           0 :                         aRetval.append(tools::adaptiveSubdivideByDistance(aCandidate, fDistanceBound));
     131             :                     }
     132             :                     else
     133             :                     {
     134           0 :                         aRetval.append(aCandidate);
     135             :                     }
     136           0 :                 }
     137             : 
     138           0 :                 return aRetval;
     139             :             }
     140             :             else
     141             :             {
     142           0 :                 return rCandidate;
     143             :             }
     144             :         }
     145             : 
     146           0 :         B2DPolyPolygon adaptiveSubdivideByAngle(const B2DPolyPolygon& rCandidate, double fAngleBound)
     147             :         {
     148           0 :             if(rCandidate.areControlPointsUsed())
     149             :             {
     150           0 :                 const sal_uInt32 nPolygonCount(rCandidate.count());
     151           0 :                 B2DPolyPolygon aRetval;
     152             : 
     153           0 :                 for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     154             :                 {
     155           0 :                     const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     156             : 
     157           0 :                     if(aCandidate.areControlPointsUsed())
     158             :                     {
     159           0 :                         aRetval.append(tools::adaptiveSubdivideByAngle(aCandidate, fAngleBound));
     160             :                     }
     161             :                     else
     162             :                     {
     163           0 :                         aRetval.append(aCandidate);
     164             :                     }
     165           0 :                 }
     166             : 
     167           0 :                 return aRetval;
     168             :             }
     169             :             else
     170             :             {
     171           0 :                 return rCandidate;
     172             :             }
     173             :         }
     174             : 
     175           0 :         B2DPolyPolygon adaptiveSubdivideByCount(const B2DPolyPolygon& rCandidate, sal_uInt32 nCount)
     176             :         {
     177           0 :             if(rCandidate.areControlPointsUsed())
     178             :             {
     179           0 :                 const sal_uInt32 nPolygonCount(rCandidate.count());
     180           0 :                 B2DPolyPolygon aRetval;
     181             : 
     182           0 :                 for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     183             :                 {
     184           0 :                     const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     185             : 
     186           0 :                     if(aCandidate.areControlPointsUsed())
     187             :                     {
     188           0 :                         aRetval.append(tools::adaptiveSubdivideByCount(aCandidate, nCount));
     189             :                     }
     190             :                     else
     191             :                     {
     192           0 :                         aRetval.append(aCandidate);
     193             :                     }
     194           0 :                 }
     195             : 
     196           0 :                 return aRetval;
     197             :             }
     198             :             else
     199             :             {
     200           0 :                 return rCandidate;
     201             :             }
     202             :         }
     203             : 
     204           0 :         bool isInside(const B2DPolyPolygon& rCandidate, const B2DPoint& rPoint, bool bWithBorder)
     205             :         {
     206           0 :             const sal_uInt32 nPolygonCount(rCandidate.count());
     207             : 
     208           0 :             if(1L == nPolygonCount)
     209             :             {
     210           0 :                 return isInside(rCandidate.getB2DPolygon(0L), rPoint, bWithBorder);
     211             :             }
     212             :             else
     213             :             {
     214           0 :                 sal_Int32 nInsideCount(0L);
     215             : 
     216           0 :                 for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     217             :                 {
     218           0 :                     const B2DPolygon aPolygon(rCandidate.getB2DPolygon(a));
     219           0 :                     const bool bInside(isInside(aPolygon, rPoint, bWithBorder));
     220             : 
     221           0 :                     if(bInside)
     222             :                     {
     223           0 :                         nInsideCount++;
     224             :                     }
     225           0 :                 }
     226             : 
     227           0 :                 return (nInsideCount % 2L);
     228             :             }
     229             :         }
     230             : 
     231           0 :         B2DRange getRange(const B2DPolyPolygon& rCandidate)
     232             :         {
     233           0 :             B2DRange aRetval;
     234           0 :             const sal_uInt32 nPolygonCount(rCandidate.count());
     235             : 
     236           0 :             for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     237             :             {
     238           0 :                 B2DPolygon aCandidate = rCandidate.getB2DPolygon(a);
     239           0 :                 aRetval.expand(tools::getRange(aCandidate));
     240           0 :             }
     241             : 
     242           0 :             return aRetval;
     243             :         }
     244             : 
     245           0 :         double getSignedArea(const B2DPolyPolygon& rCandidate)
     246             :         {
     247           0 :             double fRetval(0.0);
     248           0 :             const sal_uInt32 nPolygonCount(rCandidate.count());
     249             : 
     250           0 :             for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     251             :             {
     252           0 :                 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     253             : 
     254           0 :                 fRetval += tools::getSignedArea(aCandidate);
     255           0 :             }
     256             : 
     257           0 :             return fRetval;
     258             :         }
     259             : 
     260           0 :         double getArea(const B2DPolyPolygon& rCandidate)
     261             :         {
     262           0 :             return fabs(getSignedArea(rCandidate));
     263             :         }
     264             : 
     265           0 :         void applyLineDashing(const B2DPolyPolygon& rCandidate, const ::std::vector<double>& rDotDashArray, B2DPolyPolygon* pLineTarget, B2DPolyPolygon* pGapTarget, double fFullDashDotLen)
     266             :         {
     267           0 :             if(0.0 == fFullDashDotLen && rDotDashArray.size())
     268             :             {
     269             :                 // calculate fFullDashDotLen from rDotDashArray
     270           0 :                 fFullDashDotLen = ::std::accumulate(rDotDashArray.begin(), rDotDashArray.end(), 0.0);
     271             :             }
     272             : 
     273           0 :             if(rCandidate.count() && fFullDashDotLen > 0.0)
     274             :             {
     275           0 :                 B2DPolyPolygon aLineTarget, aGapTarget;
     276             : 
     277           0 :                 for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
     278             :                 {
     279           0 :                     const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     280             : 
     281             :                     applyLineDashing(
     282             :                         aCandidate,
     283             :                         rDotDashArray,
     284             :                         pLineTarget ? &aLineTarget : 0,
     285             :                         pGapTarget ? &aGapTarget : 0,
     286           0 :                         fFullDashDotLen);
     287             : 
     288           0 :                     if(pLineTarget)
     289             :                     {
     290           0 :                         pLineTarget->append(aLineTarget);
     291             :                     }
     292             : 
     293           0 :                     if(pGapTarget)
     294             :                     {
     295           0 :                         pGapTarget->append(aGapTarget);
     296             :                     }
     297           0 :                 }
     298             :             }
     299           0 :         }
     300             : 
     301           0 :         bool isInEpsilonRange(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance)
     302             :         {
     303           0 :             const sal_uInt32 nPolygonCount(rCandidate.count());
     304             : 
     305           0 :             for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     306             :             {
     307           0 :                 B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     308             : 
     309           0 :                 if(isInEpsilonRange(aCandidate, rTestPosition, fDistance))
     310             :                 {
     311           0 :                     return true;
     312             :                 }
     313           0 :             }
     314             : 
     315           0 :             return false;
     316             :         }
     317             : 
     318           0 :         B3DPolyPolygon createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon& rCandidate, double fZCoordinate)
     319             :         {
     320           0 :             const sal_uInt32 nPolygonCount(rCandidate.count());
     321           0 :             B3DPolyPolygon aRetval;
     322             : 
     323           0 :             for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     324             :             {
     325           0 :                 B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     326             : 
     327           0 :                 aRetval.append(createB3DPolygonFromB2DPolygon(aCandidate, fZCoordinate));
     328           0 :             }
     329             : 
     330           0 :             return aRetval;
     331             :         }
     332             : 
     333           0 :         B2DPolyPolygon createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon& rCandidate, const B3DHomMatrix& rMat)
     334             :         {
     335           0 :             const sal_uInt32 nPolygonCount(rCandidate.count());
     336           0 :             B2DPolyPolygon aRetval;
     337             : 
     338           0 :             for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     339             :             {
     340           0 :                 B3DPolygon aCandidate(rCandidate.getB3DPolygon(a));
     341             : 
     342           0 :                 aRetval.append(createB2DPolygonFromB3DPolygon(aCandidate, rMat));
     343           0 :             }
     344             : 
     345           0 :             return aRetval;
     346             :         }
     347             : 
     348           0 :         double getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPoint, sal_uInt32& rPolygonIndex, sal_uInt32& rEdgeIndex, double& rCut)
     349             :         {
     350           0 :             double fRetval(DBL_MAX);
     351           0 :             const double fZero(0.0);
     352           0 :             const sal_uInt32 nPolygonCount(rCandidate.count());
     353             : 
     354           0 :             for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     355             :             {
     356           0 :                 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     357             :                 sal_uInt32 nNewEdgeIndex;
     358           0 :                 double fNewCut(0.0);
     359           0 :                 const double fNewDistance(getSmallestDistancePointToPolygon(aCandidate, rTestPoint, nNewEdgeIndex, fNewCut));
     360             : 
     361           0 :                 if(DBL_MAX == fRetval || fNewDistance < fRetval)
     362             :                 {
     363           0 :                     fRetval = fNewDistance;
     364           0 :                     rPolygonIndex = a;
     365           0 :                     rEdgeIndex = nNewEdgeIndex;
     366           0 :                     rCut = fNewCut;
     367             : 
     368           0 :                     if(fTools::equal(fRetval, fZero))
     369             :                     {
     370             :                         // already found zero distance, cannot get better. Ensure numerical zero value and end loop.
     371           0 :                         fRetval = 0.0;
     372           0 :                         break;
     373             :                     }
     374             :                 }
     375           0 :             }
     376             : 
     377           0 :             return fRetval;
     378             :         }
     379             : 
     380           0 :         B2DPolyPolygon distort(const B2DPolyPolygon& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight)
     381             :         {
     382           0 :             const sal_uInt32 nPolygonCount(rCandidate.count());
     383           0 :             B2DPolyPolygon aRetval;
     384             : 
     385           0 :             for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     386             :             {
     387           0 :                 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     388             : 
     389           0 :                 aRetval.append(distort(aCandidate, rOriginal, rTopLeft, rTopRight, rBottomLeft, rBottomRight));
     390           0 :             }
     391             : 
     392           0 :             return aRetval;
     393             :         }
     394             : 
     395           0 :         B2DPolyPolygon expandToCurve(const B2DPolyPolygon& rCandidate)
     396             :         {
     397           0 :             const sal_uInt32 nPolygonCount(rCandidate.count());
     398           0 :             B2DPolyPolygon aRetval;
     399             : 
     400           0 :             for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     401             :             {
     402           0 :                 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
     403             : 
     404           0 :                 aRetval.append(expandToCurve(aCandidate));
     405           0 :             }
     406             : 
     407           0 :             return aRetval;
     408             :         }
     409             : 
     410           0 :         B2DPolyPolygon growInNormalDirection(const B2DPolyPolygon& rCandidate, double fValue)
     411             :         {
     412           0 :             if(0.0 != fValue)
     413             :             {
     414           0 :                 B2DPolyPolygon aRetval;
     415             : 
     416           0 :                 for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
     417             :                 {
     418           0 :                     aRetval.append(growInNormalDirection(rCandidate.getB2DPolygon(a), fValue));
     419             :                 }
     420             : 
     421           0 :                 return aRetval;
     422             :             }
     423             :             else
     424             :             {
     425           0 :                 return rCandidate;
     426             :             }
     427             :         }
     428             : 
     429           0 :         void correctGrowShrinkPolygonPair(SAL_UNUSED_PARAMETER B2DPolyPolygon& /*rOriginal*/, SAL_UNUSED_PARAMETER B2DPolyPolygon& /*rGrown*/)
     430             :         {
     431             :             //TODO!
     432           0 :         }
     433             : 
     434           0 :         B2DPolyPolygon reSegmentPolyPolygon(const B2DPolyPolygon& rCandidate, sal_uInt32 nSegments)
     435             :         {
     436           0 :             B2DPolyPolygon aRetval;
     437             : 
     438           0 :             for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
     439             :             {
     440           0 :                 aRetval.append(reSegmentPolygon(rCandidate.getB2DPolygon(a), nSegments));
     441             :             }
     442             : 
     443           0 :             return aRetval;
     444             :         }
     445             : 
     446           0 :         B2DPolyPolygon interpolate(const B2DPolyPolygon& rOld1, const B2DPolyPolygon& rOld2, double t)
     447             :         {
     448             :             OSL_ENSURE(rOld1.count() == rOld2.count(), "B2DPolyPolygon interpolate: Different geometry (!)");
     449           0 :             B2DPolyPolygon aRetval;
     450             : 
     451           0 :             for(sal_uInt32 a(0L); a < rOld1.count(); a++)
     452             :             {
     453           0 :                 aRetval.append(interpolate(rOld1.getB2DPolygon(a), rOld2.getB2DPolygon(a), t));
     454             :             }
     455             : 
     456           0 :             return aRetval;
     457             :         }
     458             : 
     459           0 :         bool isRectangle( const B2DPolyPolygon& rPoly )
     460             :         {
     461             :             // exclude some cheap cases first
     462           0 :             if( rPoly.count() != 1 )
     463           0 :                 return false;
     464             : 
     465           0 :             return isRectangle( rPoly.getB2DPolygon(0) );
     466             :         }
     467             : 
     468             :         // #i76891#
     469           0 :         B2DPolyPolygon simplifyCurveSegments(const B2DPolyPolygon& rCandidate)
     470             :         {
     471           0 :             if(rCandidate.areControlPointsUsed())
     472             :             {
     473           0 :                 B2DPolyPolygon aRetval;
     474             : 
     475           0 :                 for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
     476             :                 {
     477           0 :                     aRetval.append(simplifyCurveSegments(rCandidate.getB2DPolygon(a)));
     478             :                 }
     479             : 
     480           0 :                 return aRetval;
     481             :             }
     482             :             else
     483             :             {
     484           0 :                 return rCandidate;
     485             :             }
     486             :         }
     487             : 
     488           0 :         B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate)
     489             :         {
     490           0 :             B2DPolyPolygon aRetval;
     491             : 
     492           0 :             for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
     493             :             {
     494           0 :                 aRetval.append(snapPointsOfHorizontalOrVerticalEdges(rCandidate.getB2DPolygon(a)));
     495             :             }
     496             : 
     497           0 :             return aRetval;
     498             :         }
     499             : 
     500           0 :         bool containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon& rCandidate)
     501             :         {
     502           0 :             if(rCandidate.areControlPointsUsed())
     503             :             {
     504           0 :                 return false;
     505             :             }
     506             : 
     507           0 :             for(sal_uInt32 a(0); a < rCandidate.count(); a++)
     508             :             {
     509           0 :                 if(!containsOnlyHorizontalAndVerticalEdges(rCandidate.getB2DPolygon(a)))
     510             :                 {
     511           0 :                     return false;
     512             :                 }
     513             :             }
     514             : 
     515           0 :             return true;
     516             :         }
     517             : 
     518           0 :         B2DPolyPolygon createSevenSegmentPolyPolygon(sal_Char nNumber, bool bLitSegments)
     519             :         {
     520             :             // config here
     521             :             // {
     522           0 :             const double fTotalSize=1.0;
     523           0 :             const double fPosMiddleSegment=0.6;
     524           0 :             const double fSegmentEndChopHoriz=0.08;
     525           0 :             const double fSegmentEndChopVert =0.04;
     526             :             // }
     527             :             // config here
     528             : 
     529           0 :             const double fLeft=0.0;
     530           0 :             const double fRight=fTotalSize;
     531           0 :             const double fTop=0.0;
     532           0 :             const double fMiddle=fPosMiddleSegment;
     533           0 :             const double fBottom=fTotalSize;
     534             : 
     535             :             // from 0 to 5: pair of segment corner coordinates
     536             : 
     537             :             // segment corner indices are these:
     538             : 
     539             :             //   0 - 1
     540             :             //   |   |
     541             :             //   2 - 3
     542             :             //   |   |
     543             :             //   4 - 5
     544             : 
     545             :             static const double corners[] =
     546             :             {
     547             :                 fLeft,  fTop,
     548             :                 fRight, fTop,
     549             :                 fLeft,  fMiddle,
     550             :                 fRight, fMiddle,
     551             :                 fLeft,  fBottom,
     552             :                 fRight, fBottom
     553             :             };
     554             : 
     555             :             // from 0 to 9: which segments are 'lit' for this number?
     556             : 
     557             :             // array denotes graph edges to traverse, with -1 means
     558             :             // stop (the vertices are the corner indices from above):
     559             :             //     0
     560             :             //     -
     561             :             // 1 |   | 2
     562             :             //     - 3
     563             :             // 4 |   | 5
     564             :             //     -
     565             :             //     6
     566             : 
     567             :             static const int numbers[] =
     568             :             {
     569             :                 1, 1, 1, 0, 1, 1, 1, // 0
     570             :                 0, 0, 1, 0, 0, 1, 0, // 1
     571             :                 1, 0, 1, 1, 1, 0, 1, // 2
     572             :                 1, 0, 1, 1, 0, 1, 1, // 3
     573             :                 0, 1, 1, 1, 0, 1, 0, // 4
     574             :                 1, 1, 0, 1, 0, 1, 1, // 5
     575             :                 1, 1, 0, 1, 1, 1, 1, // 6
     576             :                 1, 0, 1, 0, 0, 1, 0, // 1
     577             :                 1, 1, 1, 1, 1, 1, 1, // 8
     578             :                 1, 1, 1, 1, 0, 1, 1, // 9
     579             :                 0, 0, 0, 1, 0, 0, 0, // '-'
     580             :                 1, 1, 0, 1, 1, 0, 1, // 'E'
     581             :             };
     582             : 
     583             :             // maps segment index to two corner ids:
     584             :             static const int index2corner[] =
     585             :             {
     586             :                 0, 2,  // 0
     587             :                 0, 4,  // 1
     588             :                 2, 6,  // 2
     589             :                 4, 6,  // 3
     590             :                 4, 8,  // 4
     591             :                 6, 10, // 5
     592             :                 8, 10, // 6
     593             :             };
     594             : 
     595           0 :             B2DPolyPolygon aRes;
     596           0 :             if( nNumber == '-' )
     597             :             {
     598           0 :                 nNumber = 10;
     599             :             }
     600           0 :             else if( nNumber == 'E' )
     601             :             {
     602           0 :                 nNumber = 11;
     603             :             }
     604           0 :             else if( nNumber == '.' )
     605             :             {
     606           0 :                 if( bLitSegments )
     607             :                     aRes.append(createPolygonFromCircle(B2DPoint(fTotalSize/2, fTotalSize),
     608           0 :                                                         fSegmentEndChopHoriz));
     609           0 :                 return aRes;
     610             :             }
     611             :             else
     612             :             {
     613           0 :                 nNumber=clamp<sal_uInt32>(nNumber,'0','9') - '0';
     614             :             }
     615             : 
     616           0 :             B2DPolygon aCurrSegment;
     617           0 :             const size_t sliceSize=SAL_N_ELEMENTS(numbers)/12;
     618           0 :             const int* pCurrSegment=numbers + nNumber*sliceSize;
     619           0 :             for( size_t i=0; i<sliceSize; i++, pCurrSegment++)
     620             :             {
     621           0 :                 if( !(*pCurrSegment ^ int(bLitSegments)) )
     622             :                 {
     623           0 :                     const size_t j=2*i;
     624           0 :                     aCurrSegment.clear();
     625           0 :                     B2DPoint start(corners[index2corner[j]],
     626           0 :                                    corners[index2corner[j]+1]  );
     627           0 :                     B2DPoint end  (corners[index2corner[j+1]],
     628           0 :                                    corners[index2corner[j+1]+1]);
     629             : 
     630           0 :                     if( start.getX() == end.getX() )
     631             :                     {
     632           0 :                         start.setY(start.getY()+fSegmentEndChopVert);
     633           0 :                         end.setY(end.getY()-fSegmentEndChopVert);
     634             :                     }
     635             :                     else
     636             :                     {
     637           0 :                         start.setX(start.getX()+fSegmentEndChopHoriz);
     638           0 :                         end.setX(end.getX()-fSegmentEndChopHoriz);
     639             :                     }
     640             : 
     641           0 :                     aCurrSegment.append(start);
     642           0 :                     aCurrSegment.append(end);
     643             :                 }
     644           0 :                 aRes.append(aCurrSegment);
     645             :             }
     646             : 
     647           0 :             return aRes;
     648             :         }
     649             : 
     650             : 
     651             :         // converters for com::sun::star::drawing::PointSequence
     652             : 
     653           0 :         B2DPolyPolygon UnoPointSequenceSequenceToB2DPolyPolygon(
     654             :             const com::sun::star::drawing::PointSequenceSequence& rPointSequenceSequenceSource,
     655             :             bool bCheckClosed)
     656             :         {
     657           0 :             B2DPolyPolygon aRetval;
     658           0 :             const com::sun::star::drawing::PointSequence* pPointSequence = rPointSequenceSequenceSource.getConstArray();
     659           0 :             const com::sun::star::drawing::PointSequence* pPointSeqEnd = pPointSequence + rPointSequenceSequenceSource.getLength();
     660             : 
     661           0 :             for(;pPointSequence != pPointSeqEnd; pPointSequence++)
     662             :             {
     663           0 :                 const B2DPolygon aNewPolygon = UnoPointSequenceToB2DPolygon(*pPointSequence, bCheckClosed);
     664           0 :                 aRetval.append(aNewPolygon);
     665           0 :             }
     666             : 
     667           0 :             return aRetval;
     668             :         }
     669             : 
     670           0 :         void B2DPolyPolygonToUnoPointSequenceSequence(
     671             :             const B2DPolyPolygon& rPolyPolygon,
     672             :             com::sun::star::drawing::PointSequenceSequence& rPointSequenceSequenceRetval)
     673             :         {
     674           0 :             const sal_uInt32 nCount(rPolyPolygon.count());
     675             : 
     676           0 :             if(nCount)
     677             :             {
     678           0 :                 rPointSequenceSequenceRetval.realloc(nCount);
     679           0 :                 com::sun::star::drawing::PointSequence* pPointSequence = rPointSequenceSequenceRetval.getArray();
     680             : 
     681           0 :                 for(sal_uInt32 a(0); a < nCount; a++)
     682             :                 {
     683           0 :                     const B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(a));
     684             : 
     685           0 :                     B2DPolygonToUnoPointSequence(aPolygon, *pPointSequence);
     686           0 :                     pPointSequence++;
     687           0 :                 }
     688             :             }
     689             :             else
     690             :             {
     691           0 :                 rPointSequenceSequenceRetval.realloc(0);
     692             :             }
     693           0 :         }
     694             : 
     695             : 
     696             :         // converters for com::sun::star::drawing::PolyPolygonBezierCoords (curved polygons)
     697             : 
     698           0 :         B2DPolyPolygon UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
     699             :             const com::sun::star::drawing::PolyPolygonBezierCoords& rPolyPolygonBezierCoordsSource,
     700             :             bool bCheckClosed)
     701             :         {
     702           0 :             B2DPolyPolygon aRetval;
     703           0 :             const sal_uInt32 nSequenceCount((sal_uInt32)rPolyPolygonBezierCoordsSource.Coordinates.getLength());
     704             : 
     705           0 :             if(nSequenceCount)
     706             :             {
     707             :                 OSL_ENSURE(nSequenceCount == (sal_uInt32)rPolyPolygonBezierCoordsSource.Flags.getLength(),
     708             :                     "UnoPolyPolygonBezierCoordsToB2DPolyPolygon: unequal number of Points and Flags (!)");
     709           0 :                 const com::sun::star::drawing::PointSequence* pPointSequence = rPolyPolygonBezierCoordsSource.Coordinates.getConstArray();
     710           0 :                 const com::sun::star::drawing::FlagSequence* pFlagSequence = rPolyPolygonBezierCoordsSource.Flags.getConstArray();
     711             : 
     712           0 :                 for(sal_uInt32 a(0); a < nSequenceCount; a++)
     713             :                 {
     714             :                     const B2DPolygon aNewPolygon(UnoPolygonBezierCoordsToB2DPolygon(
     715             :                         *pPointSequence,
     716             :                         *pFlagSequence,
     717           0 :                         bCheckClosed));
     718             : 
     719           0 :                     pPointSequence++;
     720           0 :                     pFlagSequence++;
     721           0 :                     aRetval.append(aNewPolygon);
     722           0 :                 }
     723             :             }
     724             : 
     725           0 :             return aRetval;
     726             :         }
     727             : 
     728           0 :         void B2DPolyPolygonToUnoPolyPolygonBezierCoords(
     729             :             const B2DPolyPolygon& rPolyPolygon,
     730             :             com::sun::star::drawing::PolyPolygonBezierCoords& rPolyPolygonBezierCoordsRetval)
     731             :         {
     732           0 :             const sal_uInt32 nCount(rPolyPolygon.count());
     733             : 
     734           0 :             if(nCount)
     735             :             {
     736             :                 // prepare return value memory
     737           0 :                 rPolyPolygonBezierCoordsRetval.Coordinates.realloc((sal_Int32)nCount);
     738           0 :                 rPolyPolygonBezierCoordsRetval.Flags.realloc((sal_Int32)nCount);
     739             : 
     740             :                 // get pointers to arrays
     741           0 :                 com::sun::star::drawing::PointSequence* pPointSequence = rPolyPolygonBezierCoordsRetval.Coordinates.getArray();
     742           0 :                 com::sun::star::drawing::FlagSequence*  pFlagSequence = rPolyPolygonBezierCoordsRetval.Flags.getArray();
     743             : 
     744           0 :                 for(sal_uInt32 a(0); a < nCount; a++)
     745             :                 {
     746           0 :                     const B2DPolygon aSource(rPolyPolygon.getB2DPolygon(a));
     747             : 
     748             :                     B2DPolygonToUnoPolygonBezierCoords(
     749             :                         aSource,
     750             :                         *pPointSequence,
     751           0 :                         *pFlagSequence);
     752           0 :                     pPointSequence++;
     753           0 :                     pFlagSequence++;
     754           0 :                 }
     755             :             }
     756             :             else
     757             :             {
     758           0 :                 rPolyPolygonBezierCoordsRetval.Coordinates.realloc(0);
     759           0 :                 rPolyPolygonBezierCoordsRetval.Flags.realloc(0);
     760             :             }
     761           0 :         }
     762             : 
     763             :     } // end of namespace tools
     764             : } // end of namespace basegfx
     765             : 
     766             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10