1 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2 
3 /* libmwaw
4 * Version: MPL 2.0 / LGPLv2+
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 2.0 (the "License"); you may not use this file except in compliance with
8 * the License or as specified alternatively below. You may obtain a copy of
9 * the License at http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * Major Contributor(s):
17 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
18 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
19 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
20 * Copyright (C) 2006, 2007 Andrew Ziem
21 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
22 *
23 *
24 * All Rights Reserved.
25 *
26 * For minor contributions see the git repository.
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
30 * in which case the provisions of the LGPLv2+ are applicable
31 * instead of those above.
32 */
33 
34 #ifndef RAG_TIME_5_STYLE_MANAGER
35 #  define RAG_TIME_5_STYLE_MANAGER
36 
37 #include <map>
38 #include <ostream>
39 #include <sstream>
40 #include <set>
41 #include <string>
42 #include <vector>
43 
44 #include "libmwaw_internal.hxx"
45 #include "MWAWDebug.hxx"
46 #include "MWAWEntry.hxx"
47 #include "MWAWGraphicStyle.hxx"
48 
49 #include "RagTime5ClusterManager.hxx"
50 #include "RagTime5StructManager.hxx"
51 
52 namespace RagTime5StyleManagerInternal
53 {
54 struct State;
55 }
56 
57 class RagTime5Document;
58 
59 //! basic class used to read/store RagTime 5/6 styles
60 class RagTime5StyleManager
61 {
62   friend class RagTime5Document;
63 public:
64   //! constructor
65   explicit RagTime5StyleManager(RagTime5Document &doc);
66   //! destructor
67   ~RagTime5StyleManager();
68 
69   struct GraphicStyle;
70   struct TextStyle;
71 
72   //! try to read a graphic color zone
73   bool readGraphicColors(RagTime5ClusterManager::Cluster &cluster);
74   //! try to read a main graphic styles
75   bool readGraphicStyles(RagTime5ClusterManager::Cluster &cluster);
76   //! try to read a main text styles
77   bool readTextStyles(RagTime5ClusterManager::Cluster &cluster);
78   //! try to read the list of format
79   bool readFormats(RagTime5ClusterManager::Cluster &cluster);
80 
81   //! updates a graphic style
82   bool updateSurfaceStyle(int graphicId, MWAWGraphicStyle &surfaceStyle) const;
83   //! updates a graphic style (used for textbox)
84   bool updateFrameStyle(int graphicId, MWAWGraphicStyle &surfaceStyle) const;
85   //! updates a graphic style(border)
86   bool updateBorderStyle(int graphicId, MWAWGraphicStyle &borderStyle, bool isLine) const;
87   //! returns the line color corresponding to a graphic style
88   bool getLineColor(int graphicId, MWAWColor &color) const;
89   //! update the font and the paragraph properties using a text style
90   bool updateTextStyles(int textId, MWAWFont &font, MWAWParagraph &para, MWAWSection &section, double totalWidth=0) const;
91   //! returns a cell border
92   bool getCellBorder(int graphicId, MWAWBorder &border) const;
93   //! returns the cell background
94   bool getCellBackgroundColor(int graphicId, MWAWColor &color) const;
95   //! updates the cell format
96   bool updateCellFormat(int formatId, MWAWCell &cell) const;
97 
98 protected:
99   //! recursive function use to update the style list
100   void updateTextStyles(size_t id, RagTime5StyleManager::TextStyle const &style,
101                         std::vector<RagTime5StyleManager::TextStyle> const &listReadStyles,
102                         std::multimap<size_t, size_t> const &idToChildIpMap,
103                         std::set<size_t> &seens);
104   //! recursive function use to update the style list
105   void updateGraphicStyles(size_t id, RagTime5StyleManager::GraphicStyle const &style,
106                            std::vector<RagTime5StyleManager::GraphicStyle> const &listReadStyles,
107                            std::multimap<size_t, size_t> const &idToChildIpMap,
108                            std::set<size_t> &seens);
109 
110 public:
111   //! the graphic style of a RagTime v5-v6 document
112   struct GraphicStyle {
113     //! constructor
GraphicStyleRagTime5StyleManager::GraphicStyle114     GraphicStyle()
115       : m_parentId(-1000)
116       , m_width(-1)
117       , m_dash()
118       , m_pattern()
119       , m_gradient(-1)
120       , m_gradientRotation(-1000)
121       , m_gradientCenter(MWAWVec2f(0.5f,0.5f))
122       , m_position(-1)
123       , m_cap(1)
124       , m_mitter(-1)
125       , m_limitPercent(-1)
126       , m_hidden(false)
127       , m_extra("")
128     {
129       m_colors[0]=MWAWVariable<MWAWColor>(MWAWColor::black());
130       m_colors[1]=MWAWVariable<MWAWColor>(MWAWColor::white());
131       for (auto &alpha : m_colorsAlpha) alpha=-1;
132     }
133     //! destructor
134     virtual ~GraphicStyle();
135     //! returns true if the line style is default
isDefaultRagTime5StyleManager::GraphicStyle136     bool isDefault() const
137     {
138       return m_parentId<=-1000 && m_width<0 && !m_dash.isSet() && !m_pattern &&
139              m_gradient<0 && m_gradientRotation<=-1000 && !m_gradientCenter.isSet() &&
140              m_position<0 && m_cap<0 && m_mitter<0 &&
141              !m_colors[0].isSet() && !m_colors[1].isSet() && m_colorsAlpha[0]<0 && m_colorsAlpha[1]<0 &&
142              m_limitPercent<0 && !m_hidden.isSet() && m_extra.empty();
143     }
144     //! update the first/second color using the color list
145     bool updateColor(bool first, int colorId, std::vector<MWAWColor> const &colorList);
146     //! operator<<
147     friend std::ostream &operator<<(std::ostream &o, GraphicStyle const &style);
148     //! update the current style
149     void insert(GraphicStyle const &childStyle);
150     //! try to read a graphic style
151     bool read(MWAWInputStreamPtr &input, RagTime5StructManager::Field const &field, std::vector<MWAWColor> const &colorList);
152     //! the parent id
153     int m_parentId;
154     //! the line width (in point)
155     float m_width;
156     //! the first and second color
157     MWAWVariable<MWAWColor> m_colors[2];
158     //! alpha of the first and second color
159     float m_colorsAlpha[2];
160     //! the line dash/...
161     MWAWVariable<std::vector<long> > m_dash;
162     //! the line pattern
163     std::shared_ptr<MWAWGraphicStyle::Pattern> m_pattern;
164     //! the gradient 0: none, normal, radial
165     int m_gradient;
166     //! the gradient rotation(checkme)
167     float m_gradientRotation;
168     //! the rotation center(checkme)
169     MWAWVariable<MWAWVec2f> m_gradientCenter;
170     //! the line position inside=1/normal/outside/round
171     int m_position;
172     //! the line caps ( normal=1, round, square)
173     int m_cap;
174     //! the line mitter ( triangle=1, round, out)
175     int m_mitter;
176     //! the line limit
177     float m_limitPercent;
178     //! flag to know if we need to print the shape
179     MWAWVariable<bool> m_hidden;
180     //! extra data
181     std::string m_extra;
182 
183     GraphicStyle(GraphicStyle const &)=default; // removeme
184     GraphicStyle(GraphicStyle &&)=default;
185     GraphicStyle &operator=(GraphicStyle const &)=default; // removeme
186     GraphicStyle &operator=(GraphicStyle &&)=default;
187   };
188   //! the text style of a RagTime v5-v6 document
189   struct TextStyle {
190     //! constructor
TextStyleRagTime5StyleManager::TextStyle191     TextStyle()
192       : m_linkIdList()
193       , m_dateStyleId(-1)
194       , m_graphStyleId(-1)
195       , m_graphLineStyleId(-1)
196       , m_keepWithNext(false)
197       , m_justify(-1)
198       , m_breakMethod(-1)
199       , m_tabList()
200       , m_fontName("")
201       , m_fontId(-1)
202       , m_fontSize(-1)
203       , m_scriptPosition(0)
204       , m_fontScaling(-1)
205       , m_underline(-1)
206       , m_caps(-1)
207       , m_language(-1)
208       , m_widthStreching(-1)
209       , m_numColumns(-1)
210       , m_columnGap(-1)
211       , m_extra("")
212     {
213       for (auto &parentId : m_parentId) parentId=-1;
214       for (auto &fontFlag : m_fontFlags) fontFlag=0;
215       for (auto &margin : m_margins) margin=-1;
216       for (auto &spacing : m_spacings) spacing=-1;
217       for (auto &spacingUnit : m_spacingUnits) spacingUnit=-1;
218       for (auto &letterSpacing : m_letterSpacings) letterSpacing=0;
219     }
220     //! destructor
221     virtual ~TextStyle();
222     //! returns true if the line style is default
isDefaultRagTime5StyleManager::TextStyle223     bool isDefault() const
224     {
225       if (m_parentId[0]>=0 || m_parentId[1]>=0 || !m_linkIdList.empty() ||
226           m_dateStyleId>=0 || m_graphStyleId>=0 || m_graphLineStyleId>=0 ||
227           m_keepWithNext.isSet() || m_justify>=0 || m_breakMethod>=0 || !m_tabList.empty() ||
228           !m_fontName.empty() || m_fontId>=0 || m_fontSize>=0 || m_fontFlags[0] || m_fontFlags[1] || m_scriptPosition.isSet() ||
229           m_fontScaling>=0 || m_underline>=0 || m_caps>=0 || m_language>=0 || m_widthStreching>=0 ||
230           m_numColumns>=0 || m_columnGap>=0 || !m_extra.empty())
231         return false;
232       for (int i=0; i<3; ++i) {
233         if (m_margins[i]>=0 || m_spacings[i]>=0 || m_spacingUnits[i]>=0)
234           return false;
235       }
236       for (auto spacing : m_letterSpacings) {
237         if (spacing>0 || spacing<0)
238           return false;
239       }
240       return true;
241     }
242     //! returns the language locale name corresponding to an id ( if known)
243     static std::string getLanguageLocale(int id);
244 
245     //! operator<<
246     friend std::ostream &operator<<(std::ostream &o, TextStyle const &style);
247     //! update the current style
248     void insert(TextStyle const &childStyle);
249     //! try to read a text style
250     bool read(RagTime5StructManager::Field const &field);
251     //! the parent id ( main and style ?)
252     int m_parentId[2];
253     //! the link id list
254     std::vector<int> m_linkIdList;
255     //! the date style id
256     int m_dateStyleId;
257     //! the graphic style id
258     int m_graphStyleId;
259     //! the graphic line style id
260     int m_graphLineStyleId;
261 
262     // paragraph
263 
264     //! the keep with next flag
265     MWAWVariable<bool> m_keepWithNext;
266     //! justify 0: left, 1:center, 2:right, 3:full, 4:full all
267     int m_justify;
268     //! the interline/before/after value
269     double m_spacings[3];
270     //! the interline/before/after unit 0: line, 1:point
271     int m_spacingUnits[3];
272     //! the break method 0: asIs, next container, next page, next even page, next odd page
273     int m_breakMethod;
274     //! the spacings in point ( left, right, first)
275     double m_margins[3];
276     //! the tabulations
277     std::vector<RagTime5StructManager::TabStop> m_tabList;
278 
279     // character
280 
281     //! the font name
282     librevenge::RVNGString m_fontName;
283     //! the font id
284     int m_fontId;
285     //! the font size
286     float m_fontSize;
287     //! the font flags (add and remove )
288     uint32_t m_fontFlags[2];
289     //! the font script position ( in percent)
290     MWAWVariable<float> m_scriptPosition;
291     //! the font script position ( in percent)
292     float m_fontScaling;
293     //! underline : none, single, double
294     int m_underline;
295     //! caps : none, all caps, lower caps, inital caps + other lowers
296     int m_caps;
297     //! the language
298     int m_language;
299     //! the spacings in percent ( normal, minimum, maximum)
300     double m_letterSpacings[4];
301     //! the width streching
302     double m_widthStreching;
303 
304     // column
305 
306     //! the number of columns
307     int m_numColumns;
308     //! the gap between columns
309     double m_columnGap;
310 
311     //! extra data
312     std::string m_extra;
313 
314     TextStyle(TextStyle const &)=default; // removeme
315     TextStyle(TextStyle &&)=default;
316     TextStyle &operator=(TextStyle const &)=default; // removeme
317     TextStyle &operator=(TextStyle &&)=default;
318   };
319 
320 public:
321   //! debug: print a file type
printType(unsigned long fileType)322   static std::string printType(unsigned long fileType)
323   {
324     return RagTime5StructManager::printType(fileType);
325   }
326 
327 protected:
328   //
329   // data
330   //
331 
332   //! the parser
333   RagTime5Document &m_document;
334   //! the parser state
335   MWAWParserStatePtr m_parserState;
336 
337   //! the state
338   std::shared_ptr<RagTime5StyleManagerInternal::State> m_state;
339 
340 private:
341   RagTime5StyleManager(RagTime5StyleManager const &orig) = delete;
342   RagTime5StyleManager operator=(RagTime5StyleManager const &orig) = delete;
343 };
344 
345 #endif
346 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
347