LCOV - code coverage report
Current view: top level - core/effects - qgspainteffect.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 15 21 71.4 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                              qgspainteffect.h
       3                 :            :                              ----------------
       4                 :            :     begin                : December 2014
       5                 :            :     copyright            : (C) 2014 Nyall Dawson
       6                 :            :     email                : nyall dot dawson at gmail dot com
       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                 :            : #ifndef QGSPAINTEFFECT_H
      18                 :            : #define QGSPAINTEFFECT_H
      19                 :            : 
      20                 :            : #include "qgis_core.h"
      21                 :            : #include "qgis_sip.h"
      22                 :            : #include "qgssymbollayer.h"
      23                 :            : #include <QPainter>
      24                 :            : #include <QDomDocument>
      25                 :            : #include <QDomElement>
      26                 :            : 
      27                 :            : class QgsRenderContext;
      28                 :            : 
      29                 :            : /**
      30                 :            :  * \ingroup core
      31                 :            :  * \class QgsPaintEffect
      32                 :            :  * \brief Base class for visual effects which can be applied to QPicture drawings
      33                 :            :  *
      34                 :            :  * QgsPaintEffect objects can be used to modify QPicture drawings prior to rendering
      35                 :            :  * them with a QPainter operation. There are two methods for drawing using an effect,
      36                 :            :  * either drawing a picture directly, or by intercepting drawing operations to a
      37                 :            :  * render context.
      38                 :            :  *
      39                 :            :  * To directly draw a picture, use the render() method with a source
      40                 :            :  * QPicture and destination render context.
      41                 :            :  *
      42                 :            :  * Intercepting drawing operations to a render context is achieved by first calling
      43                 :            :  * the begin() method, passing a render context. Any drawing operations
      44                 :            :  * performed on the render context will not directly affect the context's paint
      45                 :            :  * device. When the drawing operations have been completed, call the end()
      46                 :            :  * method. This will perform the paint effect on the intercepted drawing operations
      47                 :            :  * and render the result to the render context's paint device.
      48                 :            :  *
      49                 :            :  * \see QgsPaintEffectRegistry
      50                 :            :  * \since QGIS 2.9
      51                 :            :  */
      52                 :            : 
      53                 :            : class CORE_EXPORT QgsPaintEffect SIP_NODEFAULTCTORS
      54                 :            : {
      55                 :            : 
      56                 :            : #ifdef SIP_RUN
      57                 :            :     SIP_CONVERT_TO_SUBCLASS_CODE
      58                 :            :     if ( sipCpp->type() == "drawSource" && dynamic_cast<QgsDrawSourceEffect *>( sipCpp ) != NULL )
      59                 :            :     {
      60                 :            :       sipType = sipType_QgsDrawSourceEffect;
      61                 :            :     }
      62                 :            :     else if ( sipCpp->type() == "effectStack" && dynamic_cast<QgsEffectStack *>( sipCpp ) != NULL )
      63                 :            :     {
      64                 :            :       sipType = sipType_QgsEffectStack;
      65                 :            :     }
      66                 :            :     else if ( sipCpp->type() == "blur" && dynamic_cast<QgsBlurEffect *>( sipCpp ) != NULL )
      67                 :            :     {
      68                 :            :       sipType = sipType_QgsBlurEffect;
      69                 :            :     }
      70                 :            :     else if ( sipCpp->type() == "dropShadow" && dynamic_cast<QgsDropShadowEffect *>( sipCpp ) != NULL )
      71                 :            :     {
      72                 :            :       sipType = sipType_QgsDropShadowEffect;
      73                 :            :     }
      74                 :            :     else if ( sipCpp->type() == "outerGlow" && dynamic_cast<QgsOuterGlowEffect *>( sipCpp ) != NULL )
      75                 :            :     {
      76                 :            :       sipType = sipType_QgsOuterGlowEffect;
      77                 :            :     }
      78                 :            :     else if ( sipCpp->type() == "innerGlow" && dynamic_cast<QgsInnerGlowEffect *>( sipCpp ) != NULL )
      79                 :            :     {
      80                 :            :       sipType = sipType_QgsInnerGlowEffect;
      81                 :            :     }
      82                 :            :     else if ( sipCpp->type() == "transform" && dynamic_cast<QgsTransformEffect *>( sipCpp ) != NULL )
      83                 :            :     {
      84                 :            :       sipType = sipType_QgsTransformEffect;
      85                 :            :     }
      86                 :            :     else if ( sipCpp->type() == "color" && dynamic_cast<QgsColorEffect *>( sipCpp ) != NULL )
      87                 :            :     {
      88                 :            :       sipType = sipType_QgsColorEffect;
      89                 :            :     }
      90                 :            :     else
      91                 :            :     {
      92                 :            :       sipType = 0;
      93                 :            :     }
      94                 :            :     SIP_END
      95                 :            : #endif
      96                 :            : 
      97                 :            :   public:
      98                 :            : 
      99                 :            :     /**
     100                 :            :      * Drawing modes for effects. These modes are used only when effects are
     101                 :            :      * drawn as part of an effects stack
     102                 :            :      * \see QgsEffectStack
     103                 :            :      */
     104                 :            :     enum DrawMode
     105                 :            :     {
     106                 :            :       Modifier, //!< The result of the effect is not rendered, but is passed on to following effects in the stack
     107                 :            :       Render, //!< The result of the effect is rendered on the destination, but does not affect subsequent effects in the stack
     108                 :            :       ModifyAndRender //!< The result of the effect is both rendered and passed on to subsequent effects in the stack
     109                 :            :     };
     110                 :            : 
     111                 :            :     /**
     112                 :            :      * Constructor for QgsPaintEffect.
     113                 :            :      */
     114                 :        713 :     QgsPaintEffect() = default;
     115                 :            : 
     116                 :            :     QgsPaintEffect( const QgsPaintEffect &other );
     117                 :            :     virtual ~QgsPaintEffect();
     118                 :            : 
     119                 :            :     /**
     120                 :            :      * Returns the effect type.
     121                 :            :      * \returns unique string representation of the effect type
     122                 :            :      */
     123                 :            :     virtual QString type() const = 0;
     124                 :            : 
     125                 :            :     /**
     126                 :            :      * Duplicates an effect by creating a deep copy of the effect
     127                 :            :      * \returns clone of paint effect
     128                 :            :      */
     129                 :            :     virtual QgsPaintEffect *clone() const = 0 SIP_FACTORY;
     130                 :            : 
     131                 :            :     /**
     132                 :            :      * Returns the properties describing the paint effect encoded in a
     133                 :            :      * string format.
     134                 :            :      * \returns string map of properties, in the form property key, value
     135                 :            :      * \see readProperties
     136                 :            :      * \see saveProperties
     137                 :            :      */
     138                 :            :     virtual QVariantMap properties() const = 0;
     139                 :            : 
     140                 :            :     /**
     141                 :            :      * Reads a string map of an effect's properties and restores the effect
     142                 :            :      * to the state described by the properties map.
     143                 :            :      * \param props effect properties encoded in a string map
     144                 :            :      * \see properties
     145                 :            :      */
     146                 :            :     virtual void readProperties( const QVariantMap &props ) = 0;
     147                 :            : 
     148                 :            :     /**
     149                 :            :      * Saves the current state of the effect to a DOM element. The default
     150                 :            :      * behavior is to save the properties string map returned by
     151                 :            :      * properties().
     152                 :            :      * \param doc destination DOM document
     153                 :            :      * \param element destination DOM element
     154                 :            :      * \returns TRUE if save was successful
     155                 :            :      * \see readProperties
     156                 :            :      */
     157                 :            :     virtual bool saveProperties( QDomDocument &doc, QDomElement &element ) const;
     158                 :            : 
     159                 :            :     /**
     160                 :            :      * Restores the effect to the state described by a DOM element.
     161                 :            :      * \param element DOM element describing an effect's state
     162                 :            :      * \returns TRUE if read was successful
     163                 :            :      * \see saveProperties
     164                 :            :      */
     165                 :            :     virtual bool readProperties( const QDomElement &element );
     166                 :            : 
     167                 :            :     /**
     168                 :            :      * Renders a picture using the effect.
     169                 :            :      * \param picture source QPicture to render
     170                 :            :      * \param context destination render context
     171                 :            :      * \see begin
     172                 :            :      */
     173                 :            :     virtual void render( QPicture &picture, QgsRenderContext &context );
     174                 :            : 
     175                 :            :     /**
     176                 :            :      * Begins intercepting paint operations to a render context. When the corresponding
     177                 :            :      * end() member is called all intercepted paint operations will be
     178                 :            :      * drawn to the render context after being modified by the effect.
     179                 :            :      * \param context destination render context
     180                 :            :      * \see end
     181                 :            :      * \see render
     182                 :            :      */
     183                 :            :     virtual void begin( QgsRenderContext &context );
     184                 :            : 
     185                 :            :     /**
     186                 :            :      * Ends interception of paint operations to a render context, and draws the result
     187                 :            :      * to the render context after being modified by the effect.
     188                 :            :      * \param context destination render context
     189                 :            :      * \see begin
     190                 :            :      */
     191                 :            :     virtual void end( QgsRenderContext &context );
     192                 :            : 
     193                 :            :     /**
     194                 :            :      * Returns whether the effect is enabled
     195                 :            :      * \returns TRUE if effect is enabled
     196                 :            :      * \see setEnabled
     197                 :            :      */
     198                 :        100 :     bool enabled() const { return mEnabled; }
     199                 :            : 
     200                 :            :     /**
     201                 :            :      * Sets whether the effect is enabled
     202                 :            :      * \param enabled set to FALSE to disable the effect
     203                 :            :      * \see enabled
     204                 :            :      */
     205                 :            :     void setEnabled( bool enabled );
     206                 :            : 
     207                 :            :     /**
     208                 :            :      * Returns the draw mode for the effect. This property only has an
     209                 :            :      * effect if the paint effect is used in a QgsEffectStack.
     210                 :            :      * \returns draw mode for effect
     211                 :            :      * \see setDrawMode
     212                 :            :      */
     213                 :          0 :     DrawMode drawMode() const { return mDrawMode; }
     214                 :            : 
     215                 :            :     /**
     216                 :            :      * Sets the draw mode for the effect. This property only has an
     217                 :            :      * effect if the paint effect is used in a QgsEffectStack.
     218                 :            :      * \param drawMode draw mode for effect
     219                 :            :      * \see drawMode
     220                 :            :      */
     221                 :            :     void setDrawMode( DrawMode drawMode );
     222                 :            : 
     223                 :            :   protected:
     224                 :            : 
     225                 :        713 :     bool mEnabled = true;
     226                 :        713 :     DrawMode mDrawMode = ModifyAndRender;
     227                 :        713 :     bool requiresQPainterDpiFix = true;
     228                 :            : 
     229                 :            :     /**
     230                 :            :      * Handles drawing of the effect's result on to the specified render context.
     231                 :            :      * Derived classes must reimplement this method to apply any transformations to
     232                 :            :      * the source QPicture and draw the result using the context's painter.
     233                 :            :      * \param context destination render context
     234                 :            :      * \see drawSource
     235                 :            :      */
     236                 :            :     virtual void draw( QgsRenderContext &context ) = 0;
     237                 :            : 
     238                 :            :     /**
     239                 :            :      * Draws the source QPicture onto the specified painter. Handles scaling of the picture
     240                 :            :      * to account for the destination painter's DPI.
     241                 :            :      * \param painter destination painter
     242                 :            :      * \see source
     243                 :            :      * \see sourceAsImage
     244                 :            :      */
     245                 :            :     void drawSource( QPainter &painter );
     246                 :            : 
     247                 :            :     /**
     248                 :            :      * Returns the source QPicture. The draw() member can utilize this when
     249                 :            :      * drawing the effect.
     250                 :            :      * \returns source QPicture
     251                 :            :      * \see drawSource
     252                 :            :      * \see sourceAsImage
     253                 :            :      */
     254                 :          0 :     const QPicture *source() const { return mPicture; }
     255                 :            : 
     256                 :            :     /**
     257                 :            :      * Returns the source QPicture rendered to a new QImage. The draw() member can
     258                 :            :      * utilize this when drawing the effect. The image will be padded or cropped from the original
     259                 :            :      * source QPicture by the results of the boundingRect() method.
     260                 :            :      * The result is cached to speed up subsequent calls to sourceAsImage.
     261                 :            :      * \returns source QPicture rendered to an image
     262                 :            :      * \see drawSource
     263                 :            :      * \see source
     264                 :            :      * \see imageOffset
     265                 :            :      * \see boundingRect
     266                 :            :      */
     267                 :            :     QImage *sourceAsImage( QgsRenderContext &context );
     268                 :            : 
     269                 :            :     /**
     270                 :            :      * Returns the offset which should be used when drawing the source image on to a destination
     271                 :            :      * render context.
     272                 :            :      * \param context destination render context
     273                 :            :      * \returns point offset for image top left corner
     274                 :            :      * \see sourceAsImage
     275                 :            :      */
     276                 :            :     QPointF imageOffset( const QgsRenderContext &context ) const;
     277                 :            : 
     278                 :            :     /**
     279                 :            :      * Returns the bounding rect required for drawing the effect. This method can be used
     280                 :            :      * to expand the bounding rect of a source picture to account for offset or blurring
     281                 :            :      * effects.
     282                 :            :      * \param rect original source bounding rect
     283                 :            :      * \param context destination render context
     284                 :            :      * \returns modified bounding rect
     285                 :            :      * \see sourceAsImage
     286                 :            :      */
     287                 :            :     virtual QRectF boundingRect( const QRectF &rect, const QgsRenderContext &context ) const;
     288                 :            : 
     289                 :            :     /**
     290                 :            :      * Applies a workaround to a QPainter to avoid an issue with incorrect scaling
     291                 :            :      * when drawing QPictures. This may need to be called by derived classes prior
     292                 :            :      * to rendering results onto a painter.
     293                 :            :      * \param painter destination painter
     294                 :            :      */
     295                 :            :     void fixQPictureDpi( QPainter *painter ) const;
     296                 :            : 
     297                 :            :   private:
     298                 :            : 
     299                 :        713 :     const QPicture *mPicture = nullptr;
     300                 :        713 :     QImage *mSourceImage = nullptr;
     301                 :        713 :     bool mOwnsImage = false;
     302                 :            : 
     303                 :        713 :     QPainter *mPrevPainter = nullptr;
     304                 :        713 :     QPainter *mEffectPainter = nullptr;
     305                 :        713 :     QPicture *mTempPicture = nullptr;
     306                 :            : 
     307                 :            :     QRectF imageBoundingRect( const QgsRenderContext &context ) const;
     308                 :            : 
     309                 :            :     friend class QgsEffectStack;
     310                 :            : 
     311                 :            :     QgsPaintEffect &operator= ( const QgsPaintEffect & ) = delete;
     312                 :            : 
     313                 :            : };
     314                 :            : 
     315                 :            : /**
     316                 :            :  * \ingroup core
     317                 :            :  * \class QgsDrawSourceEffect
     318                 :            :  * \brief A paint effect which draws the source picture with minor or no alterations
     319                 :            :  *
     320                 :            :  * The draw source effect can be used to draw an unaltered copy of the original source
     321                 :            :  * picture. Minor changes like lowering the opacity and applying a blend mode are
     322                 :            :  * supported, however these changes will force the resultant output to be rasterized.
     323                 :            :  * If no alterations are performed then the original picture will be rendered as a vector.
     324                 :            :  *
     325                 :            :  * \since QGIS 2.9
     326                 :            :  */
     327                 :            : 
     328                 :        172 : class CORE_EXPORT QgsDrawSourceEffect : public QgsPaintEffect SIP_NODEFAULTCTORS
     329                 :            : {
     330                 :            :   public:
     331                 :            : 
     332                 :            :     //! Constructor for QgsDrawSourceEffect
     333                 :        118 :     QgsDrawSourceEffect() = default;
     334                 :            : 
     335                 :            :     /**
     336                 :            :      * Creates a new QgsDrawSource effect from a properties string map.
     337                 :            :      * \param map encoded properties string map
     338                 :            :      * \returns new QgsDrawSourceEffect
     339                 :            :      */
     340                 :            :     static QgsPaintEffect *create( const QVariantMap &map ) SIP_FACTORY;
     341                 :            : 
     342                 :          0 :     QString type() const override { return QStringLiteral( "drawSource" ); }
     343                 :            :     QgsDrawSourceEffect *clone() const override SIP_FACTORY;
     344                 :            :     QVariantMap properties() const override;
     345                 :            :     void readProperties( const QVariantMap &props ) override;
     346                 :            : 
     347                 :            :     /**
     348                 :            :      * Sets the \a opacity for the effect.
     349                 :            :      * \param opacity double between 0 and 1 inclusive, where 0 is fully transparent
     350                 :            :      * and 1 is fully opaque
     351                 :            :      * \see opacity()
     352                 :            :      */
     353                 :            :     void setOpacity( const double opacity ) { mOpacity = opacity; }
     354                 :            : 
     355                 :            :     /**
     356                 :            :      * Returns the opacity for the effect
     357                 :            :      * \returns opacity value between 0 and 1 inclusive, where 0 is fully transparent
     358                 :            :      * and 1 is fully opaque
     359                 :            :      * \see setOpacity()
     360                 :            :      */
     361                 :          0 :     double opacity() const { return mOpacity; }
     362                 :            : 
     363                 :            :     /**
     364                 :            :      * Sets the blend mode for the effect
     365                 :            :      * \param mode blend mode used for drawing the source on to a destination
     366                 :            :      * paint device
     367                 :            :      * \see blendMode
     368                 :            :      */
     369                 :            :     void setBlendMode( const QPainter::CompositionMode mode ) { mBlendMode = mode; }
     370                 :            : 
     371                 :            :     /**
     372                 :            :      * Returns the blend mode for the effect
     373                 :            :      * \returns blend mode used for drawing the source on to a destination
     374                 :            :      * paint device
     375                 :            :      * \see setBlendMode
     376                 :            :      */
     377                 :          0 :     QPainter::CompositionMode blendMode() const { return mBlendMode; }
     378                 :            : 
     379                 :            :   protected:
     380                 :            : 
     381                 :            :     void draw( QgsRenderContext &context ) override;
     382                 :            : 
     383                 :            :   private:
     384                 :            : 
     385                 :        118 :     double mOpacity = 1.0;
     386                 :        118 :     QPainter::CompositionMode mBlendMode = QPainter::CompositionMode_SourceOver;
     387                 :            : };
     388                 :            : 
     389                 :            : /**
     390                 :            :  * \ingroup core
     391                 :            :  * \class QgsEffectPainter
     392                 :            :  * \brief A class to manager painter saving and restoring required for effect drawing
     393                 :            :  *
     394                 :            :  * \since QGIS 3.0
     395                 :            :  */
     396                 :            : class CORE_EXPORT QgsEffectPainter
     397                 :            : {
     398                 :            :   public:
     399                 :            : 
     400                 :            :     /**
     401                 :            :      * QgsEffectPainter constructor
     402                 :            :      *
     403                 :            :      * \param renderContext the QgsRenderContext object
     404                 :            :      * \since QGIS 3.0
     405                 :            :      */
     406                 :            :     QgsEffectPainter( QgsRenderContext &renderContext );
     407                 :            : 
     408                 :            :     /**
     409                 :            :      * QgsEffectPainter constructor alternative if no painter translation is needed
     410                 :            :      *
     411                 :            :      * \param renderContext the QgsRenderContext object
     412                 :            :      * \param effect the QgsPaintEffect object
     413                 :            :      * \since QGIS 3.0
     414                 :            :      */
     415                 :            :     QgsEffectPainter( QgsRenderContext &renderContext, QgsPaintEffect *effect );
     416                 :            :     ~QgsEffectPainter();
     417                 :            : 
     418                 :            :     /**
     419                 :            :      * Sets the effect to be painted
     420                 :            :      *
     421                 :            :      * \param effect the QgsPaintEffect object
     422                 :            :      */
     423                 :            :     void setEffect( QgsPaintEffect *effect );
     424                 :            : 
     425                 :            :     ///@cond PRIVATE
     426                 :            : 
     427                 :            :     /**
     428                 :            :      * Access to the painter object
     429                 :            :      *
     430                 :            :      * \since QGIS 3.0
     431                 :            :      */
     432                 :          0 :     QPainter *operator->() { return mPainter; }
     433                 :            :     ///@endcond
     434                 :            : 
     435                 :            :   private:
     436                 :            : #ifdef SIP_RUN
     437                 :            :     const QgsEffectPainter &operator=( const QgsEffectPainter & );
     438                 :            : #endif
     439                 :            : 
     440                 :            :     QgsRenderContext &mRenderContext;
     441                 :            :     QPainter *mPainter = nullptr;
     442                 :            :     QgsPaintEffect *mEffect = nullptr;
     443                 :            : };
     444                 :            : 
     445                 :            : #endif // QGSPAINTEFFECT_H
     446                 :            : 

Generated by: LCOV version 1.14