/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 | } Line | Count | Source | 543 | 327k | { | 544 | 327k | return m_x; | 545 | 327k | } |
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 | } Line | Count | Source | 548 | 327k | { | 549 | 327k | return m_y; | 550 | 327k | } |
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 ¢er) 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 ¢er=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 ¢er=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: */ |