libwps_internal.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 /* libwps
00003  * Version: MPL 2.0 / LGPLv2.1+
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  * Major Contributor(s):
00010  * Copyright (C) 2002 William Lachance (william.lachance@sympatico.ca)
00011  * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
00012  *
00013  * For minor contributions see the git repository.
00014  *
00015  * Alternatively, the contents of this file may be used under the terms
00016  * of the GNU Lesser General Public License Version 2.1 or later
00017  * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
00018  * applicable instead of those above.
00019  *
00020  * For further information visit http://libwps.sourceforge.net
00021  */
00022 
00023 #ifndef LIBWPS_INTERNAL_H
00024 #define LIBWPS_INTERNAL_H
00025 
00026 #include <assert.h>
00027 #ifdef DEBUG
00028 #include <stdio.h>
00029 #endif
00030 
00031 #include <iostream>
00032 #include <map>
00033 #include <string>
00034 
00035 #include <librevenge-stream/librevenge-stream.h>
00036 #include <librevenge/librevenge.h>
00037 
00038 #if defined(_MSC_VER) || defined(__DJGPP__)
00039 typedef signed char int8_t;
00040 typedef unsigned char uint8_t;
00041 typedef signed short int16_t;
00042 typedef unsigned short uint16_t;
00043 typedef signed int int32_t;
00044 typedef unsigned int uint32_t;
00045 #else /* !_MSC_VER && !__DJGPP__*/
00046 #  include <inttypes.h>
00047 #endif /* _MSC_VER || __DJGPP__*/
00048 
00049 /* ---------- memory  --------------- */
00050 #ifdef HAVE_CONFIG_H
00051 #  include "config.h"
00052 #endif
00053 
00054 // define localtime_r on Windows, so that can use
00055 // thread-safe functions on other environments
00056 #ifdef _WIN32
00057 #  define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
00058 #  define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
00059 #endif
00060 
00061 #if defined(SHAREDPTR_TR1)
00062 #include <tr1/memory>
00063 using std::tr1::shared_ptr;
00064 #elif defined(SHAREDPTR_STD)
00065 #include <memory>
00066 using std::shared_ptr;
00067 #else
00068 #include <boost/shared_ptr.hpp>
00069 using boost::shared_ptr;
00070 #endif
00071 
00073 template <class T>
00074 struct WPS_shared_ptr_noop_deleter
00075 {
00076         void operator()(T *) {}
00077 };
00078 
00079 // basic classes and autoptr
00081 typedef shared_ptr<librevenge::RVNGInputStream> RVNGInputStreamPtr;
00082 
00083 class WPSCell;
00084 class WPSListener;
00085 class WPSContentListener;
00086 class WPSEntry;
00087 class WPSFont;
00088 class WPSHeader;
00089 class WPSPosition;
00090 class WPSSubDocument;
00091 
00092 class WKSContentListener;
00093 class WKSSubDocument;
00094 
00096 typedef shared_ptr<WPSCell> WPSCellPtr;
00098 typedef shared_ptr<WPSListener> WPSListenerPtr;
00100 typedef shared_ptr<WPSContentListener> WPSContentListenerPtr;
00102 typedef shared_ptr<WPSHeader> WPSHeaderPtr;
00104 typedef shared_ptr<WPSSubDocument> WPSSubDocumentPtr;
00105 
00107 typedef shared_ptr<WKSContentListener> WKSContentListenerPtr;
00109 typedef shared_ptr<WKSSubDocument> WKSSubDocumentPtr;
00110 
00111 /* ---------- debug  --------------- */
00112 #ifdef DEBUG
00113 #define WPS_DEBUG_MSG(M) printf M
00114 #else
00115 #define WPS_DEBUG_MSG(M)
00116 #endif
00117 
00118 /* ---------- exception  ------------ */
00119 namespace libwps
00120 {
00121 // Various exceptions
00122 class VersionException
00123 {
00124         // needless to say, we could flesh this class out a bit
00125 };
00126 
00127 class FileException
00128 {
00129         // needless to say, we could flesh this class out a bit
00130 };
00131 
00132 class ParseException
00133 {
00134         // needless to say, we could flesh this class out a bit
00135 };
00136 
00137 class GenericException
00138 {
00139         // needless to say, we could flesh this class out a bit
00140 };
00141 }
00142 
00143 /* ---------- input ----------------- */
00144 namespace libwps
00145 {
00146 uint8_t readU8(librevenge::RVNGInputStream *input);
00147 uint16_t readU16(librevenge::RVNGInputStream *input);
00148 uint32_t readU32(librevenge::RVNGInputStream *input);
00149 
00150 int8_t read8(librevenge::RVNGInputStream *input);
00151 int16_t read16(librevenge::RVNGInputStream *input);
00152 int32_t read32(librevenge::RVNGInputStream *input);
00153 
00154 inline uint8_t readU8(RVNGInputStreamPtr &input)
00155 {
00156         return readU8(input.get());
00157 }
00158 inline uint16_t readU16(RVNGInputStreamPtr &input)
00159 {
00160         return readU16(input.get());
00161 }
00162 inline uint32_t readU32(RVNGInputStreamPtr &input)
00163 {
00164         return readU32(input.get());
00165 }
00166 
00167 inline int8_t read8(RVNGInputStreamPtr &input)
00168 {
00169         return read8(input.get());
00170 }
00171 inline int16_t read16(RVNGInputStreamPtr &input)
00172 {
00173         return read16(input.get());
00174 }
00175 inline int32_t read32(RVNGInputStreamPtr &input)
00176 {
00177         return read32(input.get());
00178 }
00179 
00180 bool readData(RVNGInputStreamPtr &input, unsigned long sz, librevenge::RVNGBinaryData &data);
00181 bool readDataToEnd(RVNGInputStreamPtr &input, librevenge::RVNGBinaryData &data);
00182 }
00183 
00184 #define WPS_LE_GET_GUINT16(p)                             \
00185         (uint16_t)((((uint8_t const *)(p))[0] << 0)  |    \
00186                   (((uint8_t const *)(p))[1] << 8))
00187 #define WPS_LE_GET_GUINT32(p) \
00188         (uint32_t)((((uint8_t const *)(p))[0] << 0)  |    \
00189                   (((uint8_t const *)(p))[1] << 8)  |    \
00190                   (((uint8_t const *)(p))[2] << 16) |    \
00191                   (((uint8_t const *)(p))[3] << 24))
00192 
00193 // Various helper structures for the parser..
00194 /* ---------- small enum/class ------------- */
00195 
00196 struct WPSColumnDefinition
00197 {
00198         WPSColumnDefinition() : m_width(0), m_leftGutter(0), m_rightGutter(0)
00199         {
00200         }
00201         double m_width;
00202         double m_leftGutter;
00203         double m_rightGutter;
00204 };
00205 
00206 struct WPSColumnProperties
00207 {
00208         WPSColumnProperties() : m_attributes(0), m_alignment(0)
00209         {
00210         }
00211         uint32_t m_attributes;
00212         uint8_t m_alignment;
00213 };
00214 
00216 struct WPSBorder
00217 {
00218         enum Style { None, Single, Double, Dot, LargeDot, Dash };
00219         enum Pos { Left = 0, Right = 1, Top = 2, Bottom = 3 };
00220         enum { LeftBit = 0x01,  RightBit = 0x02, TopBit=0x4, BottomBit = 0x08 };
00221 
00223         WPSBorder() : m_style(Single), m_width(1), m_color(0) { }
00225         std::string getPropertyValue() const;
00226 
00228         bool operator==(WPSBorder const &orig) const
00229         {
00230                 return m_style == orig.m_style && m_width == orig.m_width
00231                        && m_color == orig.m_color;
00232         }
00234         bool operator!=(WPSBorder const &orig) const
00235         {
00236                 return !operator==(orig);
00237         }
00239         int compare(WPSBorder const &orig) const;
00240 
00242         friend std::ostream &operator<< (std::ostream &o, WPSBorder const &border);
00244         Style m_style;
00246         int m_width;
00248         uint32_t m_color;
00249 
00250 };
00251 
00252 namespace libwps
00253 {
00254 enum NumberingType { NONE, BULLET, ARABIC, LOWERCASE, UPPERCASE, LOWERCASE_ROMAN, UPPERCASE_ROMAN };
00255 std::string numberingTypeToString(NumberingType type);
00256 enum SubDocumentType { DOC_NONE, DOC_HEADER_FOOTER, DOC_NOTE, DOC_TABLE, DOC_TEXT_BOX, DOC_COMMENT_ANNOTATION };
00257 enum Justification { JustificationLeft, JustificationFull, JustificationCenter,
00258                      JustificationRight, JustificationFullAllLines
00259                    };
00260 enum { NoBreakBit = 0x1, NoBreakWithNextBit=0x2};
00261 }
00262 
00263 // ATTRIBUTE bits
00264 #define WPS_EXTRA_LARGE_BIT 1
00265 #define WPS_VERY_LARGE_BIT 2
00266 #define WPS_LARGE_BIT 4
00267 #define WPS_SMALL_PRINT_BIT 8
00268 #define WPS_FINE_PRINT_BIT 0x10
00269 #define WPS_SUPERSCRIPT_BIT 0x20
00270 #define WPS_SUBSCRIPT_BIT 0x40
00271 #define WPS_OUTLINE_BIT 0x80
00272 #define WPS_ITALICS_BIT 0x100
00273 #define WPS_SHADOW_BIT 0x200
00274 #define WPS_REDLINE_BIT 0x400
00275 #define WPS_DOUBLE_UNDERLINE_BIT 0x800
00276 #define WPS_BOLD_BIT 0x1000
00277 #define WPS_STRIKEOUT_BIT 0x2000
00278 #define WPS_UNDERLINE_BIT 0x4000
00279 #define WPS_SMALL_CAPS_BIT 0x8000
00280 #define WPS_BLINK_BIT 0x10000L
00281 #define WPS_REVERSEVIDEO_BIT 0x20000L
00282 #define WPS_ALL_CAPS_BIT 0x40000L
00283 #define WPS_EMBOSS_BIT 0x80000L
00284 #define WPS_ENGRAVE_BIT 0x100000L
00285 #define WPS_OVERLINE_BIT 0x400000L
00286 #define WPS_HIDDEN_BIT 0x800000L
00287 
00288 // BREAK bits
00289 #define WPS_PAGE_BREAK 0x00
00290 #define WPS_SOFT_PAGE_BREAK 0x01
00291 #define WPS_COLUMN_BREAK 0x02
00292 
00293 // Generic bits
00294 #define WPS_LEFT 0x00
00295 #define WPS_RIGHT 0x01
00296 #define WPS_CENTER 0x02
00297 #define WPS_TOP 0x03
00298 #define WPS_BOTTOM 0x04
00299 
00300 /* ---------- vec2/box2f ------------- */
00304 template <class T> class Vec2
00305 {
00306 public:
00308         Vec2(T xx=0,T yy=0) : m_x(xx), m_y(yy) { }
00310         template <class U> Vec2(Vec2<U> const &p) : m_x(T(p.x())), m_y(T(p.y())) {}
00311 
00313         T x() const
00314         {
00315                 return m_x;
00316         }
00318         T y() const
00319         {
00320                 return m_y;
00321         }
00323         T operator[](int c) const
00324         {
00325                 assert(c >= 0 && c <= 1);
00326                 return (c==0) ? m_x : m_y;
00327         }
00329         T &operator[](int c)
00330         {
00331                 assert(c >= 0 && c <= 1);
00332                 return (c==0) ? m_x : m_y;
00333         }
00334 
00336         void set(T xx, T yy)
00337         {
00338                 m_x = xx;
00339                 m_y = yy;
00340         }
00342         void setX(T xx)
00343         {
00344                 m_x = xx;
00345         }
00347         void setY(T yy)
00348         {
00349                 m_y = yy;
00350         }
00351 
00353         void add(T dx, T dy)
00354         {
00355                 m_x += dx;
00356                 m_y += dy;
00357         }
00358 
00360         Vec2<T> &operator+=(Vec2<T> const &p)
00361         {
00362                 m_x += p.m_x;
00363                 m_y += p.m_y;
00364                 return *this;
00365         }
00367         Vec2<T> &operator-=(Vec2<T> const &p)
00368         {
00369                 m_x -= p.m_x;
00370                 m_y -= p.m_y;
00371                 return *this;
00372         }
00374         template <class U>
00375         Vec2<T> &operator*=(U scale)
00376         {
00377                 m_x = T(m_x*scale);
00378                 m_y = T(m_y*scale);
00379                 return *this;
00380         }
00381 
00383         friend Vec2<T> operator+(Vec2<T> const &p1, Vec2<T> const &p2)
00384         {
00385                 Vec2<T> p(p1);
00386                 return p+=p2;
00387         }
00389         friend Vec2<T> operator-(Vec2<T> const &p1, Vec2<T> const &p2)
00390         {
00391                 Vec2<T> p(p1);
00392                 return p-=p2;
00393         }
00395         template <class U>
00396         friend Vec2<T> operator*(U scale, Vec2<T> const &p1)
00397         {
00398                 Vec2<T> p(p1);
00399                 return p *= scale;
00400         }
00401 
00403         bool operator==(Vec2<T> const &p) const
00404         {
00405                 return cmpY(p) == 0;
00406         }
00408         bool operator!=(Vec2<T> const &p) const
00409         {
00410                 return cmpY(p) != 0;
00411         }
00413         bool operator<(Vec2<T> const &p) const
00414         {
00415                 return cmpY(p) < 0;
00416         }
00418         int cmp(Vec2<T> const &p) const
00419         {
00420                 if (m_x<p.m_x) return -1;
00421                 if (m_x>p.m_x) return 1;
00422                 if (m_y<p.m_y) return -1;
00423                 if (m_y>p.m_y) return 1;
00424                 return 0;
00425         }
00427         int cmpY(Vec2<T> const &p) const
00428         {
00429                 if (m_y<p.m_y) return -1;
00430                 if (m_y>p.m_y) return 1;
00431                 if (m_x<p.m_x) return -1;
00432                 if (m_x>p.m_x) return 1;
00433                 return 0;
00434         }
00435 
00437         friend std::ostream &operator<< (std::ostream &o, Vec2<T> const &f)
00438         {
00439                 o << f.m_x << "x" << f.m_y;
00440                 return o;
00441         }
00442 
00446         struct PosSizeLtX
00447         {
00449                 bool operator()(Vec2<T> const &s1, Vec2<T> const &s2) const
00450                 {
00451                         return s1.cmp(s2) < 0;
00452                 }
00453         };
00457         typedef std::map<Vec2<T>, T,struct PosSizeLtX> MapX;
00458 
00462         struct PosSizeLtY
00463         {
00465                 bool operator()(Vec2<T> const &s1, Vec2<T> const &s2) const
00466                 {
00467                         return s1.cmpY(s2) < 0;
00468                 }
00469         };
00473         typedef std::map<Vec2<T>, T,struct PosSizeLtY> MapY;
00474 protected:
00475         T m_x, m_y;
00476 };
00477 
00479 typedef Vec2<bool> Vec2b;
00481 typedef Vec2<int> Vec2i;
00483 typedef Vec2<float> Vec2f;
00484 
00488 template <class T> class Box2
00489 {
00490 public:
00492         Box2(Vec2<T> minPt=Vec2<T>(), Vec2<T> maxPt=Vec2<T>())
00493         {
00494                 m_pt[0] = minPt;
00495                 m_pt[1] = maxPt;
00496         }
00498         template <class U> Box2(Box2<U> const &p)
00499         {
00500                 for (int c=0; c < 2; c++) m_pt[c] = p[c];
00501         }
00502 
00504         Vec2<T> const &min() const
00505         {
00506                 return m_pt[0];
00507         }
00509         Vec2<T> const &max() const
00510         {
00511                 return m_pt[1];
00512         }
00514         Vec2<T> &min()
00515         {
00516                 return m_pt[0];
00517         }
00519         Vec2<T> &max()
00520         {
00521                 return m_pt[1];
00522         }
00523 
00528         Vec2<T> const &operator[](int c) const
00529         {
00530                 assert(c >= 0 && c <= 1);
00531                 return m_pt[c];
00532         }
00534         Vec2<T> size() const
00535         {
00536                 return m_pt[1]-m_pt[0];
00537         }
00539         Vec2<T> center() const
00540         {
00541                 return 0.5*(m_pt[0]+m_pt[1]);
00542         }
00543 
00545         void set(Vec2<T> const &x, Vec2<T> const &y)
00546         {
00547                 m_pt[0] = x;
00548                 m_pt[1] = y;
00549         }
00551         void setMin(Vec2<T> const &x)
00552         {
00553                 m_pt[0] = x;
00554         }
00556         void setMax(Vec2<T> const &y)
00557         {
00558                 m_pt[1] = y;
00559         }
00560 
00562         void resizeFromMin(Vec2<T> const &sz)
00563         {
00564                 m_pt[1] = m_pt[0]+sz;
00565         }
00567         void resizeFromMax(Vec2<T> const &sz)
00568         {
00569                 m_pt[0] = m_pt[1]-sz;
00570         }
00572         void resizeFromCenter(Vec2<T> const &sz)
00573         {
00574                 Vec2<T> ctr = 0.5*(m_pt[0]+m_pt[1]);
00575                 m_pt[0] = ctr - 0.5*sz;
00576                 m_pt[1] = ctr + (sz - 0.5*sz);
00577         }
00578 
00580         template <class U> void scale(U factor)
00581         {
00582                 m_pt[0] *= factor;
00583                 m_pt[1] *= factor;
00584         }
00585 
00587         void extend(T val)
00588         {
00589                 m_pt[0] -= Vec2<T>(val/2,val/2);
00590                 m_pt[1] += Vec2<T>(val-(val/2),val-(val/2));
00591         }
00592 
00594         bool operator==(Box2<T> const &p) const
00595         {
00596                 return cmp(p) == 0;
00597         }
00599         bool operator!=(Box2<T> const &p) const
00600         {
00601                 return cmp(p) != 0;
00602         }
00604         bool operator<(Box2<T> const &p) const
00605         {
00606                 return cmp(p) < 0;
00607         }
00608 
00610         int cmp(Box2<T> const &p) const
00611         {
00612                 int diff  = m_pt[0].cmpY(p.m_pt[0]);
00613                 if (diff) return diff;
00614                 diff  = m_pt[1].cmpY(p.m_pt[1]);
00615                 if (diff) return diff;
00616                 return 0;
00617         }
00618 
00620         friend std::ostream &operator<< (std::ostream &o, Box2<T> const &f)
00621         {
00622                 o << "(" << f.m_pt[0] << "<->" << f.m_pt[1] << ")";
00623                 return o;
00624         }
00625 
00629         struct PosSizeLt
00630         {
00632                 bool operator()(Box2<T> const &s1, Box2<T> const &s2) const
00633                 {
00634                         return s1.cmp(s2) < 0;
00635                 }
00636         };
00640         typedef std::map<Box2<T>, T,struct PosSizeLt> Map;
00641 
00642 protected:
00644         Vec2<T> m_pt[2];
00645 };
00646 
00648 typedef Box2<int> Box2i;
00650 typedef Box2<float> Box2f;
00651 
00652 #endif /* LIBWPS_INTERNAL_H */
00653 /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */