libstaroffice_internal.hxx
Go to the documentation of this file.
00001 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
00002 
00003 /* libstaroffice
00004 * Version: MPL 2.0 / LGPLv2+
00005 *
00006 * The contents of this file are subject to the Mozilla Public License Version
00007 * 2.0 (the "License"); you may not use this file except in compliance with
00008 * the License or as specified alternatively below. You may obtain a copy of
00009 * the License at http://www.mozilla.org/MPL/
00010 *
00011 * Software distributed under the License is distributed on an "AS IS" basis,
00012 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013 * for the specific language governing rights and limitations under the
00014 * License.
00015 *
00016 * Major Contributor(s):
00017 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
00018 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
00019 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
00020 * Copyright (C) 2006, 2007 Andrew Ziem
00021 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
00022 *
00023 *
00024 * All Rights Reserved.
00025 *
00026 * For minor contributions see the git repository.
00027 *
00028 * Alternatively, the contents of this file may be used under the terms of
00029 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
00030 * in which case the provisions of the LGPLv2+ are applicable
00031 * instead of those above.
00032 */
00033 
00034 #ifndef LIBSTAROFFICE_INTERNAL_H
00035 #define LIBSTAROFFICE_INTERNAL_H
00036 #include <assert.h>
00037 #ifdef DEBUG
00038 #include <stdio.h>
00039 #endif
00040 
00041 #include <cmath>
00042 #include <map>
00043 #include <ostream>
00044 #include <string>
00045 #include <math.h>
00046 #include <vector>
00047 
00048 #ifndef M_PI
00049 #define M_PI 3.14159265358979323846
00050 #endif
00051 
00052 #include <librevenge-stream/librevenge-stream.h>
00053 #include <librevenge/librevenge.h>
00054 
00055 #if defined(_MSC_VER) || defined(__DJGPP__)
00056 
00057 typedef signed char int8_t;
00058 typedef unsigned char uint8_t;
00059 typedef signed short int16_t;
00060 typedef unsigned short uint16_t;
00061 typedef signed int int32_t;
00062 typedef unsigned int uint32_t;
00063 typedef unsigned __int64 uint64_t;
00064 typedef __int64 int64_t;
00065 
00066 #else /* !_MSC_VER && !__DJGPP__*/
00067 
00068 #  ifdef HAVE_CONFIG_H
00069 
00070 #    include <config.h>
00071 #    ifdef HAVE_STDINT_H
00072 #      include <stdint.h>
00073 #    endif
00074 #    ifdef HAVE_INTTYPES_H
00075 #      include <inttypes.h>
00076 #    endif
00077 
00078 #  else
00079 
00080 // assume that the headers are there inside LibreOffice build when no HAVE_CONFIG_H is defined
00081 #    include <stdint.h>
00082 #    include <inttypes.h>
00083 
00084 #  endif
00085 
00086 #endif /* _MSC_VER || __DJGPP__ */
00087 
00088 // define gmtime_r and localtime_r on Windows, so that can use
00089 // thread-safe functions on other environments
00090 #ifdef _WIN32
00091 #  define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
00092 #  define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
00093 #endif
00094 
00095 /* ---------- memory  --------------- */
00096 #if defined(SHAREDPTR_TR1)
00097 #include <tr1/memory>
00098 using std::tr1::shared_ptr;
00099 #elif defined(SHAREDPTR_STD)
00100 #include <memory>
00101 using std::shared_ptr;
00102 #else
00103 #include <boost/shared_ptr.hpp>
00104 using boost::shared_ptr;
00105 #endif
00106 
00108 template <class T>
00109 struct STOFF_shared_ptr_noop_deleter {
00110   void operator()(T *) {}
00111 };
00112 
00113 #if defined(__clang__) || defined(__GNUC__)
00114 #  define LIBSTOFF_ATTRIBUTE_PRINTF(fmt, arg) __attribute__((__format__(__printf__, fmt, arg)))
00115 #else
00116 #  define LIBSTOFF_ATTRIBUTE_PRINTF(fmt, arg)
00117 #endif
00118 
00119 /* ---------- debug  --------------- */
00120 #ifdef DEBUG
00121 namespace libstoff
00122 {
00123 void printDebugMsg(const char *format, ...) LIBSTOFF_ATTRIBUTE_PRINTF(1,2);
00124 }
00125 #define STOFF_DEBUG_MSG(M) libstoff::printDebugMsg M
00126 #else
00127 #define STOFF_DEBUG_MSG(M)
00128 #endif
00129 
00130 namespace libstoff
00131 {
00132 // Various exceptions:
00133 class VersionException
00134 {
00135 };
00136 
00137 class FileException
00138 {
00139 };
00140 
00141 class ParseException
00142 {
00143 };
00144 
00145 class GenericException
00146 {
00147 };
00148 
00149 class WrongPasswordException
00150 {
00151 };
00152 }
00153 
00154 /* ---------- input ----------------- */
00155 namespace libstoff
00156 {
00157 uint8_t readU8(librevenge::RVNGInputStream *input);
00159 void appendUnicode(uint32_t val, librevenge::RVNGString &buffer);
00161 librevenge::RVNGString getString(std::vector<uint32_t> const &unicode);
00162 }
00163 
00164 /* ---------- small enum/class ------------- */
00165 namespace libstoff
00166 {
00168 enum Position { Left = 0, Right = 1, Top = 2, Bottom = 3, HMiddle = 4, VMiddle = 5 };
00170 enum { LeftBit = 0x01,  RightBit = 0x02, TopBit=0x4, BottomBit = 0x08, HMiddleBit = 0x10, VMiddleBit = 0x20 };
00171 
00172 enum NumberingType { NONE, BULLET, ARABIC, LOWERCASE, UPPERCASE, LOWERCASE_ROMAN, UPPERCASE_ROMAN };
00173 std::string numberingTypeToString(NumberingType type);
00174 std::string numberingValueToString(NumberingType type, int value);
00175 enum SubDocumentType { DOC_NONE, DOC_CHART, DOC_CHART_ZONE, DOC_COMMENT_ANNOTATION, DOC_GRAPHIC_GROUP, DOC_HEADER_FOOTER_REGION, DOC_NOTE, DOC_SHEET, DOC_TABLE, DOC_TEXT_BOX };
00176 }
00177 
00179 struct STOFFColor {
00181   explicit STOFFColor(uint32_t argb=0) : m_value(argb)
00182   {
00183   }
00185   STOFFColor(unsigned char r, unsigned char g,  unsigned char b, unsigned char a=255) :
00186     m_value(uint32_t((a<<24)+(r<<16)+(g<<8)+b))
00187   {
00188   }
00190   STOFFColor &operator=(uint32_t argb)
00191   {
00192     m_value = argb;
00193     return *this;
00194   }
00196   static STOFFColor colorFromCMYK(unsigned char c, unsigned char m,  unsigned char y, unsigned char k)
00197   {
00198     double w=1.-double(k)/255.;
00199     return STOFFColor
00200            (static_cast<unsigned char>(255 * (1-double(c)/255) * w),
00201             static_cast<unsigned char>(255 * (1-double(m)/255) * w),
00202             static_cast<unsigned char>(255 * (1-double(y)/255) * w)
00203            );
00204   }
00206   static STOFFColor colorFromHSL(unsigned char H, unsigned char S,  unsigned char L)
00207   {
00208     double c=(1-((L>=128) ? (2*double(L)-255) : (255-2*double(L)))/255)*
00209              double(S)/255;
00210     double tmp=std::fmod((double(H)*6/255),2)-1;
00211     double x=c*(1-(tmp>0 ? tmp : -tmp));
00212     unsigned char C=static_cast<unsigned char>(255*c);
00213     unsigned char M=static_cast<unsigned char>(double(L)-255*c/2);
00214     unsigned char X=static_cast<unsigned char>(255*x);
00215     if (H<=42) return STOFFColor(static_cast<unsigned char>(M+C),static_cast<unsigned char>(M+X),static_cast<unsigned char>(M));
00216     if (H<=85) return STOFFColor(static_cast<unsigned char>(M+X),static_cast<unsigned char>(M+C),static_cast<unsigned char>(M));
00217     if (H<=127) return STOFFColor(static_cast<unsigned char>(M),static_cast<unsigned char>(M+C),static_cast<unsigned char>(M+X));
00218     if (H<=170) return STOFFColor(static_cast<unsigned char>(M),static_cast<unsigned char>(M+X),static_cast<unsigned char>(M+C));
00219     if (H<=212) return STOFFColor(static_cast<unsigned char>(M+X),static_cast<unsigned char>(M),static_cast<unsigned char>(M+C));
00220     return STOFFColor(static_cast<unsigned char>(M+C),static_cast<unsigned char>(M),static_cast<unsigned char>(M+X));
00221   }
00223   static STOFFColor black()
00224   {
00225     return STOFFColor(0,0,0);
00226   }
00228   static STOFFColor white()
00229   {
00230     return STOFFColor(255,255,255);
00231   }
00232 
00234   static STOFFColor barycenter(float alpha, STOFFColor const &colA,
00235                                float beta, STOFFColor const &colB);
00237   uint32_t value() const
00238   {
00239     return m_value;
00240   }
00242   unsigned char getAlpha() const
00243   {
00244     return static_cast<unsigned char>((m_value>>24)&0xFF);
00245   }
00247   void setAlpha(unsigned char alpha)
00248   {
00249     m_value=(m_value&0xFFFFFF)|uint32_t(alpha<<24);
00250   }
00252   unsigned char getBlue() const
00253   {
00254     return static_cast<unsigned char>(m_value&0xFF);
00255   }
00257   unsigned char getRed() const
00258   {
00259     return static_cast<unsigned char>((m_value>>16)&0xFF);
00260   }
00262   unsigned char getGreen() const
00263   {
00264     return static_cast<unsigned char>((m_value>>8)&0xFF);
00265   }
00267   bool isBlack() const
00268   {
00269     return (m_value&0xFFFFFF)==0;
00270   }
00272   bool isWhite() const
00273   {
00274     return (m_value&0xFFFFFF)==0xFFFFFF;
00275   }
00277   bool operator==(STOFFColor const &c) const
00278   {
00279     return (c.m_value&0xFFFFFF)==(m_value&0xFFFFFF);
00280   }
00282   bool operator!=(STOFFColor const &c) const
00283   {
00284     return !operator==(c);
00285   }
00287   bool operator<(STOFFColor const &c) const
00288   {
00289     return (c.m_value&0xFFFFFF)<(m_value&0xFFFFFF);
00290   }
00292   bool operator<=(STOFFColor const &c) const
00293   {
00294     return (c.m_value&0xFFFFFF)<=(m_value&0xFFFFFF);
00295   }
00297   bool operator>(STOFFColor const &c) const
00298   {
00299     return !operator<=(c);
00300   }
00302   bool operator>=(STOFFColor const &c) const
00303   {
00304     return !operator<(c);
00305   }
00307   friend std::ostream &operator<< (std::ostream &o, STOFFColor const &c);
00309   std::string str() const;
00310 protected:
00312   uint32_t m_value;
00313 };
00314 
00316 struct STOFFBorderLine {
00318   STOFFBorderLine() : m_outWidth(0), m_inWidth(0), m_color(STOFFColor::black()), m_distance(0) { }
00322   bool addTo(librevenge::RVNGPropertyList &propList, std::string which="") const;
00324   bool isEmpty() const
00325   {
00326     return m_outWidth==0 && m_inWidth==0;
00327   }
00329   bool operator==(STOFFBorderLine const &orig) const
00330   {
00331     return !operator!=(orig);
00332   }
00334   bool operator!=(STOFFBorderLine const &orig) const
00335   {
00336     return m_outWidth != orig.m_outWidth || m_inWidth != orig.m_inWidth ||
00337            m_distance != orig.m_distance || m_color != orig.m_color;
00338   }
00339 
00341   friend std::ostream &operator<< (std::ostream &o, STOFFBorderLine const &border);
00343   int m_outWidth;
00345   int m_inWidth;
00347   STOFFColor m_color;
00349   int m_distance;
00350 };
00351 
00353 struct STOFFField {
00355   STOFFField() : m_propertyList()
00356   {
00357   }
00359   void addTo(librevenge::RVNGPropertyList &propList) const;
00361   librevenge::RVNGPropertyList m_propertyList;
00362 };
00363 
00365 struct STOFFLink {
00367   STOFFLink() : m_HRef("")
00368   {
00369   }
00370 
00372   bool addTo(librevenge::RVNGPropertyList &propList) const;
00373 
00375   std::string m_HRef;
00376 };
00377 
00379 struct STOFFNote {
00381   enum Type { FootNote, EndNote };
00383   explicit STOFFNote(Type type) : m_type(type), m_label(""), m_number(-1)
00384   {
00385   }
00387   Type m_type;
00389   librevenge::RVNGString m_label;
00391   int m_number;
00392 };
00393 
00398 struct STOFFEmbeddedObject {
00400   STOFFEmbeddedObject() : m_dataList(), m_typeList(),  m_filenameLink("")
00401   {
00402   }
00404   STOFFEmbeddedObject(librevenge::RVNGBinaryData const &binaryData,
00405                       std::string type="image/pict") : m_dataList(), m_typeList(), m_filenameLink("")
00406   {
00407     add(binaryData, type);
00408   }
00410   virtual ~STOFFEmbeddedObject();
00412   bool isEmpty() const
00413   {
00414     if (!m_filenameLink.empty())
00415       return false;
00416     for (size_t i=0; i<m_dataList.size(); ++i) {
00417       if (!m_dataList[i].empty())
00418         return false;
00419     }
00420     return true;
00421   }
00423   void add(librevenge::RVNGBinaryData const &binaryData, std::string type="image/pict")
00424   {
00425     size_t pos=m_dataList.size();
00426     if (pos<m_typeList.size()) pos=m_typeList.size();
00427     m_dataList.resize(pos+1);
00428     m_dataList[pos]=binaryData;
00429     m_typeList.resize(pos+1);
00430     m_typeList[pos]=type;
00431   }
00433   bool addTo(librevenge::RVNGPropertyList &propList) const;
00435   bool addAsFillImageTo(librevenge::RVNGPropertyList &propList) const;
00437   friend std::ostream &operator<<(std::ostream &o, STOFFEmbeddedObject const &pict);
00439   int cmp(STOFFEmbeddedObject const &pict) const;
00440 
00442   std::vector<librevenge::RVNGBinaryData> m_dataList;
00444   std::vector<std::string> m_typeList;
00446   librevenge::RVNGString m_filenameLink;
00447 };
00448 
00449 // forward declarations of basic classes and smart pointers
00450 class STOFFFont;
00451 class STOFFGraphicShape;
00452 class STOFFGraphicStyle;
00453 class STOFFList;
00454 class STOFFParagraph;
00455 class STOFFSection;
00456 class STOFFPageSpan;
00457 
00458 class STOFFEntry;
00459 class STOFFHeader;
00460 class STOFFParser;
00461 class STOFFPosition;
00462 
00463 class STOFFGraphicListener;
00464 class STOFFInputStream;
00465 class STOFFListener;
00466 class STOFFListManager;
00467 class STOFFParserState;
00468 class STOFFSpreadsheetListener;
00469 class STOFFSubDocument;
00470 class STOFFTextListener;
00472 typedef shared_ptr<STOFFGraphicListener> STOFFGraphicListenerPtr;
00474 typedef shared_ptr<STOFFInputStream> STOFFInputStreamPtr;
00476 typedef shared_ptr<STOFFListener> STOFFListenerPtr;
00478 typedef shared_ptr<STOFFListManager> STOFFListManagerPtr;
00480 typedef shared_ptr<STOFFParserState> STOFFParserStatePtr;
00482 typedef shared_ptr<STOFFSpreadsheetListener> STOFFSpreadsheetListenerPtr;
00484 typedef shared_ptr<STOFFSubDocument> STOFFSubDocumentPtr;
00486 typedef shared_ptr<STOFFTextListener> STOFFTextListenerPtr;
00487 
00494 template <class T> struct STOFFVariable {
00496   STOFFVariable() : m_data(), m_set(false) {}
00498   explicit STOFFVariable(T const &def) : m_data(def), m_set(false) {}
00500   STOFFVariable(STOFFVariable const &orig) : m_data(orig.m_data), m_set(orig.m_set) {}
00502   STOFFVariable &operator=(STOFFVariable const &orig)
00503   {
00504     if (this != &orig) {
00505       m_data = orig.m_data;
00506       m_set = orig.m_set;
00507     }
00508     return *this;
00509   }
00511   STOFFVariable &operator=(T const &val)
00512   {
00513     m_data = val;
00514     m_set = true;
00515     return *this;
00516   }
00518   void insert(STOFFVariable const &orig)
00519   {
00520     if (orig.m_set) {
00521       m_data = orig.m_data;
00522       m_set = orig.m_set;
00523     }
00524   }
00526   T const *operator->() const
00527   {
00528     return &m_data;
00529   }
00531   T *operator->()
00532   {
00533     m_set = true;
00534     return &m_data;
00535   }
00537   T const &operator*() const
00538   {
00539     return m_data;
00540   }
00542   T &operator*()
00543   {
00544     m_set = true;
00545     return m_data;
00546   }
00548   T const &get() const
00549   {
00550     return m_data;
00551   }
00553   bool isSet() const
00554   {
00555     return m_set;
00556   }
00558   void setSet(bool newVal)
00559   {
00560     m_set=newVal;
00561   }
00562 protected:
00564   T m_data;
00566   bool m_set;
00567 };
00568 
00569 /* ---------- vec2/box2f ------------- */
00573 template <class T> class STOFFVec2
00574 {
00575 public:
00577   STOFFVec2(T xx=0,T yy=0) : m_x(xx), m_y(yy) { }
00579   template <class U> STOFFVec2(STOFFVec2<U> const &p) : m_x(T(p.x())), m_y(T(p.y())) {}
00580 
00582   T x() const
00583   {
00584     return m_x;
00585   }
00587   T y() const
00588   {
00589     return m_y;
00590   }
00592   T operator[](int c) const
00593   {
00594     if (c<0 || c>1) throw libstoff::GenericException();
00595     return (c==0) ? m_x : m_y;
00596   }
00598   T &operator[](int c)
00599   {
00600     if (c<0 || c>1) throw libstoff::GenericException();
00601     return (c==0) ? m_x : m_y;
00602   }
00603 
00605   void set(T xx, T yy)
00606   {
00607     m_x = xx;
00608     m_y = yy;
00609   }
00611   void setX(T xx)
00612   {
00613     m_x = xx;
00614   }
00616   void setY(T yy)
00617   {
00618     m_y = yy;
00619   }
00620 
00622   void add(T dx, T dy)
00623   {
00624     m_x += dx;
00625     m_y += dy;
00626   }
00627 
00629   STOFFVec2<T> &operator+=(STOFFVec2<T> const &p)
00630   {
00631     m_x += p.m_x;
00632     m_y += p.m_y;
00633     return *this;
00634   }
00636   STOFFVec2<T> &operator-=(STOFFVec2<T> const &p)
00637   {
00638     m_x -= p.m_x;
00639     m_y -= p.m_y;
00640     return *this;
00641   }
00643   template <class U>
00644   STOFFVec2<T> &operator*=(U scale)
00645   {
00646     m_x = T(m_x*scale);
00647     m_y = T(m_y*scale);
00648     return *this;
00649   }
00650 
00652   friend STOFFVec2<T> operator+(STOFFVec2<T> const &p1, STOFFVec2<T> const &p2)
00653   {
00654     STOFFVec2<T> p(p1);
00655     return p+=p2;
00656   }
00658   friend STOFFVec2<T> operator-(STOFFVec2<T> const &p1, STOFFVec2<T> const &p2)
00659   {
00660     STOFFVec2<T> p(p1);
00661     return p-=p2;
00662   }
00664   template <class U>
00665   friend STOFFVec2<T> operator*(U scale, STOFFVec2<T> const &p1)
00666   {
00667     STOFFVec2<T> p(p1);
00668     return p *= scale;
00669   }
00670 
00672   bool operator==(STOFFVec2<T> const &p) const
00673   {
00674     return cmpY(p) == 0;
00675   }
00677   bool operator!=(STOFFVec2<T> const &p) const
00678   {
00679     return cmpY(p) != 0;
00680   }
00682   bool operator<(STOFFVec2<T> const &p) const
00683   {
00684     return cmpY(p) < 0;
00685   }
00687   int cmp(STOFFVec2<T> const &p) const
00688   {
00689     if (m_x < p.m_x) return -1;
00690     if (m_x > p.m_x) return 1;
00691     if (m_y < p.m_y) return -1;
00692     if (m_y > p.m_y) return 1;
00693     return 0;
00694   }
00696   int cmpY(STOFFVec2<T> const &p) const
00697   {
00698     if (m_y < p.m_y) return -1;
00699     if (m_y > p.m_y) return 1;
00700     if (m_x < p.m_x) return -1;
00701     if (m_x > p.m_x) return 1;
00702     return 0;
00703   }
00704 
00706   friend std::ostream &operator<< (std::ostream &o, STOFFVec2<T> const &f)
00707   {
00708     o << f.m_x << "x" << f.m_y;
00709     return o;
00710   }
00711 
00715   struct PosSizeLtX {
00717     bool operator()(STOFFVec2<T> const &s1, STOFFVec2<T> const &s2) const
00718     {
00719       return s1.cmp(s2) < 0;
00720     }
00721   };
00725   typedef std::map<STOFFVec2<T>, T,struct PosSizeLtX> MapX;
00726 
00730   struct PosSizeLtY {
00732     bool operator()(STOFFVec2<T> const &s1, STOFFVec2<T> const &s2) const
00733     {
00734       return s1.cmpY(s2) < 0;
00735     }
00736   };
00740   typedef std::map<STOFFVec2<T>, T,struct PosSizeLtY> MapY;
00741 protected:
00742   T m_x, m_y;
00743 };
00744 
00746 typedef STOFFVec2<bool> STOFFVec2b;
00748 typedef STOFFVec2<int> STOFFVec2i;
00750 typedef STOFFVec2<long> STOFFVec2l;
00752 typedef STOFFVec2<float> STOFFVec2f;
00753 
00757 template <class T> class STOFFVec3
00758 {
00759 public:
00761   STOFFVec3(T xx=0,T yy=0,T zz=0)
00762   {
00763     m_val[0] = xx;
00764     m_val[1] = yy;
00765     m_val[2] = zz;
00766   }
00768   template <class U> STOFFVec3(STOFFVec3<U> const &p)
00769   {
00770     for (int c = 0; c < 3; c++) m_val[c] = T(p[c]);
00771   }
00772 
00774   T x() const
00775   {
00776     return m_val[0];
00777   }
00779   T y() const
00780   {
00781     return m_val[1];
00782   }
00784   T z() const
00785   {
00786     return m_val[2];
00787   }
00789   T operator[](int c) const
00790   {
00791     if (c<0 || c>2) throw libstoff::GenericException();
00792     return m_val[c];
00793   }
00795   T &operator[](int c)
00796   {
00797     if (c<0 || c>2) throw libstoff::GenericException();
00798     return m_val[c];
00799   }
00800 
00802   void set(T xx, T yy, T zz)
00803   {
00804     m_val[0] = xx;
00805     m_val[1] = yy;
00806     m_val[2] = zz;
00807   }
00809   void setX(T xx)
00810   {
00811     m_val[0] = xx;
00812   }
00814   void setY(T yy)
00815   {
00816     m_val[1] = yy;
00817   }
00819   void setZ(T zz)
00820   {
00821     m_val[2] = zz;
00822   }
00823 
00825   void add(T dx, T dy, T dz)
00826   {
00827     m_val[0] += dx;
00828     m_val[1] += dy;
00829     m_val[2] += dz;
00830   }
00831 
00833   STOFFVec3<T> &operator+=(STOFFVec3<T> const &p)
00834   {
00835     for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]+p.m_val[c]);
00836     return *this;
00837   }
00839   STOFFVec3<T> &operator-=(STOFFVec3<T> const &p)
00840   {
00841     for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]-p.m_val[c]);
00842     return *this;
00843   }
00845   template <class U>
00846   STOFFVec3<T> &operator*=(U scale)
00847   {
00848     for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]*scale);
00849     return *this;
00850   }
00851 
00853   friend STOFFVec3<T> operator+(STOFFVec3<T> const &p1, STOFFVec3<T> const &p2)
00854   {
00855     STOFFVec3<T> p(p1);
00856     return p+=p2;
00857   }
00859   friend STOFFVec3<T> operator-(STOFFVec3<T> const &p1, STOFFVec3<T> const &p2)
00860   {
00861     STOFFVec3<T> p(p1);
00862     return p-=p2;
00863   }
00865   template <class U>
00866   friend STOFFVec3<T> operator*(U scale, STOFFVec3<T> const &p1)
00867   {
00868     STOFFVec3<T> p(p1);
00869     return p *= scale;
00870   }
00871 
00873   bool operator==(STOFFVec3<T> const &p) const
00874   {
00875     return cmp(p) == 0;
00876   }
00878   bool operator!=(STOFFVec3<T> const &p) const
00879   {
00880     return cmp(p) != 0;
00881   }
00883   bool operator<(STOFFVec3<T> const &p) const
00884   {
00885     return cmp(p) < 0;
00886   }
00888   int cmp(STOFFVec3<T> const &p) const
00889   {
00890     for (int c = 0; c < 3; c++) {
00891       if (m_val[c]<p.m_val[c]) return -1;
00892       if (m_val[c]>p.m_val[c]) return 1;
00893     }
00894     return 0;
00895   }
00896 
00898   friend std::ostream &operator<< (std::ostream &o, STOFFVec3<T> const &f)
00899   {
00900     o << f.m_val[0] << "x" << f.m_val[1] << "x" << f.m_val[2];
00901     return o;
00902   }
00903 
00907   struct PosSizeLt {
00909     bool operator()(STOFFVec3<T> const &s1, STOFFVec3<T> const &s2) const
00910     {
00911       return s1.cmp(s2) < 0;
00912     }
00913   };
00917   typedef std::map<STOFFVec3<T>, T,struct PosSizeLt> Map;
00918 
00919 protected:
00921   T m_val[3];
00922 };
00923 
00925 typedef STOFFVec3<bool> STOFFVec3b;
00927 typedef STOFFVec3<unsigned char> STOFFVec3uc;
00929 typedef STOFFVec3<int> STOFFVec3i;
00931 typedef STOFFVec3<float> STOFFVec3f;
00932 
00936 template <class T> class STOFFBox2
00937 {
00938 public:
00940   STOFFBox2(STOFFVec2<T> minPt=STOFFVec2<T>(), STOFFVec2<T> maxPt=STOFFVec2<T>())
00941   {
00942     m_pt[0] = minPt;
00943     m_pt[1] = maxPt;
00944   }
00946   template <class U> STOFFBox2(STOFFBox2<U> const &p)
00947   {
00948     for (int c=0; c < 2; c++) m_pt[c] = p[c];
00949   }
00950 
00952   STOFFVec2<T> const &min() const
00953   {
00954     return m_pt[0];
00955   }
00957   STOFFVec2<T> const &max() const
00958   {
00959     return m_pt[1];
00960   }
00962   STOFFVec2<T> &min()
00963   {
00964     return m_pt[0];
00965   }
00967   STOFFVec2<T> &max()
00968   {
00969     return m_pt[1];
00970   }
00974   STOFFVec2<T> const &operator[](int c) const
00975   {
00976     if (c<0 || c>1) throw libstoff::GenericException();
00977     return m_pt[c];
00978   }
00980   STOFFVec2<T> size() const
00981   {
00982     return m_pt[1]-m_pt[0];
00983   }
00985   STOFFVec2<T> center() const
00986   {
00987     return STOFFVec2<T>((m_pt[0].x()+m_pt[1].x())/2,
00988                         (m_pt[0].y()+m_pt[1].y())/2);
00989   }
00990 
00992   void set(STOFFVec2<T> const &x, STOFFVec2<T> const &y)
00993   {
00994     m_pt[0] = x;
00995     m_pt[1] = y;
00996   }
00998   void setMin(STOFFVec2<T> const &x)
00999   {
01000     m_pt[0] = x;
01001   }
01003   void setMax(STOFFVec2<T> const &y)
01004   {
01005     m_pt[1] = y;
01006   }
01007 
01009   void resizeFromMin(STOFFVec2<T> const &sz)
01010   {
01011     m_pt[1] = m_pt[0]+sz;
01012   }
01014   void resizeFromMax(STOFFVec2<T> const &sz)
01015   {
01016     m_pt[0] = m_pt[1]-sz;
01017   }
01019   void resizeFromCenter(STOFFVec2<T> const &sz)
01020   {
01021     STOFFVec2<T> centerPt = 0.5*(m_pt[0]+m_pt[1]);
01022     m_pt[0] = centerPt - 0.5*sz;
01023     m_pt[1] = centerPt + (sz - 0.5*sz);
01024   }
01025 
01027   template <class U> void scale(U factor)
01028   {
01029     m_pt[0] *= factor;
01030     m_pt[1] *= factor;
01031   }
01032 
01034   void extend(T val)
01035   {
01036     m_pt[0] -= STOFFVec2<T>(val/2,val/2);
01037     m_pt[1] += STOFFVec2<T>(val-(val/2),val-(val/2));
01038   }
01039 
01041   STOFFBox2<T> getUnion(STOFFBox2<T> const &box) const
01042   {
01043     STOFFBox2<T> res;
01044     res.m_pt[0]=STOFFVec2<T>(m_pt[0][0]<box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
01045                              m_pt[0][1]<box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
01046     res.m_pt[1]=STOFFVec2<T>(m_pt[1][0]>box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
01047                              m_pt[1][1]>box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
01048     return res;
01049   }
01051   STOFFBox2<T> getIntersection(STOFFBox2<T> const &box) const
01052   {
01053     STOFFBox2<T> res;
01054     res.m_pt[0]=STOFFVec2<T>(m_pt[0][0]>box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
01055                              m_pt[0][1]>box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
01056     res.m_pt[1]=STOFFVec2<T>(m_pt[1][0]<box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
01057                              m_pt[1][1]<box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
01058     return res;
01059   }
01061   bool operator==(STOFFBox2<T> const &p) const
01062   {
01063     return cmp(p) == 0;
01064   }
01066   bool operator!=(STOFFBox2<T> const &p) const
01067   {
01068     return cmp(p) != 0;
01069   }
01071   bool operator<(STOFFBox2<T> const &p) const
01072   {
01073     return cmp(p) < 0;
01074   }
01075 
01077   int cmp(STOFFBox2<T> const &p) const
01078   {
01079     int diff  = m_pt[0].cmpY(p.m_pt[0]);
01080     if (diff) return diff;
01081     diff  = m_pt[1].cmpY(p.m_pt[1]);
01082     if (diff) return diff;
01083     return 0;
01084   }
01085 
01087   friend std::ostream &operator<< (std::ostream &o, STOFFBox2<T> const &f)
01088   {
01089     o << "(" << f.m_pt[0] << "<->" << f.m_pt[1] << ")";
01090     return o;
01091   }
01092 
01096   struct PosSizeLt {
01098     bool operator()(STOFFBox2<T> const &s1, STOFFBox2<T> const &s2) const
01099     {
01100       return s1.cmp(s2) < 0;
01101     }
01102   };
01106   typedef std::map<STOFFBox2<T>, T,struct PosSizeLt> Map;
01107 
01108 protected:
01110   STOFFVec2<T> m_pt[2];
01111 };
01112 
01114 typedef STOFFBox2<int> STOFFBox2i;
01116 typedef STOFFBox2<float> STOFFBox2f;
01118 typedef STOFFBox2<long> STOFFBox2l;
01119 
01120 namespace libstoff
01121 {
01122 // some conversion function
01124 template <class T>
01125 double convertMiniMToPoint(T const &value)
01126 {
01127   return 0.028346457*double(value);
01128 }
01130 template <class T>
01131 STOFFVec2f convertMiniMToPointVect(T const &value)
01132 {
01133   return 0.028346457f*STOFFVec2f(value);
01134 }
01136 bool convertToDateTime(uint32_t date, uint32_t time, std::string &dateTime);
01138 void splitString(librevenge::RVNGString const &string, librevenge::RVNGString const &delim,
01139                  librevenge::RVNGString &string1, librevenge::RVNGString &string2);
01143 librevenge::RVNGString simplifyString(librevenge::RVNGString const &s);
01144 // some geometrical function
01146 float getScaleFactor(librevenge::RVNGUnit orig, librevenge::RVNGUnit dest);
01148 STOFFVec2f rotatePointAroundCenter(STOFFVec2f const &point, STOFFVec2f const &center, float angle);
01150 STOFFBox2f rotateBoxFromCenter(STOFFBox2f const &box, float angle);
01151 }
01152 #endif /* LIBSTAROFFICE_INTERNAL_H */
01153 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: