Coverage Report

Created: 2026-09-06 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwps/src/lib/libwps_internal.h
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2
/* libwps
3
 * Version: MPL 2.0 / LGPLv2.1+
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * Major Contributor(s):
10
 * Copyright (C) 2002 William Lachance (william.lachance@sympatico.ca)
11
 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
12
 *
13
 * For minor contributions see the git repository.
14
 *
15
 * Alternatively, the contents of this file may be used under the terms
16
 * of the GNU Lesser General Public License Version 2.1 or later
17
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
18
 * applicable instead of those above.
19
 *
20
 * For further information visit http://libwps.sourceforge.net
21
 */
22
23
#ifndef LIBWPS_INTERNAL_H
24
#define LIBWPS_INTERNAL_H
25
26
#include <assert.h>
27
#ifdef DEBUG
28
#include <stdio.h>
29
#endif
30
31
#include <algorithm>
32
#include <cmath>
33
#include <iostream>
34
#include <map>
35
#include <memory>
36
#include <string>
37
#include <vector>
38
39
#include <librevenge-stream/librevenge-stream.h>
40
#include <librevenge/librevenge.h>
41
42
#ifndef M_PI
43
#define M_PI 3.14159265358979323846
44
#endif
45
46
#if defined(_MSC_VER) || defined(__DJGPP__)
47
typedef signed char int8_t;
48
typedef unsigned char uint8_t;
49
typedef signed short int16_t;
50
typedef unsigned short uint16_t;
51
typedef signed int int32_t;
52
typedef unsigned int uint32_t;
53
#else /* !_MSC_VER && !__DJGPP__*/
54
#  include <inttypes.h>
55
#endif /* _MSC_VER || __DJGPP__*/
56
57
/* ---------- time/...  --------------- */
58
#ifdef HAVE_CONFIG_H
59
#  include "config.h"
60
#endif
61
62
// define localtime_r on Windows, so that can use
63
// thread-safe functions on other environments
64
#ifdef _WIN32
65
#  define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
66
#  define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
67
#endif
68
69
/** a noop deleter used to transform a librevenge pointer in a false std::shared_ptr */
70
template <class T>
71
struct WPS_shared_ptr_noop_deleter
72
{
73
604k
  void operator()(T *) {}
WPS_shared_ptr_noop_deleter<librevenge::RVNGInputStream>::operator()(librevenge::RVNGInputStream*)
Line
Count
Source
73
158k
  void operator()(T *) {}
WPS_shared_ptr_noop_deleter<WKSContentListener>::operator()(WKSContentListener*)
Line
Count
Source
73
111k
  void operator()(T *) {}
WPS_shared_ptr_noop_deleter<WPSContentListener>::operator()(WPSContentListener*)
Line
Count
Source
73
334k
  void operator()(T *) {}
74
};
75
76
/** fall through attributes */
77
#if defined(HAVE_CLANG_ATTRIBUTE_FALLTHROUGH)
78
347k
#  define WPS_FALLTHROUGH [[clang::fallthrough]]
79
#elif defined(HAVE_GCC_ATTRIBUTE_FALLTHROUGH)
80
#  define WPS_FALLTHROUGH __attribute__((fallthrough))
81
#else
82
#  define WPS_FALLTHROUGH ((void) 0)
83
#endif
84
85
// basic classes and autoptr
86
/** shared pointer to librevenge::RVNGInputStream */
87
typedef std::shared_ptr<librevenge::RVNGInputStream> RVNGInputStreamPtr;
88
89
struct WPSStream;
90
class WPSCell;
91
class WPSListener;
92
class WPSContentListener;
93
class WPSEntry;
94
class WPSFont;
95
class WPSHeader;
96
class WPSPosition;
97
class WPSSubDocument;
98
99
class WKSContentListener;
100
class WKSSubDocument;
101
102
/** shared pointer to WPSCell */
103
typedef std::shared_ptr<WPSCell> WPSCellPtr;
104
/** shared pointer to WPSListener */
105
typedef std::shared_ptr<WPSListener> WPSListenerPtr;
106
/** shared pointer to WPSContentListener */
107
typedef std::shared_ptr<WPSContentListener> WPSContentListenerPtr;
108
/** shared pointer to WPSHeader */
109
typedef std::shared_ptr<WPSHeader> WPSHeaderPtr;
110
/** shared pointer to WPSSubDocument */
111
typedef std::shared_ptr<WPSSubDocument> WPSSubDocumentPtr;
112
113
/** shared pointer to WKSContentListener */
114
typedef std::shared_ptr<WKSContentListener> WKSContentListenerPtr;
115
/** shared pointer to WKSSubDocument */
116
typedef std::shared_ptr<WKSSubDocument> WKSSubDocumentPtr;
117
118
#if defined(HAVE_FUNC_ATTRIBUTE_FORMAT)
119
#  define WPS_ATTRIBUTE_PRINTF(fmt, arg) __attribute__((format(printf, fmt, arg)))
120
#else
121
#  define WPS_ATTRIBUTE_PRINTF(fmt, arg)
122
#endif
123
124
2.46M
#define WPS_N_ELEMENTS(m) sizeof(m)/sizeof(m[0])
125
126
/* ---------- debug  --------------- */
127
#ifdef DEBUG
128
namespace libwps
129
{
130
void printDebugMsg(const char *format, ...) WPS_ATTRIBUTE_PRINTF(1, 2);
131
}
132
#define WPS_DEBUG_MSG(M) libwps::printDebugMsg M
133
#else
134
#define WPS_DEBUG_MSG(M)
135
#endif
136
137
/* ---------- exception  ------------ */
138
namespace libwps
139
{
140
// Various exceptions
141
class VersionException
142
{
143
  // needless to say, we could flesh this class out a bit
144
};
145
146
class FileException
147
{
148
  // needless to say, we could flesh this class out a bit
149
};
150
151
class ParseException
152
{
153
  // needless to say, we could flesh this class out a bit
154
};
155
156
class PasswordException
157
{
158
  // needless to say, we could flesh this class out a bit
159
};
160
161
class GenericException
162
{
163
  // needless to say, we could flesh this class out a bit
164
};
165
}
166
167
/* ---------- input ----------------- */
168
namespace libwps
169
{
170
uint8_t readU8(librevenge::RVNGInputStream *input);
171
uint16_t readU16(librevenge::RVNGInputStream *input);
172
uint32_t readU32(librevenge::RVNGInputStream *input);
173
174
int8_t read8(librevenge::RVNGInputStream *input);
175
int16_t read16(librevenge::RVNGInputStream *input);
176
int32_t read32(librevenge::RVNGInputStream *input);
177
178
inline uint8_t readU8(RVNGInputStreamPtr const &input)
179
2.70G
{
180
2.70G
  return readU8(input.get());
181
2.70G
}
182
inline uint16_t readU16(RVNGInputStreamPtr const &input)
183
284M
{
184
284M
  return readU16(input.get());
185
284M
}
186
inline uint32_t readU32(RVNGInputStreamPtr const &input)
187
125M
{
188
125M
  return readU32(input.get());
189
125M
}
190
191
inline int8_t read8(RVNGInputStreamPtr const &input)
192
17.5M
{
193
17.5M
  return read8(input.get());
194
17.5M
}
195
inline int16_t read16(RVNGInputStreamPtr const &input)
196
135M
{
197
135M
  return read16(input.get());
198
135M
}
199
inline int32_t read32(RVNGInputStreamPtr const &input)
200
11.1M
{
201
11.1M
  return read32(input.get());
202
11.1M
}
203
204
//! read a double store with 4 bytes: mantisse 2.5 bytes, exponent 1.5 bytes
205
bool readDouble4(RVNGInputStreamPtr &input, double &res, bool &isNaN);
206
//! read a double store with 8 bytes: mantisse 6.5 bytes, exponent 1.5 bytes
207
bool readDouble8(RVNGInputStreamPtr &input, long double &res, bool &isNaN);
208
//! read a double store with 10 bytes: mantisse 8 bytes, exponent 2 bytes
209
bool readDouble10(RVNGInputStreamPtr &input, long double &res, bool &isNaN);
210
//! read a double store with 2 bytes: exponent 1.5 bytes, kind of mantisse 0.5 bytes
211
bool readDouble2Inv(RVNGInputStreamPtr &input, double &res, bool &isNaN);
212
//! read a double store with 4 bytes: exponent 3.5 bytes, mantisse 0.5 bytes
213
bool readDouble4Inv(RVNGInputStreamPtr &input, double &res, bool &isNaN);
214
215
//! try to read sz bytes from input and store them in a librevenge::RVNGBinaryData
216
bool readData(RVNGInputStreamPtr &input, unsigned long sz, librevenge::RVNGBinaryData &data);
217
//! try to read the last bytes from input and store them in a librevenge::RVNGBinaryData
218
bool readDataToEnd(RVNGInputStreamPtr &input, librevenge::RVNGBinaryData &data);
219
//! adds an unicode character to a string ( with correct encoding ).
220
void appendUnicode(uint32_t val, librevenge::RVNGString &buffer);
221
}
222
223
#define WPS_LE_GET_GUINT16(p)                     \
224
107k
        uint16_t(((reinterpret_cast<uint8_t const *>(p))[0] << 0)  |  \
225
107k
                  ((reinterpret_cast<uint8_t const *>(p))[1] << 8))
226
#define WPS_LE_GET_GUINT32(p)               \
227
0
  uint32_t(((reinterpret_cast<uint8_t const *>(p))[0] << 0) |     \
228
0
                  ((reinterpret_cast<uint8_t const *>(p))[1] << 8)  | \
229
0
                  ((reinterpret_cast<uint8_t const *>(p))[2] << 16) | \
230
0
                  ((reinterpret_cast<uint8_t const *>(p))[3] << 24))
231
232
#define WPS_LE_PUT_GUINT16(p, v)                    \
233
14.8k
  *(reinterpret_cast<uint8_t*>(p)) = uint8_t(v);              \
234
14.8k
  *((reinterpret_cast<uint8_t*>(p)) + 1) = uint8_t((v) >> 8)
235
236
#define WPS_LE_PUT_GUINT32(p, v)                    \
237
  *(reinterpret_cast<uint8_t*>(p)) = uint8_t(v);              \
238
  *((reinterpret_cast<uint8_t*>(p)) + 1) = uint8_t((v) >> 8);     \
239
  *((reinterpret_cast<uint8_t*>(p)) + 2) = uint8_t((v) >> 16);    \
240
  *((reinterpret_cast<uint8_t*>(p)) + 3) = uint8_t((v) >> 24)
241
242
// Various helper structures for the parser..
243
/* ---------- small enum/class ------------- */
244
namespace libwps
245
{
246
enum NumberingType { NONE, BULLET, ARABIC, LOWERCASE, UPPERCASE, LOWERCASE_ROMAN, UPPERCASE_ROMAN };
247
std::string numberingTypeToString(NumberingType type);
248
enum SubDocumentType { DOC_NONE, DOC_HEADER_FOOTER, DOC_NOTE, DOC_TABLE, DOC_TEXT_BOX, DOC_COMMENT_ANNOTATION, DOC_CHART_ZONE };
249
enum Justification { JustificationLeft, JustificationFull, JustificationCenter,
250
                     JustificationRight, JustificationFullAllLines
251
                   };
252
enum { NoBreakBit = 0x1, NoBreakWithNextBit=0x2};
253
}
254
255
struct WPSColumnDefinition
256
{
257
  WPSColumnDefinition()
258
602k
    : m_width(0)
259
602k
    , m_leftGutter(0)
260
602k
    , m_rightGutter(0)
261
602k
  {
262
602k
  }
263
  double m_width;
264
  double m_leftGutter;
265
  double m_rightGutter;
266
};
267
268
struct WPSColumnProperties
269
{
270
  WPSColumnProperties()
271
    : m_attributes(0)
272
    , m_alignment(0)
273
0
  {
274
0
  }
275
  uint32_t m_attributes;
276
  uint8_t m_alignment;
277
};
278
279
//! the class to store a color
280
struct WPSColor
281
{
282
  //! constructor
283
18.7M
  explicit WPSColor(uint32_t argb=0) : m_value(argb)
284
18.7M
  {
285
18.7M
  }
286
  //! constructor from color
287
  WPSColor(unsigned char r, unsigned char g,  unsigned char b, unsigned char a=255) :
288
889M
    m_value(uint32_t((a<<24)+(r<<16)+(g<<8)+b))
289
889M
  {
290
889M
  }
291
  //! copy constructor
292
  WPSColor(WPSColor const &) = default;
293
  //! move assignement
294
  WPSColor(WPSColor &&) = default;
295
  //! operator=
296
  WPSColor &operator=(uint32_t argb)
297
0
  {
298
0
    m_value = argb;
299
0
    return *this;
300
0
  }
301
  //! operator=
302
  WPSColor &operator=(WPSColor const &) = default;
303
  //! move operator=
304
  WPSColor &operator=(WPSColor &&) = default;
305
  //! return the back color
306
  static WPSColor black()
307
452M
  {
308
452M
    return WPSColor(0,0,0);
309
452M
  }
310
  //! return the white color
311
  static WPSColor white()
312
434M
  {
313
434M
    return WPSColor(255,255,255);
314
434M
  }
315
316
  //! return alpha*colA+beta*colB
317
  static WPSColor barycenter(float alpha, WPSColor const &colA,
318
                             float beta, WPSColor const &colB);
319
  //! return the rgba value
320
  uint32_t value() const
321
2.49M
  {
322
2.49M
    return m_value;
323
2.49M
  }
324
  //! returns the alpha value
325
  unsigned char getAlpha() const
326
0
  {
327
0
    return static_cast<unsigned char>((m_value>>24)&0xFF);
328
0
  }
329
  //! returns the green value
330
  unsigned char getBlue() const
331
686
  {
332
686
    return static_cast<unsigned char>(m_value&0xFF);
333
686
  }
334
  //! returns the red value
335
  unsigned char getRed() const
336
686
  {
337
686
    return static_cast<unsigned char>((m_value>>16)&0xFF);
338
686
  }
339
  //! returns the green value
340
  unsigned char getGreen() const
341
686
  {
342
686
    return static_cast<unsigned char>((m_value>>8)&0xFF);
343
686
  }
344
  //! return true if the color is black
345
  bool isBlack() const
346
4.21M
  {
347
4.21M
    return (m_value&0xFFFFFF)==0;
348
4.21M
  }
349
  //! return true if the color is white
350
  bool isWhite() const
351
9.96M
  {
352
9.96M
    return (m_value&0xFFFFFF)==0xFFFFFF;
353
9.96M
  }
354
  //! operator==
355
  bool operator==(WPSColor const &c) const
356
8.39M
  {
357
8.39M
    return (c.m_value&0xFFFFFF)==(m_value&0xFFFFFF);
358
8.39M
  }
359
  //! operator!=
360
  bool operator!=(WPSColor const &c) const
361
7.97M
  {
362
7.97M
    return !operator==(c);
363
7.97M
  }
364
  //! operator<
365
  bool operator<(WPSColor const &c) const
366
389k
  {
367
389k
    return (c.m_value&0xFFFFFF)<(m_value&0xFFFFFF);
368
389k
  }
369
  //! operator<=
370
  bool operator<=(WPSColor const &c) const
371
386k
  {
372
386k
    return (c.m_value&0xFFFFFF)<=(m_value&0xFFFFFF);
373
386k
  }
374
  //! operator>
375
  bool operator>(WPSColor const &c) const
376
386k
  {
377
386k
    return !operator<=(c);
378
386k
  }
379
  //! operator>=
380
  bool operator>=(WPSColor const &c) const
381
0
  {
382
0
    return !operator<(c);
383
0
  }
384
  //! operator<< in the form \#rrggbb
385
  friend std::ostream &operator<< (std::ostream &o, WPSColor const &c);
386
  //! print the color in the form \#rrggbb
387
  std::string str() const;
388
protected:
389
  //! the argb color
390
  uint32_t m_value;
391
};
392
393
//! a border list
394
struct WPSBorder
395
{
396
  /** the line style */
397
  enum Style { None, Simple, Dot, LargeDot, Dash };
398
  /** the line repetition */
399
  enum Type { Single, Double, Triple };
400
  enum Pos { Left = 0, Right = 1, Top = 2, Bottom = 3 };
401
  enum { LeftBit = 0x01,  RightBit = 0x02, TopBit=0x4, BottomBit = 0x08 };
402
403
  //! constructor
404
  WPSBorder()
405
8.38M
    : m_style(Simple)
406
8.38M
    , m_type(Single)
407
8.38M
    , m_width(1)
408
8.38M
    , m_widthsList()
409
8.38M
    , m_color(WPSColor::black())
410
8.38M
    , m_extra("") { }
411
412
15.4M
  WPSBorder(WPSBorder const &) = default;
413
468k
  WPSBorder(WPSBorder &&) = default;
414
3.01M
  WPSBorder &operator=(WPSBorder const &) = default;
415
  WPSBorder &operator=(WPSBorder &&) = default;
416
417
  /** add the border property to proplist (if needed )
418
419
    \note if set which must be equal to "left", "top", ... */
420
  bool addTo(librevenge::RVNGPropertyList &propList, std::string which="") const;
421
  //! returns true if the border is empty
422
  bool isEmpty() const
423
1.82M
  {
424
1.82M
    return m_style==None || m_width <= 0;
425
1.82M
  }
426
427
  //! operator==
428
  bool operator==(WPSBorder const &orig) const
429
54.0k
  {
430
54.0k
    return m_style == orig.m_style && m_type == orig.m_type && m_width == orig.m_width
431
37.3k
      && m_color == orig.m_color && m_widthsList==orig.m_widthsList;
432
54.0k
  }
433
  //! operator!=
434
  bool operator!=(WPSBorder const &orig) const
435
54.0k
  {
436
54.0k
    return !operator==(orig);
437
54.0k
  }
438
  //! compare two cell
439
  int compare(WPSBorder const &orig) const;
440
441
  //! operator<<
442
  friend std::ostream &operator<< (std::ostream &o, WPSBorder const &border);
443
  //! operator<<: prints data in form "none|dot|..."
444
  friend std::ostream &operator<< (std::ostream &o, WPSBorder::Style const &style);
445
  //! the border style
446
  Style m_style;
447
  //! the border repetition
448
  Type m_type;
449
  //! the border width
450
  int m_width;
451
  /** the different length used for each line/sep (if defined)
452
453
    \note when defined, the size of this list must be equal to 2*Type-1*/
454
  std::vector<double> m_widthsList;
455
  //! the border color
456
  WPSColor m_color;
457
  //! extra data ( if needed)
458
  std::string m_extra;
459
};
460
461
//! a field
462
struct WPSField
463
{
464
  /** Defines some basic type for field */
465
  enum Type { None, Database, Date, Link, PageCount, PageNumber, PageNumberNext, Time, Title };
466
467
  /** basic constructor */
468
  explicit WPSField(Type type)
469
407k
    : m_type(type)
470
407k
    , m_DTFormat("")
471
407k
    , m_numberingType(libwps::ARABIC)
472
407k
    , m_data("")
473
407k
  {
474
407k
  }
475
  WPSField(WPSField &&) = default;
476
  WPSField(WPSField const &) = default;
477
  WPSField &operator=(WPSField const &) = default;
478
  WPSField &operator=(WPSField &&) = default;
479
  /** add the link property to proplist (if possible) */
480
  bool addTo(librevenge::RVNGPropertyList &propList) const;
481
  //! returns a string corresponding to the field (if possible) */
482
  librevenge::RVNGString getString() const;
483
  //! the type
484
  Type m_type;
485
  //! the date/time format using strftime format if defined (see strftime)
486
  std::string m_DTFormat;
487
  //! the number type ( for number field )
488
  libwps::NumberingType m_numberingType;
489
  //! the database/link field ( if defined )
490
  std::string m_data;
491
};
492
493
// ATTRIBUTE bits
494
#define WPS_EXTRA_LARGE_BIT 1
495
#define WPS_VERY_LARGE_BIT 2
496
0
#define WPS_LARGE_BIT 4
497
0
#define WPS_SMALL_PRINT_BIT 8
498
#define WPS_FINE_PRINT_BIT 0x10
499
9.88M
#define WPS_SUPERSCRIPT_BIT 0x20
500
9.84M
#define WPS_SUBSCRIPT_BIT 0x40
501
9.25M
#define WPS_OUTLINE_BIT 0x80
502
9.46M
#define WPS_ITALICS_BIT 0x100
503
9.28M
#define WPS_SHADOW_BIT 0x200
504
#define WPS_REDLINE_BIT 0x400
505
9.30M
#define WPS_DOUBLE_UNDERLINE_BIT 0x800
506
9.47M
#define WPS_BOLD_BIT 0x1000
507
9.32M
#define WPS_STRIKEOUT_BIT 0x2000
508
9.61M
#define WPS_UNDERLINE_BIT 0x4000
509
9.26M
#define WPS_SMALL_CAPS_BIT 0x8000
510
9.23M
#define WPS_BLINK_BIT 0x10000L
511
3.14k
#define WPS_REVERSEVIDEO_BIT 0x20000L
512
9.24M
#define WPS_ALL_CAPS_BIT 0x40000L
513
9.25M
#define WPS_EMBOSS_BIT 0x80000L
514
9.24M
#define WPS_ENGRAVE_BIT 0x100000L
515
9.44M
#define WPS_OVERLINE_BIT 0x400000L
516
9.24M
#define WPS_HIDDEN_BIT 0x800000L
517
518
// BREAK bits
519
981k
#define WPS_PAGE_BREAK 0x00
520
245k
#define WPS_SOFT_PAGE_BREAK 0x01
521
65.4k
#define WPS_COLUMN_BREAK 0x02
522
523
// Generic bits
524
#define WPS_LEFT 0x00
525
#define WPS_RIGHT 0x01
526
#define WPS_CENTER 0x02
527
#define WPS_TOP 0x03
528
#define WPS_BOTTOM 0x04
529
530
/* ---------- vec2/box2f ------------- */
531
/*! \class Vec2
532
 *   \brief small class which defines a vector with 2 elements
533
 */
