/src/libetonyek/src/lib/IWAParser.h
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* |
3 | | * This file is part of the libetonyek 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 IWAPARSER_H_INCLUDED |
11 | | #define IWAPARSER_H_INCLUDED |
12 | | |
13 | | #include <deque> |
14 | | #include <functional> |
15 | | #include <map> |
16 | | #include <memory> |
17 | | #include <string> |
18 | | #include <unordered_map> |
19 | | |
20 | | #include <boost/optional.hpp> |
21 | | #include <boost/variant.hpp> |
22 | | |
23 | | #if defined(__GNUC__) && !defined(__clang__) |
24 | | #pragma GCC diagnostic push |
25 | | #pragma GCC diagnostic ignored "-Weffc++" |
26 | | #endif |
27 | | #include <mdds/flat_segment_tree.hpp> |
28 | | #if defined(__GNUC__) && !defined(__clang__) |
29 | | #pragma GCC diagnostic pop |
30 | | #endif |
31 | | |
32 | | #include "libetonyek_utils.h" |
33 | | #include "IWAMessage.h" |
34 | | #include "IWAObjectIndex.h" |
35 | | #include "IWORKLanguageManager.h" |
36 | | #include "IWORKOutputElements.h" |
37 | | #include "IWORKStyle_fwd.h" |
38 | | #include "IWORKTypes.h" |
39 | | |
40 | | namespace libetonyek |
41 | | { |
42 | | |
43 | | class IWORKCollector; |
44 | | class IWAObjectIndex; |
45 | | class IWORKPropertyMap; |
46 | | class IWORKTable; |
47 | | class IWORKText; |
48 | | |
49 | | class IWAParser |
50 | | { |
51 | | friend class IWAObjectIndex; // for readColor |
52 | | |
53 | | // disable copying |
54 | | IWAParser(const IWAParser &); |
55 | | IWAParser &operator=(const IWAParser &); |
56 | | public: |
57 | | IWAParser(const RVNGInputStreamPtr_t &fragments, const RVNGInputStreamPtr_t &package, IWORKCollector &collector); |
58 | | virtual ~IWAParser() |
59 | 2.14k | { |
60 | 2.14k | } |
61 | | |
62 | | bool parse(); |
63 | | |
64 | | protected: |
65 | | class ObjectMessage |
66 | | { |
67 | | public: |
68 | | ObjectMessage(IWAParser &parser, unsigned id, unsigned type = 0); |
69 | | ~ObjectMessage(); |
70 | | |
71 | | operator bool() const; |
72 | | const IWAMessage &get() const; |
73 | | |
74 | | unsigned getType() const; |
75 | | |
76 | | friend const IWAMessage &get(const ObjectMessage &msg) |
77 | 264k | { |
78 | 264k | return msg.get(); |
79 | 264k | } |
80 | | |
81 | | private: |
82 | | IWAParser &m_parser; |
83 | | boost::optional<IWAMessage> m_message; |
84 | | const unsigned m_id; |
85 | | unsigned m_type; |
86 | | }; |
87 | | friend class ObjectMessage; |
88 | | |
89 | | typedef std::map<unsigned, IWORKStylePtr_t> StyleMap_t; |
90 | | typedef std::function<void(unsigned, IWORKStylePtr_t &)> StyleParseFun_t; |
91 | | |
92 | | protected: |
93 | | static boost::optional<unsigned> readRef(const IWAMessage &msg, unsigned field); |
94 | | static std::deque<unsigned> readRefs(const IWAMessage &msg, unsigned field); |
95 | | static boost::optional<IWORKPosition> readPosition(const IWAMessage &msg, unsigned field); |
96 | | static boost::optional<IWORKSize> readSize(const IWAMessage &msg, unsigned field); |
97 | | static boost::optional<IWORKColor> readColor(const IWAMessage &msg, unsigned field); |
98 | | static boost::optional<std::string> readUUID(const IWAMessage &msg, unsigned field); |
99 | | static boost::optional<uint64_t> readUID(const IWAMessage &msg, unsigned field); |
100 | | static std::deque<uint64_t> readUIDs(const IWAMessage &msg, unsigned field); |
101 | | static void readStroke(const IWAMessage &msg, IWORKStroke &stroke); |
102 | | bool readFill(const IWAMessage &msg, IWORKFill &fill); |
103 | | static void readGradient(const IWAMessage &msg, IWORKGradient &gradient); |
104 | | static void readShadow(const IWAMessage &msg, IWORKShadow &shadow); |
105 | | static void readPadding(const IWAMessage &msg, IWORKPadding &padding); |
106 | | static void readDropCap(const IWAMessage &msg, IWORKDropCap &cap); |
107 | | |
108 | | bool dispatchShape(unsigned id); |
109 | | bool dispatchShapeWithMessage(const IWAMessage &msg, unsigned type); |
110 | | bool parseText(unsigned id, bool createNoteAsFootnote=true, const std::function<void(unsigned, IWORKStylePtr_t)> &openPageSpan=nullptr); |
111 | | void parseComment(unsigned id); |
112 | | void parseAuthorInComment(unsigned id); |
113 | | void parseCustomFormat(unsigned id); |
114 | | |
115 | | virtual bool parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry, boost::optional<unsigned> &flags); |
116 | | void parseMask(unsigned id, IWORKGeometryPtr_t &geometry, IWORKPathPtr_t &path); |
117 | | void updateGeometryUsingTextRef(unsigned id, IWORKGeometry &geometry, unsigned flags); |
118 | | |
119 | | const IWORKStylePtr_t queryCharacterStyle(unsigned id) const; |
120 | | const IWORKStylePtr_t queryDropCapStyle(unsigned id) const; |
121 | | const IWORKStylePtr_t queryParagraphStyle(unsigned id) const; |
122 | | const IWORKStylePtr_t querySectionStyle(unsigned id) const; |
123 | | |
124 | | const IWORKStylePtr_t queryGraphicStyle(unsigned id) const; |
125 | | const IWORKStylePtr_t queryMediaStyle(unsigned id) const; |
126 | | const IWORKStylePtr_t queryCellStyle(unsigned id) const; |
127 | | const IWORKStylePtr_t queryTableStyle(unsigned id) const; |
128 | | const IWORKStylePtr_t queryListStyle(unsigned id) const; |
129 | | |
130 | | const IWORKStylePtr_t queryStyle(unsigned id, StyleMap_t &styleMap, StyleParseFun_t parse) const; |
131 | | boost::optional<unsigned> getObjectType(unsigned id) const; |
132 | | |
133 | | protected: |
134 | | IWORKFormatNameMap m_formatNameMap; |
135 | | IWORKLanguageManager m_langManager; |
136 | | IWORKTableNameMapPtr_t m_tableNameMap; |
137 | | std::shared_ptr<IWORKText> m_currentText; |
138 | | |
139 | | private: |
140 | | struct Format |
141 | | { |
142 | | Format(); |
143 | | boost::optional<IWORKCellType> m_type; |
144 | | boost::variant<IWORKNumberFormat,IWORKDateTimeFormat,IWORKDurationFormat> m_format; |
145 | | }; |
146 | | |
147 | | struct PageMaster |
148 | | { |
149 | | PageMaster(); |
150 | | IWORKStylePtr_t m_style; |
151 | | bool m_headerFootersSameAsPrevious; |
152 | | }; |
153 | | |
154 | | struct TableHeader |
155 | | { |
156 | | TableHeader(unsigned count, float defValue=0); |
157 | | |
158 | | mdds::flat_segment_tree<unsigned, float> m_sizes; |
159 | | mdds::flat_segment_tree<unsigned, bool> m_hidden; |
160 | | }; |
161 | | |
162 | | typedef std::map<unsigned, boost::variant<std::string, unsigned, IWORKFormulaPtr_t, Format> > DataList_t; |
163 | | |
164 | | struct ConditionRule |
165 | | { |
166 | | ConditionRule(); |
167 | | |
168 | | IWORKFormulaPtr_t m_formula; |
169 | | boost::optional<unsigned> m_cellStyleRef; |
170 | | boost::optional<unsigned> m_paragraphStyleRef; |
171 | | }; |
172 | | |
173 | | typedef std::deque<ConditionRule> ConditionRule_t; |
174 | | typedef std::map<unsigned, ConditionRule_t> ConditionRuleList_t; |
175 | | |
176 | | struct TableInfo |
177 | | { |
178 | | TableInfo(const std::shared_ptr<IWORKTable> &table, unsigned columns, unsigned rows); |
179 | | |
180 | | std::shared_ptr<IWORKTable> m_table; |
181 | | |
182 | | const unsigned m_columns; |
183 | | const unsigned m_rows; |
184 | | |
185 | | IWORKStylePtr_t m_style; |
186 | | |
187 | | TableHeader m_columnHeader; |
188 | | TableHeader m_rowHeader; |
189 | | |
190 | | DataList_t m_simpleTextList; |
191 | | DataList_t m_cellStyleList; |
192 | | ConditionRuleList_t m_conditionStyleList; |
193 | | DataList_t m_formattedTextList; |
194 | | DataList_t m_formulaList; |
195 | | DataList_t m_formatList; |
196 | | DataList_t m_newFormatList; |
197 | | DataList_t m_commentList; |
198 | | }; |
199 | | |
200 | | private: |
201 | | virtual bool parseDocument() = 0; |
202 | | |
203 | | private: |
204 | | void queryObject(unsigned id, unsigned &type, boost::optional<IWAMessage> &msg) const; |
205 | | const RVNGInputStreamPtr_t queryFile(unsigned id) const; |
206 | | |
207 | | void parseObjectIndex(); |
208 | | |
209 | | void parseCharacterStyle(unsigned id, IWORKStylePtr_t &style); |
210 | | void parseDropCapStyle(unsigned id, IWORKStylePtr_t &style); |
211 | | void parseParagraphStyle(unsigned id, IWORKStylePtr_t &style); |
212 | | void parseSectionStyle(unsigned id, IWORKStylePtr_t &style); |
213 | | |
214 | | void parseGraphicStyle(unsigned id, IWORKStylePtr_t &style); |
215 | | void parseMediaStyle(unsigned id, IWORKStylePtr_t &style); |
216 | | void parseCellStyle(unsigned id, IWORKStylePtr_t &style); |
217 | | void parseTableStyle(unsigned id, IWORKStylePtr_t &style); |
218 | | void parseListStyle(unsigned id, IWORKStylePtr_t &style); |
219 | | |
220 | | void parseHeaderAndFooter(unsigned id, IWORKPageMaster &hf); |
221 | | void parsePageMaster(unsigned id, PageMaster &pageMaster); |
222 | | |
223 | | void parseTabularModel(unsigned id); |
224 | | void parseDataList(unsigned id, DataList_t &dataList); |
225 | | void parseTile(unsigned id, unsigned decalY); |
226 | | void parseTileDefinition(unsigned row, unsigned col, RVNGInputStreamPtr_t &input, unsigned endPos, bool oldFormat); |
227 | | void parseTableHeaders(unsigned id, TableHeader &header); |
228 | | void parseTableGridLines(unsigned id, IWORKGridLineMap_t (&gridLines)[4]); |
229 | | void parseTableGridLine(unsigned id, IWORKGridLineMap_t &gridLines); |
230 | | void parseLink(unsigned id, std::string &url); |
231 | | |
232 | | bool parseAttachment(unsigned id); |
233 | | bool parseConditionRules(unsigned id, ConditionRule_t &rules); |
234 | | bool parseDrawableShape(const IWAMessage &msg, bool isConnectionLine=false); |
235 | | bool parseGroup(const IWAMessage &msg); |
236 | | bool parseShapePlacement(const IWAMessage &msg); |
237 | | bool parseImage(const IWAMessage &msg); |
238 | | bool parseTabularInfo(const IWAMessage &msg); |
239 | | bool parsePath(const IWAMessage &msg, IWORKPathPtr_t &path); |
240 | | bool parseFormula(const IWAMessage &msg, IWORKFormulaPtr_t &formula); |
241 | | bool parseFormat(const IWAMessage &msg, Format &format); |
242 | | virtual bool parseStickyNote(const IWAMessage &msg); |
243 | | |
244 | | bool parseArrowProperties(const IWAMessage &msg, IWORKPropertyMap &props, bool headArrow); |
245 | | void parseCharacterProperties(const IWAMessage &msg, IWORKPropertyMap &props); |
246 | | void parseColumnsProperties(const IWAMessage &msg, IWORKPropertyMap &props); |
247 | | |
248 | | private: |
249 | | IWORKCollector &m_collector; |
250 | | |
251 | | IWAObjectIndex m_index; |
252 | | |
253 | | std::deque<unsigned> m_visited; |
254 | | |
255 | | mutable StyleMap_t m_charStyles; |
256 | | mutable StyleMap_t m_dropCapStyles; |
257 | | mutable StyleMap_t m_paraStyles; |
258 | | mutable StyleMap_t m_sectionStyles; |
259 | | |
260 | | mutable StyleMap_t m_graphicStyles; |
261 | | mutable StyleMap_t m_mediaStyles; |
262 | | mutable StyleMap_t m_cellStyles; |
263 | | mutable StyleMap_t m_tableStyles; |
264 | | mutable StyleMap_t m_listStyles; |
265 | | |
266 | | std::shared_ptr<TableInfo> m_currentTable; |
267 | | std::map<uint64_t,Format> m_uidFormatMap; |
268 | | }; |
269 | | |
270 | | } |
271 | | |
272 | | #endif |
273 | | |
274 | | /* vim:set shiftwidth=2 softtabstop=2 expandtab: */ |