LCOV - code coverage report
Current view: top level - core/dxf - qgsdxfpaintengine.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 189 0.0 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                          qgsdxpaintengine.cpp
       3                 :            :                          --------------------
       4                 :            :     begin                : November 2013
       5                 :            :     copyright            : (C) 2013 by Marco Hugentobler
       6                 :            :     email                : marco at sourcepole dot ch
       7                 :            :  ***************************************************************************/
       8                 :            : 
       9                 :            : /***************************************************************************
      10                 :            :  *                                                                         *
      11                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      12                 :            :  *   it under the terms of the GNU General Public License as published by  *
      13                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      14                 :            :  *   (at your option) any later version.                                   *
      15                 :            :  *                                                                         *
      16                 :            :  ***************************************************************************/
      17                 :            : 
      18                 :            : #include "qgsdxfpaintengine.h"
      19                 :            : #include "qgsdxfexport.h"
      20                 :            : #include "qgsdxfpaintdevice.h"
      21                 :            : #include "qgslogger.h"
      22                 :            : 
      23                 :          0 : QgsDxfPaintEngine::QgsDxfPaintEngine( const QgsDxfPaintDevice *dxfDevice, QgsDxfExport *dxf )
      24                 :          0 :   : QPaintEngine( QPaintEngine::AllFeatures /*QPaintEngine::PainterPaths | QPaintEngine::PaintOutsidePaintEvent*/ )
      25                 :          0 :   , mPaintDevice( dxfDevice )
      26                 :          0 :   , mDxf( dxf )
      27                 :          0 : {
      28                 :          0 : }
      29                 :            : 
      30                 :          0 : bool QgsDxfPaintEngine::begin( QPaintDevice *pdev )
      31                 :            : {
      32                 :            :   Q_UNUSED( pdev )
      33                 :          0 :   return true;
      34                 :            : }
      35                 :            : 
      36                 :          0 : bool QgsDxfPaintEngine::end()
      37                 :            : {
      38                 :          0 :   return true;
      39                 :            : }
      40                 :            : 
      41                 :          0 : QPaintEngine::Type QgsDxfPaintEngine::type() const
      42                 :            : {
      43                 :          0 :   return QPaintEngine::User;
      44                 :            : }
      45                 :            : 
      46                 :          0 : void QgsDxfPaintEngine::drawPixmap( const QRectF &r, const QPixmap &pm, const QRectF &sr )
      47                 :            : {
      48                 :          0 :   Q_UNUSED( r )
      49                 :          0 :   Q_UNUSED( pm )
      50                 :          0 :   Q_UNUSED( sr )
      51                 :          0 : }
      52                 :            : 
      53                 :          0 : void QgsDxfPaintEngine::updateState( const QPaintEngineState &state )
      54                 :            : {
      55                 :          0 :   if ( state.state() & QPaintEngine::DirtyTransform )
      56                 :          0 :     mTransform = state.transform();
      57                 :            : 
      58                 :          0 :   if ( state.state() & QPaintEngine::DirtyPen )
      59                 :          0 :     mPen = state.pen();
      60                 :            : 
      61                 :          0 :   if ( state.state() & QPaintEngine::DirtyBrush )
      62                 :          0 :     mBrush = state.brush();
      63                 :            : 
      64                 :          0 :   if ( state.state() & QPaintEngine::DirtyOpacity )
      65                 :            :   {
      66                 :          0 :     mOpacity = state.opacity();
      67                 :          0 :   }
      68                 :          0 : }
      69                 :            : 
      70                 :          0 : void QgsDxfPaintEngine::setRing( QgsPointSequence &polyline, const QPointF *points, int pointCount )
      71                 :            : {
      72                 :          0 :   polyline.clear();
      73                 :          0 :   for ( int i = 0; i < pointCount; ++i )
      74                 :          0 :     polyline.append( toDxfCoordinates( points[i] ) );
      75                 :          0 : }
      76                 :            : 
      77                 :          0 : void QgsDxfPaintEngine::drawPolygon( const QPointF *points, int pointCount, PolygonDrawMode mode )
      78                 :            : {
      79                 :            :   Q_UNUSED( mode )
      80                 :          0 :   if ( !mDxf || !mPaintDevice )
      81                 :          0 :     return;
      82                 :            : 
      83                 :          0 :   QgsRingSequence polygon;
      84                 :          0 :   polygon << QgsPointSequence();
      85                 :          0 :   setRing( polygon.last(), points, pointCount );
      86                 :            : 
      87                 :          0 :   if ( mode == QPaintEngine::PolylineMode )
      88                 :            :   {
      89                 :          0 :     if ( mPen.style() != Qt::NoPen && mPen.brush().style() != Qt::NoBrush )
      90                 :          0 :       mDxf->writePolyline( polygon.at( 0 ), mLayer, QStringLiteral( "CONTINUOUS" ), penColor(), currentWidth() );
      91                 :          0 :   }
      92                 :            :   else
      93                 :            :   {
      94                 :          0 :     if ( mBrush.style() != Qt::NoBrush )
      95                 :          0 :       mDxf->writePolygon( polygon, mLayer, QStringLiteral( "SOLID" ), brushColor() );
      96                 :            :   }
      97                 :          0 : }
      98                 :            : 
      99                 :          0 : void QgsDxfPaintEngine::drawPath( const QPainterPath &path )
     100                 :            : {
     101                 :          0 :   int pathLength = path.elementCount();
     102                 :          0 :   for ( int i = 0; i < pathLength; ++i )
     103                 :            :   {
     104                 :          0 :     const QPainterPath::Element &pathElem = path.elementAt( i );
     105                 :          0 :     if ( pathElem.type == QPainterPath::MoveToElement )
     106                 :            :     {
     107                 :          0 :       moveTo( pathElem.x, pathElem.y );
     108                 :          0 :     }
     109                 :          0 :     else if ( pathElem.type == QPainterPath::LineToElement )
     110                 :            :     {
     111                 :          0 :       lineTo( pathElem.x, pathElem.y );
     112                 :          0 :     }
     113                 :          0 :     else if ( pathElem.type == QPainterPath::CurveToElement )
     114                 :            :     {
     115                 :          0 :       curveTo( pathElem.x, pathElem.y );
     116                 :          0 :     }
     117                 :          0 :     else if ( pathElem.type == QPainterPath::CurveToDataElement )
     118                 :            :     {
     119                 :          0 :       mCurrentCurve.append( QPointF( pathElem.x, pathElem.y ) );
     120                 :          0 :     }
     121                 :          0 :   }
     122                 :          0 :   endCurve();
     123                 :          0 :   endPolygon();
     124                 :            : 
     125                 :          0 :   if ( !mPolygon.isEmpty() && mBrush.style() != Qt::NoBrush )
     126                 :          0 :     mDxf->writePolygon( mPolygon, mLayer, QStringLiteral( "SOLID" ), brushColor() );
     127                 :            : 
     128                 :          0 :   mPolygon.clear();
     129                 :          0 : }
     130                 :            : 
     131                 :          0 : void QgsDxfPaintEngine::moveTo( double dx, double dy )
     132                 :            : {
     133                 :          0 :   endCurve();
     134                 :          0 :   endPolygon();
     135                 :          0 :   mCurrentPolygon.append( QPointF( dx, dy ) );
     136                 :          0 : }
     137                 :            : 
     138                 :          0 : void QgsDxfPaintEngine::lineTo( double dx, double dy )
     139                 :            : {
     140                 :          0 :   endCurve();
     141                 :          0 :   mCurrentPolygon.append( QPointF( dx, dy ) );
     142                 :          0 : }
     143                 :            : 
     144                 :          0 : void QgsDxfPaintEngine::curveTo( double dx, double dy )
     145                 :            : {
     146                 :          0 :   endCurve();
     147                 :          0 :   if ( !mCurrentPolygon.isEmpty() )
     148                 :          0 :     mCurrentCurve.append( mCurrentPolygon.last() );
     149                 :            : 
     150                 :          0 :   mCurrentCurve.append( QPointF( dx, dy ) );
     151                 :          0 : }
     152                 :            : 
     153                 :          0 : void QgsDxfPaintEngine::endPolygon()
     154                 :            : {
     155                 :          0 :   if ( mCurrentPolygon.size() > 1 )
     156                 :            :   {
     157                 :          0 :     if ( mPen.style() != Qt::NoPen )
     158                 :          0 :       drawPolygon( mCurrentPolygon.constData(), mCurrentPolygon.size(), QPaintEngine::PolylineMode );
     159                 :            : 
     160                 :          0 :     mPolygon << QgsPointSequence();
     161                 :          0 :     setRing( mPolygon.last(), mCurrentPolygon.constData(), mCurrentPolygon.size() );
     162                 :          0 :   }
     163                 :          0 :   mCurrentPolygon.clear();
     164                 :          0 : }
     165                 :            : 
     166                 :          0 : void QgsDxfPaintEngine::endCurve()
     167                 :            : {
     168                 :          0 :   if ( mCurrentCurve.empty() )
     169                 :          0 :     return;
     170                 :            : 
     171                 :          0 :   if ( mCurrentPolygon.empty() )
     172                 :            :   {
     173                 :          0 :     mCurrentCurve.clear();
     174                 :          0 :     return;
     175                 :            :   }
     176                 :            : 
     177                 :          0 :   if ( mCurrentCurve.size() >= 3 )
     178                 :            :   {
     179                 :          0 :     double t = 0.05;
     180                 :          0 :     for ( int i = 1; i <= 20; ++i ) //approximate curve with 20 segments
     181                 :            :     {
     182                 :          0 :       mCurrentPolygon.append( bezierPoint( mCurrentCurve, t ) );
     183                 :          0 :       t += 0.05;
     184                 :          0 :     }
     185                 :          0 :   }
     186                 :          0 :   else if ( mCurrentCurve.size() == 2 )
     187                 :            :   {
     188                 :          0 :     mCurrentPolygon.append( mCurrentCurve.at( 1 ) );
     189                 :          0 :   }
     190                 :          0 :   mCurrentCurve.clear();
     191                 :          0 : }
     192                 :            : 
     193                 :          0 : void QgsDxfPaintEngine::drawLines( const QLineF *lines, int lineCount )
     194                 :            : {
     195                 :          0 :   if ( !mDxf || !mPaintDevice || !lines || mPen.style() == Qt::NoPen )
     196                 :          0 :     return;
     197                 :            : 
     198                 :          0 :   for ( int i = 0; i < lineCount; ++i )
     199                 :            :   {
     200                 :          0 :     mDxf->writeLine( toDxfCoordinates( lines[i].p1() ),
     201                 :          0 :                      toDxfCoordinates( lines[i].p2() ),
     202                 :          0 :                      mLayer, QStringLiteral( "CONTINUOUS" ), penColor(), currentWidth() );
     203                 :          0 :   }
     204                 :          0 : }
     205                 :            : 
     206                 :          0 : QgsPoint QgsDxfPaintEngine::toDxfCoordinates( QPointF pt ) const
     207                 :            : {
     208                 :          0 :   if ( !mPaintDevice || !mDxf )
     209                 :          0 :     return QgsPoint( pt.x(), pt.y() );
     210                 :            : 
     211                 :          0 :   QPointF dxfPt = mPaintDevice->dxfCoordinates( mTransform.map( pt ) ) + mShift;
     212                 :          0 :   return QgsPoint( dxfPt.x(), dxfPt.y() );
     213                 :          0 : }
     214                 :            : 
     215                 :            : 
     216                 :          0 : double QgsDxfPaintEngine::currentWidth() const
     217                 :            : {
     218                 :          0 :   if ( !mPaintDevice )
     219                 :          0 :     return 1;
     220                 :            : 
     221                 :          0 :   return mPen.widthF() * mPaintDevice->widthScaleFactor();
     222                 :          0 : }
     223                 :            : 
     224                 :          0 : QPointF QgsDxfPaintEngine::bezierPoint( const QList<QPointF> &controlPolygon, double t )
     225                 :            : {
     226                 :          0 :   double x = 0;
     227                 :          0 :   double y = 0;
     228                 :          0 :   int cPolySize = controlPolygon.size();
     229                 :          0 :   double bPoly  = 0;
     230                 :            : 
     231                 :          0 :   QList<QPointF>::const_iterator it = controlPolygon.constBegin();
     232                 :          0 :   int i = 0;
     233                 :          0 :   for ( ; it != controlPolygon.constEnd(); ++it )
     234                 :            :   {
     235                 :          0 :     bPoly = bernsteinPoly( cPolySize - 1, i, t );
     236                 :          0 :     x += ( it->x() * bPoly );
     237                 :          0 :     y += ( it->y() * bPoly );
     238                 :          0 :     ++i;
     239                 :          0 :   }
     240                 :            : 
     241                 :          0 :   return QPointF( x, y );
     242                 :            : }
     243                 :            : 
     244                 :          0 : double QgsDxfPaintEngine::bernsteinPoly( int n, int i, double t )
     245                 :            : {
     246                 :          0 :   if ( i < 0 )
     247                 :          0 :     return 0;
     248                 :            : 
     249                 :          0 :   return lower( n, i ) * power( t, i ) * power( ( 1 - t ), ( n - i ) );
     250                 :          0 : }
     251                 :            : 
     252                 :          0 : int QgsDxfPaintEngine::lower( int n, int i )
     253                 :            : {
     254                 :          0 :   if ( i >= 0 && i <= n )
     255                 :            :   {
     256                 :          0 :     return faculty( n ) / ( faculty( i ) * faculty( n - i ) );
     257                 :            :   }
     258                 :            :   else
     259                 :            :   {
     260                 :          0 :     return 0;
     261                 :            :   }
     262                 :          0 : }
     263                 :            : 
     264                 :          0 : double QgsDxfPaintEngine::power( double a, int b )
     265                 :            : {
     266                 :          0 :   if ( b == 0 )
     267                 :          0 :     return 1;
     268                 :            : 
     269                 :          0 :   double tmp = a;
     270                 :          0 :   for ( int i = 2; i <= std::abs( b ); i++ )
     271                 :          0 :     a *= tmp;
     272                 :            : 
     273                 :          0 :   if ( b > 0 )
     274                 :          0 :     return a;
     275                 :            :   else
     276                 :          0 :     return 1.0 / a;
     277                 :          0 : }
     278                 :            : 
     279                 :          0 : int QgsDxfPaintEngine::faculty( int n )
     280                 :            : {
     281                 :          0 :   if ( n < 0 )//Is faculty also defined for negative integers?
     282                 :          0 :     return 0;
     283                 :            : 
     284                 :            :   int i;
     285                 :          0 :   int result = n;
     286                 :            : 
     287                 :          0 :   if ( n == 0 || n == 1 )
     288                 :          0 :     return 1;  //faculty of 0 is 1!
     289                 :            : 
     290                 :          0 :   for ( i = n - 1; i >= 2; i-- )
     291                 :          0 :     result *= i;
     292                 :            : 
     293                 :          0 :   return result;
     294                 :          0 : }
     295                 :            : 
     296                 :          0 : QColor QgsDxfPaintEngine::penColor() const
     297                 :            : {
     298                 :          0 :   if ( qgsDoubleNear( mOpacity, 1.0 ) )
     299                 :            :   {
     300                 :          0 :     return mPen.color();
     301                 :            :   }
     302                 :          0 :   QColor c = mPen.color();
     303                 :          0 :   c.setAlphaF( c.alphaF() * mOpacity );
     304                 :          0 :   return c;
     305                 :          0 : }
     306                 :            : 
     307                 :          0 : QColor QgsDxfPaintEngine::brushColor() const
     308                 :            : {
     309                 :          0 :   if ( qgsDoubleNear( mOpacity, 1.0 ) )
     310                 :            :   {
     311                 :          0 :     return mBrush.color();
     312                 :            :   }
     313                 :          0 :   QColor c = mBrush.color();
     314                 :          0 :   c.setAlphaF( c.alphaF() * mOpacity );
     315                 :          0 :   return c;
     316                 :          0 : }

Generated by: LCOV version 1.14