534
template <class T> class Vec2
535
{
536
public:
537
  //! constructor
538
527M
  explicit Vec2(T xx=0,T yy=0) : m_x(xx), m_y(yy) { }
Vec2<float>::Vec2(float, float)
Line
Count
Source
538
82.6M
  explicit Vec2(T xx=0,T yy=0) : m_x(xx), m_y(yy) { }
Vec2<int>::Vec2(int, int)
Line
Count
Source
538
437M
  explicit Vec2(T xx=0,T yy=0) : m_x(xx), m_y(yy) { }
Vec2<bool>::Vec2(bool, bool)
Line
Count
Source
538
6.90M
  explicit Vec2(T xx=0,T yy=0) : m_x(xx), m_y(yy) { }
539
  //! generic copy constructor
540
327k
  template <class U> explicit Vec2(Vec2<U> const &p) : m_x(T(p.x())), m_y(T(p.y())) {}
541
  //! first element
542
  T x() const
543
840k
  {
544
840k
    return m_x;
545
840k
  }
Vec2<int>::x() const
Line
Count
Source
543
327k
  {
544
327k
    return m_x;
545
327k
  }
Vec2<float>::x() const
Line
Count
Source
543
513k
  {
544
513k
    return m_x;
545
513k
  }
546
  //! second element
547
  T y() const
548
628k
  {
549
628k
    return m_y;
550
628k
  }
Vec2<int>::y() const
Line
Count
Source
548
327k
  {
549
327k
    return m_y;
550
327k
  }
Vec2<float>::y() const
Line
Count
Source
548
301k
  {
549
301k
    return m_y;
550
301k
  }
551
  //! operator[]
552
  T operator[](int c) const
553
10.5G
  {
554
10.5G
    if (c<0 || c>1) throw libwps::GenericException();
555
10.5G
    return (c==0) ? m_x : m_y;
556
10.5G
  }
Vec2<float>::operator[](int) const
Line
Count
Source
553
11.6M
  {
554
11.6M
    if (c<0 || c>1) throw libwps::GenericException();
555
11.6M
    return (c==0) ? m_x : m_y;
556
11.6M
  }
Vec2<int>::operator[](int) const
Line
Count
Source
553
10.5G
  {
554
10.5G
    if (c<0 || c>1) throw libwps::GenericException();
555
10.5G
    return (c==0) ? m_x : m_y;
556
10.5G
  }
Vec2<bool>::operator[](int) const
Line
Count
Source
553
363k
  {
554
363k
    if (c<0 || c>1) throw libwps::GenericException();
555
363k
    return (c==0) ? m_x : m_y;
556
363k
  }
557
  //! operator[]
558
  T &operator[](int c)
559
28.0M
  {
560
28.0M
    if (c<0 || c>1) throw libwps::GenericException();
561
28.0M
    return (c==0) ? m_x : m_y;
562
28.0M
  }
Vec2<float>::operator[](int)
Line
Count
Source
559
5.78M
  {
560
5.78M
    if (c<0 || c>1) throw libwps::GenericException();
561
5.78M
    return (c==0) ? m_x : m_y;
562
5.78M
  }
Vec2<int>::operator[](int)
Line
Count
Source
559
22.1M
  {
560
22.1M
    if (c<0 || c>1) throw libwps::GenericException();
561
22.1M
    return (c==0) ? m_x : m_y;
562
22.1M
  }
Vec2<bool>::operator[](int)
Line
Count
Source
559
44.2k
  {
560
44.2k
    if (c<0 || c>1) throw libwps::GenericException();
561
44.2k
    return (c==0) ? m_x : m_y;
562
44.2k
  }
563
564
  //! resets the two elements
565
  void set(T xx, T yy)
566
0
  {
567
0
    m_x = xx;
568
0
    m_y = yy;
569
0
  }
570
  //! resets the first element
571
  void setX(T xx)
572
302k
  {
573
302k
    m_x = xx;
574
302k
  }
575
  //! resets the second element
576
  void setY(T yy)
577
433k
  {
578
433k
    m_y = yy;
579
433k
  }
580
581
  //! increases the actuals values by \a dx and \a dy
582
  void add(T dx, T dy)
583
  {
584
    m_x += dx;
585
    m_y += dy;
586
  }
587
588
  //! operator+=
589
  Vec2<T> &operator+=(Vec2<T> const &p)
590
3.10M
  {
591
3.10M
    m_x += p.m_x;
592
3.10M
    m_y += p.m_y;
593
3.10M
    return *this;
594
3.10M
  }
Vec2<float>::operator+=(Vec2<float> const&)
Line
Count
Source
590
3.05M
  {
591
3.05M
    m_x += p.m_x;
592
3.05M
    m_y += p.m_y;
593
3.05M
    return *this;
594
3.05M
  }
Vec2<int>::operator+=(Vec2<int> const&)
Line
Count
Source
590
47.7k
  {
591
47.7k
    m_x += p.m_x;
592
47.7k
    m_y += p.m_y;
593
47.7k
    return *this;
594
47.7k
  }
595
  //! operator-=
596
  Vec2<T> &operator-=(Vec2<T> const &p)
597
1.80M
  {
598
1.80M
    m_x -= p.m_x;
599
1.80M
    m_y -= p.m_y;
600
1.80M
    return *this;
601
1.80M
  }
Vec2<float>::operator-=(Vec2<float> const&)
Line
Count
Source
597
1.49M
  {
598
1.49M
    m_x -= p.m_x;
599
1.49M
    m_y -= p.m_y;
600
1.49M
    return *this;
601
1.49M
  }
Vec2<int>::operator-=(Vec2<int> const&)
Line
Count
Source
597
310k
  {
598
310k
    m_x -= p.m_x;
599
310k
    m_y -= p.m_y;
600
310k
    return *this;
601
310k
  }
602
  //! generic operator*=
603
  template <class U>
604
  Vec2<T> &operator*=(U scale)
605
412k
  {
606
412k
    m_x = m_x*T(scale);
607
412k
    m_y = m_y*T(scale);
608
412k
    return *this;
609
412k
  }
Vec2<float>& Vec2<float>::operator*=<float>(float)
Line
Count
Source
605
296k
  {
606
296k
    m_x = m_x*T(scale);
607
296k
    m_y = m_y*T(scale);
608
296k
    return *this;
609
296k
  }
Vec2<float>& Vec2<float>::operator*=<double>(double)
Line
Count
Source
605
115k
  {
606
115k
    m_x = m_x*T(scale);
607
115k
    m_y = m_y*T(scale);
608
115k
    return *this;
609
115k
  }
610
611
  //! operator+
612
  friend Vec2<T> operator+(Vec2<T> const &p1, Vec2<T> const &p2)
613
1.16M
  {
614
1.16M
    Vec2<T> p(p1);
615
1.16M
    return p+=p2;
616
1.16M
  }
operator+(Vec2<float> const&, Vec2<float> const&)
Line
Count
Source
613
1.12M
  {
614
1.12M
    Vec2<T> p(p1);
615
1.12M
    return p+=p2;
616
1.12M
  }
operator+(Vec2<int> const&, Vec2<int> const&)
Line
Count
Source
613
44.7k
  {
614
44.7k
    Vec2<T> p(p1);
615
44.7k
    return p+=p2;
616
44.7k
  }
617
  //! operator-
618
  friend Vec2<T> operator-(Vec2<T> const &p1, Vec2<T> const &p2)
619
1.80M
  {
620
1.80M
    Vec2<T> p(p1);
621
1.80M
    return p-=p2;
622
1.80M
  }
operator-(Vec2<float> const&, Vec2<float> const&)
Line
Count
Source
619
1.49M
  {
620
1.49M
    Vec2<T> p(p1);
621
1.49M
    return p-=p2;
622
1.49M
  }
operator-(Vec2<int> const&, Vec2<int> const&)
Line
Count
Source
619
310k
  {
620
310k
    Vec2<T> p(p1);
621
310k
    return p-=p2;
622
310k
  }
623
  //! generic operator*
624
  template <class U>
625
  friend Vec2<T> operator*(U scale, Vec2<T> const &p1)
626
412k
  {
627
412k
    Vec2<T> p(p1);
628
412k
    return p *= scale;
629
412k
  }
Vec2<float> operator*<float>(float, Vec2<float> const&)
Line
Count
Source
626
296k
  {
627
296k
    Vec2<T> p(p1);
628
296k
    return p *= scale;
629
296k
  }
Vec2<float> operator*<double>(double, Vec2<float> const&)
Line
Count
Source
626
115k
  {
627
115k
    Vec2<T> p(p1);
628
115k
    return p *= scale;
629
115k
  }
630
631
  //! comparison==
632
  bool operator==(Vec2<T> const &p) const
633
2.41M
  {
634
2.41M
    return cmpY(p) == 0;
635
2.41M
  }
Vec2<int>::operator==(Vec2<int> const&) const
Line
Count
Source
633
2.32M
  {
634
2.32M
    return cmpY(p) == 0;
635
2.32M
  }
Vec2<float>::operator==(Vec2<float> const&) const
Line
Count
Source
633
89.1k
  {
634
89.1k
    return cmpY(p) == 0;
635
89.1k
  }
636
  //! comparison!=
637
  bool operator!=(Vec2<T> const &p) const
638
907k
  {
639
907k
    return cmpY(p) != 0;
640
907k
  }
Vec2<float>::operator!=(Vec2<float> const&) const
Line
Count
Source
638
24.0k
  {
639
24.0k
    return cmpY(p) != 0;
640
24.0k
  }
Vec2<int>::operator!=(Vec2<int> const&) const
Line
Count
Source
638
883k
  {
639
883k
    return cmpY(p) != 0;
640
883k
  }
641
  //! comparison<: sort by y
642
  bool operator<(Vec2<T> const &p) const
643
3.56G
  {
644
3.56G
    return cmpY(p) < 0;
645
3.56G
  }
646
  //! a comparison function: which first compares x then y
647
  int cmp(Vec2<T> const &p) const
648
0
  {
649
0
    if (m_x<p.m_x) return -1;
650
0
    if (m_x>p.m_x) return 1;
651
0
    if (m_y<p.m_y) return -1;
652
0
    if (m_y>p.m_y) return 1;
653
0
    return 0;
654
0
  }
Unexecuted instantiation: Vec2<int>::cmp(Vec2<int> const&) const
Unexecuted instantiation: Vec2<float>::cmp(Vec2<float> const&) const
655
  //! a comparison function: which first compares y then x
656
  int cmpY(Vec2<T> const &p) const
657
3.57G
  {
658
3.57G
    if (m_y<p.m_y) return -1;
659
1.48G
    if (m_y>p.m_y) return 1;
660
695M
    if (m_x<p.m_x) return -1;
661
681M
    if (m_x>p.m_x) return 1;
662
671M
    return 0;
663
681M
  }
Vec2<float>::cmpY(Vec2<float> const&) const
Line
Count
Source
657
286k
  {
658
286k
    if (m_y<p.m_y) return -1;
659
271k
    if (m_y>p.m_y) return 1;
660
222k
    if (m_x<p.m_x) return -1;
661
215k
    if (m_x>p.m_x) return 1;
662
210k
    return 0;
663
215k
  }
Vec2<int>::cmpY(Vec2<int> const&) const
Line
Count
Source
657
3.56G
  {
658
3.56G
    if (m_y<p.m_y) return -1;
659
1.48G
    if (m_y>p.m_y) return 1;
660
694M
    if (m_x<p.m_x) return -1;
661
680M
    if (m_x>p.m_x) return 1;
662
670M
    return 0;
663
680M
  }
664
665
  //! operator<<: prints data in form "XxY"
666
  friend std::ostream &operator<< (std::ostream &o, Vec2<T> const &f)
667
0
  {
668
0
    o << f.m_x << "x" << f.m_y;
669
0
    return o;
670
0
  }
Unexecuted instantiation: operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Vec2<int> const&)
Unexecuted instantiation: operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Vec2<float> const&)
671
672
  /*! \struct PosSizeLtX
673
   * \brief internal struct used to create sorted map, sorted by X
674
   */
