VSDContentCollector.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* libvisio
00003  * Version: MPL 1.1 / GPLv2+ / LGPLv2+
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License or as specified alternatively below. You may obtain a copy of
00008  * the License at http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * Major Contributor(s):
00016  * Copyright (C) 2011 Fridrich Strba <fridrich.strba@bluewin.ch>
00017  * Copyright (C) 2011 Eilidh McAdam <tibbylickle@gmail.com>
00018  *
00019  *
00020  * All Rights Reserved.
00021  *
00022  * For minor contributions see the git repository.
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPLv2+"), or
00026  * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
00027  * in which case the provisions of the GPLv2+ or the LGPLv2+ are applicable
00028  * instead of those above.
00029  */
00030 
00031 #ifndef VSDCONTENTCOLLECTOR_H
00032 #define VSDCONTENTCOLLECTOR_H
00033 
00034 #include <locale.h>
00035 #include <sstream>
00036 #include <string>
00037 #include <cmath>
00038 #include <map>
00039 #include <list>
00040 #include <vector>
00041 #include <libwpg/libwpg.h>
00042 #include "libvisio_utils.h"
00043 #include "VSDCollector.h"
00044 #include "VSDParser.h"
00045 #include "VSDOutputElementList.h"
00046 #include "VSDStyles.h"
00047 #include "VSDPages.h"
00048 
00049 namespace libvisio
00050 {
00051 
00052 class VSDContentCollector : public VSDCollector
00053 {
00054 public:
00055   VSDContentCollector(
00056     libwpg::WPGPaintInterface *painter,
00057     std::vector<std::map<unsigned, XForm> > &groupXFormsSequence,
00058     std::vector<std::map<unsigned, unsigned> > &groupMembershipsSequence,
00059     std::vector<std::list<unsigned> > &documentPageShapeOrders,
00060     VSDStyles &styles, VSDStencils &stencils
00061   );
00062   virtual ~VSDContentCollector()
00063   {
00064     if (m_txtxform) delete(m_txtxform);
00065   };
00066 
00067   void collectEllipticalArcTo(unsigned id, unsigned level, double x3, double y3, double x2, double y2, double angle, double ecc);
00068   void collectForeignData(unsigned level, const WPXBinaryData &binaryData);
00069   void collectOLEList(unsigned id, unsigned level);
00070   void collectOLEData(unsigned id, unsigned level, const WPXBinaryData &oleData);
00071   void collectEllipse(unsigned id, unsigned level, double cx, double cy, double xleft, double yleft, double xtop, double ytop);
00072   void collectLine(unsigned level, const boost::optional<double> &strokeWidth, const boost::optional<Colour> &c, const boost::optional<unsigned char> &linePattern,
00073                    const boost::optional<unsigned char> &startMarker, const boost::optional<unsigned char> &endMarker,
00074                    const boost::optional<unsigned char> &lineCap);
00075   void collectFillAndShadow(unsigned level, const boost::optional<Colour> &colourFG, const boost::optional<Colour> &colourBG,
00076                             const boost::optional<unsigned char> &fillPattern, const boost::optional<double> &fillFGTransparency,
00077                             const boost::optional<double> &fillBGTransparency, const boost::optional<unsigned char> &shadowPattern,
00078                             const boost::optional<Colour> &shfgc, const boost::optional<double> &shadowOffsetX, const boost::optional<double> &shadowOffsetY);
00079   void collectFillAndShadow(unsigned level, const boost::optional<Colour> &colourFG, const boost::optional<Colour> &colourBG,
00080                             const boost::optional<unsigned char> &fillPattern, const boost::optional<double> &fillFGTransparency,
00081                             const boost::optional<double> &fillBGTransparency, const boost::optional<unsigned char> &shadowPattern,
00082                             const boost::optional<Colour> &shfgc);
00083   void collectGeometry(unsigned id, unsigned level, bool noFill, bool noLine, bool noShow);
00084   void collectMoveTo(unsigned id, unsigned level, double x, double y);
00085   void collectLineTo(unsigned id, unsigned level, double x, double y);
00086   void collectArcTo(unsigned id, unsigned level, double x2, double y2, double bow);
00087   void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, unsigned char xType, unsigned char yType, unsigned degree,
00088                       std::vector<std::pair<double, double> > controlPoints, std::vector<double> knotVector, std::vector<double> weights);
00089   void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, double knot, double knotPrev, double weight, double weightPrev, unsigned dataID);
00090   void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, double knot, double knotPrev, double weight, double weightPrev, const NURBSData &data);
00091   void collectPolylineTo(unsigned id, unsigned level, double x, double y, unsigned char xType, unsigned char yType,
00092                          const std::vector<std::pair<double, double> > &points);
00093   void collectPolylineTo(unsigned id, unsigned level, double x, double y, unsigned dataID);
00094   void collectPolylineTo(unsigned id, unsigned level, double x, double y, const PolylineData &data);
00095   void collectShapeData(unsigned id, unsigned level, unsigned char xType, unsigned char yType, unsigned degree, double lastKnot,
00096                         std::vector<std::pair<double, double> > controlPoints, std::vector<double> knotVector, std::vector<double> weights);
00097   void collectShapeData(unsigned id, unsigned level, unsigned char xType, unsigned char yType, std::vector<std::pair<double, double> > points);
00098   void collectXFormData(unsigned level, const XForm &xform);
00099   void collectTxtXForm(unsigned level, const XForm &txtxform);
00100   void collectShapesOrder(unsigned id, unsigned level, const std::vector<unsigned> &shapeIds);
00101   void collectForeignDataType(unsigned level, unsigned foreignType, unsigned foreignFormat, double offsetX, double offsetY, double width, double height);
00102   void collectPageProps(unsigned id, unsigned level, double pageWidth, double pageHeight, double shadowOffsetX, double shadowOffsetY, double scale);
00103   void collectPage(unsigned id, unsigned level, unsigned backgroundPageID, bool isBackgroundPage);
00104   void collectShape(unsigned id, unsigned level, unsigned parent, unsigned masterPage, unsigned masterShape, unsigned lineStyle, unsigned fillStyle, unsigned textStyle);
00105   void collectSplineStart(unsigned id, unsigned level, double x, double y, double secondKnot, double firstKnot, double lastKnot, unsigned degree);
00106   void collectSplineKnot(unsigned id, unsigned level, double x, double y, double knot);
00107   void collectSplineEnd();
00108   void collectInfiniteLine(unsigned id, unsigned level, double x1, double y1, double x2, double y2);
00109   void collectRelCubBezTo(unsigned id, unsigned level, double x, double y, double a, double b, double c, double d);
00110   void collectRelEllipticalArcTo(unsigned id, unsigned level, double x, double y, double a, double b, double c, double d);
00111   void collectRelLineTo(unsigned id, unsigned level, double x, double y);
00112   void collectRelMoveTo(unsigned id, unsigned level, double x, double y);
00113   void collectRelQuadBezTo(unsigned id, unsigned level, double x, double y, double a, double b);
00114 
00115   void collectUnhandledChunk(unsigned id, unsigned level);
00116 
00117   void collectText(unsigned level, const WPXBinaryData &textStream, TextFormat format);
00118   void collectCharIX(unsigned id, unsigned level, unsigned charCount, const boost::optional<VSDName> &font,
00119                      const boost::optional<Colour> &fontColour, const boost::optional<double> &fontSize, const boost::optional<bool> &bold,
00120                      const boost::optional<bool> &italic, const boost::optional<bool> &underline, const boost::optional<bool> &doubleunderline,
00121                      const boost::optional<bool> &strikeout, const boost::optional<bool> &doublestrikeout, const boost::optional<bool> &allcaps,
00122                      const boost::optional<bool> &initcaps, const boost::optional<bool> &smallcaps, const boost::optional<bool> &superscript,
00123                      const boost::optional<bool> &subscript);
00124   void collectDefaultCharStyle(unsigned charCount, const boost::optional<VSDName> &font, const boost::optional<Colour> &fontColour,
00125                                const boost::optional<double> &fontSize, const boost::optional<bool> &bold, const boost::optional<bool> &italic,
00126                                const boost::optional<bool> &underline, const boost::optional<bool> &doubleunderline, const boost::optional<bool> &strikeout,
00127                                const boost::optional<bool> &doublestrikeout, const boost::optional<bool> &allcaps, const boost::optional<bool> &initcaps,
00128                                const boost::optional<bool> &smallcaps, const boost::optional<bool> &superscript, const boost::optional<bool> &subscript);
00129   void collectParaIX(unsigned id, unsigned level, unsigned charCount, const boost::optional<double> &indFirst,
00130                      const boost::optional<double> &indLeft, const boost::optional<double> &indRight, const boost::optional<double> &spLine,
00131                      const boost::optional<double> &spBefore, const boost::optional<double> &spAfter, const boost::optional<unsigned char> &align,
00132                      const boost::optional<unsigned> &flags);
00133   void collectDefaultParaStyle(unsigned charCount, const boost::optional<double> &indFirst, const boost::optional<double> &indLeft,
00134                                const boost::optional<double> &indRight, const boost::optional<double> &spLine, const boost::optional<double> &spBefore,
00135                                const boost::optional<double> &spAfter, const boost::optional<unsigned char> &align, const boost::optional<unsigned> &flags);
00136   void collectTextBlock(unsigned level, const boost::optional<double> &leftMargin, const boost::optional<double> &rightMargin,
00137                         const boost::optional<double> &topMargin, const boost::optional<double> &bottomMargin,
00138                         const boost::optional<unsigned char> &verticalAlign, const boost::optional<bool> &isBgFilled,
00139                         const boost::optional<Colour> &bgColour, const boost::optional<double> &defaultTabStop,
00140                         const boost::optional<unsigned char> &textDirection);
00141   void collectNameList(unsigned id, unsigned level);
00142   void collectName(unsigned id, unsigned level,  const WPXBinaryData &name, TextFormat format);
00143   void collectPageSheet(unsigned id, unsigned level);
00144 
00145 
00146   // Style collectors
00147   void collectStyleSheet(unsigned id, unsigned level, unsigned parentLineStyle, unsigned parentFillStyle, unsigned parentTextStyle);
00148   void collectLineStyle(unsigned level, const boost::optional<double> &strokeWidth, const boost::optional<Colour> &c, const boost::optional<unsigned char> &linePattern,
00149                         const boost::optional<unsigned char> &startMarker, const boost::optional<unsigned char> &endMarker,
00150                         const boost::optional<unsigned char> &lineCap);
00151   void collectFillStyle(unsigned level, const boost::optional<Colour> &colourFG, const boost::optional<Colour> &colourBG,
00152                         const boost::optional<unsigned char> &fillPattern, const boost::optional<double> &fillFGTransparency,
00153                         const boost::optional<double> &fillBGTransparency, const boost::optional<unsigned char> &shadowPattern,
00154                         const boost::optional<Colour> &shfgc, const boost::optional<double> &shadowOffsetX, const boost::optional<double> &shadowOffsetY);
00155   void collectFillStyle(unsigned level, const boost::optional<Colour> &colourFG, const boost::optional<Colour> &colourBG,
00156                         const boost::optional<unsigned char> &fillPattern, const boost::optional<double> &fillFGTransparency,
00157                         const boost::optional<double> &fillBGTransparency, const boost::optional<unsigned char> &shadowPattern,
00158                         const boost::optional<Colour> &shfgc);
00159   void collectCharIXStyle(unsigned id, unsigned level, unsigned charCount, const boost::optional<VSDName> &font,
00160                           const boost::optional<Colour> &fontColour, const boost::optional<double> &fontSize, const boost::optional<bool> &bold,
00161                           const boost::optional<bool> &italic, const boost::optional<bool> &underline, const boost::optional<bool> &doubleunderline,
00162                           const boost::optional<bool> &strikeout, const boost::optional<bool> &doublestrikeout, const boost::optional<bool> &allcaps,
00163                           const boost::optional<bool> &initcaps, const boost::optional<bool> &smallcaps, const boost::optional<bool> &superscript,
00164                           const boost::optional<bool> &subscript);
00165   void collectParaIXStyle(unsigned id, unsigned level, unsigned charCount, const boost::optional<double> &indFirst,
00166                           const boost::optional<double> &indLeft, const boost::optional<double> &indRight, const boost::optional<double> &spLine,
00167                           const boost::optional<double> &spBefore, const boost::optional<double> &spAfter, const boost::optional<unsigned char> &align,
00168                           const boost::optional<unsigned> &flags);
00169   void collectTextBlockStyle(unsigned level, const boost::optional<double> &leftMargin, const boost::optional<double> &rightMargin,
00170                              const boost::optional<double> &topMargin, const boost::optional<double> &bottomMargin,
00171                              const boost::optional<unsigned char> &verticalAlign, const boost::optional<bool> &isBgFilled,
00172                              const boost::optional<Colour> &bgColour, const boost::optional<double> &defaultTabStop,
00173                              const boost::optional<unsigned char> &textDirection);
00174 
00175   // Field list
00176   void collectFieldList(unsigned id, unsigned level);
00177   void collectTextField(unsigned id, unsigned level, int nameId, int formatStringId);
00178   void collectNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId);
00179 
00180   void startPage(unsigned pageId);
00181   void endPage();
00182   void endPages();
00183 
00184 
00185 private:
00186   VSDContentCollector(const VSDContentCollector &);
00187   VSDContentCollector &operator=(const VSDContentCollector &);
00188   libwpg::WPGPaintInterface *m_painter;
00189 
00190   void applyXForm(double &x, double &y, const XForm &xform);
00191 
00192   void transformPoint(double &x, double &y, XForm *txtxform = 0);
00193   void transformAngle(double &angle, XForm *txtxform = 0);
00194   void transformFlips(bool &flipX, bool &flipY);
00195 
00196   double _NURBSBasis(unsigned knot, unsigned degree, double point, const std::vector<double> &knotVector);
00197 
00198   void _flushCurrentPath();
00199   void _flushText();
00200   void _flushCurrentForeignData();
00201   void _flushCurrentPage();
00202 
00203   void _handleLevelChange(unsigned level);
00204 
00205   void _handleForeignData(const WPXBinaryData &data);
00206 
00207   void _lineProperties(const VSDLineStyle &style, WPXPropertyList &styleProps);
00208   void _fillAndShadowProperties(const VSDFillStyle &style, WPXPropertyList &styleProps);
00209 
00210   void _applyLinePattern();
00211   const char *_linePropertiesMarkerViewbox(unsigned marker);
00212   const char *_linePropertiesMarkerPath(unsigned marker);
00213   double _linePropertiesMarkerScale(unsigned marker);
00214 
00215   void appendCharacters(WPXString &text, const std::vector<unsigned char> &characters, TextFormat format);
00216   void appendCharacters(WPXString &text, const std::vector<unsigned char> &characters);
00217   void _convertDataToString(WPXString &result, const WPXBinaryData &data, TextFormat format);
00218   bool parseFormatId( const char *formatString, unsigned short &result );
00219 
00220   bool m_isPageStarted;
00221   double m_pageWidth;
00222   double m_pageHeight;
00223   double m_shadowOffsetX;
00224   double m_shadowOffsetY;
00225   double m_scale;
00226   double m_x;
00227   double m_y;
00228   double m_originalX;
00229   double m_originalY;
00230   XForm m_xform;
00231   XForm *m_txtxform;
00232   std::vector<WPXPropertyList> m_currentFillGeometry;
00233   std::vector<WPXPropertyList> m_currentLineGeometry;
00234   std::map<unsigned, XForm> *m_groupXForms;
00235   WPXBinaryData m_currentForeignData;
00236   WPXBinaryData m_currentOLEData;
00237   WPXPropertyList m_currentForeignProps;
00238   unsigned m_currentShapeId;
00239   unsigned m_foreignType;
00240   unsigned m_foreignFormat;
00241   double m_foreignOffsetX;
00242   double m_foreignOffsetY;
00243   double m_foreignWidth;
00244   double m_foreignHeight;
00245   bool m_noLine;
00246   bool m_noFill;
00247   bool m_noShow;
00248   std::map<unsigned short, VSDFont> m_fonts;
00249   unsigned m_currentLevel;
00250   bool m_isShapeStarted;
00251   std::map<unsigned, unsigned> &m_groupMemberships;
00252   std::vector<std::map<unsigned, XForm> > &m_groupXFormsSequence;
00253   std::vector<std::map<unsigned, unsigned> > &m_groupMembershipsSequence;
00254   unsigned m_currentPageNumber;
00255   VSDOutputElementList *m_shapeOutputDrawing, *m_shapeOutputText;
00256   std::map<unsigned, VSDOutputElementList> m_pageOutputDrawing;
00257   std::map<unsigned, VSDOutputElementList> m_pageOutputText;
00258   std::vector<std::list<unsigned> > &m_documentPageShapeOrders;
00259   std::list<unsigned> &m_pageShapeOrder;
00260   bool m_isFirstGeometry;
00261 
00262   std::map<unsigned, NURBSData> m_NURBSData;
00263   std::map<unsigned, PolylineData> m_polylineData;
00264   WPXBinaryData m_textStream;
00265   std::map<unsigned, WPXString> m_names, m_stencilNames;
00266   std::vector<WPXString> m_fields;
00267   VSDFieldList m_stencilFields;
00268   unsigned m_fieldIndex;
00269   TextFormat m_textFormat;
00270   std::vector<VSDCharStyle> m_charFormats;
00271   std::vector<VSDParaStyle> m_paraFormats;
00272 
00273   VSDLineStyle m_lineStyle;
00274   VSDFillStyle m_fillStyle;
00275   VSDTextBlockStyle m_textBlockStyle;
00276 
00277   VSDCharStyle m_defaultCharStyle;
00278   VSDParaStyle m_defaultParaStyle;
00279 
00280   unsigned m_currentStyleSheet;
00281   VSDStyles m_styles;
00282 
00283   VSDStencils m_stencils;
00284   const VSDShape *m_stencilShape;
00285   bool m_isStencilStarted;
00286 
00287   unsigned m_currentGeometryCount;
00288 
00289   unsigned m_backgroundPageID;
00290   unsigned m_currentPageID;
00291   VSDPage m_currentPage;
00292   VSDPages m_pages;
00293 
00294   std::vector<std::pair<double, double> > m_splineControlPoints;
00295   std::vector<double> m_splineKnotVector;
00296   double m_splineX, m_splineY;
00297   double m_splineLastKnot;
00298   unsigned m_splineDegree;
00299   unsigned m_splineLevel;
00300   unsigned m_currentShapeLevel;
00301   bool m_isBackgroundPage;
00302 };
00303 
00304 } // namespace libvisio
00305 
00306 #endif /* VSDCONTENTCOLLECTOR_H */
00307 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */