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