675
  struct PosSizeLtX
676
  {
677
    //! comparaison function
678
    bool operator()(Vec2<T> const &s1, Vec2<T> const &s2) const
679
    {
680
      return s1.cmp(s2) < 0;
681
    }
682
  };
683
684
  /*! \struct PosSizeLtY
685
   * \brief internal struct used to create sorted map, sorted by Y
686
   */
687
  struct PosSizeLtY
688
  {
689
    //! comparaison function
690
    bool operator()(Vec2<T> const &s1, Vec2<T> const &s2) const
691
    {
692
      return s1.cmpY(s2) < 0;
693
    }
694
  };
695
protected:
696
  T m_x/*! \brief first element */, m_y/*! \brief second element */;
697
};
698
699
/*! \brief Vec2 of bool */
700
typedef Vec2<bool> Vec2b;
701
/*! \brief Vec2 of int */
702
typedef Vec2<int> Vec2i;
703
/*! \brief Vec2 of float */
704
typedef Vec2<float> Vec2f;
705
706
/*! \class WPSBox2
707
 *   \brief small class which defines a 2D WPSBox
708
 */
709
template <class T> class WPSBox2
710
{
711
public:
712
  //! constructor
713
  explicit WPSBox2(Vec2<T> minPt=Vec2<T>(), Vec2<T> maxPt=Vec2<T>())
714
16.9M
  {
715
16.9M
    m_pt[0] = minPt;
716
16.9M
    m_pt[1] = maxPt;
717
16.9M
  }
WPSBox2<float>::WPSBox2(Vec2<float>, Vec2<float>)
Line
Count
Source
714
15.4M
  {
715
15.4M
    m_pt[0] = minPt;
716
15.4M
    m_pt[1] = maxPt;
717
15.4M
  }
WPSBox2<int>::WPSBox2(Vec2<int>, Vec2<int>)
Line
Count
Source
714
1.43M
  {
715
1.43M
    m_pt[0] = minPt;
716
1.43M
    m_pt[1] = maxPt;
717
1.43M
  }
718
  //! generic constructor
719
  template <class U> explicit WPSBox2(WPSBox2<U> const &p)
720
8.37k
  {
721
25.1k
    for (int c=0; c < 2; c++) m_pt[c] = Vec2<T>(p[c]);
722
8.37k
  }
723
724
  //! the minimum 2D point (in x and in y)
725
  Vec2<T> const &min() const
726
13.9k
  {
727
13.9k
    return m_pt[0];
728
13.9k
  }
729
  //! the maximum 2D point (in x and in y)
730
  Vec2<T> const &max() const
731
11.8k
  {
732
11.8k
    return m_pt[1];
733
11.8k
  }
734
  //! the minimum 2D point (in x and in y)
735
  Vec2<T> &min()
736
246k
  {
737
246k
    return m_pt[0];
738
246k
  }
739
  //! the maximum 2D point (in x and in y)
740
  Vec2<T> &max()
741
246k
  {
742
246k
    return m_pt[1];
743
246k
  }
744
745
  /*! \brief the two extremum points which defined the box
746
   * \param c value 0 means the minimum, value 1 means the maximum
747
   */
748
  Vec2<T> const &operator[](int c) const
749
10.0G
  {
750
10.0G
    if (c<0 || c>1) throw libwps::GenericException();
751
10.0G
    return m_pt[c];
752
10.0G
  }
WPSBox2<int>::operator[](int) const
Line
Count
Source
749
10.0G
  {
750
10.0G
    if (c<0 || c>1) throw libwps::GenericException();
751
10.0G
    return m_pt[c];
752
10.0G
  }
WPSBox2<float>::operator[](int) const
Line
Count
Source
749
1.32M
  {
750
1.32M
    if (c<0 || c>1) throw libwps::GenericException();
751
1.32M
    return m_pt[c];
752
1.32M
  }
753
  //! the box size
754
  Vec2<T> size() const
755
1.30M
  {
756
1.30M
    return m_pt[1]-m_pt[0];
757
1.30M
  }
WPSBox2<float>::size() const
Line
Count
Source
755
1.25M
  {
756
1.25M
    return m_pt[1]-m_pt[0];
757
1.25M
  }
WPSBox2<int>::size() const
Line
Count
Source
755
50.3k
  {
756
50.3k
    return m_pt[1]-m_pt[0];
757
50.3k
  }
758
  //! the box center
759
  Vec2<T> center() const
760
46.0k
  {
761
46.0k
    return 0.5*(m_pt[0]+m_pt[1]);
762
46.0k
  }
763
764
  //! resets the data to minimum \a x and maximum \a y
765
  void set(Vec2<T> const &x, Vec2<T> const &y)
766
  {
767
    m_pt[0] = x;
768
    m_pt[1] = y;
769
  }
770
  //! resets the minimum point
771
  void setMin(Vec2<T> const &x)
772
57.3k
  {
773
57.3k
    m_pt[0] = x;
774
57.3k
  }
WPSBox2<float>::setMin(Vec2<float> const&)
Line
Count
Source
772
46.6k
  {
773
46.6k
    m_pt[0] = x;
774
46.6k
  }
WPSBox2<int>::setMin(Vec2<int> const&)
Line
Count
Source
772
10.7k
  {
773
10.7k
    m_pt[0] = x;
774
10.7k
  }
775
  //! resets the maximum point
776
  void setMax(Vec2<T> const &y)
777
55.5k
  {
778
55.5k
    m_pt[1] = y;
779
55.5k
  }
WPSBox2<float>::setMax(Vec2<float> const&)
Line
Count
Source
777
44.7k
  {
778
44.7k
    m_pt[1] = y;
779
44.7k
  }
WPSBox2<int>::setMax(Vec2<int> const&)
Line
Count
Source
777
10.7k
  {
778
10.7k
    m_pt[1] = y;
779
10.7k
  }
780
781
  //!  resize the box keeping the minimum
782
  void resizeFromMin(Vec2<T> const &sz)
783
  {
784
    m_pt[1] = m_pt[0]+sz;
785
  }
786
  //!  resize the box keeping the maximum
787
  void resizeFromMax(Vec2<T> const &sz)
788
  {
789
    m_pt[0] = m_pt[1]-sz;
790
  }
791
  //!  resize the box keeping the center
792
  void resizeFromCenter(Vec2<T> const &sz)
793
  {
794
    Vec2<T> ctr = 0.5*(m_pt[0]+m_pt[1]);
795
    m_pt[0] = ctr - 0.5*sz;
796
    m_pt[1] = ctr + (sz - 0.5*sz);
797
  }
798
799
  //! scales all points of the box by \a factor
800
  template <class U> void scale(U factor)
801
  {
802
    m_pt[0] *= factor;
803
    m_pt[1] *= factor;
804
  }
805
806
  //! extends the bdbox by (\a val, \a val) keeping the center
807
  void extend(T val)
808
  {
809
    m_pt[0] -= Vec2<T>(val/2,val/2);
810
    m_pt[1] += Vec2<T>(val-(val/2),val-(val/2));
811
  }
812
  //! returns the union between this and box
813
  WPSBox2<T> getUnion(WPSBox2<T> const &box) const
814
321k
  {
815
321k
    WPSBox2<T> res;
816
321k
    res.m_pt[0]=Vec2<T>(m_pt[0][0]<box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
817
321k
                        m_pt[0][1]<box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
818
321k
    res.m_pt[1]=Vec2<T>(m_pt[1][0]>box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
819
321k
                        m_pt[1][1]>box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
820
321k
    return res;
821
321k
  }
822
  //! returns the intersection between this and box
823
  WPSBox2<T> getIntersection(WPSBox2<T> const &box) const
824
  {
825
    WPSBox2<T> res;
826
    res.m_pt[0]=Vec2<T>(m_pt[0][0]>box.m_pt[0][0]?m_pt[0][0] : box.m_pt[0][0],
827
                        m_pt[0][1]>box.m_pt[0][1]?m_pt[0][1] : box.m_pt[0][1]);
828
    res.m_pt[1]=Vec2<T>(m_pt[1][0]<box.m_pt[1][0]?m_pt[1][0] : box.m_pt[1][0],
829
                        m_pt[1][1]<box.m_pt[1][1]?m_pt[1][1] : box.m_pt[1][1]);
830
    return res;
831
  }
832
833
  //! comparison operator==
834
  bool operator==(WPSBox2<T> const &p) const
835
196k
  {
836
196k
    return cmp(p) == 0;
837
196k
  }
WPSBox2<int>::operator==(WPSBox2<int> const&) const
Line
Count
Source
835
109k
  {
836
109k
    return cmp(p) == 0;
837
109k
  }
WPSBox2<float>::operator==(WPSBox2<float> const&) const
Line
Count
Source
835
87.6k
  {
836
87.6k
    return cmp(p) == 0;
837
87.6k
  }
838
  //! comparison operator!=
839
  bool operator!=(WPSBox2<T> const &p) const
840
0
  {
841
0
    return cmp(p) != 0;
842
0
  }
Unexecuted instantiation: WPSBox2<int>::operator!=(WPSBox2<int> const&) const
Unexecuted instantiation: WPSBox2<float>::operator!=(WPSBox2<float> const&) const
843
  //! comparison operator< : fist sorts min by Y,X values then max extremity
844
  bool operator<(WPSBox2<T> const &p) const
845
  {
846
    return cmp(p) < 0;
847
  }
848
849
  //! comparison function : fist sorts min by Y,X values then max extremity
850
  int cmp(WPSBox2<T> const &p) const
851
196k
  {
852
196k
    int diff  = m_pt[0].cmpY(p.m_pt[0]);
853
196k
    if (diff) return diff;
854
155k
    diff  = m_pt[1].cmpY(p.m_pt[1]);
855
155k
    if (diff) return diff;
856
135k
    return 0;
857
155k
  }
WPSBox2<int>::cmp(WPSBox2<int> const&) const
Line
Count
Source
851
109k
  {
852
109k
    int diff  = m_pt[0].cmpY(p.m_pt[0]);
853
109k
    if (diff) return diff;
854
69.2k
    diff  = m_pt[1].cmpY(p.m_pt[1]);
855
69.2k
    if (diff) return diff;
856
49.7k
    return 0;
857
69.2k
  }
WPSBox2<float>::cmp(WPSBox2<float> const&) const
Line
Count
Source
851
87.6k
  {
852
87.6k
    int diff  = m_pt[0].cmpY(p.m_pt[0]);
853
87.6k
    if (diff) return diff;
854
85.7k
    diff  = m_pt[1].cmpY(p.m_pt[1]);
855
85.7k
    if (diff) return diff;
856
85.3k
    return 0;
857
85.7k
  }
858
859
  //! print data in form X0xY0<->X1xY1
860
  friend std::ostream &operator<< (std::ostream &o, WPSBox2<T> const &f)
861
0
  {
862
0
    o << "(" << f.m_pt[0] << "<->" << f.m_pt[1] << ")";
863
0
    return o;
864
0
  }
Unexecuted instantiation: operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, WPSBox2<int> const&)
Unexecuted instantiation: operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, WPSBox2<float> const&)
865
866
  /*! \struct PosSizeLt
867
   * \brief internal struct used to create sorted map, sorted first min then max
868
   */
869
  struct PosSizeLt
870
  {
871
    //! comparaison function
872
    bool operator()(WPSBox2<T> const &s1, WPSBox2<T> const &s2) const
873
    {
874
      return s1.cmp(s2) < 0;
875
    }
876
  };
877
  /*! \typedef Map
878
   *  \brief map of WPSBox2
879
   */
880
  typedef std::map<WPSBox2<T>, T, struct PosSizeLt> Map;
881
882
protected:
883
  //! the two extremities
884
  Vec2<T> m_pt[2];
885
};
886
887
/*! \brief WPSBox2 of int */
888
typedef WPSBox2<int> WPSBox2i;
889
/*! \brief WPSBox2 of float */
890
typedef WPSBox2<float> WPSBox2f;
891
892
/*! \class WPSVec3
893
 *   \brief small class which defines a vector with 3 elements
894
 */
