libmwaw_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 /* libmwaw
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 LIBMWAW_INTERNAL_H
00035 #define LIBMWAW_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 MWAW_shared_ptr_noop_deleter {
00110   void operator()(T *) {}
00111 };
00112 
00113 #if defined(__clang__) || defined(__GNUC__)
00114 #  define LIBMWAW_ATTRIBUTE_PRINTF(fmt, arg) __attribute__((__format__(__printf__, fmt, arg)))
00115 #else
00116 #  define LIBMWAW_ATTRIBUTE_PRINTF(fmt, arg)
00117 #endif
00118 
00119 /* ---------- debug  --------------- */
00120 #ifdef DEBUG
00121 namespace libmwaw
00122 {
00123 void printDebugMsg(const char *format, ...) LIBMWAW_ATTRIBUTE_PRINTF(1,2);
00124 }
00125 #define MWAW_DEBUG_MSG(M) libmwaw::printDebugMsg M
00126 #else
00127 #define MWAW_DEBUG_MSG(M)
00128 #endif
00129 
00130 namespace libmwaw
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 libmwaw
00156 {
00157 uint8_t readU8(librevenge::RVNGInputStream *input);
00159 void appendUnicode(uint32_t val, librevenge::RVNGString &buffer);
00160 }
00161 
00162 /* ---------- small enum/class ------------- */
00163 namespace libmwaw
00164 {
00166 enum Position { Left = 0, Right = 1, Top = 2, Bottom = 3, HMiddle = 4, VMiddle = 5 };
00168 enum { LeftBit = 0x01,  RightBit = 0x02, TopBit=0x4, BottomBit = 0x08, HMiddleBit = 0x10, VMiddleBit = 0x20 };
00169 
00170 enum NumberingType { NONE, BULLET, ARABIC, LOWERCASE, UPPERCASE, LOWERCASE_ROMAN, UPPERCASE_ROMAN };
00171 std::string numberingTypeToString(NumberingType type);
00172 std::string numberingValueToString(NumberingType type, int value);
00173 enum SubDocumentType { DOC_NONE, DOC_CHART, DOC_CHART_ZONE, DOC_COMMENT_ANNOTATION, DOC_GRAPHIC_GROUP, DOC_HEADER_FOOTER, DOC_NOTE, DOC_SHEET, DOC_TABLE, DOC_TEXT_BOX };
00174 }
00175 
00177 struct MWAWColor {
00179   MWAWColor(uint32_t argb=0) : m_value(argb)
00180   {
00181   }
00183   MWAWColor(unsigned char r, unsigned char g,  unsigned char b, unsigned char a=255) :
00184     m_value(uint32_t((a<<24)+(r<<16)+(g<<8)+b))
00185   {
00186   }
00188   MWAWColor &operator=(uint32_t argb)
00189   {
00190     m_value = argb;
00191     return *this;
00192   }
00194   static MWAWColor colorFromCMYK(unsigned char c, unsigned char m,  unsigned char y, unsigned char k)
00195   {
00196     double w=1.-double(k)/255.;
00197     return MWAWColor
00198            ((unsigned char)(255 * (1-double(c)/255) * w),
00199             (unsigned char)(255 * (1-double(m)/255) * w),
00200             (unsigned char)(255 * (1-double(y)/255) * w)
00201            );
00202   }
00204   static MWAWColor colorFromHSL(unsigned char H, unsigned char S,  unsigned char L)
00205   {
00206     double c=(1-((L>=128) ? (2*double(L)-255) : (255-2*double(L)))/255)*
00207              double(S)/255;
00208     double tmp=std::fmod((double(H)*6/255),2)-1;
00209     double x=c*(1-(tmp>0 ? tmp : -tmp));
00210     unsigned char C=(unsigned char)(255*c);
00211     unsigned char M=(unsigned char)(double(L)-255*c/2);
00212     unsigned char X=(unsigned char)(255*x);
00213     if (H<=42) return MWAWColor((unsigned char)(M+C),(unsigned char)(M+X),(unsigned char)M);
00214     if (H<=85) return MWAWColor((unsigned char)(M+X),(unsigned char)(M+C),(unsigned char)M);
00215     if (H<=127) return MWAWColor((unsigned char)M,(unsigned char)(M+C),(unsigned char)(M+X));
00216     if (H<=170) return MWAWColor((unsigned char)M,(unsigned char)(M+X),(unsigned char)(M+C));
00217     if (H<=212) return MWAWColor((unsigned char)(M+X),(unsigned char)M,(unsigned char)(M+C));
00218     return MWAWColor((unsigned char)(M+C),(unsigned char)(M),(unsigned char)(M+X));
00219   }
00221   static MWAWColor black()
00222   {
00223     return MWAWColor(0,0,0);
00224   }
00226   static MWAWColor white()
00227   {
00228     return MWAWColor(255,255,255);
00229   }
00230 
00232   static MWAWColor barycenter(float alpha, MWAWColor const &colA,
00233                               float beta, MWAWColor const &colB);
00235   uint32_t value() const
00236   {
00237     return m_value;
00238   }
00240   unsigned char getAlpha() const
00241   {
00242     return (unsigned char)((m_value>>24)&0xFF);
00243   }
00245   unsigned char getBlue() const
00246   {
00247     return (unsigned char)(m_value&0xFF);
00248   }
00250   unsigned char getRed() const
00251   {
00252     return (unsigned char)((m_value>>16)&0xFF);
00253   }
00255   unsigned char getGreen() const
00256   {
00257     return (unsigned char)((m_value>>8)&0xFF);
00258   }
00260   bool isBlack() const
00261   {
00262     return (m_value&0xFFFFFF)==0;
00263   }
00265   bool isWhite() const
00266   {
00267     return (m_value&0xFFFFFF)==0xFFFFFF;
00268   }
00270   bool operator==(MWAWColor const &c) const
00271   {
00272     return (c.m_value&0xFFFFFF)==(m_value&0xFFFFFF);
00273   }
00275   bool operator!=(MWAWColor const &c) const
00276   {
00277     return !operator==(c);
00278   }
00280   bool operator<(MWAWColor const &c) const
00281   {
00282     return (c.m_value&0xFFFFFF)<(m_value&0xFFFFFF);
00283   }
00285   bool operator<=(MWAWColor const &c) const
00286   {
00287     return (c.m_value&0xFFFFFF)<=(m_value&0xFFFFFF);
00288   }
00290   bool operator>(MWAWColor const &c) const
00291   {
00292     return !operator<=(c);
00293   }
00295   bool operator>=(MWAWColor const &c) const
00296   {
00297     return !operator<(c);
00298   }
00300   friend std::ostream &operator<< (std::ostream &o, MWAWColor const &c);
00302   std::string str() const;
00303 protected:
00305   uint32_t m_value;
00306 };
00307 
00309 struct MWAWBorder {
00311   enum Style { None, Simple, Dot, LargeDot, Dash };
00313   enum Type { Single, Double, Triple };
00314 
00316   MWAWBorder() : m_style(Simple), m_type(Single), m_width(1), m_widthsList(), m_color(MWAWColor::black()), m_extra("") { }
00320   bool addTo(librevenge::RVNGPropertyList &propList, std::string which="") const;
00322   bool isEmpty() const
00323   {
00324     return m_style==None || m_width <= 0;
00325   }
00327   bool operator==(MWAWBorder const &orig) const
00328   {
00329     return !operator!=(orig);
00330   }
00332   bool operator!=(MWAWBorder const &orig) const
00333   {
00334     return m_style != orig.m_style || m_type != orig.m_type ||
00335            m_width < orig.m_width || m_width > orig.m_width || m_color != orig.m_color;
00336   }
00338   int compare(MWAWBorder const &orig) const;
00339 
00341   friend std::ostream &operator<< (std::ostream &o, MWAWBorder const &border);
00343   friend std::ostream &operator<< (std::ostream &o, MWAWBorder::Style const &style);
00345   Style m_style;
00347   Type m_type;
00349   double m_width;
00353   std::vector<double> m_widthsList;
00355   MWAWColor m_color;
00357   std::string m_extra;
00358 };
00359 
00361 struct MWAWField {
00363   enum Type { None, PageCount, PageNumber, Date, Time, Title, Database };
00364 
00366   MWAWField(Type type) : m_type(type), m_DTFormat(""), m_numberingType(libmwaw::ARABIC), m_data("")
00367   {
00368   }
00370   Type m_type;
00372   std::string m_DTFormat;
00374   libmwaw::NumberingType m_numberingType;
00376   std::string m_data;
00377 };
00378 
00380 struct MWAWLink {
00382   MWAWLink() : m_HRef("")
00383   {
00384   }
00385 
00387   bool addTo(librevenge::RVNGPropertyList &propList) const;
00388 
00390   std::string m_HRef;
00391 };
00392 
00394 struct MWAWNote {
00396   enum Type { FootNote, EndNote };
00398   MWAWNote(Type type) : m_type(type), m_label(""), m_number(-1)
00399   {
00400   }
00402   Type m_type;
00404   librevenge::RVNGString m_label;
00406   int m_number;
00407 };
00408 
00409 // forward declarations of basic classes and smart pointers
00410 class MWAWEntry;
00411 class MWAWFont;
00412 class MWAWGraphicEncoder;
00413 class MWAWGraphicShape;
00414 class MWAWGraphicStyle;
00415 class MWAWHeader;
00416 class MWAWList;
00417 class MWAWPageSpan;
00418 class MWAWParagraph;
00419 class MWAWParser;
00420 class MWAWPosition;
00421 class MWAWSection;
00422 
00423 class MWAWFontConverter;
00424 class MWAWGraphicListener;
00425 class MWAWInputStream;
00426 class MWAWListener;
00427 class MWAWListManager;
00428 class MWAWParserState;
00429 class MWAWPresentationListener;
00430 class MWAWRSRCParser;
00431 class MWAWSpreadsheetListener;
00432 class MWAWSubDocument;
00433 class MWAWTextListener;
00435 typedef shared_ptr<MWAWFontConverter> MWAWFontConverterPtr;
00437 typedef shared_ptr<MWAWGraphicListener> MWAWGraphicListenerPtr;
00439 typedef shared_ptr<MWAWInputStream> MWAWInputStreamPtr;
00441 typedef shared_ptr<MWAWListener> MWAWListenerPtr;
00443 typedef shared_ptr<MWAWListManager> MWAWListManagerPtr;
00445 typedef shared_ptr<MWAWParserState> MWAWParserStatePtr;
00447 typedef shared_ptr<MWAWPresentationListener> MWAWPresentationListenerPtr;
00449 typedef shared_ptr<MWAWRSRCParser> MWAWRSRCParserPtr;
00451 typedef shared_ptr<MWAWSpreadsheetListener> MWAWSpreadsheetListenerPtr;
00453 typedef shared_ptr<MWAWSubDocument> MWAWSubDocumentPtr;
00455 typedef shared_ptr<MWAWTextListener> MWAWTextListenerPtr;
00456 
00463 template <class T> struct MWAWVariable {
00465   MWAWVariable() : m_data(), m_set(false) {}
00467   MWAWVariable(T const &def) : m_data(def), m_set(false) {}
00469   MWAWVariable(MWAWVariable const &orig) : m_data(orig.m_data), m_set(orig.m_set) {}
00471   MWAWVariable &operator=(MWAWVariable const &orig)
00472   {
00473     if (this != &orig) {
00474       m_data = orig.m_data;
00475       m_set = orig.m_set;
00476     }
00477     return *this;
00478   }
00480   MWAWVariable &operator=(T const &val)
00481   {
00482     m_data = val;
00483     m_set = true;
00484     return *this;
00485   }
00487   void insert(MWAWVariable const &orig)
00488   {
00489     if (orig.m_set) {
00490       m_data = orig.m_data;
00491       m_set = orig.m_set;
00492     }
00493   }
00495   T const *operator->() const
00496   {
00497     return &m_data;
00498   }
00500   T *operator->()
00501   {
00502     m_set = true;
00503     return &m_data;
00504   }
00506   T const &operator*() const
00507   {
00508     return m_data;
00509   }
00511   T &operator*()
00512   {
00513     m_set = true;
00514     return m_data;
00515   }
00517   T const &get() const
00518   {
00519     return m_data;
00520   }
00522   bool isSet() const
00523   {
00524     return m_set;
00525   }
00527   void setSet(bool newVal)
00528   {
00529     m_set=newVal;
00530   }
00531 protected:
00533   T m_data;
00535   bool m_set;
00536 };
00537 
00538 /* ---------- vec2/box2f ------------- */
00542 template <class T> class MWAWVec2
00543 {
00544 public:
00546   MWAWVec2(T xx=0,T yy=0) : m_x(xx), m_y(yy) { }
00548   template <class U> MWAWVec2(MWAWVec2<U> const &p) : m_x(T(p.x())), m_y(T(p.y())) {}
00549 
00551   T x() const
00552   {
00553     return m_x;
00554   }
00556   T y() const
00557   {
00558     return m_y;
00559   }
00561   T operator[](int c) const
00562   {
00563     if (c<0 || c>1) throw libmwaw::GenericException();
00564     return (c==0) ? m_x : m_y;
00565   }
00567   T &operator[](int c)
00568   {
00569     if (c<0 || c>1) throw libmwaw::GenericException();
00570     return (c==0) ? m_x : m_y;
00571   }
00572 
00574   void set(T xx, T yy)
00575   {
00576     m_x = xx;
00577     m_y = yy;
00578   }
00580   void setX(T xx)
00581   {
00582     m_x = xx;
00583   }
00585   void setY(T yy)
00586   {
00587     m_y = yy;
00588   }
00589 
00591   void add(T dx, T dy)
00592   {
00593     m_x += dx;
00594     m_y += dy;
00595   }
00596 
00598   MWAWVec2<T> &operator+=(MWAWVec2<T> const &p)
00599   {
00600     m_x += p.m_x;
00601     m_y += p.m_y;
00602     return *this;
00603   }
00605   MWAWVec2<T> &operator-=(MWAWVec2<T> const &p)
00606   {
00607     m_x -= p.m_x;
00608     m_y -= p.m_y;
00609     return *this;
00610   }
00612   template <class U>
00613   MWAWVec2<T> &operator*=(U scale)
00614   {
00615     m_x = T(m_x*scale);
00616     m_y = T(m_y*scale);
00617     return *this;
00618   }
00619 
00621   friend MWAWVec2<T> operator+(MWAWVec2<T> const &p1, MWAWVec2<T> const &p2)
00622   {
00623     MWAWVec2<T> p(p1);
00624     return p+=p2;
00625   }
00627   friend MWAWVec2<T> operator-(MWAWVec2<T> const &p1, MWAWVec2<T> const &p2)
00628   {
00629     MWAWVec2<T> p(p1);
00630     return p-=p2;
00631   }
00633   template <class U>
00634   friend MWAWVec2<T> operator*(U scale, MWAWVec2<T> const &p1)
00635   {
00636     MWAWVec2<T> p(p1);
00637     return p *= scale;
00638   }
00639 
00641   bool operator==(MWAWVec2<T> const &p) const
00642   {
00643     return cmpY(p) == 0;
00644   }
00646   bool operator!=(MWAWVec2<T> const &p) const
00647   {
00648     return cmpY(p) != 0;
00649   }
00651   bool operator<(MWAWVec2<T> const &p) const
00652   {
00653     return cmpY(p) < 0;
00654   }
00656   int cmp(MWAWVec2<T> const &p) const
00657   {
00658     if (m_x < p.m_x) return -1;
00659     if (m_x > p.m_x) return 1;
00660     if (m_y < p.m_y) return -1;
00661     if (m_y > p.m_y) return 1;
00662     return 0;
00663   }
00665   int cmpY(MWAWVec2<T> const &p) const
00666   {
00667     if (m_y < p.m_y) return -1;
00668     if (m_y > p.m_y) return 1;
00669     if (m_x < p.m_x) return -1;
00670     if (m_x > p.m_x) return 1;
00671     return 0;
00672   }
00673 
00675   friend std::ostream &operator<< (std::ostream &o, MWAWVec2<T> const &f)
00676   {
00677     o << f.m_x << "x" << f.m_y;
00678     return o;
00679   }
00680 
00684   struct PosSizeLtX {
00686     bool operator()(MWAWVec2<T> const &s1, MWAWVec2<T> const &s2) const
00687     {
00688       return s1.cmp(s2) < 0;
00689     }
00690   };
00694   typedef std::map<MWAWVec2<T>, T,struct PosSizeLtX> MapX;
00695 
00699   struct PosSizeLtY {
00701     bool operator()(MWAWVec2<T> const &s1, MWAWVec2<T> const &s2) const
00702     {
00703       return s1.cmpY(s2) < 0;
00704     }
00705   };
00709   typedef std::map<MWAWVec2<T>, T,struct PosSizeLtY> MapY;
00710 protected:
00711   T m_x, m_y;
00712 };
00713 
00715 typedef MWAWVec2<bool> MWAWVec2b;
00717 typedef MWAWVec2<int> MWAWVec2i;
00719 typedef MWAWVec2<long> MWAWVec2l;
00721 typedef MWAWVec2<float> MWAWVec2f;
00722 
00726 template <class T> class MWAWVec3
00727 {
00728 public:
00730   MWAWVec3(T xx=0,T yy=0,T zz=0)
00731   {
00732     m_val[0] = xx;
00733     m_val[1] = yy;
00734     m_val[2] = zz;
00735   }
00737   template <class U> MWAWVec3(MWAWVec3<U> const &p)
00738   {
00739     for (int c = 0; c < 3; c++) m_val[c] = T(p[c]);
00740   }
00741 
00743   T x() const
00744   {
00745     return m_val[0];
00746   }
00748   T y() const
00749   {
00750     return m_val[1];
00751   }
00753   T z() const
00754   {
00755     return m_val[2];
00756   }
00758   T operator[](int c) const
00759   {
00760     if (c<0 || c>2) throw libmwaw::GenericException();
00761     return m_val[c];
00762   }
00764   T &operator[](int c)
00765   {
00766     if (c<0 || c>2) throw libmwaw::GenericException();
00767     return m_val[c];
00768   }
00769 
00771   void set(T xx, T yy, T zz)
00772   {
00773     m_val[0] = xx;
00774     m_val[1] = yy;
00775     m_val[2] = zz;
00776   }
00778   void setX(T xx)
00779   {
00780     m_val[0] = xx;
00781   }
00783   void setY(T yy)
00784   {
00785     m_val[1] = yy;
00786   }
00788   void setZ(T zz)
00789   {
00790     m_val[2] = zz;
00791   }
00792 
00794   void add(T dx, T dy, T dz)
00795   {
00796     m_val[0] += dx;
00797     m_val[1] += dy;
00798     m_val[2] += dz;
00799   }
00800 
00802   MWAWVec3<T> &operator+=(MWAWVec3<T> const &p)
00803   {
00804     for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]+p.m_val[c]);
00805     return *this;
00806   }
00808   MWAWVec3<T> &operator-=(MWAWVec3<T> const &p)
00809   {
00810     for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]-p.m_val[c]);
00811     return *this;
00812   }
00814   template <class U>
00815   MWAWVec3<T> &operator*=(U scale)
00816   {
00817     for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]*scale);
00818     return *this;
00819   }
00820 
00822   friend MWAWVec3<T> operator+(MWAWVec3<T> const &p1, MWAWVec3<T> const &p2)
00823   {
00824     MWAWVec3<T> p(p1);
00825     return p+=p2;
00826   }
00828   friend MWAWVec3<T> operator-(MWAWVec3<T> const &p1, MWAWVec3<T> const &p2)
00829   {
00830     MWAWVec3<T> p(p1);
00831     return p-=p2;
00832   }
00834   template <class U>
00835   friend MWAWVec3<T> operator*(U scale, MWAWVec3<T> const &p1)
00836   {
00837     MWAWVec3<T> p(p1);
00838     return p *= scale;
00839   }
00840 
00842   bool operator==(MWAWVec3<T> const &p) const
00843   {
00844     return cmp(p) == 0;
00845   }
00847   bool operator!=(MWAWVec3<T> const &p) const
00848   {
00849     return cmp(p) != 0;
00850   }
00852   bool operator<(MWAWVec3<T> const &p) const
00853   {
00854     return cmp(p) < 0;
00855   }
00857   int cmp(MWAWVec3<T> const &p) const
00858   {
00859     for (int c = 0; c < 3; c++) {
00860       T diff  = m_val[c]-p.m_val[c];
00861       if (diff) return (diff < 0) ? -1 : 1;
00862     }
00863     return 0;
00864   }
00865 
00867   friend std::ostream &operator<< (std::ostream &o, MWAWVec3<T> const &f)
00868   {
00869     o << f.m_val[0] << "x" << f.m_val[1] << "x" << f.m_val[2];
00870     return o;
00871   }
00872 
00876   struct PosSizeLt {
00878     bool operator()(MWAWVec3<T> const &s1, MWAWVec3<T> const &s2) const
00879     {
00880       return s1.cmp(s2) < 0;
00881     }
00882   };
00886   typedef std::map<MWAWVec3<T>, T,struct PosSizeLt> Map;
00887 
00888 protected:
00890   T m_val[3];
00891 };
00892 
00894 typedef MWAWVec3<unsigned char> MWAWVec3uc;
00896 typedef MWAWVec3<int> MWAWVec3i;
00898 typedef MWAWVec3<float> MWAWVec3f;
00899 
00903 template <class T> class MWAWBox2
00904 {
00905 public:
00907   MWAWBox2(MWAWVec2<T> minPt=MWAWVec2<T>(), MWAWVec2<T> maxPt=MWAWVec2<T>())
00908   {
00909     m_pt[0] = minPt;
00910     m_pt[1] = maxPt;
00911   }
00913   template <class U> MWAWBox2(MWAWBox2<U> const &p)
00914   {
00915     for (int c=0; c < 2; c++) m_pt[c] = p[c];
00916   }
00917 
00919   MWAWVec2<T> const &min() const
00920   {
00921     return m_pt[0];
00922   }
00924   MWAWVec2<T> const &max() const
00925   {
00926     return m_pt[1];
00927   }
00929   MWAWVec2<T> &min()
00930   {
00931     return m_pt[0];
00932   }
00934   MWAWVec2<T> &max()
00935   {
00936     return m_pt[1];
00937   }
00941   MWAWVec2<T> const &operator[](int c) const
00942   {
00943     if (c<0 || c>1) throw libmwaw::GenericException();
00944     return m_pt[c];
00945   }
00947   MWAWVec2<T> size() const
00948   {
00949     return m_pt[1]-m_pt[0];
00950   }
00952   MWAWVec2<T> center() const
00953   {
00954     return 0.5*(m_pt[0]+m_pt[1]);
00955   }
00956 
00958   void set(MWAWVec2<T> const &x, MWAWVec2<T> const &y)
00959   {
00960     m_pt[0] = x;
00961     m_pt[1] = y;
00962   }
00964   void setMin(MWAWVec2<T> const &x)
00965   {
00966     m_pt[0] = x;
00967   }
00969   void setMax(MWAWVec2<T> const &y)
00970   {
00971     m_pt[1] = y;
00972   }
00973 
00975   void resizeFromMin(MWAWVec2<T> const &sz)
00976   {
00977     m_pt[1] = m_pt[0]+sz;
00978   }
00980   void resizeFromMax(MWAWVec2<T> const &sz)
00981   {
00982     m_pt[0] = m_pt[1]-sz;
00983   }
00985   void resizeFromCenter(MWAWVec2<T> const &sz)
00986   {
00987     MWAWVec2<T> centerPt = 0.5*(m_pt[0]+m_pt[1]);
00988     m_pt[0] = centerPt - 0.5*sz;
00989     m_pt[1] = centerPt + (sz - 0.5*sz);
00990   }
00991 
00993   template <class U> void scale(U factor)
00994   {
00995     m_pt[0] *= factor;
00996     m_pt[1] *= factor;
00997   }
00998 
01000   void extend(T val)
01001   {
01002     m_pt[0] -= MWAWVec2<T>(val/2,val/2);
01003     m_pt[1] += MWAWVec2<T>(val-(val/2),val-(val/2));
01004   }
01005 
01007   MWAWBox2<T> getUnion(MWAWBox2<T> const &box) const
01008   {
01009     MWAWBox2<T> res;
01010     res.m_pt[0]=MWAWVec2<T>(m_pt[0][0]<box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
01011                             m_pt[0][1]<box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
01012     res.m_pt[1]=MWAWVec2<T>(m_pt[1][0]>box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
01013                             m_pt[1][1]>box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
01014     return res;
01015   }
01017   MWAWBox2<T> getIntersection(MWAWBox2<T> const &box) const
01018   {
01019     MWAWBox2<T> res;
01020     res.m_pt[0]=MWAWVec2<T>(m_pt[0][0]>box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
01021                             m_pt[0][1]>box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
01022     res.m_pt[1]=MWAWVec2<T>(m_pt[1][0]<box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
01023                             m_pt[1][1]<box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
01024     return res;
01025   }
01027   bool operator==(MWAWBox2<T> const &p) const
01028   {
01029     return cmp(p) == 0;
01030   }
01032   bool operator!=(MWAWBox2<T> const &p) const
01033   {
01034     return cmp(p) != 0;
01035   }
01037   bool operator<(MWAWBox2<T> const &p) const
01038   {
01039     return cmp(p) < 0;
01040   }
01041 
01043   int cmp(MWAWBox2<T> const &p) const
01044   {
01045     int diff  = m_pt[0].cmpY(p.m_pt[0]);
01046     if (diff) return diff;
01047     diff  = m_pt[1].cmpY(p.m_pt[1]);
01048     if (diff) return diff;
01049     return 0;
01050   }
01051 
01053   friend std::ostream &operator<< (std::ostream &o, MWAWBox2<T> const &f)
01054   {
01055     o << "(" << f.m_pt[0] << "<->" << f.m_pt[1] << ")";
01056     return o;
01057   }
01058 
01062   struct PosSizeLt {
01064     bool operator()(MWAWBox2<T> const &s1, MWAWBox2<T> const &s2) const
01065     {
01066       return s1.cmp(s2) < 0;
01067     }
01068   };
01072   typedef std::map<MWAWBox2<T>, T,struct PosSizeLt> Map;
01073 
01074 protected:
01076   MWAWVec2<T> m_pt[2];
01077 };
01078 
01080 typedef MWAWBox2<int> MWAWBox2i;
01082 typedef MWAWBox2<float> MWAWBox2f;
01084 typedef MWAWBox2<long> MWAWBox2l;
01085 
01086 // some geometrical function
01087 namespace libmwaw
01088 {
01090 MWAWBox2f rotateBoxFromCenter(MWAWBox2f const &box, float angle);
01091 }
01092 #endif /* LIBMWAW_INTERNAL_H */
01093 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: