00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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 const std::vector<std::pair<double, double> > &ctrlPnts, const std::vector<double> &kntVec, const 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, const VSDName &pageName);
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 void collectMisc(unsigned level, const VSDMisc &misc);
00145
00146
00147
00148 void collectStyleSheet(unsigned id, unsigned level, unsigned parentLineStyle, unsigned parentFillStyle, unsigned parentTextStyle);
00149 void collectLineStyle(unsigned level, const boost::optional<double> &strokeWidth, const boost::optional<Colour> &c, const boost::optional<unsigned char> &linePattern,
00150 const boost::optional<unsigned char> &startMarker, const boost::optional<unsigned char> &endMarker,
00151 const boost::optional<unsigned char> &lineCap);
00152 void collectFillStyle(unsigned level, const boost::optional<Colour> &colourFG, const boost::optional<Colour> &colourBG,
00153 const boost::optional<unsigned char> &fillPattern, const boost::optional<double> &fillFGTransparency,
00154 const boost::optional<double> &fillBGTransparency, const boost::optional<unsigned char> &shadowPattern,
00155 const boost::optional<Colour> &shfgc, const boost::optional<double> &shadowOffsetX, const boost::optional<double> &shadowOffsetY);
00156 void collectFillStyle(unsigned level, const boost::optional<Colour> &colourFG, const boost::optional<Colour> &colourBG,
00157 const boost::optional<unsigned char> &fillPattern, const boost::optional<double> &fillFGTransparency,
00158 const boost::optional<double> &fillBGTransparency, const boost::optional<unsigned char> &shadowPattern,
00159 const boost::optional<Colour> &shfgc);
00160 void collectCharIXStyle(unsigned id, unsigned level, unsigned charCount, const boost::optional<VSDName> &font,
00161 const boost::optional<Colour> &fontColour, const boost::optional<double> &fontSize, const boost::optional<bool> &bold,
00162 const boost::optional<bool> &italic, const boost::optional<bool> &underline, const boost::optional<bool> &doubleunderline,
00163 const boost::optional<bool> &strikeout, const boost::optional<bool> &doublestrikeout, const boost::optional<bool> &allcaps,
00164 const boost::optional<bool> &initcaps, const boost::optional<bool> &smallcaps, const boost::optional<bool> &superscript,
00165 const boost::optional<bool> &subscript);
00166 void collectParaIXStyle(unsigned id, unsigned level, unsigned charCount, const boost::optional<double> &indFirst,
00167 const boost::optional<double> &indLeft, const boost::optional<double> &indRight, const boost::optional<double> &spLine,
00168 const boost::optional<double> &spBefore, const boost::optional<double> &spAfter, const boost::optional<unsigned char> &align,
00169 const boost::optional<unsigned> &flags);
00170 void collectTextBlockStyle(unsigned level, const boost::optional<double> &leftMargin, const boost::optional<double> &rightMargin,
00171 const boost::optional<double> &topMargin, const boost::optional<double> &bottomMargin,
00172 const boost::optional<unsigned char> &verticalAlign, const boost::optional<bool> &isBgFilled,
00173 const boost::optional<Colour> &bgColour, const boost::optional<double> &defaultTabStop,
00174 const boost::optional<unsigned char> &textDirection);
00175
00176
00177 void collectFieldList(unsigned id, unsigned level);
00178 void collectTextField(unsigned id, unsigned level, int nameId, int formatStringId);
00179 void collectNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId);
00180
00181 void startPage(unsigned pageId);
00182 void endPage();
00183 void endPages();
00184
00185
00186 private:
00187 VSDContentCollector(const VSDContentCollector &);
00188 VSDContentCollector &operator=(const VSDContentCollector &);
00189 libwpg::WPGPaintInterface *m_painter;
00190
00191 void applyXForm(double &x, double &y, const XForm &xform);
00192
00193 void transformPoint(double &x, double &y, XForm *txtxform = 0);
00194 void transformAngle(double &angle, XForm *txtxform = 0);
00195 void transformFlips(bool &flipX, bool &flipY);
00196
00197 double _NURBSBasis(unsigned knot, unsigned degree, double point, const std::vector<double> &knotVector);
00198
00199 void _flushShape();
00200 void _flushCurrentPath();
00201 void _flushText();
00202 void _flushCurrentForeignData();
00203 void _flushCurrentPage();
00204
00205 void _handleLevelChange(unsigned level);
00206
00207 void _handleForeignData(const WPXBinaryData &data);
00208
00209 void _lineProperties(const VSDLineStyle &style, WPXPropertyList &styleProps);
00210 void _fillAndShadowProperties(const VSDFillStyle &style, WPXPropertyList &styleProps);
00211
00212 void _applyLinePattern();
00213 const char *_linePropertiesMarkerViewbox(unsigned marker);
00214 const char *_linePropertiesMarkerPath(unsigned marker);
00215 double _linePropertiesMarkerScale(unsigned marker);
00216
00217 void appendCharacters(WPXString &text, const std::vector<unsigned char> &characters, TextFormat format);
00218 void appendCharacters(WPXString &text, const std::vector<unsigned char> &characters);
00219 void _convertDataToString(WPXString &result, const WPXBinaryData &data, TextFormat format);
00220 bool parseFormatId( const char *formatString, unsigned short &result );
00221 void _appendField(WPXString &text);
00222
00223
00224 bool _isUniform(const std::vector<double> &weights) const;
00225 void _generatePolylineFromNURBS(unsigned degree, const std::vector<std::pair<double, double> > &controlPoints,
00226 const std::vector<double> &knotVector, const std::vector<double> &weights);
00227 void _generateBezierSegmentsFromNURBS(unsigned degree, const std::vector<std::pair<double, double> > &controlPoints,
00228 const std::vector<double> &knotVector);
00229 void _outputCubicBezierSegment(const std::vector<std::pair<double, double> > &points);
00230 void _outputQuadraticBezierSegment(const std::vector<std::pair<double, double> > &points);
00231 void _outputLinearBezierSegment(const std::vector<std::pair<double, double> > &points);
00232
00233 bool m_isPageStarted;
00234 double m_pageWidth;
00235 double m_pageHeight;
00236 double m_shadowOffsetX;
00237 double m_shadowOffsetY;
00238 double m_scale;
00239 double m_x;
00240 double m_y;
00241 double m_originalX;
00242 double m_originalY;
00243 XForm m_xform;
00244 XForm *m_txtxform;
00245 VSDMisc m_misc;
00246 std::vector<WPXPropertyList> m_currentFillGeometry;
00247 std::vector<WPXPropertyList> m_currentLineGeometry;
00248 std::map<unsigned, XForm> *m_groupXForms;
00249 WPXBinaryData m_currentForeignData;
00250 WPXBinaryData m_currentOLEData;
00251 WPXPropertyList m_currentForeignProps;
00252 unsigned m_currentShapeId;
00253 unsigned m_foreignType;
00254 unsigned m_foreignFormat;
00255 double m_foreignOffsetX;
00256 double m_foreignOffsetY;
00257 double m_foreignWidth;
00258 double m_foreignHeight;
00259 bool m_noLine;
00260 bool m_noFill;
00261 bool m_noShow;
00262 std::map<unsigned short, VSDFont> m_fonts;
00263 unsigned m_currentLevel;
00264 bool m_isShapeStarted;
00265 std::vector<std::map<unsigned, XForm> > &m_groupXFormsSequence;
00266 std::vector<std::map<unsigned, unsigned> > &m_groupMembershipsSequence;
00267 std::vector<std::map<unsigned, unsigned> >::iterator m_groupMemberships;
00268 unsigned m_currentPageNumber;
00269 VSDOutputElementList *m_shapeOutputDrawing, *m_shapeOutputText;
00270 std::map<unsigned, VSDOutputElementList> m_pageOutputDrawing;
00271 std::map<unsigned, VSDOutputElementList> m_pageOutputText;
00272 std::vector<std::list<unsigned> > &m_documentPageShapeOrders;
00273 std::vector<std::list<unsigned> >::iterator m_pageShapeOrder;
00274 bool m_isFirstGeometry;
00275
00276 std::map<unsigned, NURBSData> m_NURBSData;
00277 std::map<unsigned, PolylineData> m_polylineData;
00278 WPXBinaryData m_textStream;
00279 std::map<unsigned, WPXString> m_names, m_stencilNames;
00280 std::vector<WPXString> m_fields;
00281 VSDFieldList m_stencilFields;
00282 unsigned m_fieldIndex;
00283 TextFormat m_textFormat;
00284 std::vector<VSDCharStyle> m_charFormats;
00285 std::vector<VSDParaStyle> m_paraFormats;
00286
00287 VSDLineStyle m_lineStyle;
00288 VSDFillStyle m_fillStyle;
00289 VSDTextBlockStyle m_textBlockStyle;
00290
00291 VSDCharStyle m_defaultCharStyle;
00292 VSDParaStyle m_defaultParaStyle;
00293
00294 unsigned m_currentStyleSheet;
00295 VSDStyles m_styles;
00296
00297 VSDStencils m_stencils;
00298 const VSDShape *m_stencilShape;
00299 bool m_isStencilStarted;
00300
00301 unsigned m_currentGeometryCount;
00302
00303 unsigned m_backgroundPageID;
00304 unsigned m_currentPageID;
00305 VSDPage m_currentPage;
00306 VSDPages m_pages;
00307
00308 std::vector<std::pair<double, double> > m_splineControlPoints;
00309 std::vector<double> m_splineKnotVector;
00310 double m_splineX, m_splineY;
00311 double m_splineLastKnot;
00312 unsigned m_splineDegree;
00313 unsigned m_splineLevel;
00314 unsigned m_currentShapeLevel;
00315 bool m_isBackgroundPage;
00316 };
00317
00318 }
00319
00320 #endif
00321