895
template <class T> class WPSVec3
896
{
897
public:
898
  //! constructor
899
  explicit WPSVec3(T xx=0,T yy=0,T zz=0)
900
3.05M
  {
901
3.05M
    m_val[0] = xx;
902
3.05M
    m_val[1] = yy;
903
3.05M
    m_val[2] = zz;
904
3.05M
  }
WPSVec3<float>::WPSVec3(float, float, float)
Line
Count
Source
900
996k
  {
901
996k
    m_val[0] = xx;
902
996k
    m_val[1] = yy;
903
996k
    m_val[2] = zz;
904
996k
  }
WPSVec3<int>::WPSVec3(int, int, int)
Line
Count
Source
900
2.06M
  {
901
2.06M
    m_val[0] = xx;
902
2.06M
    m_val[1] = yy;
903
2.06M
    m_val[2] = zz;
904
2.06M
  }
905
  //! generic copy constructor
906
  template <class U> explicit WPSVec3(WPSVec3<U> const &p)
907
  {
908
    for (int c = 0; c < 3; c++) m_val[c] = T(p[c]);
909
  }
910
911
  //! first element
912
  T x() const
913
  {
914
    return m_val[0];
915
  }
916
  //! second element
917
  T y() const
918
  {
919
    return m_val[1];
920
  }
921
  //! third element
922
  T z() const
923
  {
924
    return m_val[2];
925
  }
926
  //! operator[]
927
  T operator[](int c) const
928
4.24G
  {
929
4.24G
    if (c<0 || c>2) throw libwps::GenericException();
930
4.24G
    return m_val[c];
931
4.24G
  }
WPSVec3<float>::operator[](int) const
Line
Count
Source
928
6.56M
  {
929
6.56M
    if (c<0 || c>2) throw libwps::GenericException();
930
6.56M
    return m_val[c];
931
6.56M
  }
WPSVec3<int>::operator[](int) const
Line
Count
Source
928
4.23G
  {
929
4.23G
    if (c<0 || c>2) throw libwps::GenericException();
930
4.23G
    return m_val[c];
931
4.23G
  }
932
  //! operator[]
933
  T &operator[](int c)
934
6.84M
  {
935
6.84M
    if (c<0 || c>2) throw libwps::GenericException();
936
6.84M
    return m_val[c];
937
6.84M
  }
WPSVec3<float>::operator[](int)
Line
Count
Source
934
426k
  {
935
426k
    if (c<0 || c>2) throw libwps::GenericException();
936
426k
    return m_val[c];
937
426k
  }
WPSVec3<int>::operator[](int)
Line
Count
Source
934
6.41M
  {
935
6.41M
    if (c<0 || c>2) throw libwps::GenericException();
936
6.41M
    return m_val[c];
937
6.41M
  }
938
939
  //! resets the three elements
940
  void set(T xx, T yy, T zz)
941
  {
942
    m_val[0] = xx;
943
    m_val[1] = yy;
944
    m_val[2] = zz;
945
  }
946
  //! resets the first element
947
  void setX(T xx)
948
  {
949
    m_val[0] = xx;
950
  }
951
  //! resets the second element
952
  void setY(T yy)
953
  {
954
    m_val[1] = yy;
955
  }
956
  //! resets the third element
957
  void setZ(T zz)
958
  {
959
    m_val[2] = zz;
960
  }
961
962
  //! increases the actuals values by \a dx, \a dy, \a dz
963
  void add(T dx, T dy, T dz)
964
  {
965
    m_val[0] += dx;
966
    m_val[1] += dy;
967
    m_val[2] += dz;
968
  }
969
970
  //! operator+=
971
  WPSVec3<T> &operator+=(WPSVec3<T> const &p)
972
  {
973
    for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]+p.m_val[c]);
