LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/ipict - shape.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 51 138 37.0 %
Date: 2012-08-25 Functions: 3 8 37.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 52 188 27.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : /** Osnola:
      30                 :            : IMPORTANT NOTE: some Quickdraw lines/frames can not be "quickly" drawn exactly:
      31                 :            : for instance, when PenSize=(1,1), the line from (0,0) to (8,0)
      32                 :            : corresponds to the rectangle (0,0)(0,1)(9,1)(9,0), which can only be drawn
      33                 :            :  by drawing a rectangle. Drawing a non horizontal/vertical will imply to draw
      34                 :            : a polygon, ...
      35                 :            : Similarly, drawing the frame of a rectangle (0,0)(0,1)(9,1)(9,0) when PenSize=(1,1),
      36                 :            : will imply to draw a rectangle (0.5,0.5)(0.5,8.5)(8.5,8.5)(8.5,0.5) with linewidth=1...
      37                 :            : 
      38                 :            : Here, we choose:
      39                 :            : - for horizontal/vertical lines and line with length less than five to draw the real line,
      40                 :            : - in the other case, we keep the same shape (even if this means some "bad" coordinates)
      41                 :            : */
      42                 :            : 
      43                 :            : #include <basegfx/polygon/b2dpolygon.hxx>
      44                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      45                 :            : #include "shape.hxx"
      46                 :            : 
      47                 :            : namespace PictReaderShapePrivate {
      48                 :            :   /** returns an inside rectangle knowing the penSize in order to obtain the ``correct'' position
      49                 :            :       when we draw a frame in wide length*/
      50                 :          0 :   Rectangle contractRectangle(bool drawFrame, Rectangle const &rect, Size const &pSize) {
      51         [ #  # ]:          0 :     if (!drawFrame) return rect;
      52                 :          0 :     long penSize=(pSize.Width()+pSize.Height())/2;
      53         [ #  # ]:          0 :     if (2*penSize > rect.Right()-rect.Left()) penSize = (rect.Right()-rect.Left()+1)/2;
      54         [ #  # ]:          0 :     if (2*penSize > rect.Bottom()-rect.Top()) penSize = (rect.Bottom()-rect.Top()+1)/2;
      55                 :          0 :     long const X[2] = { rect.Left()+penSize/2, rect.Right()-(penSize+1)/2 };
      56                 :          0 :     long const Y[2] = { rect.Top()+penSize/2, rect.Bottom()-(penSize+1)/2 };
      57         [ #  # ]:          0 :     return Rectangle(Point(X[0],Y[0]), Point(X[1], Y[1]));
      58                 :            :   }
      59                 :            : }
      60                 :            : 
      61                 :            : namespace PictReaderShape {
      62                 :            :   //--------- draws a horizontal/vertical/small line (by creating a "rectangle/polygon")  ---------
      63                 :        159 :   bool drawLineHQ(VirtualDevice *dev, Point const &orig, Point const &dest, Size const &pSize) {
      64                 :        159 :     long dir[2] = { dest.X()-orig.X(), dest.Y()-orig.Y() };
      65                 :        159 :     bool vertic = dir[0] == 0;
      66                 :        159 :     bool horiz = dir[1] == 0;
      67 [ +  + ][ +  - ]:        159 :     if (!horiz && !vertic && dir[0]*dir[0]+dir[1]*dir[1] > 25) return false;
                 [ +  + ]
      68                 :            : 
      69                 :         99 :     long X[2]={ orig.X(), dest.X() }, Y[2] = { orig.Y(), dest.Y() };
      70                 :            :     using namespace basegfx;
      71         [ +  - ]:         99 :     B2DPolygon poly;
      72 [ +  + ][ +  - ]:         99 :     if (horiz || vertic) {
      73         [ +  + ]:         99 :       if (horiz) {
      74         [ +  + ]:         69 :     if (X[0] < X[1]) X[1]+=pSize.Width();
      75                 :         36 :     else X[0]+=pSize.Width();
      76                 :         69 :     Y[1] += pSize.Height();
      77                 :            :       }
      78                 :            :       else  {
      79         [ +  + ]:         30 :     if (Y[0] < Y[1]) Y[1]+=pSize.Height();
      80                 :         15 :     else Y[0]+=pSize.Height();
      81                 :         30 :     X[1] += pSize.Width();
      82                 :            :       }
      83 [ +  - ][ +  - ]:         99 :       poly.append(B2DPoint(X[0], Y[0])); poly.append(B2DPoint(X[1], Y[0]));
      84 [ +  - ][ +  - ]:         99 :       poly.append(B2DPoint(X[1], Y[1])); poly.append(B2DPoint(X[0], Y[1]));
      85         [ +  - ]:         99 :       poly.append(B2DPoint(X[0], Y[0]));
      86                 :            :     }
      87                 :            :     else {
      88                 :          0 :       long origPt[4][2] = { { orig.X(), orig.Y() }, { orig.X()+pSize.Width(), orig.Y() },
      89                 :          0 :                { orig.X()+pSize.Width(), orig.Y()+pSize.Height() },
      90                 :          0 :                { orig.X(), orig.Y()+pSize.Height() }};
      91 [ #  # ][ #  # ]:          0 :       long origAvoid = dir[0] > 0 ? (dir[1] > 0 ? 2 : 1) : (dir[1] > 0 ? 3 : 0);
                 [ #  # ]
      92                 :          0 :       long destPt[4][2] = { { dest.X(), dest.Y() }, { dest.X()+pSize.Width(), dest.Y() },
      93                 :          0 :                { dest.X()+pSize.Width(), dest.Y()+pSize.Height() },
      94                 :          0 :                { dest.X(), dest.Y()+pSize.Height() }};
      95         [ #  # ]:          0 :       for (int w = origAvoid+1; w < origAvoid+4; w++) {
      96                 :          0 :     int wh = (w%4);
      97         [ #  # ]:          0 :     poly.append(B2DPoint(origPt[wh][0], origPt[wh][1]));
      98                 :            :       }
      99         [ #  # ]:          0 :       for (int w = origAvoid+3; w < origAvoid+6; w++) {
     100                 :          0 :     int wh = (w%4);
     101         [ #  # ]:          0 :     poly.append(B2DPoint(destPt[wh][0], destPt[wh][1]));
     102                 :            :       }
     103                 :          0 :       int wh = (origAvoid+1)%4;
     104         [ #  # ]:          0 :       poly.append(B2DPoint(origPt[wh][0], origPt[wh][1]));
     105                 :            :     }
     106                 :            : 
     107                 :            :     // HACK: here we use the line coloring when drawing the shape
     108                 :            :     //       must be changed if other parameter are changed to draw
     109                 :            :     //       a line/fill shape
     110                 :         99 :     Color oldFColor = dev->GetFillColor(), oldLColor = dev->GetLineColor();
     111 [ +  - ][ +  - ]:         99 :     dev->SetFillColor(oldLColor); dev->SetLineColor(Color(COL_TRANSPARENT));
     112         [ +  - ]:         99 :     dev->DrawPolygon(poly);
     113 [ +  - ][ +  - ]:         99 :     dev->SetLineColor(oldLColor); dev->SetFillColor(oldFColor);
     114         [ +  - ]:        159 :     return true;
     115                 :            :   }
     116                 :            : 
     117                 :            :   //
     118                 :            :   //-------------------- draws a line --------------------
     119                 :            :   //
     120                 :        159 :   void drawLine(VirtualDevice *dev, Point const &orig, Point const &dest, Size const &pSize) {
     121 [ +  - ][ +  + ]:        318 :     if (drawLineHQ(dev,orig,dest,pSize)) return;
     122                 :            : 
     123                 :         60 :     long penSize=(pSize.Width()+pSize.Height())/2;
     124                 :         60 :     long decal[2] = { pSize.Width()/2, pSize.Height()/2};
     125                 :            : 
     126                 :            :     using namespace basegfx;
     127         [ +  - ]:         60 :     B2DPolygon poly;
     128         [ +  - ]:         60 :     poly.append(B2DPoint(double(orig.X()+decal[0]), double(orig.Y()+decal[1])));
     129         [ +  - ]:         60 :     poly.append(B2DPoint(double(dest.X()+decal[0]), double(dest.Y()+decal[1])));
     130 [ +  - ][ +  - ]:        159 :     dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLINEJOIN_NONE);
     131                 :            :   }
     132                 :            : 
     133                 :            :   //--------------------  draws a rectangle --------------------
     134                 :            :   /* Note(checkme): contradically with the QuickDraw's reference 3-23, it seems better to consider
     135                 :            :      that the frame/content of a rectangle appears inside the given rectangle. Does a conversion
     136                 :            :      appear between the pascal functions and the data stored in the file ? */
     137                 :          0 :   void drawRectangle(VirtualDevice *dev, bool drawFrame, Rectangle const &orig, Size const &pSize) {
     138                 :          0 :     int penSize=(pSize.Width()+pSize.Height())/2;
     139         [ #  # ]:          0 :     Rectangle rect = PictReaderShapePrivate::contractRectangle(drawFrame, orig, pSize);
     140                 :          0 :     long const X[2] = { rect.Left(), rect.Right() };
     141                 :          0 :     long const Y[2] = { rect.Top(), rect.Bottom() };
     142                 :            : 
     143                 :            :     using namespace basegfx;
     144         [ #  # ]:          0 :     B2DPolygon poly;
     145 [ #  # ][ #  # ]:          0 :     poly.append(B2DPoint(X[0], Y[0])); poly.append(B2DPoint(X[1], Y[0]));
     146 [ #  # ][ #  # ]:          0 :     poly.append(B2DPoint(X[1], Y[1])); poly.append(B2DPoint(X[0], Y[1]));
     147         [ #  # ]:          0 :     poly.append(B2DPoint(X[0], Y[0]));
     148                 :            : 
     149         [ #  # ]:          0 :     if (drawFrame)
     150         [ #  # ]:          0 :       dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLINEJOIN_NONE);
     151                 :            :     else
     152 [ #  # ][ #  # ]:          0 :       dev->DrawPolygon(poly);
     153                 :          0 :   }
     154                 :            : 
     155                 :            :   //--------------------  draws an ellipse --------------------
     156                 :          0 :   void drawEllipse(VirtualDevice *dev, bool drawFrame, Rectangle const &orig, Size const &pSize) {
     157                 :          0 :     int penSize=(pSize.Width()+pSize.Height())/2;
     158         [ #  # ]:          0 :     Rectangle oval = PictReaderShapePrivate::contractRectangle(drawFrame, orig, pSize);
     159                 :            :     using namespace basegfx;
     160                 :          0 :     long const X[2] = { oval.Left(), oval.Right() };
     161                 :          0 :     long const Y[2] = { oval.Top(), oval.Bottom() };
     162                 :          0 :     B2DPoint center(0.5*(X[1]+X[0]), 0.5*(Y[1]+Y[0]));
     163         [ #  # ]:          0 :     B2DPolygon poly = tools::createPolygonFromEllipse(center, 0.5*(X[1]-X[0]), 0.5*(Y[1]-Y[0]));
     164         [ #  # ]:          0 :     if (drawFrame)
     165         [ #  # ]:          0 :       dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLINEJOIN_NONE);
     166                 :            :     else
     167 [ #  # ][ #  # ]:          0 :       dev->DrawPolygon(poly);
     168                 :          0 :   }
     169                 :            : 
     170                 :            :   //--------------------  draws an arc/pie --------------------
     171                 :          0 :   void drawArc(VirtualDevice *dev, bool drawFrame, Rectangle const &orig, const double& angle1, const double& angle2, Size const &pSize) {
     172                 :          0 :     int penSize=(pSize.Width()+pSize.Height())/2;
     173         [ #  # ]:          0 :     Rectangle arc = PictReaderShapePrivate::contractRectangle(drawFrame, orig, pSize);
     174                 :            :     using namespace basegfx;
     175                 :            : 
     176                 :          0 :     double const PI2 = M_PI/2.0;
     177                 :            :     // pict angle are CW with 0 at twelve oclock ( with Y-axis inverted)...
     178                 :          0 :     double angl1 = angle1-PI2;
     179                 :          0 :     double angl2 = angle2-PI2;
     180                 :          0 :     long const X[2] = { arc.Left(), arc.Right() };
     181                 :          0 :     long const Y[2] = { arc.Top(), arc.Bottom() };
     182                 :          0 :     B2DPoint center(0.5*(X[1]+X[0]), 0.5*(Y[1]+Y[0]));
     183                 :            : 
     184                 :            :     // We must have angl1 between 0 and F_2PI
     185         [ #  # ]:          0 :     while (angl1 < 0.0) { angl1 += F_2PI; angl2 += F_2PI; }
     186         [ #  # ]:          0 :     while (angl1 >= F_2PI) { angl1  -= F_2PI; angl2 -= F_2PI; }
     187                 :            : 
     188                 :            :     // if this happen, we want a complete circle
     189                 :            :     // so we set angl2 slightly less than angl1
     190         [ #  # ]:          0 :     if (angl2 >= angl1+F_2PI) angl2 = angl1-0.001;
     191                 :            : 
     192                 :            :     // We must have angl2 between 0 and F_2PI
     193         [ #  # ]:          0 :     while (angl2 < 0.0) angl2 += F_2PI;
     194         [ #  # ]:          0 :     while (angl2 >= F_2PI) angl2 -= F_2PI;
     195                 :            : 
     196         [ #  # ]:          0 :     B2DPolygon poly = tools::createPolygonFromEllipseSegment(center, 0.5*(X[1]-X[0]), 0.5*(Y[1]-Y[0]), angl1, angl2);
     197         [ #  # ]:          0 :     if (drawFrame)
     198         [ #  # ]:          0 :       dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLINEJOIN_NONE);
     199                 :            :     else {
     200                 :            :       // adds circle's center
     201         [ #  # ]:          0 :       poly.append(center);
     202         [ #  # ]:          0 :       dev->DrawPolygon(poly);
     203         [ #  # ]:          0 :     }
     204                 :          0 :   }
     205                 :            :   //--------------------  draws a rectangle with round corner --------------------
     206                 :          0 :   void drawRoundRectangle(VirtualDevice *dev, bool drawFrame, Rectangle const &orig, Size const &ovalSize, Size const &pSize) {
     207                 :          0 :     int penSize=(pSize.Width()+pSize.Height())/2;
     208         [ #  # ]:          0 :     Rectangle oval = PictReaderShapePrivate::contractRectangle(drawFrame, orig, pSize);
     209                 :          0 :     int ovalW=ovalSize.Width(), ovalH=ovalSize.Height();
     210                 :            :     using namespace basegfx;
     211                 :          0 :     long const X[2] = { oval.Left(), oval.Right() };
     212                 :          0 :     long const Y[2] = { oval.Top(), oval.Bottom() };
     213                 :          0 :     long width = X[1] - X[0];
     214                 :          0 :     long height = Y[1] - Y[0];
     215         [ #  # ]:          0 :     if (ovalW > width) ovalW = static_cast< int >( width );
     216         [ #  # ]:          0 :     if (ovalH > height) ovalH = static_cast< int >( height );
     217                 :            : 
     218         [ #  # ]:          0 :     B2DRectangle rect(B2DPoint(X[0],Y[0]), B2DPoint(X[1],Y[1]));
     219 [ #  # ][ #  # ]:          0 :     B2DPolygon poly = tools::createPolygonFromRect(rect, (width != 0.0) ? ovalW/width : 0.0, (height != 0.0) ? ovalH/height : 0.0);
                 [ #  # ]
     220                 :            : 
     221         [ #  # ]:          0 :     if (drawFrame)
     222         [ #  # ]:          0 :       dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLINEJOIN_NONE);
     223                 :            :     else
     224 [ #  # ][ #  # ]:          0 :       dev->DrawPolygon(poly);
     225                 :          0 :   }
     226                 :            : 
     227                 :            :   //--------------------  draws a polygon --------------------
     228                 :         87 :   void drawPolygon(VirtualDevice *dev, bool drawFrame, Polygon const &orig, Size const &pSize) {
     229                 :         87 :     int penSize=(pSize.Width()+pSize.Height())/2;
     230                 :         87 :     long decalTL[2] = {0, 0}, decalBR[2] = { pSize.Width(), pSize.Height()};
     231         [ -  + ]:         87 :     if (drawFrame) {
     232                 :          0 :       decalTL[0] += penSize/2; decalTL[1] += penSize/2;
     233                 :          0 :       decalBR[0] -= (penSize+1)/2; decalBR[1] -= (penSize+1)/2;
     234                 :            :     }
     235                 :            :     // Quickdraw Drawing Reference 3-82: the pen size is only used for frame
     236                 :         87 :     else decalBR[0] = decalBR[1] = 0;
     237                 :            : 
     238                 :            : 
     239         [ +  - ]:         87 :     int numPt = orig.GetSize();
     240         [ +  - ]:        174 :     if (numPt <= 1) return;
     241                 :            : 
     242                 :            :     // we compute a barycenter of the point to define the extended direction of each point
     243                 :         87 :     double bary[2] = { 0.0, 0.0 };
     244         [ +  + ]:       3990 :     for (int i = 0; i < numPt; i++) {
     245         [ +  - ]:       3903 :       Point const &pt = orig.GetPoint(i);
     246                 :       3903 :       bary[0] += double(pt.X()); bary[1] += double(pt.Y());
     247                 :            :     }
     248                 :         87 :     bary[0]/=double(numPt); bary[1]/=double(numPt);
     249                 :            : 
     250                 :            :     using namespace basegfx;
     251         [ +  - ]:         87 :     B2DPolygon poly;
     252                 :            :     // Note: a polygon can be open, so we must not close it when we draw the frame
     253         [ +  + ]:       3990 :     for (int i = 0; i < numPt; i++) {
     254         [ +  - ]:       3903 :       Point const &pt = orig.GetPoint(i);
     255         [ +  + ]:       3903 :       double x = (double(pt.X()) < bary[0]) ? pt.X()+decalTL[0] : pt.X()+decalBR[0];
     256         [ +  + ]:       3903 :       double y = (double(pt.Y()) < bary[1]) ? pt.Y()+decalTL[1] : pt.Y()+decalBR[1];
     257         [ +  - ]:       3903 :       poly.append(B2DPoint(x, y));
     258                 :            :     }
     259         [ -  + ]:         87 :     if (drawFrame)
     260         [ #  # ]:          0 :       dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLINEJOIN_NONE);
     261                 :            :     else
     262 [ +  - ][ +  - ]:         87 :       dev->DrawPolygon(poly);
     263                 :            :   }
     264                 :            : 
     265                 :            : 
     266                 :            : }
     267                 :            : 
     268                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10