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