1 /* This file is part of the KDE project
2  * Copyright (C) 2007 Thomas Zander <zander@kde.org>
3  * Copyright (C) 2011 Silvio Heinrich <plassy@web.de>
4  * Copyright (C) 2012 Inge Wallin <inge@lysator.liu.se>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #ifndef PICTURESHAPE_H
23 #define PICTURESHAPE_H
24 
25 #include <QPainterPath>
26 #include <QPixmap>
27 #include <QImage>
28 #include <QRunnable>
29 
30 #include <KoTosContainer.h>
31 #include <KoFrameShape.h>
32 #include <SvgShape.h>
33 
34 #include "ClippingRect.h"
35 
36 #define PICTURESHAPEID "PictureShape"
37 
38 class KoImageData;
39 class KoImageCollection;
40 class PictureShape;
41 class KoClipPath;
42 
43 namespace _Private
44 {
45     /**
46      * This class acts as a proxy for the PictureShape class
47      * since it is not possible to add slots to it
48      * (MOC always complains)
49      */
50     class PictureShapeProxy: public QObject
51     {
52         Q_OBJECT
53     public:
PictureShapeProxy(PictureShape * p)54         explicit PictureShapeProxy(PictureShape *p):
55             m_pictureShape(p) { }
56 
57     public Q_SLOTS:
58         void setImage(const QString& key, const QImage& image);
59 
60     private:
61         PictureShape *m_pictureShape;
62     };
63 
64     /**
65      * This class will scale an image to a given size.
66      * Instances of this class can be executed in a thread pool
67      * therefore the scaling process can be done in the background
68      */
69     class PixmapScaler: public QObject, public QRunnable
70     {
71         Q_OBJECT
72     public:
73         PixmapScaler(PictureShape *pictureShape, const QSize &pixmapSize);
74         void run() override;
75 
76     Q_SIGNALS:
77         void finished(const QString &, const QImage &);
78 
79     private:
80         QSize m_size;
81         QImage m_image;
82         quint64 m_imageKey;
83     };
84 
85     /**
86      * This method will create an outline path out of the image
87      */
88     QPainterPath generateOutline(const QImage &imageIn, int threshold = 20);
89 }
90 
91 
92 class PictureShape : public KoTosContainer, public KoFrameShape, public SvgShape
93 {
94     friend class _Private::PixmapScaler;
95     friend class _Private::PictureShapeProxy;
96 
97 public:
98     // Odf 1.2: 20.313  style:mirror
99     // The value could be 0, or a combination of one of the Horizontal* and/or Vertical
100     // separated by whitespace.
101     enum MirrorMode {
102         MirrorNone             = 0x00,
103         MirrorHorizontal       = 0x01,
104         MirrorHorizontalOnEven = 0x02,
105         MirrorHorizontalOnOdd  = 0x04,
106         MirrorVertical         = 0x08,
107 
108         MirrorMask = 0x0f      // Only used as a mask, never as a value.
109     };
110 
111     enum ColorMode {
112         Standard,
113         Greyscale,
114         Mono,
115         Watermark
116     };
117 
118     PictureShape();
119 
120     // reimplemented
121     void paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &paintcontext) override;
122     // reimplemented
123     QPainterPath shadowOutline() const override;
124     // reimplemented
125     void saveOdf(KoShapeSavingContext &context) const override;
126     // reimplemented
127     bool loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context) override;
128     // reimplemented
129     void waitUntilReady(const KoViewConverter &converter, bool asynchronous) const override;
130     // reimplemented from SvgShape
131     bool saveSvg(SvgSavingContext &context) override;
132     // reimplemented from SvgShape
133     bool loadSvg(const KoXmlElement &element, SvgLoadingContext &context) override;
134     /**
135      * Get the collection used in the shape.
136      */
137     KoImageCollection *imageCollection() const;
138     KoImageData *imageData() const;
139     QFlags<MirrorMode> mirrorMode() const;
140     ColorMode colorMode() const;
141     QRectF cropRect() const;
142     bool isPictureInProportion() const;
143 
setImageCollection(KoImageCollection * collection)144     void setImageCollection(KoImageCollection *collection) { m_imageCollection = collection; }
145     void setCropRect(const QRectF& rect);
146     void setMirrorMode(QFlags<MirrorMode> mode);
147     void setColorMode(ColorMode mode);
148     void setColoring(qreal red, qreal green, qreal blue, qreal luminance, qreal contrast);
149     void setGamma(qreal gamma);
150     KoClipPath *generateClipPath();
151 
152 
153 protected:
154     bool loadOdfFrameElement(const KoXmlElement &element, KoShapeLoadingContext &context) override;
155     QString saveStyle(KoGenStyle &style, KoShapeSavingContext &context) const override;
156     void loadStyle(const KoXmlElement &element, KoShapeLoadingContext &context) override;
157 
158 private:
159     QSize calcOptimalPixmapSize(const QSizeF &shapeSize, const QSizeF &imageSize) const;
160     ClippingRect parseClippingRectString(const QString &string) const;
161 
162 private:
163     KoImageCollection *m_imageCollection;
164     mutable QImage m_printQualityImage;
165     mutable QSizeF m_printQualityRequestedSize;
166 
167     QFlags<MirrorMode> m_mirrorMode;
168     ColorMode m_colorMode;
169     ClippingRect m_clippingRect;
170 
171     _Private::PictureShapeProxy m_proxy;
172 };
173 
174 #endif
175