974
    return *this;
975
  }
976
  //! operator-=
977
  WPSVec3<T> &operator-=(WPSVec3<T> const &p)
978
  {
979
    for (int c = 0; c < 3; c++) m_val[c] = T(m_val[c]-p.m_val[c]);
980
    return *this;
981
  }
982
  //! generic operator*=
983
  template <class U>
984
  WPSVec3<T> &operator*=(U scale)
985
  {
986
    for (auto &c : m_val) c = T(c*scale);
987
    return *this;
988
  }
989
990
  //! operator+
991
  friend WPSVec3<T> operator+(WPSVec3<T> const &p1, WPSVec3<T> const &p2)
992
  {
993
    WPSVec3<T> p(p1);
994
    return p+=p2;
995
  }
996
  //! operator-
997
  friend WPSVec3<T> operator-(WPSVec3<T> const &p1, WPSVec3<T> const &p2)
998
  {
999
    WPSVec3<T> p(p1);
1000
    return p-=p2;
1001
  }
1002
  //! generic operator*
1003
  template <class U>
1004
  friend WPSVec3<T> operator*(U scale, WPSVec3<T> const &p1)
1005
  {
1006
    WPSVec3<T> p(p1);
1007
    return p *= scale;
1008
  }
1009
1010
  //! comparison==
