File indexing completed on 2024-12-22 05:00:58

0001 /* Windows Meta File Loader
0002  *
0003  * SPDX-FileCopyrightText: 1998 Stefan Taferner
0004  * SPDX-FileCopyrightText: 2002 thierry lorthiois
0005  *
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #pragma once
0010 
0011 #include <QColor>
0012 #include <QImage>
0013 #include <QPainter>
0014 #include <QRect>
0015 #include <QString>
0016 #include <QTransform>
0017 
0018 class QBuffer;
0019 class WmfCmd;
0020 class WinObjHandle;
0021 struct WmfPlaceableHeader;
0022 
0023 /**
0024  * QWinMetaFile is a WMF viewer based on Qt toolkit
0025  * How to use QWinMetaFile :
0026  * @code
0027  * QWinMetaFile wmf;
0028  * QPicture pic;     // or QImage pic;
0029  * if ( wmf.load( filename )
0030  *    wmf.paint( &pic );
0031  * @endcode
0032  */
0033 
0034 class QWinMetaFile
0035 {
0036 public:
0037     QWinMetaFile();
0038     virtual ~QWinMetaFile();
0039 
0040     /**
0041      * Load WMF file.
0042      * @return true on success.
0043      */
0044     virtual bool load(const QString &fileName);
0045     virtual bool load(QBuffer &buffer);
0046 
0047     /**
0048      * Paint metafile to given paint-device using absolute or relative coordinate.
0049      * - absolute coord. Reset the world transfomation Matrix
0050      * - relative coord. Use the existing world transfomation Matrix
0051      *
0052      * @return true on success.
0053      */
0054     virtual bool paint(QPaintDevice *target, bool absolute = false);
0055 
0056     /**
0057      * @return true if the metafile is placeable.
0058      */
0059     [[nodiscard]] bool isPlaceable() const
0060     {
0061         return mIsPlaceable;
0062     }
0063 
0064     /**
0065      * @return true if the metafile is enhanced.
0066      */
0067     [[nodiscard]] bool isEnhanced() const
0068     {
0069         return mIsEnhanced;
0070     }
0071 
0072     /**
0073      * @return bounding rectangle
0074      */
0075     [[nodiscard]] QRect bbox() const
0076     {
0077         return mBBox;
0078     }
0079 
0080 public: // should be protected but cannot
0081     /* Metafile painter methods */
0082 
0083     /** set window origin */
0084     void setWindowOrg(long num, short *parms);
0085     /** set window extents */
0086     void setWindowExt(long num, short *parms);
0087 
0088     /****************** Drawing *******************/
0089     /** draw line to coord */
0090     void lineTo(long num, short *parms);
0091     /** move pen to coord */
0092     void moveTo(long num, short *parms);
0093     /** draw ellipse */
0094     void ellipse(long num, short *parms);
0095     /** draw polygon */
0096     void polygon(long num, short *parms);
0097     /** draw a list of polygons */
0098     void polyPolygon(long num, short *parms);
0099     /** draw series of lines */
0100     void polyline(long num, short *parms);
0101     /** draw a rectangle */
0102     void rectangle(long num, short *parms);
0103     /** draw round rectangle */
0104     void roundRect(long num, short *parms);
0105     /** draw arc */
0106     void arc(long num, short *parms);
0107     /** draw chord */
0108     void chord(long num, short *parms);
0109     /** draw pie */
0110     void pie(long num, short *parms);
0111     /** set polygon fill mode */
0112     void setPolyFillMode(long num, short *parms);
0113     /** set background pen color */
0114     void setBkColor(long num, short *parms);
0115     /** set background pen mode */
0116     void setBkMode(long num, short *parms);
0117     /** set a pixel */
0118     void setPixel(long num, short *parms);
0119     /** Set raster operation mode */
0120     void setRop(long num, short *parms);
0121     /** save device context */
0122     void saveDC(long num, short *parms);
0123     /** restore device context */
0124     void restoreDC(long num, short *parms);
0125     /**  clipping region is the intersection of this region and the original region */
0126     void intersectClipRect(long num, short *parms);
0127     /** delete a clipping rectangle of the original region */
0128     void excludeClipRect(long num, short *parms);
0129 
0130     /****************** Text *******************/
0131     /** set text color */
0132     void setTextColor(long num, short *parms);
0133     /** set text alignment */
0134     void setTextAlign(long num, short *parms);
0135     /** draw text */
0136     void textOut(long num, short *parms);
0137     void extTextOut(long num, short *parms);
0138 
0139     /****************** Bitmap *******************/
0140     /** copies a DIB into a dest location */
0141     void dibBitBlt(long num, short *parms);
0142     /** stretches a DIB into a dest location */
0143     void dibStretchBlt(long num, short *parms);
0144     void stretchDib(long num, short *parms);
0145     /** create a pattern brush */
0146     void dibCreatePatternBrush(long num, short *parms);
0147 
0148     /****************** Object handle *******************/
0149     /** Activate object handle */
0150     void selectObject(long num, short *parms);
0151     /** Free object handle */
0152     void deleteObject(long num, short *parms);
0153     /** create an empty object in the object list */
0154     void createEmptyObject(long num, short *parms);
0155     /** create a logical brush */
0156     void createBrushIndirect(long num, short *parms);
0157     /** create a logical pen */
0158     void createPenIndirect(long num, short *parms);
0159     /** create a logical font */
0160     void createFontIndirect(long num, short *parms);
0161 
0162     /****************** misc *******************/
0163     /** nothing to do */
0164     void noop(long, short *);
0165     /** end of meta file */
0166     void end(long /*num*/, short * /*parms*/);
0167     /** Resolution of the image in dots per inch */
0168     int dpi() const
0169     {
0170         return mDpi;
0171     }
0172 
0173 protected:
0174     /** Calculate header checksum */
0175     unsigned short calcCheckSum(WmfPlaceableHeader *);
0176 
0177     /** Find function in metafunc table by metafile-function.
0178         Returns index or -1 if not found. */
0179     virtual int findFunc(unsigned short aFunc) const;
0180 
0181     /** Fills given parms into mPoints. */
0182     QPolygon *pointArray(short num, short *parms);
0183 
0184     /** Returns color given by the two parameters */
0185     QColor color(short *parm);
0186 
0187     /** Converts two parameters to long */
0188     unsigned int toDWord(short *parm);
0189 
0190     /** Convert (x1,y1) and (x2, y2) positions in angle and angleLength */
0191     void xyToAngle(int xStart, int yStart, int xEnd, int yEnd, int &angle, int &aLength);
0192 
0193     /** Handle win-object-handles */
0194     void addHandle(WinObjHandle *);
0195     void deleteHandle(int);
0196 
0197     /** Convert windows rasterOp in QT rasterOp */
0198     QPainter::CompositionMode winToQtComposition(short parm) const;
0199     QPainter::CompositionMode winToQtComposition(long parm) const;
0200 
0201     /** Converts DIB to BMP */
0202     bool dibToBmp(QImage &bmp, const char *dib, long size);
0203 
0204 protected:
0205     QPainter mPainter;
0206     bool mIsPlaceable = false;
0207     bool mIsEnhanced = false;
0208     bool mValid = false;
0209 
0210     // coordinate system
0211     bool mAbsoluteCoord;
0212     QTransform mInternalWorldMatrix; // memorisation of WMF matrix transformation
0213     QRect mHeaderBoundingBox;
0214     QRect mBBox;
0215 
0216     // information shared between Metafile Functions
0217     QColor mTextColor;
0218     int mTextAlign, mRotation;
0219     bool mWinding = false;
0220 
0221     WmfCmd *mFirstCmd = nullptr;
0222     WinObjHandle **mObjHandleTab;
0223     QPolygon mPoints;
0224     int mDpi;
0225     QPoint mLastPos;
0226 };