1 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2
3 /* libmwaw
4 * Version: MPL 2.0 / LGPLv2+
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 2.0 (the "License"); you may not use this file except in compliance with
8 * the License or as specified alternatively below. You may obtain a copy of
9 * the License at http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * Major Contributor(s):
17 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
18 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
19 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
20 * Copyright (C) 2006, 2007 Andrew Ziem
21 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
22 *
23 *
24 * All Rights Reserved.
25 *
26 * For minor contributions see the git repository.
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
30 * in which case the provisions of the LGPLv2+ are applicable
31 * instead of those above.
32 */
33
34 #ifndef LIBMWAW_INTERNAL_H
35 #define LIBMWAW_INTERNAL_H
36 #ifdef DEBUG
37 #include <stdio.h>
38 #endif
39
40 #include <math.h>
41
42 #include <algorithm>
43 #include <cmath>
44 #include <limits>
45 #include <map>
46 #include <memory>
47 #include <ostream>
48 #include <string>
49 #include <vector>
50
51 #ifndef M_PI
52 #define M_PI 3.14159265358979323846
53 #endif
54
55 #include <librevenge-stream/librevenge-stream.h>
56 #include <librevenge/librevenge.h>
57
58 #if defined(_MSC_VER) || defined(__DJGPP__)
59
60 typedef signed char int8_t;
61 typedef unsigned char uint8_t;
62 typedef signed short int16_t;
63 typedef unsigned short uint16_t;
64 typedef signed int int32_t;
65 typedef unsigned int uint32_t;
66 typedef unsigned __int64 uint64_t;
67 typedef __int64 int64_t;
68
69 #else /* !_MSC_VER && !__DJGPP__*/
70
71 # ifdef HAVE_CONFIG_H
72
73 # include <config.h>
74 # ifdef HAVE_STDINT_H
75 # include <stdint.h>
76 # endif
77 # ifdef HAVE_INTTYPES_H
78 # include <inttypes.h>
79 # endif
80
81 # else
82
83 // assume that the headers are there inside LibreOffice build when no HAVE_CONFIG_H is defined
84 # include <stdint.h>
85 # include <inttypes.h>
86
87 # endif
88
89 #endif /* _MSC_VER || __DJGPP__ */
90
91 // define gmtime_r and localtime_r on Windows, so that can use
92 // thread-safe functions on other environments
93 #ifdef _WIN32
94 # define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
95 # define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
96 #endif
97
98 /* ---------- memory --------------- */
99 /** an noop deleter used to transform a libwpd pointer in a false std::shared_ptr */
100 template <class T>
101 struct MWAW_shared_ptr_noop_deleter {
operator ()MWAW_shared_ptr_noop_deleter102 void operator()(T *) {}
103 };
104
105 #if defined(HAVE_FUNC_ATTRIBUTE_FORMAT)
106 # define LIBMWAW_ATTRIBUTE_PRINTF(fmt, arg) __attribute__((format(printf, fmt, arg)))
107 #else
108 # define LIBMWAW_ATTRIBUTE_PRINTF(fmt, arg)
109 #endif
110
111 #define MWAW_N_ELEMENTS(m) sizeof(m)/sizeof(m[0])
112
113 #if defined(HAVE_CLANG_ATTRIBUTE_FALLTHROUGH)
114 # define MWAW_FALLTHROUGH [[clang::fallthrough]]
115 #elif defined(HAVE_GCC_ATTRIBUTE_FALLTHROUGH)
116 # define MWAW_FALLTHROUGH __attribute__((fallthrough))
117 #else
118 # define MWAW_FALLTHROUGH ((void) 0)
119 #endif
120
121 /* ---------- debug --------------- */
122 #ifdef DEBUG
123 namespace libmwaw
124 {
125 void printDebugMsg(const char *format, ...) LIBMWAW_ATTRIBUTE_PRINTF(1,2);
126 }
127 #define MWAW_DEBUG_MSG(M) libmwaw::printDebugMsg M
128 #else
129 #define MWAW_DEBUG_MSG(M)
130 #endif
131
132 namespace libmwaw
133 {
134 // Various exceptions:
135 class VersionException
136 {
137 };
138
139 class FileException
140 {
141 };
142
143 class ParseException
144 {
145 };
146
147 class GenericException
148 {
149 };
150
151 class WrongPasswordException
152 {
153 };
154 }
155
156 /* ---------- input ----------------- */
157 namespace libmwaw
158 {
159 uint8_t readU8(librevenge::RVNGInputStream *input);
160 //! adds an unicode character to a string
161 void appendUnicode(uint32_t val, librevenge::RVNGString &buffer);
162
163 //! checks whether addition of \c x and \c y would overflow
164 template<typename T>
checkAddOverflow(T x,T y)165 bool checkAddOverflow(T x, T y)
166 {
167 return (x < 0 && y < std::numeric_limits<T>::lowest() - x)
168 || (x > 0 && y > std::numeric_limits<T>::max() - x);
169 }
170 }
171
172 /* ---------- small enum/class ------------- */
173 namespace libmwaw
174 {
175 //! basic position enum
176 enum Position { Left = 0, Right = 1, Top = 2, Bottom = 3, HMiddle = 4, VMiddle = 5 };
177 //! basic position enum bits
178 enum { LeftBit = 0x01, RightBit = 0x02, TopBit=0x4, BottomBit = 0x08, HMiddleBit = 0x10, VMiddleBit = 0x20 };
179
180 enum NumberingType { NONE, BULLET, ARABIC, LOWERCASE, UPPERCASE, LOWERCASE_ROMAN, UPPERCASE_ROMAN };
181 std::string numberingTypeToString(NumberingType type);
182 std::string numberingValueToString(NumberingType type, int value);
183
184 //! the different writing mode
185 enum WritingMode { WritingLeftTop, WritingLeftBottom, WritingRightTop, WritingRightBottom, WritingInherited };
186 //! a function to convert a writing mode in string lt-rb, ...
187 std::string writingModeToString(WritingMode mode);
188 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 };
189 }
190
191 //! the class to store a color
192 struct MWAWColor {
193 //! constructor
MWAWColorMWAWColor194 explicit MWAWColor(uint32_t argb=0)
195 : m_value(argb)
196 {
197 }
198 //! constructor from color
MWAWColorMWAWColor199 MWAWColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a=255)
200 : m_value(uint32_t((a<<24)+(r<<16)+(g<<8)+b))
201 {
202 }
203 //! copy constructor
204 MWAWColor(MWAWColor const &) = default;
205 //! move assignement
206 MWAWColor(MWAWColor &&) = default;
207 //! operator=
208 MWAWColor &operator=(MWAWColor const &) = default;
209 //! move operator=
210 MWAWColor &operator=(MWAWColor &&) = default;
211 //! operator=
operator =MWAWColor212 MWAWColor &operator=(uint32_t argb)
213 {
214 m_value = argb;
215 return *this;
216 }
217 //! return a color from a cmyk color ( basic)
colorFromCMYKMWAWColor218 static MWAWColor colorFromCMYK(unsigned char c, unsigned char m, unsigned char y, unsigned char k)
219 {
220 double w=1.-static_cast<double>(k)/255.;
221 return MWAWColor
222 (static_cast<unsigned char>(255 * (1-static_cast<double>(c)/255) * w),
223 static_cast<unsigned char>(255 * (1-static_cast<double>(m)/255) * w),
224 static_cast<unsigned char>(255 * (1-static_cast<double>(y)/255) * w)
225 );
226 }
227 //! return a color from a hsl color (basic)
colorFromHSLMWAWColor228 static MWAWColor colorFromHSL(unsigned char H, unsigned char S, unsigned char L)
229 {
230 double c=(1-((L>=128) ? (2*static_cast<double>(L)-255) : (255-2*static_cast<double>(L)))/255)*
231 static_cast<double>(S)/255;
232 double tmp=std::fmod((static_cast<double>(H)*6/255),2)-1;
233 double x=c*(1-(tmp>0 ? tmp : -tmp));
234 auto C=static_cast<unsigned char>(255*c);
235 auto M=static_cast<unsigned char>(static_cast<double>(L)-255*c/2);
236 auto X=static_cast<unsigned char>(255*x);
237 if (H<=42) return MWAWColor(static_cast<unsigned char>(M+C),static_cast<unsigned char>(M+X),static_cast<unsigned char>(M));
238 if (H<=85) return MWAWColor(static_cast<unsigned char>(M+X),static_cast<unsigned char>(M+C),static_cast<unsigned char>(M));
239 if (H<=127) return MWAWColor(static_cast<unsigned char>(M),static_cast<unsigned char>(M+C),static_cast<unsigned char>(M+X));
240 if (H<=170) return MWAWColor(static_cast<unsigned char>(M),static_cast<unsigned char>(M+X),static_cast<unsigned char>(M+C));
241 if (H<=212) return MWAWColor(static_cast<unsigned char>(M+X),static_cast<unsigned char>(M),static_cast<unsigned char>(M+C));
242 return MWAWColor(static_cast<unsigned char>(M+C),static_cast<unsigned char>(M),static_cast<unsigned char>(M+X));
243 }
244 //! return the back color
blackMWAWColor245 static MWAWColor black()
246 {
247 return MWAWColor(0,0,0);
248 }
249 //! return the white color
whiteMWAWColor250 static MWAWColor white()
251 {
252 return MWAWColor(255,255,255);
253 }
254
255 //! return alpha*colA+beta*colB
256 static MWAWColor barycenter(float alpha, MWAWColor const &colA,
257 float beta, MWAWColor const &colB);
258 //! return the rgba value
valueMWAWColor259 uint32_t value() const
260 {
261 return m_value;
262 }
263 //! returns the alpha value
getAlphaMWAWColor264 unsigned char getAlpha() const
265 {
266 return static_cast<unsigned char>((m_value>>24)&0xFF);
267 }
268 //! returns the green value
getBlueMWAWColor269 unsigned char getBlue() const
270 {
271 return static_cast<unsigned char>(m_value&0xFF);
272 }
273 //! returns the red value
getRedMWAWColor274 unsigned char getRed() const
275 {
276 return static_cast<unsigned char>((m_value>>16)&0xFF);
277 }
278 //! returns the green value
getGreenMWAWColor279 unsigned char getGreen() const
280 {
281 return static_cast<unsigned char>((m_value>>8)&0xFF);
282 }
283 //! return true if the color is black
isBlackMWAWColor284 bool isBlack() const
285 {
286 return (m_value&0xFFFFFF)==0;
287 }
288 //! return true if the color is white
isWhiteMWAWColor289 bool isWhite() const
290 {
291 return (m_value&0xFFFFFF)==0xFFFFFF;
292 }
293 //! operator==
operator ==MWAWColor294 bool operator==(MWAWColor const &c) const
295 {
296 return (c.m_value&0xFFFFFF)==(m_value&0xFFFFFF);
297 }
298 //! operator!=
operator !=MWAWColor299 bool operator!=(MWAWColor const &c) const
300 {
301 return !operator==(c);
302 }
303 //! operator<
operator <MWAWColor304 bool operator<(MWAWColor const &c) const
305 {
306 return (c.m_value&0xFFFFFF)<(m_value&0xFFFFFF);
307 }
308 //! operator<=
operator <=MWAWColor309 bool operator<=(MWAWColor const &c) const
310 {
311 return (c.m_value&0xFFFFFF)<=(m_value&0xFFFFFF);
312 }
313 //! operator>
operator >MWAWColor314 bool operator>(MWAWColor const &c) const
315 {
316 return !operator<=(c);
317 }
318 //! operator>=
operator >=MWAWColor319 bool operator>=(MWAWColor const &c) const
320 {
321 return !operator<(c);
322 }
323 //! operator<< in the form \#rrggbb
324 friend std::ostream &operator<< (std::ostream &o, MWAWColor const &c);
325 //! print the color in the form \#rrggbb
326 std::string str() const;
327 protected:
328 //! the argb color
329 uint32_t m_value;
330 };
331
332 //! a border
333 struct MWAWBorder {
334 /** the line style */
335 enum Style { None, Simple, Dot, LargeDot, Dash };
336 /** the line repetition */
337 enum Type { Single, Double, Triple };
338
339 //! constructor
MWAWBorderMWAWBorder340 MWAWBorder()
341 : m_style(Simple)
342 , m_type(Single)
343 , m_width(1)
344 , m_widthsList()
345 , m_color(MWAWColor::black())
346 , m_extra("") { }
347 MWAWBorder(MWAWBorder const &) = default;
348 MWAWBorder(MWAWBorder &&) = default;
349 MWAWBorder &operator=(MWAWBorder const &) = default;
350 MWAWBorder &operator=(MWAWBorder &&) = default;
351 /** add the border property to proplist (if needed )
352
353 \note if set which must be equal to "left", "top", ... */
354 bool addTo(librevenge::RVNGPropertyList &propList, std::string which="") const;
355 //! returns true if the border is empty
isEmptyMWAWBorder356 bool isEmpty() const
357 {
358 return m_style==None || m_width <= 0;
359 }
360 //! operator==
operator ==MWAWBorder361 bool operator==(MWAWBorder const &orig) const
362 {
363 return !operator!=(orig);
364 }
365 //! operator!=
operator !=MWAWBorder366 bool operator!=(MWAWBorder const &orig) const
367 {
368 return m_style != orig.m_style || m_type != orig.m_type ||
369 m_width < orig.m_width || m_width > orig.m_width || m_color != orig.m_color ||
370 m_widthsList != orig.m_widthsList;
371 }
372 //! compare two borders
373 int compare(MWAWBorder const &orig) const;
374
375 //! operator<<
376 friend std::ostream &operator<< (std::ostream &o, MWAWBorder const &border);
377 //! operator<<: prints data in form "none|dot|..."
378 friend std::ostream &operator<< (std::ostream &o, MWAWBorder::Style const &style);
379 //! the border style
380 Style m_style;
381
382 // multiple borders
383
384 //! the border repetition
385 Type m_type;
386 //! the border total width in point
387 double m_width;
388 /** the different length used for each line/sep (if defined)
389
390 \note when defined, the size of this list must be equal to 2*Type-1*/
391 std::vector<double> m_widthsList;
392 //! the border color
393 MWAWColor m_color;
394 //! extra data ( if needed)
395 std::string m_extra;
396 };
397
398 //! a field
399 struct MWAWField {
400 /** Defines some basic type for field */
401 enum Type { None, PageCount, PageNumber, Date, Time, Title, Database, BookmarkStart, BookmarkEnd };
402
403 /** basic constructor */
MWAWFieldMWAWField404 explicit MWAWField(Type type)
405 : m_type(type)
406 , m_numberingType(libmwaw::ARABIC)
407 , m_DTFormat("")
408 , m_data("")
409 {
410 }
411 MWAWField(MWAWField &&) = default;
412 MWAWField(MWAWField const &) = default;
413 MWAWField &operator=(MWAWField const &) = default;
414 MWAWField &operator=(MWAWField &&) = default;
415 /** add the link property to proplist (if possible) */
416 bool addTo(librevenge::RVNGPropertyList &propList) const;
417 //! returns a string corresponding to the field (if possible) */
418 librevenge::RVNGString getString() const;
419 //! the type
420 Type m_type;
421 //! the number type ( for number field )
422 libmwaw::NumberingType m_numberingType;
423 //! the date/time format using strftime format if defined
424 std::string m_DTFormat;
425 //! the database/link field ( if defined ) or the bookmark name
426 std::string m_data;
427 };
428
429 //! a link
430 struct MWAWLink {
431 /** basic constructor */
MWAWLinkMWAWLink432 MWAWLink()
433 : m_HRef("")
434 {
435 }
436
437 /** add the link property to proplist (if needed ) */
438 bool addTo(librevenge::RVNGPropertyList &propList) const;
439
440 //! the href field
441 std::string m_HRef;
442 };
443
444 //! a note
445 struct MWAWNote {
446 //! enum to define note type
447 enum Type { FootNote, EndNote };
448 //! constructor
MWAWNoteMWAWNote449 explicit MWAWNote(Type type)
450 : m_type(type)
451 , m_label("")
452 , m_number(-1)
453 {
454 }
455 //! the note type
456 Type m_type;
457 //! the note label
458 librevenge::RVNGString m_label;
459 //! the note number if defined
460 int m_number;
461 };
462
463 /** small class use to define a embedded object
464
465 \note mainly used to store picture
466 */
467 struct MWAWEmbeddedObject {
468 //! empty constructor
MWAWEmbeddedObjectMWAWEmbeddedObject469 MWAWEmbeddedObject()
470 : m_dataList()
471 , m_typeList()
472 {
473 }
474 //! constructor
MWAWEmbeddedObjectMWAWEmbeddedObject475 MWAWEmbeddedObject(librevenge::RVNGBinaryData const &binaryData,
476 std::string const &type="image/pict") : m_dataList(), m_typeList()
477 {
478 add(binaryData, type);
479 }
480 MWAWEmbeddedObject(MWAWEmbeddedObject const &)=default;
481 MWAWEmbeddedObject &operator=(MWAWEmbeddedObject const &)=default;
482 MWAWEmbeddedObject &operator=(MWAWEmbeddedObject &&)=default;
483 //! destructor
484 ~MWAWEmbeddedObject();
485 //! return true if the picture contains no data
isEmptyMWAWEmbeddedObject486 bool isEmpty() const
487 {
488 for (auto const &data : m_dataList) {
489 if (!data.empty())
490 return false;
491 }
492 return true;
493 }
494 //! add a picture
addMWAWEmbeddedObject495 void add(librevenge::RVNGBinaryData const &binaryData, std::string const &type="image/pict")
496 {
497 size_t pos=m_dataList.size();
498 if (pos<m_typeList.size()) pos=m_typeList.size();
499 m_dataList.resize(pos+1);
500 m_dataList[pos]=binaryData;
501 m_typeList.resize(pos+1);
502 m_typeList[pos]=type;
503 }
504 /** add the link property to proplist */
505 bool addTo(librevenge::RVNGPropertyList &propList) const;
506 /** operator<<*/
507 friend std::ostream &operator<<(std::ostream &o, MWAWEmbeddedObject const &pict);
508 /** a comparison function */
509 int cmp(MWAWEmbeddedObject const &pict) const;
510
511 //! the picture content: one data by representation
512 std::vector<librevenge::RVNGBinaryData> m_dataList;
513 //! the picture type: one type by representation
514 std::vector<std::string> m_typeList;
515 };
516
517 // forward declarations of basic classes and smart pointers
518 struct MWAWStream;
519 class MWAWEntry;
520 class MWAWFont;
521 class MWAWGraphicEncoder;
522 class MWAWGraphicShape;
523 class MWAWGraphicStyle;
524 class MWAWHeader;
525 class MWAWList;
526 class MWAWPageSpan;
527 class MWAWParagraph;
528 class MWAWParser;
529 class MWAWPosition;
530 class MWAWSection;
531
532 class MWAWFontConverter;
533 class MWAWFontManager;
534 class MWAWGraphicListener;
535 class MWAWInputStream;
536 class MWAWListener;
537 class MWAWListManager;
538 class MWAWParserState;
539 class MWAWPresentationListener;
540 class MWAWRSRCParser;
541 class MWAWSpreadsheetListener;
542 class MWAWSubDocument;
543 class MWAWTextListener;
544 //! a smart pointer of MWAWFontConverter
545 typedef std::shared_ptr<MWAWFontConverter> MWAWFontConverterPtr;
546 //! a smart pointer of MWAWFontManager
547 typedef std::shared_ptr<MWAWFontManager> MWAWFontManagerPtr;
548 //! a smart pointer of MWAWGraphicListener
549 typedef std::shared_ptr<MWAWGraphicListener> MWAWGraphicListenerPtr;
550 //! a smart pointer of MWAWInputStream
551 typedef std::shared_ptr<MWAWInputStream> MWAWInputStreamPtr;
552 //! a smart pointer of MWAWListener
553 typedef std::shared_ptr<MWAWListener> MWAWListenerPtr;
554 //! a smart pointer of MWAWListManager
555 typedef std::shared_ptr<MWAWListManager> MWAWListManagerPtr;
556 //! a smart pointer of MWAWParserState
557 typedef std::shared_ptr<MWAWParserState> MWAWParserStatePtr;
558 //! a smart pointer of MWAWPresentationListener
559 typedef std::shared_ptr<MWAWPresentationListener> MWAWPresentationListenerPtr;
560 //! a smart pointer of MWAWRSRCParser
561 typedef std::shared_ptr<MWAWRSRCParser> MWAWRSRCParserPtr;
562 //! a smart pointer of MWAWSpreadsheetListener
563 typedef std::shared_ptr<MWAWSpreadsheetListener> MWAWSpreadsheetListenerPtr;
564 //! a smart pointer of MWAWSubDocument
565 typedef std::shared_ptr<MWAWSubDocument> MWAWSubDocumentPtr;
566 //! a smart pointer of MWAWTextListener
567 typedef std::shared_ptr<MWAWTextListener> MWAWTextListenerPtr;
568
569 /** a generic variable template: value + flag to know if the variable is set
570
571 \note the variable is considered set as soon a new value is set or
572 when its content is acceded by a function which returns a not-const
573 reference... You can use the function setSet to unset it.
574
575 \note must be replaced by std::optional when we will be comptable with std::c++-17
576 */
577 template <class T> struct MWAWVariable {
578 //! constructor
MWAWVariableMWAWVariable579 MWAWVariable()
580 : m_data()
581 , m_set(false) {}
582 //! constructor with a default value
MWAWVariableMWAWVariable583 explicit MWAWVariable(T const &def)
584 : m_data(def)
585 , m_set(false) {}
586 //! copy constructor
MWAWVariableMWAWVariable587 MWAWVariable(MWAWVariable const &orig)
588 : m_data(orig.m_data)
589 , m_set(orig.m_set) {}
590 //! copy operator
591 MWAWVariable &operator=(MWAWVariable const &) = default;
592 //! set a value
operator =MWAWVariable593 MWAWVariable &operator=(T const &val)
594 {
595 m_data = val;
596 m_set = true;
597 return std::forward<MWAWVariable &>(*this);
598 }
599 //! update the current value if orig is set
insertMWAWVariable600 void insert(MWAWVariable const &orig)
601 {
602 if (orig.m_set) {
603 m_data = orig.m_data;
604 m_set = orig.m_set;
605 }
606 }
607 //! operator*
operator ->MWAWVariable608 T const *operator->() const
609 {
610 return &m_data;
611 }
612 /** operator* */
operator ->MWAWVariable613 T *operator->()
614 {
615 m_set = true;
616 return &m_data;
617 }
618 //! operator*
operator *MWAWVariable619 T const &operator*() const
620 {
621 return m_data;
622 }
623 //! operator*
operator *MWAWVariable624 T &operator*()
625 {
626 m_set = true;
627 return m_data;
628 }
629 //! return the current value
getMWAWVariable630 T const &get() const
631 {
632 return m_data;
633 }
634 //! return true if the variable is set
isSetMWAWVariable635 bool isSet() const
636 {
637 return m_set;
638 }
639 //! define if the variable is set
setSetMWAWVariable640 void setSet(bool newVal)
641 {
642 m_set=newVal;
643 }
644 protected:
645 //! the value
646 T m_data;
647 //! a flag to know if the variable is set or not
648 bool m_set;
649 };
650
651 /* ---------- vec2/box2f ------------- */
652 /*! \class MWAWVec2
653 * \brief small class which defines a vector with 2 elements
654 */
655 template <class T> class MWAWVec2
656 {
657 public:
658 //! constructor
MWAWVec2(T xx=0,T yy=0)659 explicit MWAWVec2(T xx=0,T yy=0)
660 : m_x(xx)
661 , m_y(yy) { }
662 //! generic copy constructor
MWAWVec2(MWAWVec2<U> const & p)663 template <class U> explicit MWAWVec2(MWAWVec2<U> const &p)
664 : m_x(T(p.x()))
665 , m_y(T(p.y())) {}
666
667 //! first element
x() const668 T x() const
669 {
670 return m_x;
671 }
672 //! second element
y() const673 T y() const
674 {
675 return m_y;
676 }
677 //! operator[]
operator [](int c) const678 T operator[](int c) const
679 {
680 if (c<0 || c>1) throw libmwaw::GenericException();
681 return (c==0) ? m_x : m_y;
682 }
683 //! operator[]
operator [](int c)684 T &operator[](int c)
685 {
686 if (c<0 || c>1) throw libmwaw::GenericException();
687 return (c==0) ? m_x : m_y;
688 }
689
690 //! resets the two elements
set(T xx,T yy)691 void set(T xx, T yy)
692 {
693 m_x = xx;
694 m_y = yy;
695 }
696 //! resets the first element
setX(T xx)697 void setX(T xx)
698 {
699 m_x = xx;
700 }
701 //! resets the second element
setY(T yy)702 void setY(T yy)
703 {
704 m_y = yy;
705 }
706
707 //! increases the actuals values by \a dx and \a dy
add(T dx,T dy)708 void add(T dx, T dy)
709 {
710 if (libmwaw::checkAddOverflow(m_x, dx) || libmwaw::checkAddOverflow(m_y, dy))
711 throw libmwaw::GenericException();
712 m_x += dx;
713 m_y += dy;
714 }
715
716 //! operator+=
operator +=(MWAWVec2<T> const & p)717 MWAWVec2<T> &operator+=(MWAWVec2<T> const &p)
718 {
719 add(p.m_x, p.m_y);
720 return *this;
721 }
722 //! operator-=
operator -=(MWAWVec2<T> const & p)723 MWAWVec2<T> &operator-=(MWAWVec2<T> const &p)
724 {
725 // check if negation of either of the coords will cause overflow
726 const T diff = std::numeric_limits<T>::min() + std::numeric_limits<T>::max();
727 if (libmwaw::checkAddOverflow(p.m_x, diff) || libmwaw::checkAddOverflow(p.m_y, diff))
728 throw libmwaw::GenericException();
729 add(-p.m_x, -p.m_y);
730 return *this;
731 }
732 //! generic operator*=
733 template <class U>
operator *=(U scale)734 MWAWVec2<T> &operator*=(U scale)
735 {
736 m_x = T(m_x*scale);
737 m_y = T(m_y*scale);
738 return *this;
739 }
740
741 //! operator+
operator +(MWAWVec2<T> const & p1,MWAWVec2<T> const & p2)742 friend MWAWVec2<T> operator+(MWAWVec2<T> const &p1, MWAWVec2<T> const &p2)
743 {
744 MWAWVec2<T> p(p1);
745 return p+=p2;
746 }
747 //! operator-
operator -(MWAWVec2<T> const & p1,MWAWVec2<T> const & p2)748 friend MWAWVec2<T> operator-(MWAWVec2<T> const &p1, MWAWVec2<T> const &p2)
749 {
750 MWAWVec2<T> p(p1);
751 return p-=p2;
752 }
753 //! generic operator*
754 template <class U>
operator *(U scale,MWAWVec2<T> const & p1)755 friend MWAWVec2<T> operator*(U scale, MWAWVec2<T> const &p1)
756 {
757 MWAWVec2<T> p(p1);
758 return p *= scale;
759 }
760
761 //! comparison==
operator ==(MWAWVec2<T> const & p) const762 bool operator==(MWAWVec2<T> const &p) const
763 {
764 return cmpY(p) == 0;
765 }
766 //! comparison!=
operator !=(MWAWVec2<T> const & p) const767 bool operator!=(MWAWVec2<T> const &p) const
768 {
769 return cmpY(p) != 0;
770 }
771 //! comparison<: sort by y
operator <(MWAWVec2<T> const & p) const772 bool operator<(MWAWVec2<T> const &p) const
773 {
774 return cmpY(p) < 0;
775 }
776 //! a comparison function: which first compares x then y
cmp(MWAWVec2<T> const & p) const777 int cmp(MWAWVec2<T> const &p) const
778 {
779 if (m_x < p.m_x) return -1;
780 if (m_x > p.m_x) return 1;
781 if (m_y < p.m_y) return -1;
782 if (m_y > p.m_y) return 1;
783 return 0;
784 }
785 //! a comparison function: which first compares y then x
cmpY(MWAWVec2<T> const & p) const786 int cmpY(MWAWVec2<T> const &p) const
787 {
788 if (m_y < p.m_y) return -1;
789 if (m_y > p.m_y) return 1;
790 if (m_x < p.m_x) return -1;
791 if (m_x > p.m_x) return 1;
792 return 0;
793 }
794
795 //! operator<<: prints data in form "XxY"
operator <<(std::ostream & o,MWAWVec2<T> const & f)796 friend std::ostream &operator<< (std::ostream &o, MWAWVec2<T> const &f)
797 {
798 o << f.m_x << "x" << f.m_y;
799 return o;
800 }
801
802 /*! \struct PosSizeLtX
803 * \brief internal struct used to create sorted map, sorted by X
804 */
805 struct PosSizeLtX {
806 //! comparaison function
operator ()MWAWVec2::PosSizeLtX807 bool operator()(MWAWVec2<T> const &s1, MWAWVec2<T> const &s2) const
808 {
809 return s1.cmp(s2) < 0;
810 }
811 };
812 /*! \typedef MapX
813 * \brief map of MWAWVec2
814 */
815 typedef std::map<MWAWVec2<T>, T,struct PosSizeLtX> MapX;
816
817 /*! \struct PosSizeLtY
818 * \brief internal struct used to create sorted map, sorted by Y
819 */
820 struct PosSizeLtY {
821 //! comparaison function
operator ()MWAWVec2::PosSizeLtY822 bool operator()(MWAWVec2<T> const &s1, MWAWVec2<T> const &s2) const
823 {
824 return s1.cmpY(s2) < 0;
825 }
826 };
827 /*! \typedef MapY
828 * \brief map of MWAWVec2
829 */
830 typedef std::map<MWAWVec2<T>, T,struct PosSizeLtY> MapY;
831 protected:
832 T m_x/*! \brief first element */, m_y/*! \brief second element */;
833 };
834
835 /*! \brief MWAWVec2 of bool */
836 typedef MWAWVec2<bool> MWAWVec2b;
837 /*! \brief MWAWVec2 of int */
838 typedef MWAWVec2<int> MWAWVec2i;
839 /*! \brief MWAWVec2 of long */
840 typedef MWAWVec2<long> MWAWVec2l;
841 /*! \brief MWAWVec2 of float */
842 typedef MWAWVec2<float> MWAWVec2f;
843
844 /*! \class MWAWVec3
845 * \brief small class which defines a vector with 3 elements
846 */
847 template <class T> class MWAWVec3
848 {
849 public:
850 //! constructor
MWAWVec3(T xx=0,T yy=0,T zz=0)851 explicit MWAWVec3(T xx=0,T yy=0,T zz=0)
852 {
853 m_val[0] = xx;
854 m_val[1] = yy;
855 m_val[2] = zz;
856 }
857 //! generic copy constructor
MWAWVec3(MWAWVec3<U> const & p)858 template <class U> explicit MWAWVec3(MWAWVec3<U> const &p)
859 {
860 for (int c = 0; c < 3; c++) m_val[c] = T(p[c]);
861 }
862
863 //! first element
x() const864 T x() const
865 {
866 return m_val[0];
867 }
868 //! second element
y() const869 T y() const
870 {
871 return m_val[1];
872 }
873 //! third element
z() const874 T z() const
875 {
876 return m_val[2];
877 }
878 //! operator[]
operator [](int c) const879 T operator[](int c) const
880 {
881 if (c<0 || c>2) throw libmwaw::GenericException();
882 return m_val[c];
883 }
884 //! operator[]
operator [](int c)885 T &operator[](int c)
886 {
887 if (c<0 || c>2) throw libmwaw::GenericException();
888 return m_val[c];
889 }
890
891 //! resets the three elements
set(T xx,T yy,T zz)892 void set(T xx, T yy, T zz)
893 {
894 m_val[0] = xx;
895 m_val[1] = yy;
896 m_val[2] = zz;
897 }
898 //! resets the first element
setX(T xx)899 void setX(T xx)
900 {
901 m_val[0] = xx;
902 }
903 //! resets the second element
setY(T yy)904 void setY(T yy)
905 {
906 m_val[1] = yy;
907 }
908 //! resets the third element
setZ(T zz)909 void setZ(T zz)
910 {
911 m_val[2] = zz;
912 }
913
914 //! increases the actuals values by \a dx, \a dy, \a dz
add(T dx,T dy,T dz)915 void add(T dx, T dy, T dz)
916 {
917 m_val[0] += dx;
918 m_val[1] += dy;
919 m_val[2] += dz;
920 }
921
922 //! operator+=
operator +=(MWAWVec3<T> const & p)923 MWAWVec3<T> &operator+=(MWAWVec3<T> const &p)
924 {
925 for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]+p.m_val[c]);
926 return *this;
927 }
928 //! operator-=
operator -=(MWAWVec3<T> const & p)929 MWAWVec3<T> &operator-=(MWAWVec3<T> const &p)
930 {
931 for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]-p.m_val[c]);
932 return *this;
933 }
934 //! generic operator*=
935 template <class U>
operator *=(U scale)936 MWAWVec3<T> &operator*=(U scale)
937 {
938 for (auto &c : m_val) c = T(c*scale);
939 return *this;
940 }
941
942 //! operator+
operator +(MWAWVec3<T> const & p1,MWAWVec3<T> const & p2)943 friend MWAWVec3<T> operator+(MWAWVec3<T> const &p1, MWAWVec3<T> const &p2)
944 {
945 MWAWVec3<T> p(p1);
946 return p+=p2;
947 }
948 //! operator-
operator -(MWAWVec3<T> const & p1,MWAWVec3<T> const & p2)949 friend MWAWVec3<T> operator-(MWAWVec3<T> const &p1, MWAWVec3<T> const &p2)
950 {
951 MWAWVec3<T> p(p1);
952 return p-=p2;
953 }
954 //! generic operator*
955 template <class U>
operator *(U scale,MWAWVec3<T> const & p1)956 friend MWAWVec3<T> operator*(U scale, MWAWVec3<T> const &p1)
957 {
958 MWAWVec3<T> p(p1);
959 return p *= scale;
960 }
961
962 //! comparison==
operator ==(MWAWVec3<T> const & p) const963 bool operator==(MWAWVec3<T> const &p) const
964 {
965 return cmp(p) == 0;
966 }
967 //! comparison!=
operator !=(MWAWVec3<T> const & p) const968 bool operator!=(MWAWVec3<T> const &p) const
969 {
970 return cmp(p) != 0;
971 }
972 //! comparison<: which first compares x values, then y values then z values.
operator <(MWAWVec3<T> const & p) const973 bool operator<(MWAWVec3<T> const &p) const
974 {
975 return cmp(p) < 0;
976 }
977 //! a comparison function: which first compares x values, then y values then z values.
cmp(MWAWVec3<T> const & p) const978 int cmp(MWAWVec3<T> const &p) const
979 {
980 for (int c = 0; c < 3; c++) {
981 if (m_val[c]<p.m_val[c]) return -1;
982 if (m_val[c]>p.m_val[c]) return 1;
983 }
984 return 0;
985 }
986
987 //! operator<<: prints data in form "XxYxZ"
operator <<(std::ostream & o,MWAWVec3<T> const & f)988 friend std::ostream &operator<< (std::ostream &o, MWAWVec3<T> const &f)
989 {
990 o << f.m_val[0] << "x" << f.m_val[1] << "x" << f.m_val[2];
991 return o;
992 }
993
994 /*! \struct PosSizeLt
995 * \brief internal struct used to create sorted map, sorted by X, Y, Z
996 */
997 struct PosSizeLt {
998 //! comparaison function
operator ()MWAWVec3::PosSizeLt999 bool operator()(MWAWVec3<T> const &s1, MWAWVec3<T> const &s2) const
1000 {
1001 return s1.cmp(s2) < 0;
1002 }
1003 };
1004 /*! \typedef Map
1005 * \brief map of MWAWVec3
1006 */
1007 typedef std::map<MWAWVec3<T>, T,struct PosSizeLt> Map;
1008
1009 protected:
1010 //! the values
1011 T m_val[3];
1012 };
1013
1014 /*! \brief MWAWVec3 of unsigned char */
1015 typedef MWAWVec3<unsigned char> MWAWVec3uc;
1016 /*! \brief MWAWVec3 of int */
1017 typedef MWAWVec3<int> MWAWVec3i;
1018 /*! \brief MWAWVec3 of float */
1019 typedef MWAWVec3<float> MWAWVec3f;
1020
1021 /*! \class MWAWBox2
1022 * \brief small class which defines a 2D Box
1023 */
1024 template <class T> class MWAWBox2
1025 {
1026 public:
1027 //! constructor
MWAWBox2(MWAWVec2<T> minPt=MWAWVec2<T> (),MWAWVec2<T> maxPt=MWAWVec2<T> ())1028 explicit MWAWBox2(MWAWVec2<T> minPt=MWAWVec2<T>(), MWAWVec2<T> maxPt=MWAWVec2<T>())
1029 : m_data(minPt, maxPt)
1030 {
1031 }
1032 //! generic constructor
MWAWBox2(MWAWBox2<U> const & p)1033 template <class U> explicit MWAWBox2(MWAWBox2<U> const &p)
1034 : m_data(MWAWVec2<T>(p.min()), MWAWVec2<T>(p.max()))
1035 {
1036 }
1037
1038 //! the minimum 2D point (in x and in y)
min() const1039 MWAWVec2<T> const &min() const
1040 {
1041 return m_data.first;
1042 }
1043 //! the maximum 2D point (in x and in y)
max() const1044 MWAWVec2<T> const &max() const
1045 {
1046 return m_data.second;
1047 }
1048 //! the minimum 2D point (in x and in y)
min()1049 MWAWVec2<T> &min()
1050 {
1051 return m_data.first;
1052 }
1053 //! the maximum 2D point (in x and in y)
max()1054 MWAWVec2<T> &max()
1055 {
1056 return m_data.second;
1057 }
1058 /*! \brief the two extremum points which defined the box
1059 * \param c 0 means the minimum and 1 the maximum
1060 */
operator [](int c) const1061 MWAWVec2<T> const &operator[](int c) const
1062 {
1063 if (c<0 || c>1) throw libmwaw::GenericException();
1064 return c==0 ? m_data.first : m_data.second;
1065 }
1066 //! the box size
size() const1067 MWAWVec2<T> size() const
1068 {
1069 return m_data.second-m_data.first;
1070 }
1071 //! the box center
center() const1072 MWAWVec2<T> center() const
1073 {
1074 return MWAWVec2<T>((m_data.first.x()+m_data.second.x())/2,
1075 (m_data.first.y()+m_data.second.y())/2);
1076 }
1077
1078 //! resets the data to minimum \a x and maximum \a y
set(MWAWVec2<T> const & x,MWAWVec2<T> const & y)1079 void set(MWAWVec2<T> const &x, MWAWVec2<T> const &y)
1080 {
1081 m_data.first = x;
1082 m_data.second = y;
1083 }
1084 //! resets the minimum point
setMin(MWAWVec2<T> const & x)1085 void setMin(MWAWVec2<T> const &x)
1086 {
1087 m_data.first = x;
1088 }
1089 //! resets the maximum point
setMax(MWAWVec2<T> const & y)1090 void setMax(MWAWVec2<T> const &y)
1091 {
1092 m_data.second = y;
1093 }
1094
1095 //! resize the box keeping the minimum
resizeFromMin(MWAWVec2<T> const & sz)1096 void resizeFromMin(MWAWVec2<T> const &sz)
1097 {
1098 m_data.second = m_data.first+sz;
1099 }
1100 //! resize the box keeping the maximum
resizeFromMax(MWAWVec2<T> const & sz)1101 void resizeFromMax(MWAWVec2<T> const &sz)
1102 {
1103 m_data.first = m_data.second-sz;
1104 }
1105 //! resize the box keeping the center
resizeFromCenter(MWAWVec2<T> const & sz)1106 void resizeFromCenter(MWAWVec2<T> const &sz)
1107 {
1108 MWAWVec2<T> centerPt = center();
1109 MWAWVec2<T> decal(sz.x()/2,sz.y()/2);
1110 m_data.first = centerPt - decal;
1111 m_data.second = centerPt + (sz - decal);
1112 }
1113
1114 //! scales all points of the box by \a factor
scale(U factor)1115 template <class U> void scale(U factor)
1116 {
1117 m_data.first *= factor;
1118 m_data.second *= factor;
1119 }
1120
1121 //! extends the bdbox by (\a val, \a val) keeping the center
extend(T val)1122 void extend(T val)
1123 {
1124 m_data.first -= MWAWVec2<T>(val/2,val/2);
1125 m_data.second += MWAWVec2<T>(val-(val/2),val-(val/2));
1126 }
1127
1128 //! returns the union between this and box
getUnion(MWAWBox2<T> const & box) const1129 MWAWBox2<T> getUnion(MWAWBox2<T> const &box) const
1130 {
1131 MWAWBox2<T> res;
1132 res.m_data.first=MWAWVec2<T>(m_data.first[0]<box.m_data.first[0]?m_data.first[0] : box.m_data.first[0],
1133 m_data.first[1]<box.m_data.first[1]?m_data.first[1] : box.m_data.first[1]);
1134 res.m_data.second=MWAWVec2<T>(m_data.second[0]>box.m_data.second[0]?m_data.second[0] : box.m_data.second[0],
1135 m_data.second[1]>box.m_data.second[1]?m_data.second[1] : box.m_data.second[1]);
1136 return res;
1137 }
1138 //! returns the intersection between this and box
getIntersection(MWAWBox2<T> const & box) const1139 MWAWBox2<T> getIntersection(MWAWBox2<T> const &box) const
1140 {
1141 MWAWBox2<T> res;
1142 res.m_data.first=MWAWVec2<T>(m_data.first[0]>box.m_data.first[0]?m_data.first[0] : box.m_data.first[0],
1143 m_data.first[1]>box.m_data.first[1]?m_data.first[1] : box.m_data.first[1]);
1144 res.m_data.second=MWAWVec2<T>(m_data.second[0]<box.m_data.second[0]?m_data.second[0] : box.m_data.second[0],
1145 m_data.second[1]<box.m_data.second[1]?m_data.second[1] : box.m_data.second[1]);
1146 return res;
1147 }
1148 //! operator==
operator ==(MWAWBox2<T> const & mat) const1149 bool operator==(MWAWBox2<T> const &mat) const
1150 {
1151 return m_data==mat.m_data;
1152 }
1153 //! operator!=
operator !=(MWAWBox2<T> const & mat) const1154 bool operator!=(MWAWBox2<T> const &mat) const
1155 {
1156 return m_data!=mat.m_data;
1157 }
1158 //! operator<
operator <(MWAWBox2<T> const & mat) const1159 bool operator<(MWAWBox2<T> const &mat) const
1160 {
1161 return m_data<mat.m_data;
1162 }
1163 //! operator<=
operator <=(MWAWBox2<T> const & mat) const1164 bool operator<=(MWAWBox2<T> const &mat) const
1165 {
1166 return m_data<=mat.m_data;
1167 }
1168 //! operator>
operator >(MWAWBox2<T> const & mat) const1169 bool operator>(MWAWBox2<T> const &mat) const
1170 {
1171 return m_data>mat.m_data;
1172 }
1173 //! operator>=
operator >=(MWAWBox2<T> const & mat) const1174 bool operator>=(MWAWBox2<T> const &mat) const
1175 {
1176 return m_data>=mat.m_data;
1177 }
1178 //! print data in form X0xY0<->X1xY1
operator <<(std::ostream & o,MWAWBox2<T> const & f)1179 friend std::ostream &operator<< (std::ostream &o, MWAWBox2<T> const &f)
1180 {
1181 o << "(" << f.min() << "<->" << f.max() << ")";
1182 return o;
1183 }
1184
1185 protected:
1186 //! the data
1187 std::pair<MWAWVec2<T>, MWAWVec2<T> > m_data;
1188 };
1189
1190 /*! \brief MWAWBox2 of int */
1191 typedef MWAWBox2<int> MWAWBox2i;
1192 /*! \brief MWAWBox2 of float */
1193 typedef MWAWBox2<float> MWAWBox2f;
1194 /*! \brief MWAWBox2 of long */
1195 typedef MWAWBox2<long> MWAWBox2l;
1196
1197 /** a transformation which stored the first row of a 3x3 perspective matrix */
1198 class MWAWTransformation
1199 {
1200 public:
1201 //! constructor
MWAWTransformation(MWAWVec3f const & xRow=MWAWVec3f (1,0,0),MWAWVec3f const & yRow=MWAWVec3f (0,1,0))1202 explicit MWAWTransformation(MWAWVec3f const &xRow=MWAWVec3f(1,0,0), MWAWVec3f const &yRow=MWAWVec3f(0,1,0))
1203 : m_data(xRow, yRow)
1204 , m_isIdentity(false)
1205 {
1206 checkIdentity();
1207 }
1208 //! returns true if the matrix is an identity matrix
isIdentity() const1209 bool isIdentity() const
1210 {
1211 return m_isIdentity;
1212 }
1213 //! check if a matrix is the identity matrix
checkIdentity() const1214 void checkIdentity() const
1215 {
1216 m_isIdentity= m_data.first==MWAWVec3f(1,0,0) && m_data.second==MWAWVec3f(0,1,0);
1217 }
1218 /*! \brief the two extremum points which defined the box
1219 * \param c 0 means the minimum and 1 the maximum
1220 */
operator [](int c) const1221 MWAWVec3f const &operator[](int c) const
1222 {
1223 if (c<0 || c>1) throw libmwaw::GenericException();
1224 return c==0 ? m_data.first : m_data.second;
1225 }
1226 //! operator* for vec2f
operator *(MWAWVec2f const & pt) const1227 MWAWVec2f operator*(MWAWVec2f const &pt) const
1228 {
1229 if (m_isIdentity) return pt;
1230 return multiplyDirection(pt)+MWAWVec2f(m_data.first[2],m_data.second[2]);
1231 }
1232 //! operator* for direction
multiplyDirection(MWAWVec2f const & dir) const1233 MWAWVec2f multiplyDirection(MWAWVec2f const &dir) const
1234 {
1235 if (m_isIdentity) return dir;
1236 MWAWVec2f res;
1237 for (int coord=0; coord<2; ++coord) {
1238 MWAWVec3f const &row=coord==0 ? m_data.first : m_data.second;
1239 float value=0;
1240 for (int i=0; i<2; ++i)
1241 value+=row[i]*dir[i];
1242 res[coord]=value;
1243 }
1244 return res;
1245 }
1246 //! operator* for box2f
operator *(MWAWBox2f const & box) const1247 MWAWBox2f operator*(MWAWBox2f const &box) const
1248 {
1249 if (m_isIdentity) return box;
1250 return MWAWBox2f(operator*(box.min()), operator*(box.max()));
1251 }
1252 //! operator* for transform
operator *(MWAWTransformation const & mat) const1253 MWAWTransformation operator*(MWAWTransformation const &mat) const
1254 {
1255 if (mat.m_isIdentity) return *this;
1256 MWAWTransformation res;
1257 for (int row=0; row<2; ++row) {
1258 MWAWVec3f &resRow=row==0 ? res.m_data.first : res.m_data.second;
1259 for (int col=0; col<3; ++col) {
1260 float value=0;
1261 for (int i=0; i<3; ++i)
1262 value+=(*this)[row][i]*(i==2 ? (col==2 ? 1.f : 0.f) : mat[i][col]);
1263 resRow[col]=value;
1264 }
1265 }
1266 res.checkIdentity();
1267 return res;
1268 }
1269 //! operator*=
operator *=(MWAWTransformation const & mat)1270 MWAWTransformation &operator*=(MWAWTransformation const &mat)
1271 {
1272 if (!mat.m_isIdentity)
1273 *this=(*this)*mat;
1274 return *this;
1275 }
1276 //! operator==
operator ==(MWAWTransformation const & mat) const1277 bool operator==(MWAWTransformation const &mat) const
1278 {
1279 return m_data==mat.m_data;
1280 }
1281 //! operator!=
operator !=(MWAWTransformation const & mat) const1282 bool operator!=(MWAWTransformation const &mat) const
1283 {
1284 return m_data!=mat.m_data;
1285 }
1286 //! operator<
operator <(MWAWTransformation const & mat) const1287 bool operator<(MWAWTransformation const &mat) const
1288 {
1289 return m_data<mat.m_data;
1290 }
1291 //! operator<=
operator <=(MWAWTransformation const & mat) const1292 bool operator<=(MWAWTransformation const &mat) const
1293 {
1294 return m_data<=mat.m_data;
1295 }
1296 //! operator>
operator >(MWAWTransformation const & mat) const1297 bool operator>(MWAWTransformation const &mat) const
1298 {
1299 return m_data>mat.m_data;
1300 }
1301 //! operator>=
operator >=(MWAWTransformation const & mat) const1302 bool operator>=(MWAWTransformation const &mat) const
1303 {
1304 return m_data>=mat.m_data;
1305 }
1306 /** try to decompose the matrix in a rotation + scaling/translation matrix.
1307
1308 Note: the center of rotation is given before applying the transformation(this) */
1309 bool decompose(float &rotation, MWAWVec2f &shearing, MWAWTransformation &transform, MWAWVec2f const ¢er) const;
1310
1311 /** returns a translation transformation */
translation(MWAWVec2f const & trans)1312 static MWAWTransformation translation(MWAWVec2f const &trans)
1313 {
1314 return MWAWTransformation(MWAWVec3f(1, 0, trans[0]), MWAWVec3f(0, 1, trans[1]));
1315 }
1316 /** returns a scaling transformation */
scale(MWAWVec2f const & trans)1317 static MWAWTransformation scale(MWAWVec2f const &trans)
1318 {
1319 return MWAWTransformation(MWAWVec3f(trans[0], 0, 0), MWAWVec3f(0, trans[1], 0));
1320 }
1321 /** returns a rotation transformation around center.
1322
1323 \note angle must be given in degree */
1324 static MWAWTransformation rotation(float angle, MWAWVec2f const ¢er=MWAWVec2f(0,0));
1325 /** returns a shear transformation letting center invariant, ie. a matrix
1326 ( 1 s[0] -s[0]*center[1], s[1] 1 -s[1]*center[0], 0 0 1)
1327 */
shear(MWAWVec2f s,MWAWVec2f const & center=MWAWVec2f (0,0))1328 static MWAWTransformation shear(MWAWVec2f s, MWAWVec2f const ¢er=MWAWVec2f(0,0))
1329 {
1330 return MWAWTransformation(MWAWVec3f(1, s[0], -s[0]*center[1]), MWAWVec3f(s[1], 1, -s[1]*center[0]));
1331 }
1332 protected:
1333 //! the data
1334 std::pair<MWAWVec3f, MWAWVec3f > m_data;
1335 //! flag to know if this matrix is an identity matrix
1336 mutable bool m_isIdentity;
1337 };
1338
1339 // some format function
1340 namespace libmwaw
1341 {
1342 //! convert a DTFormat in a propertyList
1343 bool convertDTFormat(std::string const &dtFormat, librevenge::RVNGPropertyListVector &propVect);
1344 }
1345
1346 // some geometrical function
1347 namespace libmwaw
1348 {
1349 //! rotate a point around center, angle is given in degree
1350 MWAWVec2f rotatePointAroundCenter(MWAWVec2f const &point, MWAWVec2f const ¢er, float angle);
1351 //! rotate a bdox and returns the final bdbox, angle is given in degree
1352 MWAWBox2f rotateBoxFromCenter(MWAWBox2f const &box, float angle);
1353 }
1354 #endif /* LIBMWAW_INTERNAL_H */
1355 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
1356