1011
  bool operator==(WPSVec3<T> const &p) const
1012
1.32M
  {
1013
1.32M
    return cmp(p) == 0;
1014
1.32M
  }
WPSVec3<float>::operator==(WPSVec3<float> const&) const
Line
Count
Source
1012
489k
  {
1013
489k
    return cmp(p) == 0;
1014
489k
  }
WPSVec3<int>::operator==(WPSVec3<int> const&) const
Line
Count
Source
1012
837k
  {
1013
837k
    return cmp(p) == 0;
1014
837k
  }
1015
  //! comparison!=
1016
  bool operator!=(WPSVec3<T> const &p) const
1017
  {
1018
    return cmp(p) != 0;
1019
  }
1020
  //! comparison<: which first compares x values, then y values then z values.
1021
  bool operator<(WPSVec3<T> const &p) const
1022
0
  {
1023
0
    return cmp(p) < 0;
1024
0
  }
1025
  //! a comparison function: which first compares x values, then y values then z values.
1026
  int cmp(WPSVec3<T> const &p) const
1027
1.32M
  {
1028
2.82M
    for (int c = 0; c < 3; c++)
1029
2.34M
    {
1030
2.34M
      if (m_val[c]<p.m_val[c]) return -1;
1031
1.59M
      if (m_val[c]>p.m_val[c]) return 1;
1032
1.59M
    }
1033
474k
    return 0;
1034
1.32M
  }
WPSVec3<float>::cmp(WPSVec3<float> const&) const
Line
Count
Source
1027
489k
  {
1028
1.42M
    for (int c = 0; c < 3; c++)
1029
1.12M
    {
1030
1.12M
      if (m_val[c]<p.m_val[c]) return -1;
1031
998k
      if (m_val[c]>p.m_val[c]) return 1;
1032
998k
    }
1033
299k
    return 0;
1034
489k
  }
WPSVec3<int>::cmp(WPSVec3<int> const&) const
Line
Count
Source
1027
837k
  {
1028
1.39M
    for (int c = 0; c < 3; c++)
1029
1.22M
    {
1030
1.22M
      if (m_val[c]<p.m_val[c]) return -1;
1031
600k
      if (m_val[c]>p.m_val[c]) return 1;
1032
600k
    }
1033
174k
    return 0;
1034
837k
  }
1035
1036
  //! operator<<: prints data in form "XxYxZ"
1037
  friend std::ostream &operator<< (std::ostream &o, WPSVec3<T> const &f)
1038
  {
1039
    o << f.m_val[0] << "x" << f.m_val[1] << "x" << f.m_val[2];
1040
    return o;
1041
  }
1042
1043
  /*! \struct PosSizeLt
1044
   * \brief internal struct used to create sorted map, sorted by X, Y, Z
1045
   */
1046
  struct PosSizeLt
1047
  {
1048
    //! comparaison function
1049
    bool operator()(WPSVec3<T> const &s1, WPSVec3<T> const &s2) const
1050
    {
1051
      return s1.cmp(s2) < 0;
1052
    }
1053
  };
1054
  /*! \typedef Map
1055
   *  \brief map of WPSVec3
1056
   */
1057
  typedef std::map<WPSVec3<T>, T, struct PosSizeLt> Map;
1058
1059
protected:
1060
  //! the values
1061
  T m_val[3];
1062
};
1063
1064
/*! \brief WPSVec3 of unsigned char */
1065
typedef WPSVec3<unsigned char> WPSVec3uc;
1066
/*! \brief WPSVec3 of int */
1067
typedef WPSVec3<int> WPSVec3i;
1068
/*! \brief WPSVec3 of float */
1069
typedef WPSVec3<float> WPSVec3f;
1070
1071
1072
/** small class use to define a embedded object
1073
1074
    \note mainly used to store picture
1075
 */
