File indexing completed on 2024-12-08 12:55:55

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