1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * This file is part of the libqxp project.
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 
10 #ifndef QXPTYPES_H_INCLUDED
11 #define QXPTYPES_H_INCLUDED
12 
13 #include "libqxp_utils.h"
14 #include <boost/optional.hpp>
15 #include <boost/variant.hpp>
16 
17 #include <memory>
18 #include <vector>
19 #include <utility>
20 
21 namespace libqxp
22 {
23 
24 struct Point
25 {
26   double x;
27   double y;
28 
PointPoint29   Point()
30     : x(0.0), y(0.0)
31   { }
32 
PointPoint33   Point(double xVal, double yVal)
34     : x(xVal), y(yVal)
35   { }
36 
37   Point move(double dx, double dy) const;
38   Point rotateDeg(double rotationDeg, const Point &center) const;
39 
40   double distance(const Point &p2) const;
41 };
42 
43 bool operator==(const Point &lhs, const Point &rhs);
44 bool operator!=(const Point &lhs, const Point &rhs);
45 
46 struct Rect
47 {
48   double top;
49   double right;
50   double bottom;
51   double left;
52 
53   Rect();
54   Rect(double t, double r, double b, double l);
55 
56   double width() const;
57   double height() const;
58 
59   Point center() const;
60   Point topLeft() const;
61   Point topRight() const;
62   Point bottomRight() const;
63   Point bottomLeft() const;
64 
65   Rect shrink(const double diff) const;
66 };
67 
68 struct Color
69 {
70   uint8_t red;
71   uint8_t green;
72   uint8_t blue;
73 
ColorColor74   Color()
75     : red(0), green(0), blue(0)
76   {  }
77 
ColorColor78   Color(uint8_t r, uint8_t g, uint8_t b)
79     : red(r), green(g), blue(b)
80   {  }
81 
82   librevenge::RVNGString toString() const;
83 
84   Color applyShade(double shade) const;
85 };
86 
87 enum class GradientType
88 {
89   LINEAR,
90   MIDLINEAR,
91   RECTANGULAR,
92   DIAMOND,
93   CIRCULAR,
94   FULLCIRCULAR
95 };
96 
97 struct Gradient
98 {
99   GradientType type;
100   Color color1;
101   Color color2;
102   double angle;
103 
GradientGradient104   Gradient()
105     : type(), color1(), color2(), angle(0.0)
106   { }
107 };
108 
109 typedef boost::variant<Color, Gradient> Fill;
110 
111 enum class LineCapType
112 {
113   BUTT,
114   ROUND,
115   RECT,
116   STRETCH
117 };
118 
119 enum class LineJoinType
120 {
121   MITER,
122   ROUND,
123   BEVEL
124 };
125 
126 struct LineStyle
127 {
128   std::vector<double> segmentLengths;
129   bool isStripe;
130   bool isProportional;
131   double patternLength;
132   LineCapType endcapType;
133   LineJoinType joinType;
134 
LineStyleLineStyle135   LineStyle()
136     : segmentLengths(), isStripe(false), isProportional(true), patternLength(6.0), endcapType(LineCapType::BUTT), joinType(LineJoinType::MITER)
137   { }
138 
LineStyleLineStyle139   LineStyle(std::vector<double> segments, bool proportional, double pattern, LineCapType endcap, LineJoinType join)
140     : segmentLengths(std::move(segments)), isStripe(false), isProportional(proportional), patternLength(pattern), endcapType(endcap), joinType(join)
141   { }
142 };
143 
144 struct CharFormat
145 {
146   librevenge::RVNGString fontName;
147   double fontSize;
148   double baselineShift;
149   Color color;
150   bool bold;
151   bool italic;
152   bool underline;
153   bool outline;
154   bool shadow;
155   bool superscript;
156   bool subscript;
157   bool superior;
158   bool strike;
159   bool allCaps;
160   bool smallCaps;
161   bool wordUnderline;
162 
163   bool isControlChars;
164 
CharFormatCharFormat165   CharFormat()
166     : fontName("Arial"), fontSize(12.0), baselineShift(0.0), color(0, 0, 0),
167       bold(false), italic(false), underline(false), outline(false), shadow(false), superscript(false), subscript(false), superior(false),
168       strike(false), allCaps(false), smallCaps(false), wordUnderline(false),
169       isControlChars(false)
170   {  }
171 };
172 
173 struct HJ
174 {
HJHJ175   HJ()
176     : hyphenate(true)
177     , minBefore(3)
178     , minAfter(2)
179     , maxInRow(0)
180     , singleWordJustify(true)
181   {
182   }
183 
184   bool hyphenate;
185   unsigned minBefore;
186   unsigned minAfter;
187   unsigned maxInRow;
188   bool singleWordJustify;
189 };
190 
191 enum class HorizontalAlignment
192 {
193   LEFT,
194   CENTER,
195   RIGHT,
196   JUSTIFIED,
197   FORCED
198 };
199 
200 enum class VerticalAlignment
201 {
202   TOP,
203   CENTER,
204   BOTTOM,
205   JUSTIFIED
206 };
207 
208 enum class TabStopType
209 {
210   LEFT,
211   CENTER,
212   RIGHT,
213   ALIGN
214 };
215 
216 struct TabStop
217 {
218   TabStopType type;
219   double position;
220   librevenge::RVNGString fillChar;
221   librevenge::RVNGString alignChar;
222 
isDefinedTabStop223   bool isDefined() const
224   {
225     return position >= 0;
226   }
227 
TabStopTabStop228   TabStop()
229     : type(TabStopType::LEFT), position(0.0), fillChar(), alignChar()
230   {  }
231 };
232 
233 struct ParagraphRule
234 {
235   double width;
236   Color color;
237   const LineStyle *lineStyle;
238   double leftMargin;
239   double rightMargin;
240   double offset;
241 
ParagraphRuleParagraphRule242   ParagraphRule()
243     : width(1.0), color(0, 0, 0), lineStyle(nullptr), leftMargin(0), rightMargin(0), offset(0)
244   {  }
245 };
246 
247 struct ParagraphFormat
248 {
249   HorizontalAlignment alignment;
250   Rect margin;
251   double firstLineIndent;
252   double leading;
253   bool incrementalLeading;
254   std::shared_ptr<ParagraphRule> ruleAbove;
255   std::shared_ptr<ParagraphRule> ruleBelow;
256   std::vector<TabStop> tabStops;
257   std::shared_ptr<HJ> hj;
258 
ParagraphFormatParagraphFormat259   ParagraphFormat()
260     : alignment(HorizontalAlignment::LEFT), margin(), firstLineIndent(0), leading(0), incrementalLeading(false),
261       ruleAbove(nullptr), ruleBelow(nullptr), tabStops(), hj(nullptr)
262   {  }
263 };
264 
265 enum class ContentType
266 {
267   UNKNOWN,
268   OBJECTS, // group
269   NONE,
270   TEXT,
271   PICTURE
272 };
273 
274 struct TextSpec
275 {
276   const unsigned startIndex;
277   const unsigned length;
278 
endIndexTextSpec279   unsigned endIndex() const
280   {
281     return startIndex + length - 1;
282   }
283 
afterEndIndexTextSpec284   unsigned afterEndIndex() const
285   {
286     return startIndex + length;
287   }
288 
289   bool overlaps(const TextSpec &other) const;
290 
291 protected:
TextSpecTextSpec292   TextSpec(unsigned start, unsigned len)
293     : startIndex(start), length(len)
294   { }
295 };
296 
297 struct CharFormatSpec : public TextSpec
298 {
299   std::shared_ptr<CharFormat> format;
300 
CharFormatSpecCharFormatSpec301   CharFormatSpec(const std::shared_ptr<CharFormat> &f, unsigned start, unsigned len)
302     : TextSpec(start, len), format(f)
303   { }
304 };
305 
306 struct ParagraphSpec : public TextSpec
307 {
308   std::shared_ptr<ParagraphFormat> format;
309 
ParagraphSpecParagraphSpec310   ParagraphSpec(const std::shared_ptr<ParagraphFormat> &f, unsigned start, unsigned len)
311     : TextSpec(start, len), format(f)
312   { }
313 };
314 
315 struct Text
316 {
317   std::string text;
318   const char *encoding;
319   std::vector<ParagraphSpec> paragraphs;
320   std::vector<CharFormatSpec> charFormats;
321 
322   double maxFontSize() const;
323   double maxFontSize(const ParagraphSpec &paragraph) const;
324 
TextText325   Text()
326     : text(), encoding("cp1252"), paragraphs(), charFormats()
327   { }
328 
329   Text(const Text &other) = default;
330   Text &operator=(const Text &other) = default;
331 };
332 
333 struct Arrow
334 {
335   const std::string path;
336   const std::string viewbox;
337   const double scale;
338 
339   explicit Arrow(const std::string &d, const std::string &vbox = "0 0 10 10", double s = 3)
pathArrow340     : path(d), viewbox(vbox), scale(s)
341   { }
342 };
343 
344 struct Frame
345 {
346   double width;
347   boost::optional<Color> color;
348   boost::optional<Color> gapColor;
349   const LineStyle *lineStyle;
350   const Arrow *startArrow;
351   const Arrow *endArrow;
352 
FrameFrame353   Frame()
354     : width(1.0), color(), gapColor(), lineStyle(nullptr), startArrow(nullptr), endArrow(nullptr)
355   { }
356 
357   Frame(const Frame &other) = default;
358   Frame &operator=(const Frame &other) = default;
359 };
360 
361 struct LinkedTextSettings
362 {
363   unsigned linkId;
364   unsigned offsetIntoText;
365   unsigned linkedIndex;
366   unsigned nextLinkedIndex;
367   boost::optional<unsigned> textLength;
368 
LinkedTextSettingsLinkedTextSettings369   LinkedTextSettings()
370     : linkId(0), offsetIntoText(0), linkedIndex(0), nextLinkedIndex(0), textLength()
371   { }
372 };
373 
374 struct TextObject
375 {
376   LinkedTextSettings linkSettings;
377   boost::optional<std::shared_ptr<Text>> text;
378 
TextObjectTextObject379   TextObject()
380     : linkSettings(), text()
381   { }
382 
383   bool isLinked() const;
384 };
385 
386 struct TextSettings
387 {
388   unsigned columnsCount;
389   double gutterWidth;
390   VerticalAlignment verticalAlignment;
391   Rect inset;
392   double rotation;
393   double skew;
394 
TextSettingsTextSettings395   TextSettings()
396     : columnsCount(1), gutterWidth(12.0), verticalAlignment(VerticalAlignment::TOP), inset(), rotation(0), skew(0)
397   { }
398 };
399 
400 enum class TextPathAlignment
401 {
402   ASCENT,
403   CENTER,
404   BASELINE,
405   DESCENT
406 };
407 
408 enum class TextPathLineAlignment
409 {
410   TOP,
411   CENTER,
412   BOTTOM
413 };
414 
415 struct TextPathSettings
416 {
417   bool rotate;
418   bool skew;
419   TextPathAlignment alignment;
420   TextPathLineAlignment lineAlignment;
421 
TextPathSettingsTextPathSettings422   TextPathSettings()
423     : rotate(false), skew(false), alignment(TextPathAlignment::BASELINE), lineAlignment(TextPathLineAlignment::TOP)
424   { }
425 };
426 
427 struct CurveComponent
428 {
429   Rect boundingBox;
430   std::vector<Point> points;
431 
CurveComponentCurveComponent432   CurveComponent()
433     : boundingBox(), points()
434   { }
435 };
436 
437 struct Object
438 {
439   Rect boundingBox;
440   bool runaround; // we probably don't need other runaround properties because ODF doesn't support them
441   unsigned zIndex;
442 
443 protected:
ObjectObject444   Object()
445     : boundingBox(), runaround(false), zIndex(0)
446   { }
447 };
448 
449 struct Line : Object
450 {
451   double rotation;
452   Frame style;
453   std::vector<CurveComponent> curveComponents;
454 
LineLine455   Line()
456     : rotation(0), style(), curveComponents()
457   { }
458 };
459 
460 struct TextPath : Line, TextObject
461 {
462   TextPathSettings settings;
463 
TextPathTextPath464   TextPath()
465     : settings()
466   { }
467 };
468 
469 enum class CornerType
470 {
471   DEFAULT,
472   ROUNDED,
473   BEVELED,
474   CONCAVE
475 };
476 
477 enum class BoxType
478 {
479   UNKNOWN,
480   RECTANGLE,
481   OVAL,
482   POLYGON,
483   BEZIER
484 };
485 
486 struct Box : Object
487 {
488   boost::optional<Fill> fill;
489   Frame frame;
490   BoxType boxType;
491   CornerType cornerType;
492   double cornerRadius;
493   double rotation;
494   std::vector<Point> customPoints;
495   std::vector<CurveComponent> curveComponents;
496 
BoxBox497   Box()
498     : fill(), frame(), boxType(BoxType::UNKNOWN), cornerType(CornerType::DEFAULT), cornerRadius(0.0), rotation(0),
499       customPoints(), curveComponents()
500   { }
501 };
502 
503 struct TextBox : Box, TextObject
504 {
505   TextSettings settings;
506 
TextBoxTextBox507   TextBox()
508     : settings()
509   { }
510 };
511 
512 struct PictureBox : Box
513 {
514   double pictureRotation;
515   double pictureSkew;
516   double offsetLeft;
517   double offsetTop;
518   double scaleHor;
519   double scaleVert;
520 
PictureBoxPictureBox521   PictureBox()
522     : pictureRotation(0.0), pictureSkew(0.0),
523       offsetLeft(0.0), offsetTop(0.0), scaleHor(0.0), scaleVert(0.0)
524   { }
525 };
526 
527 struct Group : Object
528 {
529   std::vector<unsigned> objectsIndexes;
530 
GroupGroup531   Group()
532     : objectsIndexes()
533   { }
534 };
535 
536 struct PageSettings
537 {
538   Rect offset;
539 
PageSettingsPageSettings540   PageSettings()
541     : offset()
542   { }
543 };
544 
545 struct Page
546 {
547   std::vector<PageSettings> pageSettings;
548   unsigned objectsCount;
549 
PagePage550   Page()
551     : pageSettings(), objectsCount(0)
552   { }
553 
isFacingPage554   bool isFacing() const
555   {
556     return pageSettings.size() == 2;
557   }
558 };
559 
560 struct QXPDocumentProperties
561 {
QXPDocumentPropertiesQXPDocumentProperties562   QXPDocumentProperties()
563     : superscriptOffset(1.0 / 3)
564     , superscriptHScale(1.0)
565     , superscriptVScale(1.0)
566     , subscriptOffset(-1.0 / 3)
567     , subscriptHScale(1.0)
568     , subscriptVScale(1.0)
569     , superiorHScale(0.5)
570     , superiorVScale(0.5)
571     , m_autoLeading(0.2)
572   {
573   }
574 
575   double superscriptOffset;
576   double superscriptHScale;
577   double superscriptVScale;
578   double subscriptOffset;
579   double subscriptHScale;
580   double subscriptVScale;
581   double superiorHScale;
582   double superiorVScale;
583 
584   void setAutoLeading(const double val);
585   double autoLeading() const;
586 
587   // there should be a flag to detect this...
isIncrementalAutoLeadingQXPDocumentProperties588   bool isIncrementalAutoLeading() const
589   {
590     return autoLeading() < 0 || autoLeading() > 1;
591   }
592 
593 private:
594   double m_autoLeading;
595 };
596 
597 }
598 
599 #endif // QXPTYPES_H_INCLUDED
600 
601 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
602