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 <cmath>
00032 #include <iostream>
00033 #include <map>
00034 #include <string>
00035 #include <vector>
00036 
00037 #include <librevenge-stream/librevenge-stream.h>
00038 #include <librevenge/librevenge.h>
00039 
00040 #ifndef M_PI
00041 #define M_PI 3.14159265358979323846
00042 #endif
00043 
00044 #if defined(_MSC_VER) || defined(__DJGPP__)
00045 typedef signed char int8_t;
00046 typedef unsigned char uint8_t;
00047 typedef signed short int16_t;
00048 typedef unsigned short uint16_t;
00049 typedef signed int int32_t;
00050 typedef unsigned int uint32_t;
00051 #else /* !_MSC_VER && !__DJGPP__*/
00052 #  include <inttypes.h>
00053 #endif /* _MSC_VER || __DJGPP__*/
00054 
00055 /* ---------- memory  --------------- */
00056 #ifdef HAVE_CONFIG_H
00057 #  include "config.h"
00058 #endif
00059 
00060 // define localtime_r on Windows, so that can use
00061 // thread-safe functions on other environments
00062 #ifdef _WIN32
00063 #  define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
00064 #  define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
00065 #endif
00066 
00067 #if defined(SHAREDPTR_TR1)
00068 #include <tr1/memory>
00069 using std::tr1::shared_ptr;
00070 #elif defined(SHAREDPTR_STD)
00071 #include <memory>
00072 using std::shared_ptr;
00073 #else
00074 #include <boost/shared_ptr.hpp>
00075 using boost::shared_ptr;
00076 #endif
00077 
00079 template <class T>
00080 struct WPS_shared_ptr_noop_deleter
00081 {
00082         void operator()(T *) {}
00083 };
00084 
00085 // basic classes and autoptr
00087 typedef shared_ptr<librevenge::RVNGInputStream> RVNGInputStreamPtr;
00088 
00089 class WPSCell;
00090 class WPSListener;
00091 class WPSContentListener;
00092 class WPSEntry;
00093 class WPSFont;
00094 class WPSHeader;
00095 class WPSPosition;
00096 class WPSSubDocument;
00097 
00098 class WKSContentListener;
00099 class WKSSubDocument;
00100 
00102 typedef shared_ptr<WPSCell> WPSCellPtr;
00104 typedef shared_ptr<WPSListener> WPSListenerPtr;
00106 typedef shared_ptr<WPSContentListener> WPSContentListenerPtr;
00108 typedef shared_ptr<WPSHeader> WPSHeaderPtr;
00110 typedef shared_ptr<WPSSubDocument> WPSSubDocumentPtr;
00111 
00113 typedef shared_ptr<WKSContentListener> WKSContentListenerPtr;
00115 typedef shared_ptr<WKSSubDocument> WKSSubDocumentPtr;
00116 
00117 #if defined(__clang__) || defined(__GNUC__)
00118 #  define WPS_ATTRIBUTE_PRINTF(fmt, arg) __attribute__((__format__(__printf__, fmt, arg)))
00119 #else
00120 #  define WPS_ATTRIBUTE_PRINTF(fmt, arg)
00121 #endif
00122 /* ---------- debug  --------------- */
00123 #ifdef DEBUG
00124 namespace libwps
00125 {
00126 void printDebugMsg(const char *format, ...) WPS_ATTRIBUTE_PRINTF(1, 2);
00127 }
00128 #define WPS_DEBUG_MSG(M) libwps::printDebugMsg M
00129 #else
00130 #define WPS_DEBUG_MSG(M)
00131 #endif
00132 
00133 /* ---------- exception  ------------ */
00134 namespace libwps
00135 {
00136 // Various exceptions
00137 class VersionException
00138 {
00139         // needless to say, we could flesh this class out a bit
00140 };
00141 
00142 class FileException
00143 {
00144         // needless to say, we could flesh this class out a bit
00145 };
00146 
00147 class ParseException
00148 {
00149         // needless to say, we could flesh this class out a bit
00150 };
00151 
00152 class GenericException
00153 {
00154         // needless to say, we could flesh this class out a bit
00155 };
00156 }
00157 
00158 /* ---------- input ----------------- */
00159 namespace libwps
00160 {
00161 uint8_t readU8(librevenge::RVNGInputStream *input);
00162 uint16_t readU16(librevenge::RVNGInputStream *input);
00163 uint32_t readU32(librevenge::RVNGInputStream *input);
00164 
00165 int8_t read8(librevenge::RVNGInputStream *input);
00166 int16_t read16(librevenge::RVNGInputStream *input);
00167 int32_t read32(librevenge::RVNGInputStream *input);
00168 
00169 inline uint8_t readU8(RVNGInputStreamPtr &input)
00170 {
00171         return readU8(input.get());
00172 }
00173 inline uint16_t readU16(RVNGInputStreamPtr &input)
00174 {
00175         return readU16(input.get());
00176 }
00177 inline uint32_t readU32(RVNGInputStreamPtr &input)
00178 {
00179         return readU32(input.get());
00180 }
00181 
00182 inline int8_t read8(RVNGInputStreamPtr &input)
00183 {
00184         return read8(input.get());
00185 }
00186 inline int16_t read16(RVNGInputStreamPtr &input)
00187 {
00188         return read16(input.get());
00189 }
00190 inline int32_t read32(RVNGInputStreamPtr &input)
00191 {
00192         return read32(input.get());
00193 }
00194 
00196 bool readDouble4(RVNGInputStreamPtr &input, double &res, bool &isNaN);
00198 bool readDouble8(RVNGInputStreamPtr &input, double &res, bool &isNaN);
00200 bool readDouble10(RVNGInputStreamPtr &input, double &res, bool &isNaN);
00202 bool readDouble2Inv(RVNGInputStreamPtr &input, double &res, bool &isNaN);
00204 bool readDouble4Inv(RVNGInputStreamPtr &input, double &res, bool &isNaN);
00205 
00207 bool readData(RVNGInputStreamPtr &input, unsigned long sz, librevenge::RVNGBinaryData &data);
00209 bool readDataToEnd(RVNGInputStreamPtr &input, librevenge::RVNGBinaryData &data);
00211 void appendUnicode(uint32_t val, librevenge::RVNGString &buffer);
00212 }
00213 
00214 #define WPS_LE_GET_GUINT16(p)                                                   \
00215         (uint16_t)((((uint8_t const *)(p))[0] << 0)  |  \
00216                   (((uint8_t const *)(p))[1] << 8))
00217 #define WPS_LE_GET_GUINT32(p)                                                   \
00218         (uint32_t)((((uint8_t const *)(p))[0] << 0) |   \
00219                   (((uint8_t const *)(p))[1] << 8)  |   \
00220                   (((uint8_t const *)(p))[2] << 16) |   \
00221                   (((uint8_t const *)(p))[3] << 24))
00222 
00223 #define WPS_LE_PUT_GUINT16(p, v)                                                \
00224         *((uint8_t*)(p)) = uint8_t(v);                                          \
00225         *(((uint8_t*)(p)) + 1) = uint8_t((v) >> 8)
00226 
00227 #define WPS_LE_PUT_GUINT32(p, v)                                                \
00228         *((uint8_t*)(p)) = uint8_t(v);                                          \
00229         *(((uint8_t*)(p)) + 1) = uint8_t((v) >> 8);                     \
00230         *(((uint8_t*)(p)) + 2) = uint8_t((v) >> 16);            \
00231         *(((uint8_t*)(p)) + 3) = uint8_t((v) >> 24)
00232 
00233 // Various helper structures for the parser..
00234 /* ---------- small enum/class ------------- */
00235 
00236 struct WPSColumnDefinition
00237 {
00238         WPSColumnDefinition() : m_width(0), m_leftGutter(0), m_rightGutter(0)
00239         {
00240         }
00241         double m_width;
00242         double m_leftGutter;
00243         double m_rightGutter;
00244 };
00245 
00246 struct WPSColumnProperties
00247 {
00248         WPSColumnProperties() : m_attributes(0), m_alignment(0)
00249         {
00250         }
00251         uint32_t m_attributes;
00252         uint8_t m_alignment;
00253 };
00254 
00256 struct WPSColor
00257 {
00259         WPSColor(uint32_t argb=0) : m_value(argb)
00260         {
00261         }
00263         WPSColor(unsigned char r, unsigned char g,  unsigned char b, unsigned char a=255) :
00264                 m_value(uint32_t((a<<24)+(r<<16)+(g<<8)+b))
00265         {
00266         }
00268         WPSColor &operator=(uint32_t argb)
00269         {
00270                 m_value = argb;
00271                 return *this;
00272         }
00274         static WPSColor black()
00275         {
00276                 return WPSColor(0,0,0);
00277         }
00279         static WPSColor white()
00280         {
00281                 return WPSColor(255,255,255);
00282         }
00283 
00285         static WPSColor barycenter(float alpha, WPSColor const &colA,
00286                                    float beta, WPSColor const &colB);
00288         uint32_t value() const
00289         {
00290                 return m_value;
00291         }
00293         unsigned char getAlpha() const
00294         {
00295                 return (unsigned char)((m_value>>24)&0xFF);
00296         }
00298         unsigned char getBlue() const
00299         {
00300                 return (unsigned char)(m_value&0xFF);
00301         }
00303         unsigned char getRed() const
00304         {
00305                 return (unsigned char)((m_value>>16)&0xFF);
00306         }
00308         unsigned char getGreen() const
00309         {
00310                 return (unsigned char)((m_value>>8)&0xFF);
00311         }
00313         bool isBlack() const
00314         {
00315                 return (m_value&0xFFFFFF)==0;
00316         }
00318         bool isWhite() const
00319         {
00320                 return (m_value&0xFFFFFF)==0xFFFFFF;
00321         }
00323         bool operator==(WPSColor const &c) const
00324         {
00325                 return (c.m_value&0xFFFFFF)==(m_value&0xFFFFFF);
00326         }
00328         bool operator!=(WPSColor const &c) const
00329         {
00330                 return !operator==(c);
00331         }
00333         bool operator<(WPSColor const &c) const
00334         {
00335                 return (c.m_value&0xFFFFFF)<(m_value&0xFFFFFF);
00336         }
00338         bool operator<=(WPSColor const &c) const
00339         {
00340                 return (c.m_value&0xFFFFFF)<=(m_value&0xFFFFFF);
00341         }
00343         bool operator>(WPSColor const &c) const
00344         {
00345                 return !operator<=(c);
00346         }
00348         bool operator>=(WPSColor const &c) const
00349         {
00350                 return !operator<(c);
00351         }
00353         friend std::ostream &operator<< (std::ostream &o, WPSColor const &c);
00355         std::string str() const;
00356 protected:
00358         uint32_t m_value;
00359 };
00360 
00362 struct WPSBorder
00363 {
00365         enum Style { None, Simple, Dot, LargeDot, Dash };
00367         enum Type { Single, Double, Triple };
00368         enum Pos { Left = 0, Right = 1, Top = 2, Bottom = 3 };
00369         enum { LeftBit = 0x01,  RightBit = 0x02, TopBit=0x4, BottomBit = 0x08 };
00370 
00372         WPSBorder() : m_style(Simple), m_type(Single), m_width(1), m_widthsList(), m_color(WPSColor::black()), m_extra("") { }
00376         bool addTo(librevenge::RVNGPropertyList &propList, std::string which="") const;
00378         bool isEmpty() const
00379         {
00380                 return m_style==None || m_width <= 0;
00381         }
00382 
00384         bool operator==(WPSBorder const &orig) const
00385         {
00386                 return m_style == orig.m_style && m_type == orig.m_type && m_width == orig.m_width
00387                        && m_color == orig.m_color;
00388         }
00390         bool operator!=(WPSBorder const &orig) const
00391         {
00392                 return !operator==(orig);
00393         }
00395         int compare(WPSBorder const &orig) const;
00396 
00398         friend std::ostream &operator<< (std::ostream &o, WPSBorder const &border);
00400         friend std::ostream &operator<< (std::ostream &o, WPSBorder::Style const &style);
00402         Style m_style;
00404         Type m_type;
00406         int m_width;
00410         std::vector<double> m_widthsList;
00412         WPSColor m_color;
00414         std::string m_extra;
00415 };
00416 
00421 struct WPSEmbeddedObject
00422 {
00424         WPSEmbeddedObject() : m_dataList(), m_typeList()
00425         {
00426         }
00428         WPSEmbeddedObject(librevenge::RVNGBinaryData const &binaryData,
00429                           std::string type="image/pict") : m_dataList(), m_typeList()
00430         {
00431                 add(binaryData, type);
00432         }
00434         virtual ~WPSEmbeddedObject()
00435         {
00436         }
00438         bool isEmpty() const
00439         {
00440                 for (size_t i=0; i<m_dataList.size(); ++i)
00441                 {
00442                         if (!m_dataList[i].empty())
00443                                 return false;
00444                 }
00445                 return true;
00446         }
00448         void add(librevenge::RVNGBinaryData const &binaryData, std::string type="image/pict")
00449         {
00450                 size_t pos=m_dataList.size();
00451                 if (pos<m_typeList.size()) pos=m_typeList.size();
00452                 m_dataList.resize(pos+1);
00453                 m_dataList[pos]=binaryData;
00454                 m_typeList.resize(pos+1);
00455                 m_typeList[pos]=type;
00456         }
00458         bool addTo(librevenge::RVNGPropertyList &propList) const;
00460         friend std::ostream &operator<<(std::ostream &o, WPSEmbeddedObject const &pict);
00461 
00463         std::vector<librevenge::RVNGBinaryData> m_dataList;
00465         std::vector<std::string> m_typeList;
00466 };
00467 
00468 namespace libwps
00469 {
00470 enum NumberingType { NONE, BULLET, ARABIC, LOWERCASE, UPPERCASE, LOWERCASE_ROMAN, UPPERCASE_ROMAN };
00471 std::string numberingTypeToString(NumberingType type);
00472 enum SubDocumentType { DOC_NONE, DOC_HEADER_FOOTER, DOC_NOTE, DOC_TABLE, DOC_TEXT_BOX, DOC_COMMENT_ANNOTATION };
00473 enum Justification { JustificationLeft, JustificationFull, JustificationCenter,
00474                      JustificationRight, JustificationFullAllLines
00475                    };
00476 enum { NoBreakBit = 0x1, NoBreakWithNextBit=0x2};
00477 }
00478 
00479 // ATTRIBUTE bits
00480 #define WPS_EXTRA_LARGE_BIT 1
00481 #define WPS_VERY_LARGE_BIT 2
00482 #define WPS_LARGE_BIT 4
00483 #define WPS_SMALL_PRINT_BIT 8
00484 #define WPS_FINE_PRINT_BIT 0x10
00485 #define WPS_SUPERSCRIPT_BIT 0x20
00486 #define WPS_SUBSCRIPT_BIT 0x40
00487 #define WPS_OUTLINE_BIT 0x80
00488 #define WPS_ITALICS_BIT 0x100
00489 #define WPS_SHADOW_BIT 0x200
00490 #define WPS_REDLINE_BIT 0x400
00491 #define WPS_DOUBLE_UNDERLINE_BIT 0x800
00492 #define WPS_BOLD_BIT 0x1000
00493 #define WPS_STRIKEOUT_BIT 0x2000
00494 #define WPS_UNDERLINE_BIT 0x4000
00495 #define WPS_SMALL_CAPS_BIT 0x8000
00496 #define WPS_BLINK_BIT 0x10000L
00497 #define WPS_REVERSEVIDEO_BIT 0x20000L
00498 #define WPS_ALL_CAPS_BIT 0x40000L
00499 #define WPS_EMBOSS_BIT 0x80000L
00500 #define WPS_ENGRAVE_BIT 0x100000L
00501 #define WPS_OVERLINE_BIT 0x400000L
00502 #define WPS_HIDDEN_BIT 0x800000L
00503 
00504 // BREAK bits
00505 #define WPS_PAGE_BREAK 0x00
00506 #define WPS_SOFT_PAGE_BREAK 0x01
00507 #define WPS_COLUMN_BREAK 0x02
00508 
00509 // Generic bits
00510 #define WPS_LEFT 0x00
00511 #define WPS_RIGHT 0x01
00512 #define WPS_CENTER 0x02
00513 #define WPS_TOP 0x03
00514 #define WPS_BOTTOM 0x04
00515 
00516 /* ---------- vec2/box2f ------------- */
00520 template <class T> class Vec2
00521 {
00522 public:
00524         Vec2(T xx=0,T yy=0) : m_x(xx), m_y(yy) { }
00526         template <class U> Vec2(Vec2<U> const &p) : m_x(T(p.x())), m_y(T(p.y())) {}
00527 
00529         T x() const
00530         {
00531                 return m_x;
00532         }
00534         T y() const
00535         {
00536                 return m_y;
00537         }
00539         T operator[](int c) const
00540         {
00541                 if (c<0 || c>1) throw libwps::GenericException();
00542                 return (c==0) ? m_x : m_y;
00543         }
00545         T &operator[](int c)
00546         {
00547                 if (c<0 || c>1) throw libwps::GenericException();
00548                 return (c==0) ? m_x : m_y;
00549         }
00550 
00552         void set(T xx, T yy)
00553         {
00554                 m_x = xx;
00555                 m_y = yy;
00556         }
00558         void setX(T xx)
00559         {
00560                 m_x = xx;
00561         }
00563         void setY(T yy)
00564         {
00565                 m_y = yy;
00566         }
00567 
00569         void add(T dx, T dy)
00570         {
00571                 m_x += dx;
00572                 m_y += dy;
00573         }
00574 
00576         Vec2<T> &operator+=(Vec2<T> const &p)
00577         {
00578                 m_x += p.m_x;
00579                 m_y += p.m_y;
00580                 return *this;
00581         }
00583         Vec2<T> &operator-=(Vec2<T> const &p)
00584         {
00585                 m_x -= p.m_x;
00586                 m_y -= p.m_y;
00587                 return *this;
00588         }
00590         template <class U>
00591         Vec2<T> &operator*=(U scale)
00592         {
00593                 m_x = T(m_x*scale);
00594                 m_y = T(m_y*scale);
00595                 return *this;
00596         }
00597 
00599         friend Vec2<T> operator+(Vec2<T> const &p1, Vec2<T> const &p2)
00600         {
00601                 Vec2<T> p(p1);
00602                 return p+=p2;
00603         }
00605         friend Vec2<T> operator-(Vec2<T> const &p1, Vec2<T> const &p2)
00606         {
00607                 Vec2<T> p(p1);
00608                 return p-=p2;
00609         }
00611         template <class U>
00612         friend Vec2<T> operator*(U scale, Vec2<T> const &p1)
00613         {
00614                 Vec2<T> p(p1);
00615                 return p *= scale;
00616         }
00617 
00619         bool operator==(Vec2<T> const &p) const
00620         {
00621                 return cmpY(p) == 0;
00622         }
00624         bool operator!=(Vec2<T> const &p) const
00625         {
00626                 return cmpY(p) != 0;
00627         }
00629         bool operator<(Vec2<T> const &p) const
00630         {
00631                 return cmpY(p) < 0;
00632         }
00634         int cmp(Vec2<T> const &p) const
00635         {
00636                 if (m_x<p.m_x) return -1;
00637                 if (m_x>p.m_x) return 1;
00638                 if (m_y<p.m_y) return -1;
00639                 if (m_y>p.m_y) return 1;
00640                 return 0;
00641         }
00643         int cmpY(Vec2<T> const &p) const
00644         {
00645                 if (m_y<p.m_y) return -1;
00646                 if (m_y>p.m_y) return 1;
00647                 if (m_x<p.m_x) return -1;
00648                 if (m_x>p.m_x) return 1;
00649                 return 0;
00650         }
00651 
00653         friend std::ostream &operator<< (std::ostream &o, Vec2<T> const &f)
00654         {
00655                 o << f.m_x << "x" << f.m_y;
00656                 return o;
00657         }
00658 
00662         struct PosSizeLtX
00663         {
00665                 bool operator()(Vec2<T> const &s1, Vec2<T> const &s2) const
00666                 {
00667                         return s1.cmp(s2) < 0;
00668                 }
00669         };
00673         typedef std::map<Vec2<T>, T,struct PosSizeLtX> MapX;
00674 
00678         struct PosSizeLtY
00679         {
00681                 bool operator()(Vec2<T> const &s1, Vec2<T> const &s2) const
00682                 {
00683                         return s1.cmpY(s2) < 0;
00684                 }
00685         };
00689         typedef std::map<Vec2<T>, T,struct PosSizeLtY> MapY;
00690 protected:
00691         T m_x, m_y;
00692 };
00693 
00695 typedef Vec2<bool> Vec2b;
00697 typedef Vec2<int> Vec2i;
00699 typedef Vec2<float> Vec2f;
00700 
00704 template <class T> class Box2
00705 {
00706 public:
00708         Box2(Vec2<T> minPt=Vec2<T>(), Vec2<T> maxPt=Vec2<T>())
00709         {
00710                 m_pt[0] = minPt;
00711                 m_pt[1] = maxPt;
00712         }
00714         template <class U> Box2(Box2<U> const &p)
00715         {
00716                 for (int c=0; c < 2; c++) m_pt[c] = p[c];
00717         }
00718 
00720         Vec2<T> const &min() const
00721         {
00722                 return m_pt[0];
00723         }
00725         Vec2<T> const &max() const
00726         {
00727                 return m_pt[1];
00728         }
00730         Vec2<T> &min()
00731         {
00732                 return m_pt[0];
00733         }
00735         Vec2<T> &max()
00736         {
00737                 return m_pt[1];
00738         }
00739 
00743         Vec2<T> const &operator[](int c) const
00744         {
00745                 if (c<0 || c>1) throw libwps::GenericException();
00746                 return m_pt[c];
00747         }
00749         Vec2<T> size() const
00750         {
00751                 return m_pt[1]-m_pt[0];
00752         }
00754         Vec2<T> center() const
00755         {
00756                 return 0.5*(m_pt[0]+m_pt[1]);
00757         }
00758 
00760         void set(Vec2<T> const &x, Vec2<T> const &y)
00761         {
00762                 m_pt[0] = x;
00763                 m_pt[1] = y;
00764         }
00766         void setMin(Vec2<T> const &x)
00767         {
00768                 m_pt[0] = x;
00769         }
00771         void setMax(Vec2<T> const &y)
00772         {
00773                 m_pt[1] = y;
00774         }
00775 
00777         void resizeFromMin(Vec2<T> const &sz)
00778         {
00779                 m_pt[1] = m_pt[0]+sz;
00780         }
00782         void resizeFromMax(Vec2<T> const &sz)
00783         {
00784                 m_pt[0] = m_pt[1]-sz;
00785         }
00787         void resizeFromCenter(Vec2<T> const &sz)
00788         {
00789                 Vec2<T> ctr = 0.5*(m_pt[0]+m_pt[1]);
00790                 m_pt[0] = ctr - 0.5*sz;
00791                 m_pt[1] = ctr + (sz - 0.5*sz);
00792         }
00793 
00795         template <class U> void scale(U factor)
00796         {
00797                 m_pt[0] *= factor;
00798                 m_pt[1] *= factor;
00799         }
00800 
00802         void extend(T val)
00803         {
00804                 m_pt[0] -= Vec2<T>(val/2,val/2);
00805                 m_pt[1] += Vec2<T>(val-(val/2),val-(val/2));
00806         }
00808         Box2<T> getUnion(Box2<T> const &box) const
00809         {
00810                 Box2<T> res;
00811                 res.m_pt[0]=Vec2<T>(m_pt[0][0]<box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
00812                                     m_pt[0][1]<box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
00813                 res.m_pt[1]=Vec2<T>(m_pt[1][0]>box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
00814                                     m_pt[1][1]>box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
00815                 return res;
00816         }
00818         Box2<T> getIntersection(Box2<T> const &box) const
00819         {
00820                 Box2<T> res;
00821                 res.m_pt[0]=Vec2<T>(m_pt[0][0]>box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
00822                                     m_pt[0][1]>box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
00823                 res.m_pt[1]=Vec2<T>(m_pt[1][0]<box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
00824                                     m_pt[1][1]<box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
00825                 return res;
00826         }
00827 
00829         bool operator==(Box2<T> const &p) const
00830         {
00831                 return cmp(p) == 0;
00832         }
00834         bool operator!=(Box2<T> const &p) const
00835         {
00836                 return cmp(p) != 0;
00837         }
00839         bool operator<(Box2<T> const &p) const
00840         {
00841                 return cmp(p) < 0;
00842         }
00843 
00845         int cmp(Box2<T> const &p) const
00846         {
00847                 int diff  = m_pt[0].cmpY(p.m_pt[0]);
00848                 if (diff) return diff;
00849                 diff  = m_pt[1].cmpY(p.m_pt[1]);
00850                 if (diff) return diff;
00851                 return 0;
00852         }
00853 
00855         friend std::ostream &operator<< (std::ostream &o, Box2<T> const &f)
00856         {
00857                 o << "(" << f.m_pt[0] << "<->" << f.m_pt[1] << ")";
00858                 return o;
00859         }
00860 
00864         struct PosSizeLt
00865         {
00867                 bool operator()(Box2<T> const &s1, Box2<T> const &s2) const
00868                 {
00869                         return s1.cmp(s2) < 0;
00870                 }
00871         };
00875         typedef std::map<Box2<T>, T,struct PosSizeLt> Map;
00876 
00877 protected:
00879         Vec2<T> m_pt[2];
00880 };
00881 
00883 typedef Box2<int> Box2i;
00885 typedef Box2<float> Box2f;
00886 
00887 #endif /* LIBWPS_INTERNAL_H */
00888 /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */