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 <map>
00042 #include <ostream>
00043 #include <string>
00044 #include <math.h>
00045 #include <vector>
00046 
00047 #ifndef M_PI
00048 #define M_PI 3.14159265358979323846
00049 #endif
00050 
00051 #include <libwpd-stream/libwpd-stream.h>
00052 #include <libwpd/libwpd.h>
00053 
00054 #if defined(_MSC_VER) || defined(__DJGPP__)
00055 
00056 typedef signed char int8_t;
00057 typedef unsigned char uint8_t;
00058 typedef signed short int16_t;
00059 typedef unsigned short uint16_t;
00060 typedef signed int int32_t;
00061 typedef unsigned int uint32_t;
00062 typedef unsigned __int64 uint64_t;
00063 typedef __int64 int64_t;
00064 
00065 #else /* !_MSC_VER && !__DJGPP__*/
00066 
00067 #  ifdef HAVE_CONFIG_H
00068 
00069 #    include <config.h>
00070 #    ifdef HAVE_STDINT_H
00071 #      include <stdint.h>
00072 #    endif
00073 #    ifdef HAVE_INTTYPES_H
00074 #      include <inttypes.h>
00075 #    endif
00076 
00077 #  else
00078 
00079 // assume that the headers are there inside LibreOffice build when no HAVE_CONFIG_H is defined
00080 #    include <stdint.h>
00081 #    include <inttypes.h>
00082 
00083 #  endif
00084 
00085 #endif /* _MSC_VER || __DJGPP__ */
00086 
00087 // define gmtime_r and localtime_r on Windows, so that can use
00088 // thread-safe functions on other environments
00089 #ifdef _WIN32
00090 #  define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
00091 #  define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
00092 #endif
00093 
00094 /* ---------- memory  --------------- */
00095 #if defined(SHAREDPTR_TR1)
00096 #include <tr1/memory>
00097 using std::tr1::shared_ptr;
00098 #elif defined(SHAREDPTR_STD)
00099 #include <memory>
00100 using std::shared_ptr;
00101 #else
00102 #include <boost/shared_ptr.hpp>
00103 using boost::shared_ptr;
00104 #endif
00105 
00107 template <class T>
00108 struct MWAW_shared_ptr_noop_deleter {
00109   void operator() (T *) {}
00110 };
00111 
00112 /* ---------- debug  --------------- */
00113 #ifdef DEBUG
00114 #define MWAW_DEBUG_MSG(M) printf M
00115 #else
00116 #define MWAW_DEBUG_MSG(M)
00117 #endif
00118 
00119 namespace libmwaw
00120 {
00121 // Various exceptions:
00122 class VersionException
00123 {
00124 };
00125 
00126 class FileException
00127 {
00128 };
00129 
00130 class ParseException
00131 {
00132 };
00133 
00134 class GenericException
00135 {
00136 };
00137 
00138 class WrongPasswordException
00139 {
00140 };
00141 }
00142 
00143 /* ---------- input ----------------- */
00144 namespace libmwaw
00145 {
00146 uint8_t readU8(WPXInputStream *input);
00148 void appendUnicode(uint32_t val, WPXString &buffer);
00149 }
00150 
00151 /* ---------- small enum/class ------------- */
00152 namespace libmwaw
00153 {
00155 enum Position { Left = 0, Right = 1, Top = 2, Bottom = 3, HMiddle = 4, VMiddle = 5 };
00157 enum { LeftBit = 0x01,  RightBit = 0x02, TopBit=0x4, BottomBit = 0x08, HMiddleBit = 0x10, VMiddleBit = 0x20 };
00158 
00159 enum NumberingType { NONE, BULLET, ARABIC, LOWERCASE, UPPERCASE, LOWERCASE_ROMAN, UPPERCASE_ROMAN };
00160 std::string numberingTypeToString(NumberingType type);
00161 std::string numberingValueToString(NumberingType type, int value);
00162 enum SubDocumentType { DOC_NONE, DOC_HEADER_FOOTER, DOC_NOTE, DOC_TABLE, DOC_TEXT_BOX, DOC_COMMENT_ANNOTATION, DOC_GRAPHIC_GROUP };
00163 }
00164 
00166 struct MWAWColor {
00168   MWAWColor(uint32_t argb=0) : m_value(argb) {
00169   }
00171   MWAWColor(unsigned char r, unsigned char g,  unsigned char b, unsigned char a=0) :
00172     m_value(uint32_t((a<<24)+(r<<16)+(g<<8)+b)) {
00173   }
00175   MWAWColor &operator=(uint32_t argb) {
00176     m_value = argb;
00177     return *this;
00178   }
00180   static MWAWColor black() {
00181     return MWAWColor(0);
00182   }
00184   static MWAWColor white() {
00185     return MWAWColor(0xFFFFFF);
00186   }
00187 
00189   static MWAWColor barycenter(float alpha, MWAWColor const &colA,
00190                               float beta, MWAWColor const &colB);
00192   uint32_t value() const {
00193     return m_value;
00194   }
00196   bool isBlack() const {
00197     return (m_value&0xFFFFFF)==0;
00198   }
00200   bool isWhite() const {
00201     return (m_value&0xFFFFFF)==0xFFFFFF;
00202   }
00204   bool operator==(MWAWColor const &c) const {
00205     return (c.m_value&0xFFFFFF)==(m_value&0xFFFFFF);
00206   }
00208   bool operator!=(MWAWColor const &c) const {
00209     return !operator==(c);
00210   }
00212   bool operator<(MWAWColor const &c) const {
00213     return (c.m_value&0xFFFFFF)<(m_value&0xFFFFFF);
00214   }
00216   bool operator<=(MWAWColor const &c) const {
00217     return (c.m_value&0xFFFFFF)<=(m_value&0xFFFFFF);
00218   }
00220   bool operator>(MWAWColor const &c) const {
00221     return !operator<=(c);
00222   }
00224   bool operator>=(MWAWColor const &c) const {
00225     return !operator<(c);
00226   }
00228   friend std::ostream &operator<< (std::ostream &o, MWAWColor const &c);
00230   std::string str() const;
00231 protected:
00233   uint32_t m_value;
00234 };
00235 
00237 struct MWAWBorder {
00239   enum Style { None, Simple, Dot, LargeDot, Dash };
00241   enum Type { Single, Double, Triple };
00242 
00244   MWAWBorder() : m_style(Simple), m_type(Single), m_width(1), m_widthsList(), m_color(MWAWColor::black()), m_extra("") { }
00248   bool addTo(WPXPropertyList &propList, std::string which="") const;
00250   bool isEmpty() const {
00251     return m_style==None || m_width <= 0;
00252   }
00254   bool operator==(MWAWBorder const &orig) const {
00255     return !operator!=(orig);
00256   }
00258   bool operator!=(MWAWBorder const &orig) const {
00259     return m_style != orig.m_style || m_type != orig.m_type ||
00260            m_width < orig.m_width || m_width > orig.m_width || m_color != orig.m_color;
00261   }
00263   int compare(MWAWBorder const &orig) const;
00264 
00266   friend std::ostream &operator<< (std::ostream &o, MWAWBorder const &border);
00268   friend std::ostream &operator<< (std::ostream &o, MWAWBorder::Style const &style);
00270   Style m_style;
00272   Type m_type;
00274   double m_width;
00278   std::vector<double> m_widthsList;
00280   MWAWColor m_color;
00282   std::string m_extra;
00283 };
00284 
00286 struct MWAWField {
00288   enum Type { None, PageCount, PageNumber, Date, Time, Title, Link, Database };
00289 
00291   MWAWField(Type type) : m_type(type), m_DTFormat(""), m_numberingType(libmwaw::ARABIC), m_data("") {
00292   }
00294   Type m_type;
00296   std::string m_DTFormat;
00298   libmwaw::NumberingType m_numberingType;
00300   std::string m_data;
00301 };
00302 
00304 struct MWAWNote {
00306   enum Type { FootNote, EndNote };
00308   MWAWNote(Type type) : m_type(type), m_label(""), m_number(-1) {
00309   }
00311   Type m_type;
00313   WPXString m_label;
00315   int m_number;
00316 };
00317 
00318 // forward declarations of basic classes and smart pointers
00319 class MWAWEntry;
00320 class MWAWFont;
00321 class MWAWGraphicInterface;
00322 class MWAWGraphicShape;
00323 class MWAWGraphicStyle;
00324 class MWAWHeader;
00325 class MWAWList;
00326 class MWAWPageSpan;
00327 class MWAWParagraph;
00328 class MWAWParser;
00329 class MWAWPosition;
00330 class MWAWSection;
00331 
00332 class MWAWContentListener;
00333 class MWAWFontConverter;
00334 class MWAWGraphicListener;
00335 class MWAWInputStream;
00336 class MWAWListener;
00337 class MWAWListManager;
00338 class MWAWParserState;
00339 class MWAWRSRCParser;
00340 class MWAWSubDocument;
00342 typedef shared_ptr<MWAWContentListener> MWAWContentListenerPtr;
00344 typedef shared_ptr<MWAWFontConverter> MWAWFontConverterPtr;
00346 typedef shared_ptr<MWAWGraphicListener> MWAWGraphicListenerPtr;
00348 typedef shared_ptr<MWAWInputStream> MWAWInputStreamPtr;
00350 typedef shared_ptr<MWAWListener> MWAWListenerPtr;
00352 typedef shared_ptr<MWAWListManager> MWAWListManagerPtr;
00354 typedef shared_ptr<MWAWRSRCParser> MWAWRSRCParserPtr;
00356 typedef shared_ptr<MWAWParserState> MWAWParserStatePtr;
00358 typedef shared_ptr<MWAWSubDocument> MWAWSubDocumentPtr;
00359 
00366 template <class T> struct Variable {
00368   Variable() : m_data(), m_set(false) {}
00370   Variable(T def) : m_data(def), m_set(false) {}
00372   Variable(Variable const &orig) : m_data(orig.m_data), m_set(orig.m_set) {}
00374   Variable &operator=(Variable const &orig) {
00375     if (this != &orig) {
00376       m_data = orig.m_data;
00377       m_set = orig.m_set;
00378     }
00379     return *this;
00380   }
00382   Variable &operator=(T val) {
00383     m_data = val;
00384     m_set = true;
00385     return *this;
00386   }
00388   void insert(Variable const &orig) {
00389     if (orig.m_set) {
00390       m_data = orig.m_data;
00391       m_set = orig.m_set;
00392     }
00393   }
00395   T const *operator->() const {
00396     return &m_data;
00397   }
00399   T *operator->() {
00400     m_set = true;
00401     return &m_data;
00402   }
00404   T const &operator*() const {
00405     return m_data;
00406   }
00408   T &operator*() {
00409     m_set = true;
00410     return m_data;
00411   }
00413   T const &get() const {
00414     return m_data;
00415   }
00417   bool isSet() const {
00418     return m_set;
00419   }
00421   void setSet(bool newVal) {
00422     m_set=newVal;
00423   }
00424 protected:
00426   T m_data;
00428   bool m_set;
00429 };
00430 
00431 /* ---------- vec2/box2f ------------- */
00435 template <class T> class Vec2
00436 {
00437 public:
00439   Vec2(T xx=0,T yy=0) : m_x(xx), m_y(yy) { }
00441   template <class U> Vec2(Vec2<U> const &p) : m_x(T(p.x())), m_y(T(p.y())) {}
00442 
00444   T x() const {
00445     return m_x;
00446   }
00448   T y() const {
00449     return m_y;
00450   }
00452   T operator[](int c) const {
00453     assert(c >= 0 && c <= 1);
00454     return (c==0) ? m_x : m_y;
00455   }
00457   T &operator[](int c) {
00458     assert(c >= 0 && c <= 1);
00459     return (c==0) ? m_x : m_y;
00460   }
00461 
00463   void set(T xx, T yy) {
00464     m_x = xx;
00465     m_y = yy;
00466   }
00468   void setX(T xx) {
00469     m_x = xx;
00470   }
00472   void setY(T yy) {
00473     m_y = yy;
00474   }
00475 
00477   void add(T dx, T dy) {
00478     m_x += dx;
00479     m_y += dy;
00480   }
00481 
00483   Vec2<T> &operator+=(Vec2<T> const &p) {
00484     m_x += p.m_x;
00485     m_y += p.m_y;
00486     return *this;
00487   }
00489   Vec2<T> &operator-=(Vec2<T> const &p) {
00490     m_x -= p.m_x;
00491     m_y -= p.m_y;
00492     return *this;
00493   }
00495   template <class U>
00496   Vec2<T> &operator*=(U scale) {
00497     m_x = T(m_x*scale);
00498     m_y = T(m_y*scale);
00499     return *this;
00500   }
00501 
00503   friend Vec2<T> operator+(Vec2<T> const &p1, Vec2<T> const &p2) {
00504     Vec2<T> p(p1);
00505     return p+=p2;
00506   }
00508   friend Vec2<T> operator-(Vec2<T> const &p1, Vec2<T> const &p2) {
00509     Vec2<T> p(p1);
00510     return p-=p2;
00511   }
00513   template <class U>
00514   friend Vec2<T> operator*(U scale, Vec2<T> const &p1) {
00515     Vec2<T> p(p1);
00516     return p *= scale;
00517   }
00518 
00520   bool operator==(Vec2<T> const &p) const {
00521     return cmpY(p) == 0;
00522   }
00524   bool operator!=(Vec2<T> const &p) const {
00525     return cmpY(p) != 0;
00526   }
00528   bool operator<(Vec2<T> const &p) const {
00529     return cmpY(p) < 0;
00530   }
00532   int cmp(Vec2<T> const &p) const {
00533     T diff  = m_x-p.m_x;
00534     if (diff < 0) return -1;
00535     if (diff > 0) return 1;
00536     diff = m_y-p.m_y;
00537     if (diff < 0) return -1;
00538     if (diff > 0) return 1;
00539     return 0;
00540   }
00542   int cmpY(Vec2<T> const &p) const {
00543     T diff  = m_y-p.m_y;
00544     if (diff < 0) return -1;
00545     if (diff > 0) return 1;
00546     diff = m_x-p.m_x;
00547     if (diff < 0) return -1;
00548     if (diff > 0) return 1;
00549     return 0;
00550   }
00551 
00553   friend std::ostream &operator<< (std::ostream &o, Vec2<T> const &f) {
00554     o << f.m_x << "x" << f.m_y;
00555     return o;
00556   }
00557 
00561   struct PosSizeLtX {
00563     bool operator()(Vec2<T> const &s1, Vec2<T> const &s2) const {
00564       return s1.cmp(s2) < 0;
00565     }
00566   };
00570   typedef std::map<Vec2<T>, T,struct PosSizeLtX> MapX;
00571 
00575   struct PosSizeLtY {
00577     bool operator()(Vec2<T> const &s1, Vec2<T> const &s2) const {
00578       return s1.cmpY(s2) < 0;
00579     }
00580   };
00584   typedef std::map<Vec2<T>, T,struct PosSizeLtY> MapY;
00585 protected:
00586   T m_x, m_y;
00587 };
00588 
00590 typedef Vec2<bool> Vec2b;
00592 typedef Vec2<int> Vec2i;
00594 typedef Vec2<long> Vec2l;
00596 typedef Vec2<float> Vec2f;
00597 
00601 template <class T> class Vec3
00602 {
00603 public:
00605   Vec3(T xx=0,T yy=0,T zz=0) {
00606     m_val[0] = xx;
00607     m_val[1] = yy;
00608     m_val[2] = zz;
00609   }
00611   template <class U> Vec3(Vec3<U> const &p) {
00612     for (int c = 0; c < 3; c++) m_val[c] = T(p[c]);
00613   }
00614 
00616   T x() const {
00617     return m_val[0];
00618   }
00620   T y() const {
00621     return m_val[1];
00622   }
00624   T z() const {
00625     return m_val[2];
00626   }
00628   T operator[](int c) const {
00629     assert(c >= 0 && c <= 2);
00630     return m_val[c];
00631   }
00633   T &operator[](int c) {
00634     assert(c >= 0 && c <= 2);
00635     return m_val[c];
00636   }
00637 
00639   void set(T xx, T yy, T zz) {
00640     m_val[0] = xx;
00641     m_val[1] = yy;
00642     m_val[2] = zz;
00643   }
00645   void setX(T xx) {
00646     m_val[0] = xx;
00647   }
00649   void setY(T yy) {
00650     m_val[1] = yy;
00651   }
00653   void setZ(T zz) {
00654     m_val[2] = zz;
00655   }
00656 
00658   void add(T dx, T dy, T dz) {
00659     m_val[0] += dx;
00660     m_val[1] += dy;
00661     m_val[2] += dz;
00662   }
00663 
00665   Vec3<T> &operator+=(Vec3<T> const &p) {
00666     for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]+p.m_val[c]);
00667     return *this;
00668   }
00670   Vec3<T> &operator-=(Vec3<T> const &p) {
00671     for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]-p.m_val[c]);
00672     return *this;
00673   }
00675   template <class U>
00676   Vec3<T> &operator*=(U scale) {
00677     for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]*scale);
00678     return *this;
00679   }
00680 
00682   friend Vec3<T> operator+(Vec3<T> const &p1, Vec3<T> const &p2) {
00683     Vec3<T> p(p1);
00684     return p+=p2;
00685   }
00687   friend Vec3<T> operator-(Vec3<T> const &p1, Vec3<T> const &p2) {
00688     Vec3<T> p(p1);
00689     return p-=p2;
00690   }
00692   template <class U>
00693   friend Vec3<T> operator*(U scale, Vec3<T> const &p1) {
00694     Vec3<T> p(p1);
00695     return p *= scale;
00696   }
00697 
00699   bool operator==(Vec3<T> const &p) const {
00700     return cmp(p) == 0;
00701   }
00703   bool operator!=(Vec3<T> const &p) const {
00704     return cmp(p) != 0;
00705   }
00707   bool operator<(Vec3<T> const &p) const {
00708     return cmp(p) < 0;
00709   }
00711   int cmp(Vec3<T> const &p) const {
00712     for (int c = 0; c < 3; c++) {
00713       T diff  = m_val[c]-p.m_val[c];
00714       if (diff) return (diff < 0) ? -1 : 1;
00715     }
00716     return 0;
00717   }
00718 
00720   friend std::ostream &operator<< (std::ostream &o, Vec3<T> const &f) {
00721     o << f.m_val[0] << "x" << f.m_val[1] << "x" << f.m_val[2];
00722     return o;
00723   }
00724 
00728   struct PosSizeLt {
00730     bool operator()(Vec3<T> const &s1, Vec3<T> const &s2) const {
00731       return s1.cmp(s2) < 0;
00732     }
00733   };
00737   typedef std::map<Vec3<T>, T,struct PosSizeLt> Map;
00738 
00739 protected:
00741   T m_val[3];
00742 };
00743 
00745 typedef Vec3<unsigned char> Vec3uc;
00747 typedef Vec3<int> Vec3i;
00749 typedef Vec3<float> Vec3f;
00750 
00754 template <class T> class Box2
00755 {
00756 public:
00758   Box2(Vec2<T> minPt=Vec2<T>(), Vec2<T> maxPt=Vec2<T>()) {
00759     m_pt[0] = minPt;
00760     m_pt[1] = maxPt;
00761   }
00763   template <class U> Box2(Box2<U> const &p) {
00764     for (int c=0; c < 2; c++) m_pt[c] = p[c];
00765   }
00766 
00768   Vec2<T> const &min() const {
00769     return m_pt[0];
00770   }
00772   Vec2<T> const &max() const {
00773     return m_pt[1];
00774   }
00776   Vec2<T> &min() {
00777     return m_pt[0];
00778   }
00780   Vec2<T> &max() {
00781     return m_pt[1];
00782   }
00787   Vec2<T> const &operator[](int c) const {
00788     assert(c >= 0 && c <= 1);
00789     return m_pt[c];
00790   }
00792   Vec2<T> size() const {
00793     return m_pt[1]-m_pt[0];
00794   }
00796   Vec2<T> center() const {
00797     return 0.5*(m_pt[0]+m_pt[1]);
00798   }
00799 
00801   void set(Vec2<T> const &x, Vec2<T> const &y) {
00802     m_pt[0] = x;
00803     m_pt[1] = y;
00804   }
00806   void setMin(Vec2<T> const &x) {
00807     m_pt[0] = x;
00808   }
00810   void setMax(Vec2<T> const &y) {
00811     m_pt[1] = y;
00812   }
00813 
00815   void resizeFromMin(Vec2<T> const &sz) {
00816     m_pt[1] = m_pt[0]+sz;
00817   }
00819   void resizeFromMax(Vec2<T> const &sz) {
00820     m_pt[0] = m_pt[1]-sz;
00821   }
00823   void resizeFromCenter(Vec2<T> const &sz) {
00824     Vec2<T> centerPt = 0.5*(m_pt[0]+m_pt[1]);
00825     m_pt[0] = centerPt - 0.5*sz;
00826     m_pt[1] = centerPt + (sz - 0.5*sz);
00827   }
00828 
00830   template <class U> void scale(U factor) {
00831     m_pt[0] *= factor;
00832     m_pt[1] *= factor;
00833   }
00834 
00836   void extend(T val) {
00837     m_pt[0] -= Vec2<T>(val/2,val/2);
00838     m_pt[1] += Vec2<T>(val-(val/2),val-(val/2));
00839   }
00840 
00842   Box2<T> getUnion(Box2<T> const &box) const {
00843     Box2<T> res;
00844     res.m_pt[0]=Vec2<T>(m_pt[0][0]<box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
00845                         m_pt[0][1]<box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
00846     res.m_pt[1]=Vec2<T>(m_pt[1][0]>box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
00847                         m_pt[1][1]>box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
00848     return res;
00849   }
00851   Box2<T> getIntersection(Box2<T> const &box) const {
00852     Box2<T> res;
00853     res.m_pt[0]=Vec2<T>(m_pt[0][0]>box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
00854                         m_pt[0][1]>box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
00855     res.m_pt[1]=Vec2<T>(m_pt[1][0]<box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
00856                         m_pt[1][1]<box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
00857     return res;
00858   }
00860   bool operator==(Box2<T> const &p) const {
00861     return cmp(p) == 0;
00862   }
00864   bool operator!=(Box2<T> const &p) const {
00865     return cmp(p) != 0;
00866   }
00868   bool operator<(Box2<T> const &p) const {
00869     return cmp(p) < 0;
00870   }
00871 
00873   int cmp(Box2<T> const &p) const {
00874     int diff  = m_pt[0].cmpY(p.m_pt[0]);
00875     if (diff) return diff;
00876     diff  = m_pt[1].cmpY(p.m_pt[1]);
00877     if (diff) return diff;
00878     return 0;
00879   }
00880 
00882   friend std::ostream &operator<< (std::ostream &o, Box2<T> const &f) {
00883     o << "(" << f.m_pt[0] << "<->" << f.m_pt[1] << ")";
00884     return o;
00885   }
00886 
00890   struct PosSizeLt {
00892     bool operator()(Box2<T> const &s1, Box2<T> const &s2) const {
00893       return s1.cmp(s2) < 0;
00894     }
00895   };
00899   typedef std::map<Box2<T>, T,struct PosSizeLt> Map;
00900 
00901 protected:
00903   Vec2<T> m_pt[2];
00904 };
00905 
00907 typedef Box2<int> Box2i;
00909 typedef Box2<float> Box2f;
00911 typedef Box2<long> Box2l;
00912 
00913 // some geometrical function
00914 namespace libmwaw
00915 {
00917 Box2f rotateBoxFromCenter(Box2f const &box, float angle);
00918 }
00919 #endif /* LIBMWAW_INTERNAL_H */
00920 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: