File indexing completed on 2025-01-19 10:49:10

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 2010 KO GmbH <jos.van.den.oever@kogmbh.com>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef ODRAWTOODF_H
0008 #define ODRAWTOODF_H
0009 
0010 #include "generated/simpleParser.h"
0011 #include "writer.h"
0012 
0013 class DrawStyle;
0014 class QColor;
0015 class QPainterPath;
0016 
0017 class ODrawToOdf
0018 {
0019 public:
0020     class Client
0021     {
0022     public:
0023         virtual ~Client() {}
0024         /**
0025          * Get the bounding rect that defines the position and dimensions of
0026          * the shape in the hosting document.
0027          **/
0028         virtual QRectF getRect(const MSO::OfficeArtClientAnchor&) = 0;
0029 
0030         /**
0031          * Get the bounding rect that defines the position and dimensions of
0032          * the shape in the hosting document if OfficeArtClientAnchor is
0033          * missing.
0034          */
0035         virtual QRectF getReserveRect(void) = 0;
0036 
0037         /**
0038          * Get the path in the ODF document that corresponds to the
0039          * image generated from the image with the given pib.
0040          **/
0041         virtual QString getPicturePath(const quint32 pib) = 0;
0042         /**
0043          * Check if the clientdata is the main content of a drawing object.
0044          **/
0045         virtual bool onlyClientData(const MSO::OfficeArtClientData& o) = 0;
0046         /**
0047          * Process the client data into ODF in a host application specific
0048          * manner.
0049          **/
0050         virtual void processClientData(const MSO::OfficeArtClientTextBox* ct,
0051                                        const MSO::OfficeArtClientData& o,
0052                                        Writer& out) = 0;
0053         virtual void processClientTextBox(const MSO::OfficeArtClientTextBox& ct,
0054                                           const MSO::OfficeArtClientData* cd,
0055                                           Writer& out) = 0;
0056 
0057         /**
0058          * Ask the host application whether to process an msosptRectangle type
0059          * shape container as an msosptTextBox.
0060          */
0061         virtual bool processRectangleAsTextBox(const MSO::OfficeArtClientData& cd) = 0;
0062 
0063         /**
0064          * Create a fitting style for the current object.
0065          * This will be a style that can contain graphic style elements. So the
0066          * style will belong to one of the families 'graphic', 'presentation',
0067          * or 'chart'.
0068          **/
0069         virtual KoGenStyle createGraphicStyle(
0070             const MSO::OfficeArtClientTextBox* ct,
0071             const MSO::OfficeArtClientData* cd,
0072             const DrawStyle& ds,
0073             Writer& out) = 0;
0074 
0075         /**
0076          * Add host application specific formatting properties for text and
0077          * paragraphs to the style of the draw element.  These properties are
0078          * attributes to style:paragraph-properties or style:text-properties.
0079          * Also add host application specific attributes to the draw element.
0080          **/
0081         virtual void addTextStyles(
0082             const MSO::OfficeArtClientTextBox* clientTextbox,
0083             const MSO::OfficeArtClientData* clientData,
0084             KoGenStyle& style,
0085             Writer& out) = 0;
0086 
0087         /**
0088          * Convert the OfficeArtCOLORREF to a QColor.  This conversion requires
0089          * color scheme information.
0090          **/
0091         virtual QColor toQColor(const MSO::OfficeArtCOLORREF& c) = 0;
0092 
0093         /**
0094          *
0095          */
0096         virtual QString formatPos(qreal v) = 0;
0097 
0098         /**
0099          * Retrieve the OfficeArtDggContainer that contains global information
0100          * relating to the drawings.
0101          **/
0102         virtual const MSO::OfficeArtDggContainer* getOfficeArtDggContainer() = 0;
0103 
0104         /**
0105          * Retrieve the OfficeArtSpContainer of the master shape.
0106          * @param spid identifier of the master shape.
0107          **/
0108         virtual const MSO::OfficeArtSpContainer* getMasterShapeContainer(quint32 spid) = 0;
0109 
0110         quint16 m_currentShapeType;
0111 
0112     }; //End class Client
0113 
0114 private:
0115     Client* const client;
0116 
0117     /**
0118      * Both OfficeArtClientAnchorData and OfficeArtChildAnchor might contain a
0119      * 90 degrees rotated rectangle.  It depends on the value of the rotation
0120      * property and the intervals differ for each shape type.
0121      *
0122      * @param shapeType
0123      * @param rotation [degrees] - normalization will be applied
0124      * @param rect the group, client or child rectangle
0125      * @return copy of the rectangle free of any transformations
0126      */
0127     QRectF processRect(const quint16 shapeType, const qreal rotation, QRectF &rect);
0128 
0129     /**
0130      * MSOffice 2003/2007 use different values for the rotation property so we
0131      * have to normalize before processing.
0132      *
0133      * @param rotation [degrees]
0134      * @return rotation in <0, 360>
0135      */
0136     qint16 normalizeRotation(qreal rotation);
0137 
0138     QRectF getRect(const MSO::OfficeArtFSPGR &r);
0139     QRectF getRect(const MSO::OfficeArtSpContainer &o);
0140     void processRectangle(const MSO::OfficeArtSpContainer& o, Writer& out);
0141     void processTextBox(const MSO::OfficeArtSpContainer& o, Writer& out);
0142     void processLine(const MSO::OfficeArtSpContainer& o, Writer& out);
0143     void processStraightConnector1(const MSO::OfficeArtSpContainer& o, Writer& out);
0144     void processPictureFrame(const MSO::OfficeArtSpContainer& o, Writer& out);
0145     void processNotPrimitive(const MSO::OfficeArtSpContainer& o, Writer& out);
0146 
0147     typedef void (ODrawToOdf::*PathArtist)(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0148     void drawStraightConnector1(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0149     void drawPathBentConnector2(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0150     void drawPathBentConnector3(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0151     void drawPathBentConnector4(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0152     void drawPathBentConnector5(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0153     void drawPathCurvedConnector2(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0154     void drawPathCurvedConnector3(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0155     void drawPathCurvedConnector4(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0156     void drawPathCurvedConnector5(qreal l, qreal t, qreal r, qreal b, Writer& out, QPainterPath &shapePath) const;
0157     void processConnector(const MSO::OfficeArtSpContainer& o, Writer& out, PathArtist drawPath);
0158 
0159     // shapes2.cpp
0160     void processRoundRectangle(const MSO::OfficeArtSpContainer& o, Writer& out);
0161     void processEllipse(const MSO::OfficeArtSpContainer& o, Writer& out);
0162     void processDiamond(const MSO::OfficeArtSpContainer& o, Writer& out);
0163     void processIsocelesTriangle(const MSO::OfficeArtSpContainer& o, Writer& out);
0164     void processRightTriangle(const MSO::OfficeArtSpContainer& o, Writer& out);
0165     void processParallelogram(const MSO::OfficeArtSpContainer& o, Writer& out);
0166     void processTrapezoid(const MSO::OfficeArtSpContainer& o, Writer& out);
0167     void processHexagon(const MSO::OfficeArtSpContainer& o, Writer& out);
0168     void processOctagon(const MSO::OfficeArtSpContainer& o, Writer& out);
0169     void processPlus(const MSO::OfficeArtSpContainer& o, Writer& out);
0170     void processStar(const MSO::OfficeArtSpContainer& o, Writer& out);
0171     void processArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0172     void processHomePlate(const MSO::OfficeArtSpContainer& o, Writer& out);
0173     void processCube(const MSO::OfficeArtSpContainer& o, Writer& out);
0174     void processPlaque(const MSO::OfficeArtSpContainer& o, Writer& out);
0175     void processCan(const MSO::OfficeArtSpContainer& o, Writer& out);
0176     void processDonut(const MSO::OfficeArtSpContainer& o, Writer& out);
0177     void processCallout1(const MSO::OfficeArtSpContainer& o, Writer& out);
0178     void processCallout2(const MSO::OfficeArtSpContainer& o, Writer& out);
0179     void processCallout3(const MSO::OfficeArtSpContainer& o, Writer& out);
0180     void processAccentCallout1(const MSO::OfficeArtSpContainer& o, Writer& out);
0181     void processAccentCallout2(const MSO::OfficeArtSpContainer& o, Writer& out);
0182     void processAccentCallout3(const MSO::OfficeArtSpContainer& o, Writer& out);
0183     void processBorderCallout1(const MSO::OfficeArtSpContainer& o, Writer& out);
0184     void processBorderCallout2(const MSO::OfficeArtSpContainer& o, Writer& out);
0185     void processBorderCallout3(const MSO::OfficeArtSpContainer& o, Writer& out);
0186     void processAccentBorderCallout1(const MSO::OfficeArtSpContainer& o, Writer& out);
0187     void processAccentBorderCallout2(const MSO::OfficeArtSpContainer& o, Writer& out);
0188     void processAccentBorderCallout3(const MSO::OfficeArtSpContainer& o, Writer& out);
0189     void processRibbon(const MSO::OfficeArtSpContainer& o, Writer& out);
0190     void processRibbon2(const MSO::OfficeArtSpContainer& o, Writer& out);
0191     void processChevron(const MSO::OfficeArtSpContainer& o, Writer& out);
0192     void processPentagon(const MSO::OfficeArtSpContainer& o, Writer& out);
0193     void processNoSmoking(const MSO::OfficeArtSpContainer& o, Writer& out);
0194     void processSeal8(const MSO::OfficeArtSpContainer& o, Writer& out);
0195     void processSeal16(const MSO::OfficeArtSpContainer& o, Writer& out);
0196     void processSeal32(const MSO::OfficeArtSpContainer& o, Writer& out);
0197     void processWedgeRectCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0198     void processWedgeRRectCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0199     void processWedgeEllipseCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0200     void processWave(const MSO::OfficeArtSpContainer& o, Writer& out);
0201     void processFoldedCorner(const MSO::OfficeArtSpContainer& o, Writer& out);
0202     void processLeftArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0203     void processDownArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0204     void processUpArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0205     void processLeftRightArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0206     void processUpDownArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0207     void processIrregularSeal1(const MSO::OfficeArtSpContainer& o, Writer& out);
0208     void processIrregularSeal2(const MSO::OfficeArtSpContainer& o, Writer& out);
0209     void processLightningBolt(const MSO::OfficeArtSpContainer& o, Writer& out);
0210     void processHeart(const MSO::OfficeArtSpContainer& o, Writer& out);
0211     void processQuadArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0212     void processLeftArrowCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0213     void processRightArrowCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0214     void processUpArrowCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0215     void processDownArrowCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0216     void processLeftRightArrowCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0217     void processUpDownArrowCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0218     void processQuadArrowCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0219     void processBevel(const MSO::OfficeArtSpContainer& o, Writer& out);
0220     void processLeftBracket(const MSO::OfficeArtSpContainer& o, Writer& out);
0221     void processRightBracket(const MSO::OfficeArtSpContainer& o, Writer& out);
0222     void processLeftBrace(const MSO::OfficeArtSpContainer& o, Writer& out);
0223     void processRightBrace(const MSO::OfficeArtSpContainer& o, Writer& out);
0224     void processLeftUpArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0225     void processBentUpArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0226     void processBentArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0227     void processSeal24(const MSO::OfficeArtSpContainer& o, Writer& out);
0228     void processStripedRightArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0229     void processNotchedRightArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0230     void processBlockArc(const MSO::OfficeArtSpContainer& o, Writer& out);
0231     void processSmileyFace(const MSO::OfficeArtSpContainer& o, Writer& out);
0232     void processVerticalScroll(const MSO::OfficeArtSpContainer& o, Writer& out);
0233     void processHorizontalScroll(const MSO::OfficeArtSpContainer& o, Writer& out);
0234     void processCircularArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0235     void processNotchedCircularArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0236     void processUturnArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0237     void processCurvedRightArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0238     void processCurvedLeftArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0239     void processCurvedUpArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0240     void processCurvedDownArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0241     void processCloudCallout(const MSO::OfficeArtSpContainer& o, Writer& out);
0242     void processEllipseRibbon(const MSO::OfficeArtSpContainer& o, Writer& out);
0243     void processEllipseRibbon2(const MSO::OfficeArtSpContainer& o, Writer& out);
0244     void processFlowChartProcess(const MSO::OfficeArtSpContainer& o, Writer& out);
0245     void processFlowChartDecision(const MSO::OfficeArtSpContainer& o, Writer& out);
0246     void processFlowChartInputOutput(const MSO::OfficeArtSpContainer& o, Writer& out);
0247     void processFlowChartPredefinedProcess(const MSO::OfficeArtSpContainer& o, Writer& out);
0248     void processFlowChartInternalStorage(const MSO::OfficeArtSpContainer& o, Writer& out);
0249     void processFlowChartDocument(const MSO::OfficeArtSpContainer& o, Writer& out);
0250     void processFlowChartMultidocument(const MSO::OfficeArtSpContainer& o, Writer& out);
0251     void processFlowChartTerminator(const MSO::OfficeArtSpContainer& o, Writer& out);
0252     void processFlowChartPreparation(const MSO::OfficeArtSpContainer& o, Writer& out);
0253     void processFlowChartManualInput(const MSO::OfficeArtSpContainer& o, Writer& out);
0254     void processFlowChartManualOperation(const MSO::OfficeArtSpContainer& o, Writer& out);
0255     void processFlowChartConnector(const MSO::OfficeArtSpContainer& o, Writer& out);
0256     void processFlowChartPunchedCard(const MSO::OfficeArtSpContainer& o, Writer& out);
0257     void processFlowChartPunchedTape(const MSO::OfficeArtSpContainer& o, Writer& out);
0258     void processFlowChartSummingJunction(const MSO::OfficeArtSpContainer& o, Writer& out);
0259     void processFlowChartOr(const MSO::OfficeArtSpContainer& o, Writer& out);
0260     void processFlowChartCollate(const MSO::OfficeArtSpContainer& o, Writer& out);
0261     void processFlowChartSort(const MSO::OfficeArtSpContainer& o, Writer& out);
0262     void processFlowChartExtract(const MSO::OfficeArtSpContainer& o, Writer& out);
0263     void processFlowChartMerge(const MSO::OfficeArtSpContainer& o, Writer& out);
0264     void processFlowChartOnlineStorage(const MSO::OfficeArtSpContainer& o, Writer& out);
0265     void processFlowChartMagneticTape(const MSO::OfficeArtSpContainer& o, Writer& out);
0266     void processFlowChartMagneticDisk(const MSO::OfficeArtSpContainer& o, Writer& out);
0267     void processFlowChartMagneticDrum(const MSO::OfficeArtSpContainer& o, Writer& out);
0268     void processFlowChartDisplay(const MSO::OfficeArtSpContainer& o, Writer& out);
0269     void processFlowChartDelay(const MSO::OfficeArtSpContainer& o, Writer& out);
0270     void processFlowChartAlternateProcess(const MSO::OfficeArtSpContainer& o, Writer& out);
0271     void processFlowChartOffpageConnector(const MSO::OfficeArtSpContainer& o, Writer& out);
0272     void processCallout90(const MSO::OfficeArtSpContainer& o, Writer& out);
0273     void processAccentCallout90(const MSO::OfficeArtSpContainer& o, Writer& out);
0274     void processBorderCallout90(const MSO::OfficeArtSpContainer& o, Writer& out);
0275     void processAccentBorderCallout90(const MSO::OfficeArtSpContainer& o, Writer& out);
0276     void processLeftRightUpArrow(const MSO::OfficeArtSpContainer& o, Writer& out);
0277     void processSun(const MSO::OfficeArtSpContainer& o, Writer& out);
0278     void processMoon(const MSO::OfficeArtSpContainer& o, Writer& out);
0279     void processBracketPair(const MSO::OfficeArtSpContainer& o, Writer& out);
0280     void processBracePair(const MSO::OfficeArtSpContainer& o, Writer& out);
0281     void processSeal4(const MSO::OfficeArtSpContainer& o, Writer& out);
0282     void processDoubleWave(const MSO::OfficeArtSpContainer& o, Writer& out);
0283     void processActionButtonBlank(const MSO::OfficeArtSpContainer& o, Writer& out);
0284     void processActionButtonHome(const MSO::OfficeArtSpContainer& o, Writer& out);
0285     void processActionButtonHelp(const MSO::OfficeArtSpContainer& o, Writer& out);
0286     void processActionButtonInformation(const MSO::OfficeArtSpContainer& o, Writer& out);
0287     void processActionButtonForwardNext(const MSO::OfficeArtSpContainer& o, Writer& out);
0288     void processActionButtonBackPrevious(const MSO::OfficeArtSpContainer& o, Writer& out);
0289     void processActionButtonEnd(const MSO::OfficeArtSpContainer& o, Writer& out);
0290     void processActionButtonBeginning(const MSO::OfficeArtSpContainer& o, Writer& out);
0291     void processActionButtonReturn(const MSO::OfficeArtSpContainer& o, Writer& out);
0292     void processActionButtonDocument(const MSO::OfficeArtSpContainer& o, Writer& out);
0293     void processActionButtonSound(const MSO::OfficeArtSpContainer& o, Writer& out);
0294     void processActionButtonMovie(const MSO::OfficeArtSpContainer& o, Writer& out);
0295 
0296 
0297     void processStyle(const MSO::OfficeArtSpContainer& o, Writer& out);
0298     void processText(const MSO::OfficeArtSpContainer& o, Writer& out);
0299     void processStyleAndText(const MSO::OfficeArtSpContainer& o, Writer& out);
0300 
0301     void processModifiers(const MSO::OfficeArtSpContainer& o, Writer& out, const QList<int>& defaults = QList<int>());
0302     /**
0303      * @brief set the width, height rotation and starting point for the given
0304      * container
0305      */
0306     void set2dGeometry(const MSO::OfficeArtSpContainer& o, Writer& out);
0307     void setEnhancedGeometry(const MSO::OfficeArtSpContainer& o, Writer& out);
0308     QString path2svg(const QPainterPath &path);
0309     void setShapeMirroring(const MSO::OfficeArtSpContainer& o, Writer& out);
0310 
0311 public:
0312     explicit ODrawToOdf(Client& c) :client(&c) {}
0313     void processGroupShape(const MSO::OfficeArtSpgrContainer& o, Writer& out);
0314     void processDrawing(const MSO::OfficeArtSpgrContainerFileBlock& o, Writer& out);
0315     void processDrawingObject(const MSO::OfficeArtSpContainer& o, Writer& out);
0316     void defineGraphicProperties(KoGenStyle& style, const DrawStyle& ds, KoGenStyles& styles);
0317     void addGraphicStyleToDrawElement(Writer& out, const MSO::OfficeArtSpContainer& o);
0318     void defineGradientStyle(KoGenStyle& style, const DrawStyle& ds);
0319     QString defineDashStyle(KoGenStyles& styles, const quint32 lineDashing);
0320 
0321     /**
0322      * Define and insert standard marker style into styles collection.
0323      * @return the name that has been assigned for the inserted style
0324      * or an empty string in case of an unsupported arrowType.
0325      */
0326     QString defineMarkerStyle(KoGenStyles& styles, const quint32 arrowType);
0327 
0328     /**
0329      * Apply the logic defined in MS-ODRAW subsection 2.2.2 to the provided
0330      * OfficeArtCOLORREF record.
0331      *
0332      * @param c OfficeArtCOLORREF record
0333      * @param ds DrawStyle to access shape properties and client specific f.
0334      * @return final color
0335      */
0336     QColor processOfficeArtCOLORREF(const MSO::OfficeArtCOLORREF& c, const DrawStyle& ds);
0337 };
0338 
0339 /**
0340  * Convert FixedPoint to a qreal
0341  */
0342 inline qreal toQReal(const MSO::FixedPoint& f)
0343 {
0344     return f.integral + f.fractional / 65536.0;
0345 }
0346 
0347 const char* getFillRule(quint16 shapeType);
0348 const char* getFillType(quint32 fillType);
0349 const char* getRepeatStyle(quint32 fillType);
0350 const char* getGradientRendering(quint32 fillType);
0351 const char* getHorizontalPos(quint32 posH);
0352 const char* getHorizontalRel(quint32 posRelH);
0353 const char* getVerticalPos(quint32 posV);
0354 const char* getVerticalRel(quint32 posRelV);
0355 const char* getHorizontalAlign(quint32 anchorText);
0356 const char* getVerticalAlign(quint32 anchorText);
0357 const char* getStrokeLineCap(quint32 capStyle);
0358 const char* getStrokeLineJoin(quint32 joinStyle);
0359 
0360 #endif