File indexing completed on 2024-04-28 04:20:22

0001 
0002 // REFACTOR: Split this class into one for each distinct functionality category
0003 //           (e.g. effects, mask operations)?
0004 
0005 /*
0006    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0007    All rights reserved.
0008 
0009    Redistribution and use in source and binary forms, with or without
0010    modification, are permitted provided that the following conditions
0011    are met:
0012 
0013    1. Redistributions of source code must retain the above copyright
0014       notice, this list of conditions and the following disclaimer.
0015    2. Redistributions in binary form must reproduce the above copyright
0016       notice, this list of conditions and the following disclaimer in the
0017       documentation and/or other materials provided with the distribution.
0018 
0019    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0020    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0021    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0022    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0023    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0024    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0025    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0026    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0027    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0028    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029 */
0030 
0031 
0032 #ifndef KP_PIXMAP_FX_H
0033 #define KP_PIXMAP_FX_H
0034 
0035 
0036 #include <QRect>
0037 
0038 #include <KLocalizedString>
0039 
0040 #include "imagelib/kpColor.h"
0041 
0042 
0043 class QColor;
0044 class QImage;
0045 class QTransform;
0046 class QPen;
0047 class QImage;
0048 class QPoint;
0049 class QPolygon;
0050 
0051 //
0052 // QPixmap (view) Manipulation.
0053 //
0054 // Anything that is supposed to be manipulating the document contents
0055 // (i.e. kpImage), should be moved to kpPainter.
0056 //
0057 // kpPainter uses us for its Qt backend but we don't use kpPainter.
0058 // TODO: We should not use kpColor nor kpImage for the same reason.
0059 //
0060 class kpPixmapFX
0061 {
0062 //
0063 // Get/Set Parts of Pixmap
0064 //
0065 
0066 public:
0067 
0068     //
0069     // Returns the pixel and mask data found at the <rect> in <pm>.
0070     //
0071     static QImage getPixmapAt (const QImage &pm, const QRect &rect);
0072 
0073     //
0074     // Sets the pixel and mask data at <destRect> in <*destPixmapPtr>
0075     // to <srcPixmap>.  Neither <destRect>'s width nor height are allowed
0076     // to be bigger than <srcPixmap>'s (you can't copy more than you have).
0077     // On the other hand, you can copy less than the size of <srcPixmap>
0078     // - no scaling is done.
0079     //
0080     static void setPixmapAt (QImage *destPixmapPtr, const QRect &destRect,
0081                              const QImage &srcPixmap);
0082 
0083     //
0084     // Sets the pixel and mask data at the rectangle in <*destPixmapPtr>,
0085     // with the top-left <destAt> and dimensions <srcPixmap.rect()>,
0086     // to <srcPixmap>.
0087     //
0088     static void setPixmapAt (QImage *destPixmapPtr, const QPoint &destAt,
0089                              const QImage &srcPixmap);
0090     static void setPixmapAt (QImage *destPixmapPtr, int destX, int destY,
0091                              const QImage &srcPixmap);
0092 
0093     //
0094     // Draws <srcPixmap> on top of <*destPixmapPtr> at <destAt>.
0095     // The mask of <*destPixmapPtr> is adjusted so that all opaque
0096     // pixels in <srcPixmap> will be opaque in <*destPixmapPtr>.
0097     //
0098     static void paintPixmapAt (QImage *destPixmapPtr, const QPoint &destAt,
0099                                const QImage &srcPixmap);
0100     static void paintPixmapAt (QImage *destPixmapPtr, int destX, int destY,
0101                                const QImage &srcPixmap);
0102 
0103     //
0104     // Returns the colour of the pixel at <at> in <pm>.
0105     // If the pixel is transparent, a value is returned such that
0106     // kpTool::isColorTransparent(<return_value>) will return true.
0107     //
0108     static kpColor getColorAtPixel (const QImage &pm, const QPoint &at);
0109     static kpColor getColorAtPixel (const QImage &pm, int x, int y);
0110 
0111 //
0112 // Transforms
0113 //
0114 
0115 public:
0116 
0117     //
0118     // Resizes an image to the given width and height,
0119     // filling any new areas with <backgroundColor>.
0120     //
0121     static void resize (QImage *destPtr, int w, int h,
0122                         const kpColor &backgroundColor);
0123     static QImage resize (const QImage &pm, int w, int h,
0124                            const kpColor &backgroundColor);
0125 
0126     //
0127     // Scales an image to the given width and height.
0128     // If <pretty> is true, a smooth scale will be used.
0129     //
0130     static void scale (QImage *destPtr, int w, int h, bool pretty = false);
0131     static QImage scale (const QImage &pm, int w, int h, bool pretty = false);
0132 
0133 
0134     // The minimum difference between 2 angles (in degrees) such that they are
0135     // considered different.  This gives you at least enough precision to
0136     // rotate an image whose width <= 10000 such that its height increases
0137     // by just 1 (and similarly with height <= 10000 and width).
0138     //
0139     // Currently used for skew & rotate operations.
0140     static const double AngleInDegreesEpsilon;
0141 
0142 
0143     //
0144     // Skews an image.
0145     //
0146     // <hangle>             horizontal angle clockwise (-90 < x < 90)
0147     // <vangle>             vertical angle clockwise (-90 < x < 90)
0148     // <backgroundColor>    color to fill new areas with
0149     // <targetWidth>        if > 0, the desired width of the resultant pixmap
0150     // <targetHeight>       if > 0, the desired height of the resultant pixmap
0151     //
0152     // Using <targetWidth> & <targetHeight> to generate preview pixmaps is
0153     // significantly more efficient than skewing and then scaling yourself.
0154     //
0155     static QTransform skewMatrix (int width, int height, double hangle, double vangle);
0156     static QTransform skewMatrix (const QImage &pixmap, double hangle, double vangle);
0157 
0158     static void skew (QImage *destPixmapPtr, double hangle, double vangle,
0159                       const kpColor &backgroundColor,
0160                       int targetWidth = -1, int targetHeight = -1);
0161     static QImage skew (const QImage &pm, double hangle, double vangle,
0162                          const kpColor &backgroundColor,
0163                          int targetWidth = -1, int targetHeight = -1);
0164 
0165     //
0166     // Rotates an image.
0167     //
0168     // <angle>              clockwise angle to rotate by
0169     // <backgroundColor>    color to fill new areas with
0170     // <targetWidth>        if > 0, the desired width of the resultant pixmap
0171     // <targetHeight>       if > 0, the desired height of the resultant pixmap
0172     //
0173     // Using <targetWidth> & <targetHeight> to generate preview pixmaps is
0174     // significantly more efficient than rotating and then scaling yourself.
0175     //
0176     static QTransform rotateMatrix (int width, int height, double angle);
0177     static QTransform rotateMatrix (const QImage &pixmap, double angle);
0178 
0179     static bool isLosslessRotation (double angle);
0180 
0181     static void rotate (QImage *destPixmapPtr, double angle,
0182                         const kpColor &backgroundColor,
0183                         int targetWidth = -1, int targetHeight = -1);
0184     static QImage rotate (const QImage &pm, double angle,
0185                            const kpColor &backgroundColor,
0186                            int targetWidth = -1, int targetHeight = -1);
0187 
0188 //
0189 // Drawing Shapes
0190 //
0191 
0192 public:
0193 
0194     // Returns a pen suitable for drawing a rectangle with 90 degree
0195     // corners ("MiterJoin").  This is necessary since Qt4 defaults to
0196     // "BevelJoin".  <qtWidth> is passed straight to QPen without modification.
0197     static QPen QPainterDrawRectPen (const QColor &color, int qtWidth);
0198 
0199     // Returns a pen suitable for drawing lines / polylines / polygons /
0200     // curves with rounded corners.  This is necessary since Qt4 defaults
0201     // to square corners ("SquareCap") and "BevelJoin".
0202     // <qtWidth> is passed straight to QPen without modification.
0203     static QPen QPainterDrawLinePen (const QColor &color, int qtWidth);
0204 
0205     static bool Only1PixelInPointArray(const QPolygon &points);
0206 
0207     // Draws a line from (x1,y1) to (x2,y2) onto <image>, with <color>
0208     // and <width>.  The corners are rounded and centred at those
0209     // coordinates so if <width> > 1, the line is likely to extend past
0210     // a rectangle with those corners.
0211     //
0212     // If <stippleColor> is valid, it draws a stippled line alternating
0213     // between long strips of <color> and short strips of <stippleColor>.
0214     static void drawPolyline (QImage *image,
0215         const QPolygon &points,
0216         const kpColor &color, int penWidth,
0217         const kpColor &stippleColor = kpColor::Invalid);
0218 
0219     // <isFinal> = shape completed else drawing but haven't finalised.
0220     // If not <isFinal>, the edge that would form the closure, if the
0221     // shape were finalised now, is highlighted specially.
0222     //
0223     // Odd-even fill.
0224     static void drawPolygon (QImage *image,
0225         const QPolygon &points,
0226         const kpColor &fcolor, int penWidth,
0227         const kpColor &bcolor = kpColor::Invalid,
0228         bool isFinal = true,
0229         const kpColor &fStippleColor = kpColor::Invalid);
0230 
0231     static void fillRect (QImage *image,
0232         int x, int y, int width, int height,
0233         const kpColor &color,
0234         const kpColor &stippleColor = kpColor::Invalid);
0235 
0236     static void drawStippleRect(QImage *image,
0237             int x, int y, int width, int height,
0238             const kpColor &fcolor,
0239             const kpColor &fStippleColor);
0240 
0241 };
0242 
0243 
0244 #endif  // KP_PIXMAP_FX_H