1076
struct WPSEmbeddedObject
1077
{
1078
  //! empty constructor
1079
556k
  WPSEmbeddedObject() : m_size(), m_dataList(), m_typeList(), m_sent(false)
1080
556k
  {
1081
556k
  }
1082
883
  WPSEmbeddedObject(WPSEmbeddedObject const &) = default;
1083
2.02k
  WPSEmbeddedObject &operator=(WPSEmbeddedObject const &) = default;
1084
0
  WPSEmbeddedObject(WPSEmbeddedObject &&) = default;
1085
48
  WPSEmbeddedObject &operator=(WPSEmbeddedObject &&) = default;
1086
  //! constructor
1087
  explicit WPSEmbeddedObject(librevenge::RVNGBinaryData const &binaryData, std::string const &type="image/pict") :
1088
61
    m_size(), m_dataList(), m_typeList(), m_sent(false)
1089
61
  {
1090
61
    add(binaryData, type);
1091
61
  }
1092
  //! destructor
1093
  virtual ~WPSEmbeddedObject();
1094
  //! return true if the picture contains no data
1095
  bool isEmpty() const
1096
48.1k
  {
1097
48.1k
    for (auto const &data : m_dataList)
1098
1.16k
    {
1099
1.16k
      if (!data.empty())
1100
1.14k
        return false;
1101
1.16k
    }
1102
46.9k
    return true;
1103
48.1k
  }
1104
  //! add a picture
1105
  void add(librevenge::RVNGBinaryData const &binaryData, std::string const &type="image/pict")
1106
3.55k
  {
1107
3.55k
    size_t pos=m_dataList.size();
1108
3.55k
    if (pos<m_typeList.size()) pos=m_typeList.size();
1109
3.55k
    m_dataList.resize(pos+1);
1110
3.55k
    m_dataList[pos]=binaryData;
1111
3.55k
    m_typeList.resize(pos+1);
1112
3.55k
    m_typeList[pos]=type;
1113
3.55k
  }
1114
  /** add the link property to proplist */
1115
  bool addTo(librevenge::RVNGPropertyList &propList) const;
1116
  /** operator<<*/
1117
  friend std::ostream &operator<<(std::ostream &o, WPSEmbeddedObject const &pict);
1118
1119
  //! the picture size in inches(if known)
1120
  Vec2f m_size;
1121
  //! the picture content: one data by representation
1122
  std::vector<librevenge::RVNGBinaryData> m_dataList;
1123
  //! the picture type: one type by representation
1124
  std::vector<std::string> m_typeList;
1125
  //! a mutable flag which can be used to know if the picture was send to a listener
1126
  mutable bool m_sent;
1127
};
1128
1129
/** a transformation which stored the first row of a 3x3 perspective matrix */
1130
class WPSTransformation
1131
{
1132
public:
1133
  //! constructor
1134
  explicit WPSTransformation(WPSVec3f const &xRow=WPSVec3f(1,0,0), WPSVec3f const &yRow=WPSVec3f(0,1,0))
1135
253k
    : m_data(xRow, yRow)
1136
253k
    , m_isIdentity(false)
1137
253k
  {
1138
253k
    checkIdentity();
1139
253k
  }
1140
  WPSTransformation(WPSTransformation const &)=default;
1141
  WPSTransformation(WPSTransformation &&)=default;
1142
1.95k
  WPSTransformation &operator=(WPSTransformation const &)=default;
1143
60.1k
  WPSTransformation &operator=(WPSTransformation &&)=default;
1144
  //! returns true if the matrix is an identity matrix
1145
  bool isIdentity() const
1146
157k
  {
1147
157k
    return m_isIdentity;
1148
157k
  }
1149
  //! check if a matrix is the identity matrix
1150
  void checkIdentity() const
1151
324k
  {
1152
324k
    m_isIdentity= m_data.first==WPSVec3f(1,0,0) && m_data.second==WPSVec3f(0,1,0);
1153
324k
  }
1154
  /*! \brief the two extremum points which defined the box
1155
   * \param c 0 means the minimum and 1 the maximum
1156
   */
1157
  WPSVec3f const &operator[](int c) const
1158
2.70M
  {
1159
2.70M
    if (c<0 || c>1) throw libwps::GenericException();
1160
2.70M
    return c==0 ? m_data.first : m_data.second;
1161
2.70M
  }
1162
  //! operator* for vec2f
1163
  Vec2f operator*(Vec2f const &pt) const
1164
547k
  {
1165
547k
    if (m_isIdentity) return pt;
1166
547k
    return multiplyDirection(pt)+Vec2f(m_data.first[2],m_data.second[2]);
1167
547k
  }
1168
  //! operator* for direction
1169
  Vec2f multiplyDirection(Vec2f const &dir) const
1170
644k
  {
1171
644k
    if (m_isIdentity) return dir;
1172
644k
    Vec2f res;
1173
1.93M
    for (int coord=0; coord<2; ++coord)
1174
1.28M
    {
1175
1.28M
      WPSVec3f const &row=coord==0 ? m_data.first : m_data.second;
1176
1.28M
      float value=0;
1177
3.86M
      for (int i=0; i<2; ++i)
1178
2.57M
        value+=row[i]*dir[i];
1179
1.28M
      res[coord]=value;
1180
1.28M
    }
1181
644k
    return res;
1182
644k
  }
1183
  //! operator* for box2f
1184
  WPSBox2f operator*(WPSBox2f const &box) const
1185
0
  {
1186
0
    if (m_isIdentity) return box;
1187
0
    return WPSBox2f(operator*(box.min()), operator*(box.max()));
1188
0
  }
1189
  //! operator* for transform
1190
  WPSTransformation operator*(WPSTransformation const &mat) const
1191
92.9k
  {
1192
92.9k
    if (mat.m_isIdentity) return *this;
1193
71.0k
    WPSTransformation res;
1194
213k
    for (int row=0; row<2; ++row)
1195
142k
    {
1196
142k
      WPSVec3f &resRow=row==0 ? res.m_data.first : res.m_data.second;
1197
568k
      for (int col=0; col<3; ++col)
1198
426k
      {
1199
426k
        float value=0;
1200
1.70M
        for (int i=0; i<3; ++i)
1201
1.27M
          value+=(*this)[row][i]*(i==2 ? (col==2 ? 1.f : 0.f) : mat[i][col]);
1202
426k
        resRow[col]=value;
1203
426k
      }
1204
142k
    }
1205
71.0k
    res.checkIdentity();
1206
71.0k
    return res;
1207
92.9k
  }
1208
  //! operator*=
1209
  WPSTransformation &operator*=(WPSTransformation const &mat)
1210
0
  {
1211
0
    if (!mat.m_isIdentity)
1212
0
      *this=(*this)*mat;
1213
0
    return *this;
1214
0
  }
1215
  //! operator==
1216
  bool operator==(WPSTransformation const &mat) const
1217
0
  {
1218
0
    return m_data==mat.m_data;
1219
0
  }
1220
  //! operator!=
1221
  bool operator!=(WPSTransformation const &mat) const
1222
0
  {
1223
0
    return m_data!=mat.m_data;
1224
0
  }
1225
  //! operator<
1226
  bool operator<(WPSTransformation const &mat) const
1227
0
  {
1228
0
    return m_data<mat.m_data;
1229
0
  }
1230
  //! operator<=
1231
  bool operator<=(WPSTransformation const &mat) const
1232
0
  {
1233
0
    return m_data<=mat.m_data;
1234
0
  }
1235
  //! operator>
1236
  bool operator>(WPSTransformation const &mat) const
1237
0
  {
1238
0
    return m_data>mat.m_data;
1239
0
  }
1240
  //! operator>=
1241
  bool operator>=(WPSTransformation const &mat) const
1242
0
  {
1243
0
    return m_data>=mat.m_data;
1244
0
  }
1245
  /** try to decompose the matrix in a rotation + scaling/translation matrix.
1246
1247
      Note: the center of rotation is given before applying the transformation(this) */
1248
  bool decompose(float &rotation, Vec2f &shearing, WPSTransformation &transform, Vec2f const &center) const;
1249
1250
  /** returns a translation transformation */
1251
  static WPSTransformation translation(Vec2f const &trans)
1252
12.9k
  {
1253
12.9k
    return WPSTransformation(WPSVec3f(1, 0, trans[0]), WPSVec3f(0, 1, trans[1]));
1254
12.9k
  }
1255
  /** returns a scaling transformation */
1256
  static WPSTransformation scale(Vec2f const &trans)
1257
10.9k
  {
1258
10.9k
    return WPSTransformation(WPSVec3f(trans[0], 0, 0), WPSVec3f(0, trans[1], 0));
1259
10.9k
  }
1260
  /** returns a rotation transformation around center.
1261
1262
   \note angle must be given in degree */
1263
  static WPSTransformation rotation(float angle, Vec2f const &center=Vec2f(0,0));
1264
  /** returns a shear transformation letting center invariant, ie. a matrix
1265
      ( 1 s[0] -s[0]*center[1], s[1] 1 -s[1]*center[0], 0 0 1)
1266
   */
1267
  static WPSTransformation shear(Vec2f s, Vec2f const &center=Vec2f(0,0))
1268
27.3k
  {
1269
27.3k
    return WPSTransformation(WPSVec3f(1, s[0], -s[0]*center[1]), WPSVec3f(s[1], 1, -s[1]*center[0]));
1270
27.3k
  }
1271
protected:
1272
  //! the data
1273
  std::pair<WPSVec3f, WPSVec3f > m_data;
1274
  //! flag to know if this matrix is an identity matrix
1275
  mutable bool m_isIdentity;
1276
};
1277
1278
//
1279
// utility
1280
//
1281
1282
namespace libwps
1283
{
1284
//! returns the cell name corresponding to a cell's position
1285
std::string getCellName(Vec2i const &cellPos, Vec2b const &relative=Vec2b(true,true));
1286
//! returns the checksum and the keys (to encode a lotus file) given a password file
1287
bool encodeLotusPassword(char const *password, uint16_t &key, std::vector<uint8_t> &keys, uint8_t const(&defValues)[16]);
1288
}
1289
#endif /* LIBWPS_INTERNAL_H */
1290
/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */