/src/libmwaw/src/lib/WingzGraph.cxx
Line | Count | Source |
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 | | #include <algorithm> |
35 | | #include <cmath> |
36 | | #include <iomanip> |
37 | | #include <iostream> |
38 | | #include <limits> |
39 | | #include <map> |
40 | | #include <sstream> |
41 | | #include <stack> |
42 | | |
43 | | #include <librevenge/librevenge.h> |
44 | | |
45 | | #include "MWAWFont.hxx" |
46 | | #include "MWAWFontConverter.hxx" |
47 | | #include "MWAWGraphicShape.hxx" |
48 | | #include "MWAWListener.hxx" |
49 | | #include "MWAWParagraph.hxx" |
50 | | #include "MWAWPosition.hxx" |
51 | | #include "MWAWSubDocument.hxx" |
52 | | |
53 | | #include "WingzParser.hxx" |
54 | | |
55 | | #include "WingzGraph.hxx" |
56 | | |
57 | | /** Internal: the structures of a WingzGraph */ |
58 | | namespace WingzGraphInternal |
59 | | { |
60 | | //! Internal a Graphic of a WingzGraph |
61 | | struct Graphic { |
62 | | //! the constructor |
63 | | Graphic() |
64 | 521k | : m_type(-1) |
65 | 521k | , m_order(-1) |
66 | 521k | , m_position() |
67 | 521k | , m_relativePosition() |
68 | 521k | , m_style(MWAWGraphicStyle::emptyStyle()) |
69 | 521k | , m_vertices() |
70 | 521k | , m_children() |
71 | | |
72 | 521k | , m_textType(-1) |
73 | 521k | , m_textEntry() |
74 | 521k | , m_fontList() |
75 | 521k | , m_posToFontId() |
76 | 521k | , m_paragraph() |
77 | | |
78 | 521k | , m_flag(0) |
79 | 521k | { |
80 | 1.04M | for (auto &angle : m_angles) angle=0; |
81 | 521k | } |
82 | | //! the file type |
83 | | int m_type; |
84 | | //! the order |
85 | | int m_order; |
86 | | //! the cell |
87 | | MWAWBox2i m_position; |
88 | | //! the relative position (% of cell) |
89 | | MWAWBox2f m_relativePosition; |
90 | | //! the graphic style |
91 | | MWAWGraphicStyle m_style; |
92 | | //! the angles: for arc |
93 | | float m_angles[2]; |
94 | | //! the vertices list: poly (% of box) |
95 | | std::vector<MWAWVec2f> m_vertices; |
96 | | //! the children: group |
97 | | std::vector<std::shared_ptr<Graphic> > m_children; |
98 | | //! the data : if picture 0: data, if textbox/button 0:button, 1:title |
99 | | MWAWEntry m_entry[2]; |
100 | | //! the name/title basic font |
101 | | MWAWFont m_font[2]; |
102 | | |
103 | | // textbox |
104 | | //! the textbox type |
105 | | int m_textType; |
106 | | //! the textbox entry |
107 | | MWAWEntry m_textEntry; |
108 | | //! list of fonts: textbox |
109 | | std::vector<MWAWFont> m_fontList; |
110 | | //! map pos to fontId |
111 | | std::map<int, size_t> m_posToFontId; |
112 | | //! the paragraph: textbox |
113 | | MWAWParagraph m_paragraph; |
114 | | |
115 | | //! some flag (depending of type) |
116 | | int m_flag; |
117 | | }; |
118 | | |
119 | | //////////////////////////////////////// |
120 | | //! Internal: the state of a WingzGraph |
121 | | struct State { |
122 | | //! constructor |
123 | | State() |
124 | 8.31k | : m_patternList() |
125 | 8.31k | , m_pictureList() |
126 | 8.31k | , m_groupStack() |
127 | 8.31k | , m_inGroupDepth(0) |
128 | 8.31k | { |
129 | 8.31k | } |
130 | | //! init the pattern list |
131 | | void initPatterns(int vers); |
132 | | //! add a new graphic |
133 | | void addGraphic(std::shared_ptr<WingzGraphInternal::Graphic> graphic) |
134 | 203k | { |
135 | 203k | if (!m_groupStack.empty() && m_groupStack.top()) |
136 | 132k | m_groupStack.top()->m_children.push_back(graphic); |
137 | 71.1k | else |
138 | 71.1k | m_pictureList.push_back(graphic); |
139 | 203k | } |
140 | | //! the patterns list |
141 | | std::vector<MWAWGraphicStyle::Pattern> m_patternList; |
142 | | //! the list of picture |
143 | | std::vector<std::shared_ptr<Graphic> > m_pictureList; |
144 | | //! the group stack |
145 | | std::stack<std::shared_ptr<Graphic> > m_groupStack; |
146 | | //! the group actual depth |
147 | | int m_inGroupDepth; |
148 | | }; |
149 | | |
150 | | void State::initPatterns(int vers) |
151 | 1.57k | { |
152 | 1.57k | if (!m_patternList.empty()) |
153 | 0 | return; |
154 | 1.57k | static uint16_t const patternsWingz[] = { |
155 | 1.57k | 0x0,0x0,0x0,0x0/*none*/, 0xffff,0xffff,0xffff,0xffff, 0xfffb,0xffbf,0xfffb,0xffbf, 0xff77,0xffdd,0xff77,0xffdd, |
156 | 1.57k | 0x4411,0x4411,0x4411,0x4411, 0xfffb,0xfffb,0xfffb,0xfffb, 0x3333,0x3333,0x3333,0x3333, 0xfcf9,0xf3e7,0xcf9f,0x3f8e, |
157 | 1.57k | 0x1111,0x1111,0x1111,0x1111, 0x1881,0xb136,0x0660,0x631b, 0x2004,0x8010,0x0108,0x4002, 0x1010,0x1010,0x1010,0x01ff, |
158 | 1.57k | 0x0101,0x01ff,0x1010,0x10ff, |
159 | 1.57k | 0x0001,0x0010,0x0001,0x0010, 0x8040,0x2000,0x0001,0x0204, 0x7088,0x0505,0x0588,0x7002, 0xc7ab,0x11ba,0x7cba,0x91eb, |
160 | 1.57k | 0x1010,0x3844,0x8283,0x4428, 0x8142,0x2424,0x2424,0x1800, 0x007e,0x7e62,0x6262,0x7e00, 0x0000,0x0000,0x0000,0x0000, |
161 | 1.57k | 0x0000,0x0010,0x0000,0x0001, 0x0001,0x0010,0x0001,0x0010, 0x0044,0x0011,0x0044,0x0011, 0x0011,0x0011,0x0011,0x0011, |
162 | 1.57k | 0x00ff,0x00ff,0x00ff,0x00ff, |
163 | 1.57k | 0x1122,0x4488,0x1122,0x4488, 0x000f,0x000f,0x000f,0x000f, 0x1020,0x4080,0x1020,0x4080, 0x4000,0x40aa,0x4000,0x4000, |
164 | 1.57k | 0x4040,0x40ff,0x4040,0x4040, 0x1028,0x4482,0x0102,0x0408, 0x0814,0x2241,0x8800,0xaa00, 0x40a0,0x0000,0x040a,0x0000, |
165 | 1.57k | 0x8004,0x040a,0x1221,0xa030, 0xa141,0x221a,0x0808,0x1422, 0x0102,0x0408,0x102a,0x66ff, 0x62e3,0xe3dd,0x263e,0x3edd, |
166 | 1.57k | 0x0502,0x0002,0x058a,0x558a |
167 | 1.57k | }; |
168 | 1.57k | static uint16_t const patternsResolve[] = { |
169 | 1.57k | 0x0, 0x0, 0x0, 0x0, 0xffff, 0xffff, 0xffff, 0xffff, 0x7fff, 0xffff, 0xf7ff, 0xffff, 0x7fff, 0xf7ff, 0x7fff, 0xf7ff, |
170 | 1.57k | 0xffee, 0xffbb, 0xffee, 0xffbb, 0x77dd, 0x77dd, 0x77dd, 0x77dd, 0xaa55, 0xaa55, 0xaa55, 0xaa55, 0x8822, 0x8822, 0x8822, 0x8822, |
171 | 1.57k | 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0x4400, 0xaa00, 0x1100, 0x8800, 0xaa00, 0x8800, 0xaa00, 0x8800, 0x2200, 0x8800, 0x2200, |
172 | 1.57k | 0x8000, 0x800, 0x8000, 0x800, 0x0, 0x11, 0x0, 0x11, 0x8000, 0x0, 0x800, 0x0, 0x0, 0x0, 0x0, 0x0, |
173 | 1.57k | 0xeedd, 0xbb77, 0xeedd, 0xbb77, 0x3366, 0xcc99, 0x3366, 0xcc99, 0x1122, 0x4488, 0x1122, 0x4488, 0x8307, 0xe1c, 0x3870, 0xe0c1, |
174 | 1.57k | 0x306, 0xc18, 0x3060, 0xc081, 0x102, 0x408, 0x1020, 0x4080, 0xffff, 0x0, 0x0, 0x0, 0xff00, 0x0, 0x0, 0x0, |
175 | 1.57k | 0x77bb, 0xddee, 0x77bb, 0xddee, 0x99cc, 0x6633, 0x99cc, 0x6633, 0x8844, 0x2211, 0x8844, 0x2211, 0xe070, 0x381c, 0xe07, 0x83c1, |
176 | 1.57k | 0xc060, 0x3018, 0xc06, 0x381, 0x8040, 0x2010, 0x804, 0x201, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0x8080, 0x8080, 0x8080, 0x8080, |
177 | 1.57k | 0xffaa, 0xffaa, 0xffaa, 0xffaa, 0xe4e4, 0xe4e4, 0xe4e4, 0xe4e4, 0xffff, 0xff00, 0xff, 0x0, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, |
178 | 1.57k | 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0x0, 0xff00, 0x0, 0x8888, 0x8888, 0x8888, 0x8888, 0xff80, 0x8080, 0x8080, 0x8080, |
179 | 1.57k | 0x4ecf, 0xfce4, 0x473f, 0xf372, 0x6006, 0x36b1, 0x8118, 0x1b63, 0x2004, 0x4002, 0x1080, 0x801, 0x9060, 0x609, 0x9060, 0x609, |
180 | 1.57k | 0x8814, 0x2241, 0x8800, 0xaa00, 0x2050, 0x8888, 0x8888, 0x502, 0xaa00, 0x8000, 0x8800, 0x8000, 0x2040, 0x8000, 0x804, 0x200, |
181 | 1.57k | 0xf0f0, 0xf0f0, 0xf0f, 0xf0f, 0x77, 0x7777, 0x77, 0x7777, 0xff88, 0x8888, 0xff88, 0x8888, 0xaa44, 0xaa11, 0xaa44, 0xaa11, |
182 | 1.57k | 0x8244, 0x2810, 0x2844, 0x8201, 0x8080, 0x413e, 0x808, 0x14e3, 0x8142, 0x2418, 0x1020, 0x4080, 0x40a0, 0x0, 0x40a, 0x0, |
183 | 1.57k | 0x7789, 0x8f8f, 0x7798, 0xf8f8, 0xf1f8, 0x6cc6, 0x8f1f, 0x3663, 0xbf00, 0xbfbf, 0xb0b0, 0xb0b0, 0xff80, 0x8080, 0xff08, 0x808, |
184 | 1.57k | 0x1020, 0x54aa, 0xff02, 0x408, 0x8, 0x142a, 0x552a, 0x1408, 0x55a0, 0x4040, 0x550a, 0x404, 0x8244, 0x3944, 0x8201, 0x101 |
185 | 1.57k | }; |
186 | 1.57k | MWAWGraphicStyle::Pattern pat; |
187 | 1.57k | pat.m_dim=MWAWVec2i(8,8); |
188 | 1.57k | pat.m_data.resize(8); |
189 | 1.57k | pat.m_colors[0]=MWAWColor::white(); |
190 | 1.57k | pat.m_colors[1]=MWAWColor::black(); |
191 | 1.57k | uint16_t const *patPtr=vers==2 ? patternsWingz : patternsResolve; |
192 | 101k | for (int i=0; i<(vers==2 ? 39 : 64); ++i) { |
193 | 499k | for (size_t j=0; j<8; j+=2, ++patPtr) { |
194 | 399k | pat.m_data[j]=uint8_t((*patPtr)>>8); |
195 | 399k | pat.m_data[j+1]=uint8_t((*patPtr)&0xFF); |
196 | 399k | } |
197 | 99.9k | m_patternList.push_back(pat); |
198 | 99.9k | } |
199 | 1.57k | } |
200 | | |
201 | | //////////////////////////////////////// |
202 | | //! Internal: the subdocument of a WingzGraph |
203 | | class SubDocument final : public MWAWSubDocument |
204 | | { |
205 | | public: |
206 | | SubDocument(WingzGraph &pars, MWAWInputStreamPtr const &input, Graphic const &graph) |
207 | 60.5k | : MWAWSubDocument(pars.m_mainParser, input, MWAWEntry()) |
208 | 60.5k | , m_graphParser(pars) |
209 | 60.5k | , m_graphic(graph) |
210 | 60.5k | { |
211 | 60.5k | } |
212 | | |
213 | | //! destructor |
214 | 0 | ~SubDocument() final {} |
215 | | |
216 | | //! operator!= |
217 | | bool operator!=(MWAWSubDocument const &doc) const final; |
218 | | |
219 | | //! the parser function |
220 | | void parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType type) final; |
221 | | |
222 | | protected: |
223 | | /** the graph parser */ |
224 | | WingzGraph &m_graphParser; |
225 | | /** the graphic */ |
226 | | Graphic const &m_graphic; |
227 | | private: |
228 | | SubDocument(SubDocument const &orig) = delete; |
229 | | SubDocument &operator=(SubDocument const &orig) = delete; |
230 | | }; |
231 | | |
232 | | void SubDocument::parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType /*type*/) |
233 | 60.5k | { |
234 | 60.5k | if (!listener.get()) { |
235 | 0 | MWAW_DEBUG_MSG(("WingzGraphInternal::SubDocument::parse: no listener\n")); |
236 | 0 | return; |
237 | 0 | } |
238 | 60.5k | long pos = m_input->tell(); |
239 | 60.5k | m_graphParser.sendText(m_graphic); |
240 | 60.5k | m_input->seek(pos, librevenge::RVNG_SEEK_SET); |
241 | 60.5k | } |
242 | | |
243 | | bool SubDocument::operator!=(MWAWSubDocument const &doc) const |
244 | 0 | { |
245 | 0 | if (MWAWSubDocument::operator!=(doc)) return true; |
246 | 0 | auto const *sDoc = dynamic_cast<SubDocument const *>(&doc); |
247 | 0 | if (!sDoc) return true; |
248 | 0 | if (&m_graphParser != &sDoc->m_graphParser) return true; |
249 | 0 | if (&m_graphic != &sDoc->m_graphic) return true; |
250 | 0 | return false; |
251 | 0 | } |
252 | | } |
253 | | |
254 | | //////////////////////////////////////////////////////////// |
255 | | // constructor/destructor, ... |
256 | | //////////////////////////////////////////////////////////// |
257 | | WingzGraph::WingzGraph(WingzParser &parser) |
258 | 8.31k | : m_parserState(parser.getParserState()) |
259 | 8.31k | , m_state(new WingzGraphInternal::State) |
260 | 8.31k | , m_mainParser(&parser) |
261 | 8.31k | { |
262 | 8.31k | } |
263 | | |
264 | | WingzGraph::~WingzGraph() |
265 | 8.31k | { } |
266 | | |
267 | | int WingzGraph::version() const |
268 | 523k | { |
269 | 523k | return m_parserState->m_version; |
270 | 523k | } |
271 | | |
272 | | //////////////////////////////////////////////////////////// |
273 | | // |
274 | | // Intermediate level |
275 | | // |
276 | | //////////////////////////////////////////////////////////// |
277 | | |
278 | | //////////////////////////////////////////////////////////// |
279 | | // read a graphic zone |
280 | | //////////////////////////////////////////////////////////// |
281 | | bool WingzGraph::readGraphic() |
282 | 521k | { |
283 | 521k | auto input = m_parserState->m_input; |
284 | 521k | auto &ascFile = m_parserState->m_asciiFile; |
285 | 521k | long pos = input->tell(); |
286 | 521k | if (!input->checkPosition(pos+60)) { |
287 | 225 | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: the header seems bad\n")); |
288 | 225 | return false; |
289 | 225 | } |
290 | 521k | auto graphic=std::make_shared<WingzGraphInternal::Graphic>(); |
291 | 521k | auto type=static_cast<int>(input->readULong(1)); |
292 | 521k | if (type!=0xe) return false; |
293 | 521k | auto fl=static_cast<int>(input->readULong(1)); |
294 | 521k | auto dSz=static_cast<int>(input->readULong(2)); |
295 | 521k | int id= (fl==0) ? 0 : static_cast<int>(input->readULong(2)); |
296 | 521k | libmwaw::DebugStream f; |
297 | 521k | f << "Entries(Graphic):"; |
298 | 521k | if (fl!=0x80) f << "fl=" << std::hex << fl << std::dec << ","; |
299 | 521k | if (id) f << "id=" << id << ","; |
300 | 521k | long actPos=input->tell(); |
301 | 521k | auto nSz=static_cast<int>(input->readULong(1)); |
302 | 521k | if (nSz>15) { |
303 | 343k | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: the graphic title seems bad\n")); |
304 | 343k | f << "#nSz=" << nSz << ","; |
305 | 343k | } |
306 | 178k | else if (nSz) { |
307 | 62.1k | std::string name(""); |
308 | 519k | for (int i=0; i<nSz; ++i) name+=char(input->readULong(1)); |
309 | 62.1k | f << name << ","; |
310 | 62.1k | } |
311 | 521k | input->seek(actPos+16, librevenge::RVNG_SEEK_SET); |
312 | 521k | graphic->m_order=static_cast<int>(input->readULong(2)); |
313 | 521k | f << "order=" << graphic->m_order << ","; |
314 | 521k | auto val=static_cast<int>(input->readULong(2)); // always 0 |
315 | 521k | if (val) f << "f1=" << val << ","; |
316 | | // the position seem to be stored as cell + % of the cell width... |
317 | 521k | float decal[4]; |
318 | 2.08M | for (auto &d : decal) d=static_cast<float>(input->readULong(1))/255.f; |
319 | 521k | graphic->m_relativePosition=MWAWBox2f(MWAWVec2f(decal[2],decal[0]),MWAWVec2f(decal[3],decal[1])); |
320 | 521k | int dim[4]; // the cells which included the picture |
321 | 2.08M | for (auto &d : dim) d=static_cast<int>(input->readULong(2)); |
322 | 521k | graphic->m_position=MWAWBox2i(MWAWVec2i(dim[0],dim[1]),MWAWVec2i(dim[2],dim[3])); |
323 | 521k | f << "dim=" << dim[0] << ":" << decal[2] << "x" |
324 | 521k | << dim[1] << ":" << decal[0] << "<->" |
325 | 521k | << dim[2] << ":" << decal[3] << "x" |
326 | 521k | << dim[3] << ":" << decal[1] << ","; |
327 | 521k | type=graphic->m_type=static_cast<int>(input->readULong(2)); |
328 | 521k | val=static_cast<int>(input->readULong(2)); // always 0 |
329 | 521k | if (val) f << "f2=" << val << ","; |
330 | | |
331 | 521k | long endPos=pos+(version()==1 ? 4 : 8)+dSz; |
332 | 521k | long dataPos=input->tell(); |
333 | 521k | if (type==0 || type==2) { |
334 | 360k | for (int i=0; i<2; ++i) { // name, title |
335 | 240k | auto sSz=static_cast<int>(input->readULong(1)); |
336 | 240k | if (!input->checkPosition(input->tell()+sSz+1)) { |
337 | 99 | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: can not find the textbox name%d\n", i)); |
338 | 99 | return false; |
339 | 99 | } |
340 | 240k | if (!sSz) |
341 | 116k | continue; |
342 | 123k | graphic->m_entry[i].setBegin(input->tell()); |
343 | 123k | graphic->m_entry[i].setLength(sSz); |
344 | 123k | std::string name(""); |
345 | 5.32M | for (int c=0; c<sSz; ++c) name+=char(input->readULong(1)); |
346 | 123k | f << name << ","; |
347 | 123k | } |
348 | 120k | auto hasMacro=static_cast<int>(input->readLong(1)); |
349 | 120k | if (hasMacro==1) { |
350 | 8.61k | f << "macro,"; |
351 | 8.61k | if (!m_mainParser->readMacro()) return false; |
352 | 8.61k | } |
353 | 111k | else if (hasMacro) { |
354 | 13.7k | f << "###macro=" << hasMacro << ","; |
355 | 13.7k | ascFile.addPos(pos); |
356 | 13.7k | ascFile.addNote(f.str().c_str()); |
357 | 13.7k | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: can not find the textbox type\n")); |
358 | 13.7k | return false; |
359 | 13.7k | } |
360 | 120k | } |
361 | 499k | if (type==0 || type==2 || (type>=5 && type<=9)) { |
362 | 114k | bool canHaveShadow=true; |
363 | 114k | if (type>=5 && type<=9) { |
364 | 16.7k | static int const expectedSize[]= {0x38, 0x3c, 0x34, 0x40, 0x40 }; |
365 | 16.7k | if (!input->checkPosition(endPos) || dSz < expectedSize[type-5]) { |
366 | 1.62k | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: find bad size for shape\n")); |
367 | 1.62k | return false; |
368 | 1.62k | } |
369 | 15.0k | canHaveShadow=type==8; |
370 | 15.0k | } |
371 | 98.0k | else if (!input->checkPosition(input->tell()+30)) { |
372 | 51 | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: find bad size for text/button\n")); |
373 | 51 | return false; |
374 | 51 | } |
375 | 113k | int patId; |
376 | 113k | MWAWColor color; |
377 | 113k | MWAWGraphicStyle::Pattern pattern; |
378 | 113k | readPattern(pattern, patId); |
379 | 113k | if (patId) { |
380 | 75.9k | if (pattern.getUniqueColor(color)) { |
381 | 61.1k | graphic->m_style.setSurfaceColor(color); |
382 | 61.1k | if (!color.isWhite()) |
383 | 59.7k | f << "surf[col]=" << color << ","; |
384 | 61.1k | } |
385 | 14.8k | else { |
386 | 14.8k | f << "surf=" << pattern << ","; |
387 | 14.8k | graphic->m_style.setPattern(pattern); |
388 | 14.8k | } |
389 | 75.9k | } |
390 | 37.1k | else |
391 | 37.1k | f << "surf[col]=none,"; |
392 | 113k | val=int(input->readLong(1)); |
393 | 113k | if (val!=1) f << "f0=" << val << ","; |
394 | 113k | if (canHaveShadow) { |
395 | 98.7k | graphic->m_flag=val; |
396 | 98.7k | readColor(color, patId); |
397 | 98.7k | if (patId) { |
398 | 34.6k | if (graphic->m_flag&2) |
399 | 11.2k | graphic->m_style.setShadowColor(color); |
400 | 34.6k | f << "shadow[col]=" << color << ","; |
401 | 34.6k | } |
402 | 98.7k | val=int(input->readLong(1)); |
403 | 98.7k | if (val) f << "f1=" << val << ","; |
404 | 98.7k | } |
405 | 113k | readColor(color, patId); |
406 | 113k | bool hasLine=true; |
407 | 113k | if (patId && !color.isBlack()) { |
408 | 68.9k | f << "line[col]=" << color << ","; |
409 | 68.9k | graphic->m_style.m_lineColor=color; |
410 | 68.9k | } |
411 | 44.1k | else if (!patId) { |
412 | 40.1k | hasLine=false; |
413 | 40.1k | f << "line[col]=none,"; |
414 | 40.1k | } |
415 | 113k | val=int(input->readLong(1)); |
416 | 113k | if (val!=1) f << "f2=" << val << ","; |
417 | | |
418 | 113k | val=static_cast<int>(input->readLong(2)); |
419 | 113k | if (hasLine) graphic->m_style.m_lineWidth=float(val)/20.f; |
420 | 113k | if (val!=5) f << "line[w]=" << float(val)/20.f << ","; |
421 | 113k | if (canHaveShadow) { |
422 | 296k | for (int i=0; i<2; ++i) dim[i]=int(input->readLong(2)); |
423 | 98.7k | if (dim[0]!=20 || dim[1]!=20) { |
424 | 98.5k | graphic->m_style.m_shadowOffset=MWAWVec2f(float(dim[0])/20.f,float(dim[1])/20.f); |
425 | 98.5k | f << "shadow[pos]=" << graphic->m_style.m_shadowOffset << ","; |
426 | 98.5k | } |
427 | 98.7k | } |
428 | 113k | } |
429 | 497k | switch (type) { |
430 | 86.8k | case 0: // button |
431 | 98.0k | case 2: { // textbox |
432 | 98.0k | f << "TextZone,g0=" << std::hex << dSz << std::dec << ","; |
433 | 98.0k | ascFile.addPos(pos); |
434 | 98.0k | ascFile.addNote(f.str().c_str()); |
435 | 98.0k | return readTextZone(graphic); |
436 | 86.8k | } |
437 | 2.87k | case 4: |
438 | 2.87k | f << "Chart,"; |
439 | 2.87k | ascFile.addPos(pos); |
440 | 2.87k | ascFile.addNote(f.str().c_str()); |
441 | 2.87k | return readChartData(graphic); |
442 | 658 | case 5: |
443 | 3.94k | case 6: |
444 | 4.86k | case 7: |
445 | 5.61k | case 8: |
446 | 15.0k | case 9: { |
447 | 15.0k | static int const expectedSize[]= {0x38, 0x3c, 0x34, 0x40, 0x40 }; |
448 | 15.0k | if (!input->checkPosition(endPos) || dSz < expectedSize[type-5]) { |
449 | 0 | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: find bad size for shape\n")); |
450 | 0 | return false; |
451 | 0 | } |
452 | 15.0k | static char const* const what[]= {"line", "arc", "circle", "rectangle", "poly" }; |
453 | 15.0k | f << what[type-5] << ","; |
454 | 15.0k | switch (type) { |
455 | 658 | case 5: { |
456 | 658 | int arrowWidth=static_cast<int>(input->readLong(2)); |
457 | 658 | if (arrowWidth!=0x21c) f << "arrow[size]=" << double(arrowWidth)/20. << ","; // default 27 point |
458 | 658 | val=static_cast<int>(input->readULong(2)); |
459 | 658 | if (val&0x40) { |
460 | 269 | f << "start[arrow],"; |
461 | 269 | graphic->m_style.m_arrows[0]= |
462 | 269 | MWAWGraphicStyle::Arrow(float(arrowWidth)/20.f, MWAWBox2i(MWAWVec2i(0,0),MWAWVec2i(3000,3000)), |
463 | 269 | "M1500 0l1500 3000h-3000zM1500 447l-1176 2353h2353z", false); |
464 | 269 | } |
465 | 658 | if (val&0x80) { |
466 | 271 | f << "start[end],"; |
467 | 271 | graphic->m_style.m_arrows[1]= |
468 | 271 | MWAWGraphicStyle::Arrow(float(arrowWidth)/20.f, MWAWBox2i(MWAWVec2i(0,0),MWAWVec2i(3000,3000)), |
469 | 271 | "M1500 0l1500 3000h-3000zM1500 447l-1176 2353h2353z", false); |
470 | 271 | } |
471 | 658 | graphic->m_flag=(val&3); |
472 | 658 | if (graphic->m_flag&3) f << "rot=" << (graphic->m_flag&3) << ","; |
473 | 658 | val &= 0xff3c; |
474 | 658 | if (val) f << "fl=" << std::hex << val << std::dec << ","; |
475 | 658 | break; |
476 | 0 | } |
477 | 3.29k | case 6: { |
478 | 9.87k | for (int i=0; i<2; ++i) { // 0|3fff |
479 | 6.58k | val=int(input->readULong(2)); |
480 | 6.58k | if (!val) continue; |
481 | 5.79k | if (val==0x3fff) |
482 | 14 | f << "h" << i << "*,"; |
483 | 5.78k | else |
484 | 5.78k | f << "h" << i << "=" << val << ","; |
485 | 5.79k | } |
486 | 6.58k | for (auto &angle : graphic->m_angles) angle=float(input->readLong(2))/10.f; |
487 | 3.29k | f << "angles=" << MWAWVec2f(graphic->m_angles[0],graphic->m_angles[1]) << ","; |
488 | 3.29k | break; |
489 | 0 | } |
490 | 918 | case 7: |
491 | 918 | break; |
492 | 743 | case 8: { |
493 | 743 | break; |
494 | 0 | } |
495 | 9.48k | case 9: { |
496 | 9.48k | val=static_cast<int>(input->readULong(2)); |
497 | 9.48k | if (val&1) f << "closed,"; |
498 | 9.48k | if (val&2) f << "smooth,"; |
499 | 9.48k | graphic->m_flag=val; |
500 | 9.48k | int arrowWidth=static_cast<int>(input->readLong(2)); |
501 | 9.48k | if (arrowWidth!=0x21c) f << "arrow[size]=" << double(arrowWidth)/20. << ","; // default 27 point |
502 | 9.48k | if (val&0x40) { |
503 | 423 | f << "start[arrow],"; |
504 | 423 | graphic->m_style.m_arrows[0]= |
505 | 423 | MWAWGraphicStyle::Arrow(float(arrowWidth)/20.f, MWAWBox2i(MWAWVec2i(0,0),MWAWVec2i(3000,3000)), |
506 | 423 | "M1500 0l1500 3000h-3000zM1500 447l-1176 2353h2353z", false); |
507 | 423 | } |
508 | 9.48k | if (val&0x80) { |
509 | 2.81k | f << "start[end],"; |
510 | 2.81k | graphic->m_style.m_arrows[0]= |
511 | 2.81k | MWAWGraphicStyle::Arrow(float(arrowWidth)/20.f, MWAWBox2i(MWAWVec2i(0,0),MWAWVec2i(3000,3000)), |
512 | 2.81k | "M1500 0l1500 3000h-3000zM1500 447l-1176 2353h2353z", false); |
513 | 2.81k | } |
514 | 9.48k | val &= 0xff3c; |
515 | 9.48k | if (val) f << "h0=" << val << ","; |
516 | 9.48k | int nbPt=int(input->readULong(2)); |
517 | 9.48k | f << "nbPt=" << nbPt << ","; |
518 | 9.48k | if (input->tell()+nbPt*4>endPos) { |
519 | 1.84k | f << "###"; |
520 | 1.84k | break; |
521 | 1.84k | } |
522 | 7.63k | f << "pts=["; |
523 | 47.5k | for (int i=0; i<nbPt; ++i) { |
524 | 39.9k | float pts[2]; |
525 | 79.8k | for (auto &pt : pts) pt=float(input->readULong(2))/float(0x3fff); |
526 | 39.9k | graphic->m_vertices.push_back(MWAWVec2f(pts[0],pts[1])); |
527 | 39.9k | f << graphic->m_vertices.back() << ","; |
528 | 39.9k | } |
529 | 7.63k | f << "],"; |
530 | 7.63k | break; |
531 | 9.48k | } |
532 | 0 | default: |
533 | 0 | break; |
534 | 15.0k | } |
535 | 15.0k | break; |
536 | 15.0k | } |
537 | 43.2k | case 0xa: { |
538 | 43.2k | if (!input->checkPosition(endPos)) { |
539 | 55 | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: find bad size for picture\n")); |
540 | 55 | return false; |
541 | 55 | } |
542 | 43.1k | f << "picture,"; |
543 | 43.1k | auto pSz=long(input->readULong(2)); |
544 | 129k | for (int i=0; i<2; ++i) { // g0=0, g1=2 |
545 | 86.3k | val=static_cast<int>(input->readULong(2)); |
546 | 86.3k | if (val) f << "g" << i << "=" << val << ","; |
547 | 86.3k | } |
548 | 43.1k | ascFile.addPos(pos); |
549 | 43.1k | ascFile.addNote(f.str().c_str()); |
550 | 43.1k | if (!pSz || !input->checkPosition(dataPos+6+pSz)) { |
551 | 2.47k | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: can not find the picture data\n")); |
552 | 2.47k | return false; |
553 | 2.47k | } |
554 | 40.6k | graphic->m_entry[0].setBegin(dataPos+6); |
555 | 40.6k | graphic->m_entry[0].setLength(pSz); |
556 | | #ifdef DEBUG_WITH_FILES |
557 | | ascFile.skipZone(dataPos+6, dataPos+6+pSz-1); |
558 | | librevenge::RVNGBinaryData file; |
559 | | input->seek(dataPos+6, librevenge::RVNG_SEEK_SET); |
560 | | input->readDataBlock(pSz, file); |
561 | | static int volatile pictName = 0; |
562 | | libmwaw::DebugStream f2; |
563 | | f2.str(""); |
564 | | f2 << "PICT-" << ++pictName; |
565 | | libmwaw::Debug::dumpFile(file, f2.str().c_str()); |
566 | | #endif |
567 | 40.6k | input->seek(dataPos+6+pSz, librevenge::RVNG_SEEK_SET); |
568 | 40.6k | break; |
569 | 43.1k | } |
570 | 86.8k | case 0xb: { |
571 | 86.8k | if (!input->checkPosition(endPos)) { |
572 | 57 | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: find bad size for group\n")); |
573 | 57 | return false; |
574 | 57 | } |
575 | 86.8k | f << "group,"; |
576 | 86.8k | break; |
577 | 86.8k | } |
578 | 251k | default: |
579 | 251k | MWAW_DEBUG_MSG(("WingzGraph::readGraphic: find some unknown type %d\n", type)); |
580 | 251k | f << "#typ=" << type << ","; |
581 | 251k | ascFile.addPos(pos); |
582 | 251k | ascFile.addNote(f.str().c_str()); |
583 | 251k | return false; |
584 | 497k | } |
585 | 142k | m_state->addGraphic(graphic); |
586 | 142k | if (graphic->m_type==0xb) |
587 | 86.8k | m_state->m_groupStack.push(graphic); |
588 | 142k | if (input->tell()!=pos && input->tell()!=endPos) |
589 | 142k | ascFile.addDelimiter(input->tell(),'|'); |
590 | 142k | ascFile.addPos(pos); |
591 | 142k | ascFile.addNote(f.str().c_str()); |
592 | 142k | input->seek(endPos, librevenge::RVNG_SEEK_SET); |
593 | 142k | return true; |
594 | 497k | } |
595 | | |
596 | | bool WingzGraph::readEndGroup() |
597 | 601 | { |
598 | 601 | auto input = m_parserState->m_input; |
599 | 601 | auto &ascFile = m_parserState->m_asciiFile; |
600 | 601 | long pos = input->tell(); |
601 | 601 | if (!input->checkPosition(pos+4)) { |
602 | 0 | MWAW_DEBUG_MSG(("WingzGraph::readEndGroup: the header seems bad\n")); |
603 | 0 | return false; |
604 | 0 | } |
605 | 601 | auto type=static_cast<int>(input->readULong(1)); |
606 | 601 | if (type!=0xf) return false; |
607 | 601 | auto fl=static_cast<int>(input->readULong(1)); |
608 | 601 | auto dSz=static_cast<int>(input->readULong(2)); |
609 | 601 | int id= (fl==0) ? 0 : static_cast<int>(input->readULong(2)); |
610 | 601 | libmwaw::DebugStream f; |
611 | 601 | f << "Entries(Group)[end]:"; |
612 | 601 | if (fl!=0x80) f << "fl=" << std::hex << fl << std::dec << ","; |
613 | 601 | if (id) f << "id=" << id << ","; |
614 | 601 | if (!input->checkPosition(input->tell()+dSz)) { |
615 | 9 | MWAW_DEBUG_MSG(("WingzGraph::readEndGroup: the header seems bad\n")); |
616 | 9 | return false; |
617 | 9 | } |
618 | 592 | if (dSz) { |
619 | 103 | ascFile.addDelimiter(input->tell(),'|'); |
620 | 103 | input->seek(dSz, librevenge::RVNG_SEEK_CUR); |
621 | 103 | } |
622 | 592 | ascFile.addPos(pos); |
623 | 592 | ascFile.addNote(f.str().c_str()); |
624 | 592 | if (m_state->m_groupStack.empty()) { |
625 | 490 | MWAW_DEBUG_MSG(("WingzGraph::readEndGroup: can not found the group beginning\n")); |
626 | 490 | } |
627 | 102 | else |
628 | 102 | m_state->m_groupStack.pop(); |
629 | 592 | return true; |
630 | 601 | } |
631 | | |
632 | | //////////////////////////////////////////////////////////// |
633 | | // text box |
634 | | //////////////////////////////////////////////////////////// |
635 | | bool WingzGraph::readTextZone(std::shared_ptr<WingzGraphInternal::Graphic> graphic) |
636 | 98.0k | { |
637 | 98.0k | auto input = m_parserState->m_input; |
638 | 98.0k | auto &ascFile = m_parserState->m_asciiFile; |
639 | 98.0k | long pos = input->tell(); |
640 | 98.0k | if (!input->checkPosition(pos+18)) { |
641 | 52 | MWAW_DEBUG_MSG(("WingzGraph::readTextZone: the zone seems too short\n")); |
642 | 52 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
643 | 52 | return false; |
644 | 52 | } |
645 | | |
646 | 97.9k | libmwaw::DebugStream f; |
647 | 97.9k | f << "Entries(TextZone):"; |
648 | 97.9k | int patId; |
649 | 97.9k | MWAWColor color; |
650 | 97.9k | readColor(color, patId); |
651 | 97.9k | if (patId) |
652 | 59.9k | f << "col[unkn]=" << color << ","; |
653 | 97.9k | int val=int(input->readULong(1)); |
654 | 97.9k | if (val!=1) f << "f0=" << val << ","; |
655 | 97.9k | auto fontConverter=m_parserState->m_fontConverter; |
656 | 237k | for (int i=0; i<2; ++i) { // actual font and generic font ? |
657 | 176k | MWAWFont font; |
658 | 176k | f << "font" << i << "=["; |
659 | 176k | unsigned char colors[3]; |
660 | 530k | for (auto &c : colors) c=static_cast<unsigned char>(input->readULong(1)); |
661 | 176k | font.setColor(MWAWColor(colors[0],colors[1],colors[2])); |
662 | 176k | val=int(input->readLong(1)); // 0 |
663 | 176k | if (val) f << "f0=" << val << ","; |
664 | 176k | font.setSize(float(input->readULong(1))); |
665 | 176k | auto flag=static_cast<int>(input->readULong(1)); |
666 | 176k | uint32_t flags=0; |
667 | 176k | if (flag&0x1) flags |= MWAWFont::boldBit; |
668 | 176k | if (flag&0x2) flags |= MWAWFont::italicBit; |
669 | 176k | if (flag&0x4) font.setUnderlineStyle(MWAWFont::Line::Simple); |
670 | 176k | if (flag&0x8) flags |= MWAWFont::embossBit; |
671 | 176k | if (flag&0x10) flags |= MWAWFont::shadowBit; |
672 | 176k | if (flag&0x60) |
673 | 32.5k | f << "#font[flag]=" << std::hex << (flag&0x60) << std::dec << ","; |
674 | 176k | font.setFlags(flags); |
675 | 176k | auto sSz=static_cast<int>(input->readULong(1)); |
676 | 176k | if (!sSz || !input->checkPosition(input->tell()+4+sSz)) { |
677 | 36.8k | MWAW_DEBUG_MSG(("WingzGraph::readTextZone: can not determine the string zone %d\n", i)); |
678 | 36.8k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
679 | 36.8k | return false; |
680 | 36.8k | } |
681 | 139k | std::string name(""); |
682 | 5.37M | for (int j=0; j<sSz; ++j) |
683 | 5.23M | name+=char(input->readLong(1)); |
684 | 139k | font.setId(fontConverter->getId(name)); |
685 | 139k | f << font.getDebugString(fontConverter); |
686 | 139k | f << "],"; |
687 | 139k | graphic->m_font[i]=font; |
688 | 139k | } |
689 | 244k | for (int i=0; i<3; ++i) { |
690 | 183k | val=static_cast<int>(input->readLong(2)); |
691 | 183k | if (val) f << "g" << i << "=" << val; |
692 | 183k | } |
693 | 61.1k | ascFile.addPos(pos); |
694 | 61.1k | ascFile.addNote(f.str().c_str()); |
695 | | |
696 | 61.1k | pos=input->tell(); |
697 | 61.1k | f.str(""); |
698 | 61.1k | f << "TextZone-A:"; |
699 | 61.1k | graphic->m_textType=static_cast<int>(input->readLong(1)); |
700 | 61.1k | m_state->addGraphic(graphic); |
701 | 61.1k | bool ok=true; |
702 | 61.1k | switch (graphic->m_textType) { |
703 | 1.32k | case 0: |
704 | 1.32k | f << "button,"; |
705 | 1.32k | val=static_cast<int>(input->readLong(1)); |
706 | 1.32k | if (val!=3) f << "f0=" << val << ","; |
707 | 1.32k | val=static_cast<int>(input->readLong(1)); |
708 | 1.32k | if (val==0) f << "noContent,"; |
709 | 1.20k | else if (val!=1) f << "#content=" << val << ","; |
710 | 1.32k | val=static_cast<int>(input->readLong(1)); |
711 | 1.32k | if (val==1) f << "title,"; |
712 | 1.28k | else if (val) f << "#title=" << val << ","; |
713 | 1.32k | val=static_cast<int>(input->readULong(1)); |
714 | 1.32k | if (val) f << "h[content]=" << val << ","; |
715 | 1.32k | val=static_cast<int>(input->readULong(1)); |
716 | 1.32k | if (val) f << "h[title]=" << val << ","; |
717 | 1.32k | ascFile.addPos(pos); |
718 | 1.32k | ascFile.addNote(f.str().c_str()); |
719 | 1.32k | return true; |
720 | 43.1k | case 1: |
721 | 43.1k | ok=input->checkPosition(pos+60); |
722 | 43.1k | if (!ok) break; |
723 | 43.1k | f << "text,"; |
724 | 43.1k | break; |
725 | 2.98k | case 5: { |
726 | 2.98k | ok=input->checkPosition(pos+53); |
727 | 2.98k | if (!ok) break; |
728 | 2.98k | f << "wheel,"; |
729 | 17.9k | for (int i=0; i<5; ++i) { |
730 | 14.9k | val=int(input->readLong(1)); |
731 | 14.9k | int const expected[]= {3,0,0,0,0}; |
732 | 14.9k | if (val!=expected[i]) f << "f" << i << "=" << val << ","; |
733 | 14.9k | } |
734 | 2.98k | bool isNan; |
735 | 2.98k | double value; |
736 | 2.98k | f << "val=["; |
737 | 17.9k | for (int i=0; i<5; ++i) { // val, minVal, maxVal, incr?, maxVal-minVal? |
738 | 14.9k | if (!input->readDoubleReverted8(value,isNan)) { |
739 | 4.98k | f << "###,"; |
740 | 4.98k | input->seek(pos+6+8*(i+1), librevenge::RVNG_SEEK_SET); |
741 | 4.98k | } |
742 | 9.94k | else |
743 | 9.94k | f << value << ","; |
744 | 14.9k | } |
745 | 2.98k | f << "],"; |
746 | 11.9k | for (int i=0; i<3; ++i) { // small number |
747 | 8.95k | val=int(input->readLong(2)); |
748 | 8.95k | if (val) f << "g" << i << "=" << val << ","; |
749 | 8.95k | } |
750 | 2.98k | ascFile.addDelimiter(input->tell(),'|'); |
751 | 2.98k | input->seek(pos+53, librevenge::RVNG_SEEK_SET); |
752 | 2.98k | break; |
753 | 2.98k | } |
754 | 525 | case 6: { |
755 | 525 | ok=input->checkPosition(pos+40); |
756 | 525 | if (!ok) break; |
757 | 524 | f << "button[wheel],"; |
758 | 3.14k | for (int i=0; i<5; ++i) { |
759 | 2.62k | val=int(input->readLong(1)); |
760 | 2.62k | int const expected[]= {3,0,0,0,0}; |
761 | 2.62k | if (val!=expected[i]) f << "f" << i << "=" << val << ","; |
762 | 2.62k | } |
763 | 524 | bool isNan; |
764 | 524 | double value; |
765 | 524 | f << "val=["; |
766 | 2.62k | for (int i=0; i<4; ++i) { // val?, min, max, increment? |
767 | 2.09k | if (!input->readDoubleReverted8(value,isNan)) { |
768 | 1.02k | f << "###,"; |
769 | 1.02k | input->seek(pos+6+8*(i+1), librevenge::RVNG_SEEK_SET); |
770 | 1.02k | } |
771 | 1.07k | else |
772 | 1.07k | f << value << ","; |
773 | 2.09k | } |
774 | 524 | f << "],"; |
775 | 524 | val=int(input->readLong(2)); // 0 |
776 | 524 | if (val) f << "f5=" << val << ","; |
777 | 524 | input->seek(pos+40, librevenge::RVNG_SEEK_SET); |
778 | 524 | break; |
779 | 525 | } |
780 | 13.1k | default: |
781 | 13.1k | MWAW_DEBUG_MSG(("WingzGraph::readTextZone: find unknown type %d\n", graphic->m_textType)); |
782 | 13.1k | f << "###type=" << graphic->m_textType; |
783 | 13.1k | ok=false; |
784 | 13.1k | break; |
785 | 61.1k | } |
786 | | |
787 | 59.8k | if (!ok || graphic->m_textType!=1) { |
788 | 16.6k | ascFile.addPos(pos); |
789 | 16.6k | ascFile.addNote(f.str().c_str()); |
790 | 16.6k | if (ok) return true; |
791 | 13.1k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
792 | 13.1k | return m_mainParser->findNextZone(0xe) && input->tell()>pos; |
793 | 16.6k | } |
794 | 43.1k | val=static_cast<int>(input->readLong(1)); |
795 | 43.1k | if (val!=3) f<<"f0=" << val << ","; |
796 | 43.1k | auto ¶=graphic->m_paragraph; |
797 | 258k | for (int i=0; i<5; ++i) { |
798 | 215k | val=static_cast<int>(input->readULong(2)); |
799 | 215k | if (i==2 && (val>>12)) { // 1 left, 2 center, 3 right |
800 | 25.5k | switch ((val>>12)&3) { |
801 | 1.34k | case 0: |
802 | 1.34k | default: |
803 | 1.34k | f << "#align=0,"; |
804 | 1.34k | break; |
805 | 9.20k | case 1: // left |
806 | 9.20k | break; |
807 | 10.7k | case 2: |
808 | 10.7k | para.m_justify = MWAWParagraph::JustificationCenter; |
809 | 10.7k | f << "center,"; |
810 | 10.7k | break; |
811 | 4.24k | case 3: |
812 | 4.24k | para.m_justify = MWAWParagraph::JustificationRight; |
813 | 4.24k | f << "right,"; |
814 | 4.24k | break; |
815 | 25.5k | } |
816 | 25.5k | val &= 0xCFFF; |
817 | 25.5k | } |
818 | 215k | if (val) f<<"f" << i+1 << "=" << std::hex << val << std::dec << ","; |
819 | 215k | } |
820 | 43.1k | val=static_cast<int>(input->readULong(4)); |
821 | 43.1k | auto textSize=static_cast<int>(input->readLong(4)); |
822 | 43.1k | if (val!=textSize) |
823 | 37.2k | f << "selection="<<val << ","; |
824 | 43.1k | val=static_cast<int>(input->readLong(2)); // 1|7 |
825 | 43.1k | if (val!=1) f << "g0=" << val << ","; |
826 | 43.1k | val=static_cast<int>(input->readLong(2)); |
827 | 43.1k | if (val) f << "g1=" << val << ","; |
828 | 129k | for (int i=0; i< 2; ++i) { // g2=0|1, g3=4|6, g3=64 -> scroll bar, g3&1 -> cell note? |
829 | 86.2k | val=static_cast<int>(input->readULong(1)); |
830 | 86.2k | static int const expected[]= {0,0x40}; |
831 | 86.2k | if (val!=expected[i]) |
832 | 60.2k | f << "g" << i+2 << "=" << std::hex << val << std::dec << ","; |
833 | 86.2k | } |
834 | 43.1k | auto numFonts=static_cast<int>(input->readLong(2)); |
835 | 43.1k | if (numFonts!=1) f << "numFonts=" << numFonts << ","; |
836 | 43.1k | val=static_cast<int>(input->readLong(2)); |
837 | 43.1k | if (val) f << "h0=" << val << ","; |
838 | 43.1k | auto numPos=static_cast<int>(input->readULong(2)); |
839 | 43.1k | if (numPos!=1) f << "numPos=" << numPos << ","; |
840 | 647k | for (int i=0; i<14; ++i) { |
841 | 603k | val=static_cast<int>(input->readLong(2)); |
842 | 603k | if (!val) continue; |
843 | 382k | if (i==3) f << "marg[top]=" << double(val)/20. << ","; |
844 | 352k | else if (i==4) f << "marg[bottom]=" << double(val)/20. << ","; |
845 | 326k | else if (i==7) f << "tabs[repeat]=" << double(val)/20. << ","; |
846 | 297k | else |
847 | 297k | f << "h" << i+1 << "=" << val << ","; |
848 | 382k | } |
849 | 43.1k | ascFile.addPos(pos); |
850 | 43.1k | ascFile.addNote(f.str().c_str()); |
851 | | |
852 | 43.1k | pos=input->tell(); |
853 | 43.1k | if (textSize<0 || (long)((unsigned long)pos+(unsigned long)textSize)<pos || !input->checkPosition(pos+textSize)) { |
854 | 4.84k | MWAW_DEBUG_MSG(("WingzGraph::readTextZone: the text zone seems bad\n")); |
855 | 4.84k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
856 | 4.84k | return false; |
857 | 4.84k | } |
858 | 38.2k | f.str(""); |
859 | 38.2k | f << "TextZone[text]:"; |
860 | 38.2k | graphic->m_textEntry.setBegin(input->tell()); |
861 | 38.2k | graphic->m_textEntry.setLength(textSize); |
862 | 38.2k | std::string text(""); |
863 | 2.20M | for (int i=0; i< textSize; ++i) text+=char(input->readULong(1)); |
864 | 38.2k | f << text; |
865 | 38.2k | ascFile.addPos(pos); |
866 | 38.2k | ascFile.addNote(f.str().c_str()); |
867 | | |
868 | 38.2k | pos=input->tell(); |
869 | 38.2k | if (!input->checkPosition(pos+numFonts*7)) { |
870 | 2.66k | MWAW_DEBUG_MSG(("WingzGraph::readTextZone: the fonts zone seems bad\n")); |
871 | 2.66k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
872 | 2.66k | return false; |
873 | 2.66k | } |
874 | 35.6k | f.str(""); |
875 | 35.6k | f << "TextZone[fonts]:"; |
876 | 92.7k | for (int i=0; i<numFonts; ++i) { |
877 | 70.0k | f << "font" << i << "=["; |
878 | 70.0k | MWAWFont font; |
879 | 70.0k | unsigned char colors[3]; |
880 | 210k | for (auto &c : colors) c=static_cast<unsigned char>(input->readULong(1)); |
881 | 70.0k | font.setColor(MWAWColor(colors[0],colors[1],colors[2])); |
882 | 70.0k | val=int(input->readLong(1)); // 0 |
883 | 70.0k | if (val) f << "f0=" << val << ","; |
884 | 70.0k | font.setSize(float(input->readULong(1))); |
885 | 70.0k | auto flag=static_cast<int>(input->readULong(1)); |
886 | 70.0k | uint32_t flags=0; |
887 | 70.0k | if (flag&0x1) flags |= MWAWFont::boldBit; |
888 | 70.0k | if (flag&0x2) flags |= MWAWFont::italicBit; |
889 | 70.0k | if (flag&0x4) font.setUnderlineStyle(MWAWFont::Line::Simple); |
890 | 70.0k | if (flag&0x8) flags |= MWAWFont::embossBit; |
891 | 70.0k | if (flag&0x10) flags |= MWAWFont::shadowBit; |
892 | 70.0k | if (flag&0x60) |
893 | 34.3k | f << "#font[flag]=" << std::hex << (flag&0x60) << std::dec << ","; |
894 | 70.0k | font.setFlags(flags); |
895 | 70.0k | auto sSz=static_cast<int>(input->readULong(1)); |
896 | 70.0k | if (!sSz || !input->checkPosition(input->tell()+sSz)) { |
897 | 12.9k | MWAW_DEBUG_MSG(("WingzGraph::readTextZone: can not determine the string zone %d\n", i)); |
898 | 12.9k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
899 | 12.9k | return false; |
900 | 12.9k | } |
901 | 57.1k | std::string name(""); |
902 | 4.11M | for (int j=0; j<sSz; ++j) |
903 | 4.05M | name+=char(input->readLong(1)); |
904 | 57.1k | font.setId(fontConverter->getId(name)); |
905 | 57.1k | f << font.getDebugString(fontConverter); |
906 | 57.1k | f << "],"; |
907 | 57.1k | graphic->m_fontList.push_back(font); |
908 | 57.1k | } |
909 | 22.7k | ascFile.addPos(pos); |
910 | 22.7k | ascFile.addNote(f.str().c_str()); |
911 | | |
912 | 22.7k | pos=input->tell(); |
913 | 22.7k | if (!input->checkPosition(pos+16+numPos*6)) { |
914 | 1.26k | MWAW_DEBUG_MSG(("WingzGraph::readTextZone: the last zone seems bad\n")); |
915 | 1.26k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
916 | 1.26k | return false; |
917 | 1.26k | } |
918 | 21.4k | f.str(""); |
919 | 21.4k | f << "TextZone-B:"; |
920 | 21.4k | double extraLeading=0; |
921 | 21.4k | para.m_marginsUnit=librevenge::RVNG_POINT; |
922 | 171k | for (int i=0; i<7; ++i) { |
923 | 150k | val=static_cast<int>(input->readLong(2)); |
924 | 150k | if (val==0) continue; |
925 | 91.5k | switch (i) { |
926 | 16.0k | case 2: |
927 | 16.0k | para.m_margins[1]=double(val)/20.; |
928 | 16.0k | f << "marg[left]=" << double(val)/20. << ","; |
929 | 16.0k | break; |
930 | 11.8k | case 3: |
931 | 11.8k | para.m_margins[2]=double(val)/20.; |
932 | 11.8k | f << "marg[right]=" << double(val)/20. << ","; |
933 | 11.8k | break; |
934 | 14.9k | case 4: |
935 | 14.9k | para.m_margins[0]=double(val)/20.; |
936 | 14.9k | f << "para[indent]=" << double(val)/20. << ","; |
937 | 14.9k | break; |
938 | 13.7k | case 5: |
939 | 13.7k | extraLeading=double(val)/20; |
940 | 13.7k | f << "height[leading]=" << extraLeading << ","; |
941 | 13.7k | break; |
942 | 35.0k | default: |
943 | 35.0k | f << "f" << i << "=" << val << ","; |
944 | 35.0k | break; |
945 | 91.5k | } |
946 | 91.5k | } |
947 | 21.4k | val=static_cast<int>(input->readLong(1)); |
948 | 21.4k | switch (val) { |
949 | 1.50k | case 1: // normal |
950 | 1.50k | break; |
951 | 363 | case 2: |
952 | 363 | para.setInterline(2, librevenge::RVNG_PERCENT); |
953 | 363 | f << "interline=200%,"; |
954 | 363 | break; |
955 | 413 | case 3: |
956 | 413 | para.setInterline(1.5, librevenge::RVNG_PERCENT); |
957 | 413 | f << "interline=150%,"; |
958 | 413 | break; |
959 | 4 | case 4: |
960 | 4 | f << "interline=fixed,"; |
961 | 4 | break; |
962 | 477 | case 5: |
963 | 477 | para.m_spacings[1]=extraLeading/72.; |
964 | 477 | f << "interline=extra[leading],"; |
965 | 477 | break; |
966 | 18.7k | default: |
967 | 18.7k | f << "#interline=" << val << ","; |
968 | 18.7k | break; |
969 | 21.4k | } |
970 | 21.4k | val=static_cast<int>(input->readLong(1)); // 1|2 |
971 | 21.4k | if (val!=1) f << "f8=" << val << ","; |
972 | 21.4k | int lastPos=0; |
973 | 21.4k | f << "pos=["; |
974 | 49.2k | for (int i=0; i<numPos; ++i) { |
975 | 49.1k | auto newPos=static_cast<int>(input->readULong(4)); |
976 | 49.1k | auto ft=static_cast<int>(input->readULong(2)); |
977 | 49.1k | if ((i==0 && newPos!=0) || (i && (newPos<lastPos || newPos>textSize)) || (ft>numFonts)) { |
978 | 21.2k | MWAW_DEBUG_MSG(("WingzGraph::readTextZone: the position zone seems bad\n")); |
979 | 21.2k | f << "##"; |
980 | 21.2k | ascFile.addPos(pos); |
981 | 21.2k | ascFile.addNote(f.str().c_str()); |
982 | 21.2k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
983 | 21.2k | return false; |
984 | 21.2k | } |
985 | 27.8k | if (ft<numFonts) |
986 | 25.5k | graphic->m_posToFontId[newPos]=size_t(ft); |
987 | 27.8k | f << std::hex << newPos << std::dec << ":" << ft << ","; |
988 | 27.8k | } |
989 | 173 | f << "],"; |
990 | | |
991 | 173 | ascFile.addPos(pos); |
992 | 173 | ascFile.addNote(f.str().c_str()); |
993 | 173 | return true; |
994 | 21.4k | } |
995 | | |
996 | | //////////////////////////////////////////////////////////// |
997 | | // color/pattern |
998 | | //////////////////////////////////////////////////////////// |
999 | | bool WingzGraph::readPattern(MWAWGraphicStyle::Pattern &pattern, int &patId) |
1000 | 511k | { |
1001 | 511k | auto input = m_parserState->m_input; |
1002 | 511k | long pos = input->tell(); |
1003 | 511k | if (!input->checkPosition(pos+7)) { |
1004 | 0 | MWAW_DEBUG_MSG(("WingzGraph::readPattern: the zone seems to short\n")); |
1005 | 0 | return false; |
1006 | 0 | } |
1007 | 511k | MWAWColor colors[2]; |
1008 | 511k | unsigned char col[3]; |
1009 | 1.53M | for (auto &c : col) c=static_cast<unsigned char>(input->readULong(1)); |
1010 | 511k | colors[0]=MWAWColor(col[0],col[1],col[2]); |
1011 | 511k | patId=int(input->readULong(1)); |
1012 | 1.53M | for (auto &c : col) c=static_cast<unsigned char>(input->readULong(1)); |
1013 | 511k | colors[1]=MWAWColor(col[0],col[1],col[2]); |
1014 | 511k | if (m_state->m_patternList.empty()) |
1015 | 1.57k | m_state->initPatterns(version()); |
1016 | 511k | if (patId>=0 && patId<int(m_state->m_patternList.size())) |
1017 | 359k | pattern=m_state->m_patternList[size_t(patId)]; |
1018 | 151k | else |
1019 | 151k | pattern=m_state->m_patternList[0]; |
1020 | 1.53M | for (int i=0; i<2; ++i) |
1021 | 1.02M | pattern.m_colors[i]=colors[1-i]; |
1022 | 511k | return true; |
1023 | 511k | } |
1024 | | |
1025 | | bool WingzGraph::readColor(MWAWColor &color, int &patId) |
1026 | 398k | { |
1027 | 398k | MWAWGraphicStyle::Pattern pat; |
1028 | 398k | if (!readPattern(pat, patId)) |
1029 | 0 | return false; |
1030 | 398k | pat.getAverageColor(color); |
1031 | 398k | return true; |
1032 | 398k | } |
1033 | | |
1034 | | //////////////////////////////////////////////////////////// |
1035 | | // chart |
1036 | | //////////////////////////////////////////////////////////// |
1037 | | bool WingzGraph::readChartData(std::shared_ptr<WingzGraphInternal::Graphic>) |
1038 | 2.87k | { |
1039 | 2.87k | auto input = m_parserState->m_input; |
1040 | 2.87k | auto &ascFile = m_parserState->m_asciiFile; |
1041 | 2.87k | long pos = input->tell(), debPos=pos; |
1042 | 2.87k | libmwaw::DebugStream f; |
1043 | 2.87k | f << "Entries(Chart):"; |
1044 | 2.87k | auto val=static_cast<int>(input->readLong(2)); |
1045 | 2.87k | f << "f0=" << val << ","; |
1046 | 2.87k | val=static_cast<int>(input->readLong(2)); |
1047 | 2.87k | f << "f1=" << val << ","; |
1048 | 2.87k | ascFile.addPos(pos); |
1049 | 2.87k | ascFile.addNote(f.str().c_str()); |
1050 | 2.87k | if (val>0) |
1051 | 1.22k | return true; |
1052 | 1.65k | if (!input->checkPosition(pos+866)) { |
1053 | 45 | MWAW_DEBUG_MSG(("WingzGraph::readChartData: the zone seems to short\n")); |
1054 | 45 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1055 | 45 | return false; |
1056 | 45 | } |
1057 | 1.60k | MWAWColor color; |
1058 | 1.60k | int patId; |
1059 | 1.60k | bool ok=true; |
1060 | 11.2k | for (int i=0; i<6; ++i) { |
1061 | 9.65k | pos=input->tell(); |
1062 | 9.65k | f.str(""); |
1063 | 9.65k | char const *wh[]= {"title", "footnote", "background", "plotArea", "serie,label", "interior"}; |
1064 | 9.65k | f << "Chart[" << wh[i] << "]:"; |
1065 | 9.65k | if (!readColor(color, patId)) { |
1066 | 0 | ok=false; |
1067 | 0 | break; |
1068 | 0 | } |
1069 | 9.65k | if (patId && !color.isWhite()) |
1070 | 4.28k | f << "surf[col]=" << color << ","; |
1071 | 5.36k | else if (!patId) |
1072 | 3.51k | f << "surf[col]=none,"; |
1073 | 9.65k | if (i==5) { |
1074 | 1.60k | val=int(input->readLong(1)); |
1075 | 1.60k | if (val!=1) f << "f0=" << val << ","; |
1076 | 1.60k | } |
1077 | 8.04k | else { |
1078 | 8.04k | val=int(input->readLong(1)); // shadow type 4: none, 5: 2d, 6: 3d |
1079 | 8.04k | if (val!=4) f << "shadow[type]=" << val << ","; |
1080 | 8.04k | if (!readColor(color, patId)) { |
1081 | 0 | ok=false; |
1082 | 0 | break; |
1083 | 0 | } |
1084 | 8.04k | if (patId && !color.isBlack()) |
1085 | 3.82k | f << "shadow[col]=" << color << ","; |
1086 | 4.22k | else if (!patId) |
1087 | 2.18k | f << "shadow[col]=none,"; |
1088 | 8.04k | val=int(input->readULong(1)); // related to shadow |
1089 | 8.04k | if (val!=0xff) f << "f1=" << std::hex << val << std::dec << ","; |
1090 | 8.04k | } |
1091 | 9.65k | if (!readColor(color, patId)) { |
1092 | 0 | ok=false; |
1093 | 0 | break; |
1094 | 0 | } |
1095 | 9.65k | if (patId && !color.isBlack()) |
1096 | 6.19k | f << "line[col]=" << color << ","; |
1097 | 3.46k | else if (!patId) |
1098 | 2.51k | f << "line[col]=none,"; |
1099 | 9.65k | val=int(input->readLong(1)); |
1100 | 9.65k | if (val!=1) f << "h0=" << val << ","; |
1101 | 9.65k | val=int(input->readULong(1)); |
1102 | 9.65k | if (val!=5) f << "line[w]=" << float(val)/20.f << ","; |
1103 | 9.65k | val=int(input->readLong(1)); |
1104 | 9.65k | if (val) f << "h1=" << val << ","; |
1105 | 9.65k | if (i!=5) { |
1106 | 8.04k | int dim[2]; |
1107 | 16.0k | for (auto &d : dim) d=int(input->readULong(2)); |
1108 | 8.04k | if (dim[0]!=20 || dim[1]!=20) f << "shadow[pos]=" << 0.05f * MWAWVec2f(float(dim[0]), float(dim[1])) << ","; |
1109 | 8.04k | } |
1110 | 9.65k | if (i<2) { |
1111 | 3.21k | int cell[4]; |
1112 | 12.8k | for (auto &d : cell) d=int(input->readLong(2)); |
1113 | 3.21k | if (cell[1]>=0) |
1114 | 2.15k | f << MWAWBox2i(MWAWVec2i(cell[0],cell[1]),MWAWVec2i(cell[2],cell[3])) << ","; |
1115 | 3.21k | ascFile.addDelimiter(input->tell(),'|'); |
1116 | 3.21k | input->seek(pos+42, librevenge::RVNG_SEEK_SET); |
1117 | 3.21k | } |
1118 | 9.65k | ascFile.addPos(pos); |
1119 | 9.65k | ascFile.addNote(f.str().c_str()); |
1120 | 9.65k | } |
1121 | 1.60k | if (!ok) { |
1122 | 0 | input->seek(debPos, librevenge::RVNG_SEEK_SET); |
1123 | 0 | return false; |
1124 | 0 | } |
1125 | 1.60k | pos=input->tell(); |
1126 | 1.60k | f.str(""); |
1127 | 1.60k | f << "Chart-A5:"; |
1128 | 12.8k | for (int j=0; j<7; ++j) { // 0 and 1 : the table's data |
1129 | 11.2k | int cell[4]; |
1130 | 45.0k | for (auto &d : cell) d=int(input->readLong(2)); |
1131 | 11.2k | if (cell[1]>=0) |
1132 | 5.46k | f << "ce" << j << "=" << MWAWBox2i(MWAWVec2i(cell[0],cell[1]),MWAWVec2i(cell[2],cell[3])) << ","; |
1133 | 11.2k | } |
1134 | 11.2k | for (int j=0; j<6; ++j) { // f0=0|1,f3=1|2|b|e|13:type?,f5=1-4,b-c|10|1b|23|40|47 |
1135 | 9.65k | val=int(input->readLong(2)); |
1136 | 9.65k | int const expected[]= {0,0xf0,0,0,0,0}; |
1137 | 9.65k | if (j==3) |
1138 | | /* 0: bar, 1: line, 2:layer, 3:step, 4: bar/line |
1139 | | 5: bar 3d, 6: line 3d, 7: layer 3d, 8: step 3d, 9: bar/line 3d |
1140 | | 10:pie, 11: pie 3d, 12:High-Low, 14: XY, 16: scatter, |
1141 | | 17: polar, 18: wireframe, 19: contour, 20: surface |
1142 | | */ |
1143 | 1.60k | f << "type=" << val << ","; |
1144 | 8.04k | else if (val!=expected[j]) |
1145 | 7.36k | f << "f" << j << "=" << val << ","; |
1146 | 9.65k | } |
1147 | 1.60k | ascFile.addDelimiter(input->tell(),'|'); |
1148 | 1.60k | ascFile.addPos(pos); |
1149 | 1.60k | ascFile.addNote(f.str().c_str()); |
1150 | 1.60k | pos+=70; |
1151 | | |
1152 | 1.60k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1153 | 1.60k | f.str(""); |
1154 | 1.60k | f << "Chart-header:"; |
1155 | 1.60k | auto numSeries=static_cast<int>(input->readULong(2)); |
1156 | 1.60k | f << "numSerie=" << numSeries << ","; |
1157 | 1.60k | long endPos=debPos+866+73*numSeries; |
1158 | 1.60k | if (!input->checkPosition(endPos)) { |
1159 | 1.48k | MWAW_DEBUG_MSG(("WingzGraph::readChartData: the zone seems to short\n")); |
1160 | 1.48k | ok=input->checkPosition(debPos+866); |
1161 | 1.48k | if (ok) { |
1162 | 1.48k | input->seek(debPos+866, librevenge::RVNG_SEEK_SET); |
1163 | 1.48k | ok=m_mainParser->findNextZone(0xe); |
1164 | 1.48k | } |
1165 | 1.48k | if (!ok) { |
1166 | 22 | MWAW_DEBUG_MSG(("WingzGraph::readChartData: can not find the next zone\n")); |
1167 | 22 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1168 | 22 | return false; |
1169 | 22 | } |
1170 | 1.45k | numSeries=0; |
1171 | 1.45k | endPos=input->tell(); |
1172 | 1.45k | input->seek(pos+2, librevenge::RVNG_SEEK_SET); |
1173 | 1.45k | } |
1174 | 6.34k | for (int i=0; i<3; ++i) { // f1: some id, f2&0xff: subtype |
1175 | 4.76k | val=int(input->readULong(2)); |
1176 | 4.76k | if (val) |
1177 | 4.30k | f << "f" << i << "=" << std::hex << val << std::dec << ","; |
1178 | 4.76k | } |
1179 | 1.58k | readColor(color, patId); |
1180 | 1.58k | if (patId && !color.isWhite()) |
1181 | 833 | f << "surf[col]=" << color << ","; |
1182 | 754 | else if (!patId) |
1183 | 286 | f << "surf[col]=none,"; |
1184 | 1.58k | val=int(input->readLong(1)); // shadow type 4: none, 5: 2d, 6: 3d |
1185 | 1.58k | if (val!=4) f << "shadow[type]=" << val << ","; |
1186 | 1.58k | readColor(color, patId); |
1187 | 1.58k | if (patId && !color.isBlack()) |
1188 | 1.27k | f << "shadow[col]=" << color << ","; |
1189 | 314 | else if (!patId) |
1190 | 193 | f << "shadow[col]=none,"; |
1191 | 1.58k | val=int(input->readULong(1)); // related to shadow |
1192 | 1.58k | if (val!=0xff) |
1193 | 1.09k | f << "f4=" << std::hex << val << std::dec << ","; |
1194 | 1.58k | readColor(color, patId); |
1195 | 1.58k | if (patId && !color.isBlack()) |
1196 | 1.43k | f << "line[col]=" << color << ","; |
1197 | 152 | else if (!patId) |
1198 | 52 | f << "line[col]=none,"; |
1199 | 1.58k | val=int(input->readLong(1)); |
1200 | 1.58k | if (val!=1) f << "g0=" << val << ","; |
1201 | 1.58k | val=int(input->readULong(1)); |
1202 | 1.58k | if (val!=5) f << "line[w]=" << float(val)/20.f << ","; |
1203 | 1.58k | val=int(input->readLong(1)); |
1204 | 1.58k | if (val) f << "g1=" << val << ","; |
1205 | 1.58k | int dim[2]; |
1206 | 3.17k | for (auto &d : dim) d=int(input->readULong(2)); |
1207 | 1.58k | if (dim[0]!=20 || dim[1]!=20) f << "shadow[pos]=" << 0.05f * MWAWVec2f(float(dim[0]), float(dim[1])) << ","; |
1208 | 1.58k | ascFile.addDelimiter(input->tell(),'|'); |
1209 | 1.58k | input->seek(18, librevenge::RVNG_SEEK_CUR); |
1210 | 1.58k | ascFile.addDelimiter(input->tell(),'|'); |
1211 | 1.58k | val=int(input->readLong(1)); |
1212 | 1.58k | if (val!=1) |
1213 | 1.57k | f << "g2=" << val << ","; |
1214 | 1.58k | val=int(input->readLong(1)); |
1215 | 1.58k | if (val!=1) |
1216 | 1.46k | f << "g3=" << val << ","; |
1217 | 19.0k | for (int i=0; i<11; ++i) { |
1218 | 17.4k | val=int(input->readLong(1)); |
1219 | 17.4k | if (val) |
1220 | 10.5k | f << "h" << i << "=" << val << ","; |
1221 | 17.4k | } |
1222 | 1.58k | ascFile.addPos(pos); |
1223 | 1.58k | ascFile.addNote(f.str().c_str()); |
1224 | | |
1225 | 1.58k | pos+=80; |
1226 | 1.58k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1227 | 7.93k | for (int i=0; i<4; ++i) { |
1228 | 6.34k | pos=input->tell(); |
1229 | 6.34k | f.str(""); |
1230 | 6.34k | char const *wh[]= {"axisX", "axisZ", "axisY", "B3"}; |
1231 | 6.34k | f << "Chart[" << wh[i] << "]:"; |
1232 | 6.34k | val=int(input->readULong(2)); |
1233 | 6.34k | if (val!=0x4024) f << "fl=" << std::hex << val << std::dec << ","; |
1234 | 6.34k | if (!readColor(color, patId)) { |
1235 | 0 | ok=false; |
1236 | 0 | break; |
1237 | 0 | } |
1238 | 6.34k | if (patId && !color.isWhite()) |
1239 | 3.54k | f << "surf[col]=" << color << ","; |
1240 | 2.80k | else if (!patId) |
1241 | 2.02k | f << "surf[col]=none,"; |
1242 | 6.34k | val=int(input->readLong(1)); // shadow type 4: none, 5: 2d, 6: 3d |
1243 | 6.34k | if (val!=4) f << "shadow[type]=" << val << ","; |
1244 | 6.34k | if (!readColor(color, patId)) { |
1245 | 0 | ok=false; |
1246 | 0 | break; |
1247 | 0 | } |
1248 | 6.34k | if (patId && !color.isBlack()) |
1249 | 3.95k | f << "shadow[col]=" << color << ","; |
1250 | 2.39k | else if (!patId) |
1251 | 1.96k | f << "shadow[col]=none,"; |
1252 | 6.34k | val=int(input->readULong(1)); // related to shadow |
1253 | 6.34k | if (val!=0xff) f << "f1=" << std::hex << val << std::dec << ","; |
1254 | 6.34k | if (!readColor(color, patId)) { |
1255 | 0 | ok=false; |
1256 | 0 | break; |
1257 | 0 | } |
1258 | 6.34k | if (patId && !color.isBlack()) |
1259 | 3.92k | f << "line[col]=" << color << ","; |
1260 | 2.42k | else if (!patId) |
1261 | 1.89k | f << "line[col]=none,"; |
1262 | 6.34k | val=int(input->readLong(1)); |
1263 | 6.34k | if (val!=1) f << "h0=" << val << ","; |
1264 | 6.34k | val=int(input->readULong(1)); |
1265 | 6.34k | if (val!=5) f << "line[w]=" << float(val)/20.f << ","; |
1266 | 6.34k | val=int(input->readLong(1)); |
1267 | 6.34k | if (val) f << "h1=" << val << ","; |
1268 | 12.6k | for (auto &d : dim) d=int(input->readULong(2)); |
1269 | 6.34k | if (dim[0]!=20 || dim[1]!=20) f << "shadow[pos]=" << 0.05f * MWAWVec2f(float(dim[0]), float(dim[1])) << ","; |
1270 | 6.34k | int cell[4]; |
1271 | 25.3k | for (auto &d : cell) d=int(input->readLong(2)); |
1272 | 6.34k | if (cell[1]>=0) |
1273 | 4.54k | f << MWAWBox2i(MWAWVec2i(cell[0],cell[1]),MWAWVec2i(cell[2],cell[3])) << ","; |
1274 | 19.0k | for (int j=0; j<2; ++j) { // h2=1 for axisY |
1275 | 12.6k | int const expected[]= {0,2}; |
1276 | 12.6k | val=int(input->readLong(2)); |
1277 | 12.6k | if (val!=expected[j]) f << "h" << j+2 << "=" << val << ","; |
1278 | 12.6k | } |
1279 | 19.0k | for (int k=0; k<2; ++k) { // k=0, real axis line color |
1280 | 12.6k | std::string what(k==0 ? "line2" : "unkn"); |
1281 | 12.6k | if (!readColor(color, patId)) { |
1282 | 0 | ok=false; |
1283 | 0 | break; |
1284 | 0 | } |
1285 | 12.6k | if (patId && !color.isBlack()) |
1286 | 7.38k | f << what << "[col]=" << color << ","; |
1287 | 5.31k | else if (!patId) |
1288 | 3.81k | f << what << "[col]=none,"; |
1289 | 12.6k | val=int(input->readLong(1)); |
1290 | 12.6k | if (val!=1) f << what << "[f0]=" << val << ","; |
1291 | 12.6k | val=int(input->readULong(1)); |
1292 | 12.6k | if (val!=5) f << what << "[w]=" << float(val)/20.f << ","; |
1293 | 12.6k | val=int(input->readLong(1)); |
1294 | 12.6k | if (val) f << what << "[f1]=" << val << ","; |
1295 | 12.6k | } |
1296 | 6.34k | if (!readColor(color, patId)) { |
1297 | 0 | ok=false; |
1298 | 0 | break; |
1299 | 0 | } |
1300 | 6.34k | if (patId) |
1301 | 4.49k | f << "unkn2[col]=" << color << ","; |
1302 | 6.34k | val=int(input->readLong(1)); |
1303 | 6.34k | if (val!=1) f << "l0=" << val << ","; |
1304 | 6.34k | ascFile.addDelimiter(input->tell(),'|'); |
1305 | 6.34k | ascFile.addPos(pos); |
1306 | 6.34k | ascFile.addNote(f.str().c_str()); |
1307 | | |
1308 | 6.34k | input->seek(pos+113, librevenge::RVNG_SEEK_SET); |
1309 | 6.34k | } |
1310 | 1.58k | if (!ok) { |
1311 | 0 | input->seek(debPos, librevenge::RVNG_SEEK_SET); |
1312 | 0 | return false; |
1313 | 0 | } |
1314 | 1.58k | pos=input->tell(); |
1315 | 1.58k | f.str(""); |
1316 | 1.58k | f << "Chart-B5:"; |
1317 | 9.52k | for (int i=0; i<5; ++i) { |
1318 | 7.93k | int const expected[]= {0x1e, 0x1e, 0x32, 0x32, 0x109}; |
1319 | 7.93k | val=int(input->readLong(2)); |
1320 | 7.93k | if (val==expected[i]) continue; |
1321 | 7.55k | char const *wh[] = {"f0", "f1", "x[vanish,3d]", "y[vanish,3d]", "distance[3d]"}; |
1322 | 7.55k | f << wh[i] << "=" << val << ","; |
1323 | 7.55k | } |
1324 | 7.93k | for (int i=0; i<4; ++i) { |
1325 | 6.34k | if (!readColor(color, patId)) { |
1326 | 0 | ok=false; |
1327 | 0 | break; |
1328 | 0 | } |
1329 | 6.34k | char const *wh[] = {"top", "side", "shadow", "line"}; |
1330 | 6.34k | if (patId && ((i<2 && !color.isWhite()) || (i>=2 && !color.isBlack()))) |
1331 | 3.28k | f << wh[i] << "[3d,col]=" << color << ","; |
1332 | 3.06k | else if (!patId) |
1333 | 2.09k | f << wh[i] << "[3d,col]=none,"; |
1334 | 6.34k | val=int(input->readULong(1)); |
1335 | 6.34k | if (i<2) { |
1336 | 3.17k | if (val!=4) |
1337 | 2.97k | f << "f" << i+2 << "=" << val << ","; |
1338 | 3.17k | } |
1339 | 3.17k | else if (i==2) { |
1340 | 1.58k | if (val!=0x4b) // val something like ~2*tint in percent |
1341 | 1.58k | f << "shadow[tint]=" << val << ","; |
1342 | 1.58k | } |
1343 | 1.58k | else if (val!=1) |
1344 | 1.43k | f << "f" << i+2 << "=" << val << ","; |
1345 | 6.34k | } |
1346 | 1.58k | val=int(input->readULong(1)); |
1347 | 1.58k | if (val!=5) f << "line[w,3d]=" << float(val)/20.f << ","; |
1348 | 1.58k | if (!ok) { |
1349 | 0 | input->seek(debPos, librevenge::RVNG_SEEK_SET); |
1350 | 0 | return false; |
1351 | 0 | } |
1352 | 1.58k | ascFile.addDelimiter(input->tell(),'|'); |
1353 | 1.58k | ascFile.addPos(pos); |
1354 | 1.58k | ascFile.addNote(f.str().c_str()); |
1355 | 1.58k | pos+=68; |
1356 | 1.58k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1357 | | |
1358 | 15.1k | for (int i=0; i<numSeries; ++i) { |
1359 | 13.5k | pos=input->tell(); |
1360 | 13.5k | f.str(""); |
1361 | 13.5k | f << "Chart-Serie" << i << ":"; |
1362 | | |
1363 | 13.5k | input->seek(pos+70, librevenge::RVNG_SEEK_SET); |
1364 | 13.5k | val=int(input->readLong(1)); |
1365 | 13.5k | if (val!=2) { |
1366 | 10.6k | if (val) { |
1367 | 6.29k | f << "###type=" << val << ","; |
1368 | 6.29k | MWAW_DEBUG_MSG(("WingzGraph::readChartData: find unexpected serie type\n")); |
1369 | 6.29k | } |
1370 | 10.6k | f << "_,"; |
1371 | 10.6k | ascFile.addPos(pos); |
1372 | 10.6k | ascFile.addNote(f.str().c_str()); |
1373 | 10.6k | input->seek(pos+73, librevenge::RVNG_SEEK_SET); |
1374 | 10.6k | continue; |
1375 | 10.6k | } |
1376 | | |
1377 | 2.91k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1378 | 2.91k | if (!readColor(color, patId)) |
1379 | 0 | break; |
1380 | 2.91k | if (patId && !color.isWhite()) |
1381 | 2.83k | f << "surf[col]=" << color << ","; |
1382 | 85 | else if (!patId) |
1383 | 77 | f << "surf[col]=none,"; |
1384 | 2.91k | val=int(input->readLong(1)); |
1385 | 2.91k | if (val!=1) f << "f0=" << val << ","; |
1386 | | |
1387 | 2.91k | if (!readColor(color, patId)) |
1388 | 0 | break; |
1389 | 2.91k | if (patId) |
1390 | 2.62k | f << "shadow[col]=" << color << ","; |
1391 | | |
1392 | 2.91k | val=int(input->readLong(1)); |
1393 | 2.91k | if (val) f << "f1=" << val << ","; |
1394 | 2.91k | if (!readColor(color, patId)) |
1395 | 0 | break; |
1396 | 2.91k | if (patId && !color.isBlack()) |
1397 | 2.74k | f << "line[col]=" << color << ","; |
1398 | 176 | else if (!patId) |
1399 | 82 | f << "line[col]=none,"; |
1400 | 2.91k | val=int(input->readLong(1)); |
1401 | 2.91k | if (val!=1) f << "f2=" << val << ","; |
1402 | 2.91k | val=int(input->readLong(2)); |
1403 | 2.91k | if (val!=40) f << "f3=" << val << ","; |
1404 | 2.91k | if (!readColor(color, patId)) |
1405 | 0 | break; |
1406 | 2.91k | if (patId && !color.isBlack()) |
1407 | 2.60k | f << "unkn[col]=" << color << ","; |
1408 | 313 | else if (!patId) |
1409 | 67 | f << "unkn[col]=none,"; |
1410 | 2.91k | val=int(input->readLong(1)); |
1411 | 2.91k | if (val!=1) f << "g0=" << val << ","; |
1412 | 2.91k | val=int(input->readULong(1)); |
1413 | 2.91k | if (val!=5) f << "line[w]=" << float(val)/20.f << ","; |
1414 | 2.91k | val=int(input->readLong(1)); |
1415 | 2.91k | if (val) f << "g1=" << val << ","; |
1416 | 11.6k | for (int j=0; j<3; ++j) { // 0: data, 1: label? |
1417 | 8.75k | int cell[4]; |
1418 | 35.0k | for (auto &c : cell) c=int(input->readLong(2)); |
1419 | 8.75k | if (cell[1]>=0) |
1420 | 8.24k | f << "cells" << j << "=" << MWAWBox2i(MWAWVec2i(cell[0],cell[1]),MWAWVec2i(cell[2],cell[3])) << ","; |
1421 | 8.75k | } |
1422 | 17.5k | for (int j=0; j<5; ++j) { // h1=serie[id] ? |
1423 | 14.5k | val=int(input->readLong(2)); |
1424 | 14.5k | if (val) |
1425 | 13.4k | f << "h" << j << "=" << val << ","; |
1426 | 14.5k | } |
1427 | 2.91k | ascFile.addDelimiter(input->tell(),'|'); |
1428 | 2.91k | ascFile.addPos(pos); |
1429 | 2.91k | ascFile.addNote(f.str().c_str()); |
1430 | 2.91k | input->seek(pos+73, librevenge::RVNG_SEEK_SET); |
1431 | 2.91k | } |
1432 | 1.58k | if (input->tell()!=endPos) { |
1433 | 1.45k | MWAW_DEBUG_MSG(("WingzGraph::readChartData: find some extra data\n")); |
1434 | 1.45k | ascFile.addPos(input->tell()); |
1435 | 1.45k | ascFile.addNote("Chart-end:###"); |
1436 | 1.45k | } |
1437 | 1.58k | input->seek(endPos, librevenge::RVNG_SEEK_SET); |
1438 | 1.58k | return true; |
1439 | 1.58k | } |
1440 | | |
1441 | | //////////////////////////////////////////////////////////// |
1442 | | // send data |
1443 | | //////////////////////////////////////////////////////////// |
1444 | | bool WingzGraph::sendGraphic(WingzGraphInternal::Graphic const &graphic, MWAWPosition const &pos) |
1445 | 125k | { |
1446 | 125k | MWAWListenerPtr listener=m_parserState->getMainListener(); |
1447 | 125k | if (!listener) { |
1448 | 0 | MWAW_DEBUG_MSG(("WingzGraph::sendGraphic: listener is not set\n")); |
1449 | 0 | return false; |
1450 | 0 | } |
1451 | 125k | MWAWPosition fPos; |
1452 | 125k | if (!m_state->m_inGroupDepth) { |
1453 | 71.1k | MWAWVec2f begPos=m_mainParser->getPosition(graphic.m_position[0], graphic.m_relativePosition[0]); |
1454 | 71.1k | MWAWVec2f endPos=m_mainParser->getPosition(graphic.m_position[1], graphic.m_relativePosition[1]); |
1455 | 71.1k | fPos=MWAWPosition(begPos, endPos-begPos, librevenge::RVNG_POINT); |
1456 | 71.1k | } |
1457 | 54.2k | else { // special case relative to the group box |
1458 | 54.2k | auto const &orig=pos.origin(); |
1459 | 54.2k | auto const &size=pos.size(); |
1460 | 54.2k | MWAWVec2f begPos(orig[0]+size[0]*float(graphic.m_position[0][0])/float(0x3fff), |
1461 | 54.2k | orig[1]+size[1]*float(graphic.m_position[0][1])/float(0x3fff)); |
1462 | 54.2k | MWAWVec2f endPos(orig[0]+size[0]*float(graphic.m_position[1][0])/float(0x3fff), |
1463 | 54.2k | orig[1]+size[1]*float(graphic.m_position[1][1])/float(0x3fff)); |
1464 | 54.2k | fPos=MWAWPosition(begPos, endPos-begPos, librevenge::RVNG_POINT); |
1465 | 54.2k | } |
1466 | 125k | fPos.m_anchorTo=MWAWPosition::Page; |
1467 | 125k | fPos.setOrder(graphic.m_order); |
1468 | 125k | switch (graphic.m_type) { |
1469 | 51.9k | case 0: |
1470 | 60.5k | case 2: { |
1471 | 60.5k | std::shared_ptr<MWAWSubDocument> doc(new WingzGraphInternal::SubDocument(*this, m_parserState->m_input, graphic)); |
1472 | 60.5k | listener->insertTextBox(fPos, doc, graphic.m_style); |
1473 | 60.5k | return true; |
1474 | 51.9k | } |
1475 | 658 | case 5: |
1476 | 3.88k | case 6: |
1477 | 4.59k | case 7: |
1478 | 5.18k | case 8: |
1479 | 14.6k | case 9: |
1480 | 14.6k | return sendShape(graphic, fPos); |
1481 | 24.3k | case 0xa: |
1482 | 24.3k | return sendPicture(graphic, fPos); |
1483 | 25.8k | case 0xb: // group |
1484 | 25.8k | listener->openGroup(pos); |
1485 | 25.8k | ++m_state->m_inGroupDepth; |
1486 | 54.2k | for (auto const &c : graphic.m_children) { |
1487 | 54.2k | if (c) sendGraphic(*c, fPos); |
1488 | 54.2k | } |
1489 | 25.8k | --m_state->m_inGroupDepth; |
1490 | 25.8k | listener->closeGroup(); |
1491 | 25.8k | return true; |
1492 | 0 | default: |
1493 | 0 | break; |
1494 | 125k | } |
1495 | 0 | static bool first=true; |
1496 | 0 | if (first) { |
1497 | 0 | MWAW_DEBUG_MSG(("WingzGraph::sendGraphic: oops, unsure how to send some graphic[%d]\n", graphic.m_type)); |
1498 | 0 | first=false; |
1499 | 0 | } |
1500 | 0 | return false; |
1501 | 125k | } |
1502 | | |
1503 | | bool WingzGraph::sendPicture(WingzGraphInternal::Graphic const &graphic, MWAWPosition const &pos) |
1504 | 24.3k | { |
1505 | 24.3k | MWAWListenerPtr listener=m_parserState->getMainListener(); |
1506 | 24.3k | if (!listener) { |
1507 | 0 | MWAW_DEBUG_MSG(("WingzGraph::sendPicture: listener is not set\n")); |
1508 | 0 | return false; |
1509 | 0 | } |
1510 | 24.3k | if (!graphic.m_entry[0].valid()) { |
1511 | 0 | MWAW_DEBUG_MSG(("WingzGraph::sendPicture: can not find the picture\n")); |
1512 | 0 | return false; |
1513 | 0 | } |
1514 | 24.3k | auto input = m_parserState->m_input; |
1515 | 24.3k | long actPos=input->tell(); |
1516 | 24.3k | librevenge::RVNGBinaryData file; |
1517 | 24.3k | input->seek(graphic.m_entry[0].begin(), librevenge::RVNG_SEEK_SET); |
1518 | 24.3k | input->readDataBlock(graphic.m_entry[0].length(), file); |
1519 | 24.3k | MWAWEmbeddedObject object(file); |
1520 | 24.3k | listener->insertPicture(pos, object); |
1521 | 24.3k | input->seek(actPos, librevenge::RVNG_SEEK_SET); |
1522 | 24.3k | return true; |
1523 | 24.3k | } |
1524 | | |
1525 | | bool WingzGraph::sendShape(WingzGraphInternal::Graphic const &graphic, MWAWPosition const &pos) |
1526 | 14.6k | { |
1527 | 14.6k | MWAWListenerPtr listener=m_parserState->getMainListener(); |
1528 | 14.6k | if (!listener) { |
1529 | 0 | MWAW_DEBUG_MSG(("WingzGraph::sendShape: listener is not set\n")); |
1530 | 0 | return false; |
1531 | 0 | } |
1532 | 14.6k | auto const &orig=pos.origin(); |
1533 | 14.6k | auto end=orig+pos.size(); |
1534 | 14.6k | MWAWGraphicShape shape; |
1535 | 14.6k | switch (graphic.m_type) { |
1536 | 658 | case 5: |
1537 | 658 | switch (graphic.m_flag&3) { |
1538 | 77 | case 1: |
1539 | 77 | shape=MWAWGraphicShape::line(MWAWVec2f(end[0],orig[1]),MWAWVec2f(orig[0],end[1])); |
1540 | 77 | break; |
1541 | 65 | case 2: |
1542 | 65 | shape=MWAWGraphicShape::line(MWAWVec2f(orig[0],end[1]),MWAWVec2f(end[0],orig[1])); |
1543 | 65 | break; |
1544 | 194 | case 3: |
1545 | 194 | shape=MWAWGraphicShape::line(end,orig); |
1546 | 194 | break; |
1547 | 322 | case 0: |
1548 | 322 | default: |
1549 | 322 | shape=MWAWGraphicShape::line(orig,end); |
1550 | 322 | break; |
1551 | 658 | } |
1552 | 658 | break; |
1553 | 3.22k | case 6: { |
1554 | 3.22k | float angle[2] = { graphic.m_angles[0], graphic.m_angles[1] }; |
1555 | 3.22k | if (angle[0] > angle[1]) std::swap(angle[0],angle[1]); |
1556 | 20.0k | while (angle[1] > 360) { |
1557 | 16.8k | angle[0]-=360; |
1558 | 16.8k | angle[1]-=360; |
1559 | 16.8k | } |
1560 | 13.7k | while (angle[0] < -360) { |
1561 | 10.5k | angle[0]+=360; |
1562 | 10.5k | angle[1]+=360; |
1563 | 10.5k | } |
1564 | | |
1565 | 3.22k | MWAWBox2f box(orig,end); |
1566 | | // we must compute the real bd box |
1567 | 3.22k | float minVal[2] = { 0, 0 }, maxVal[2] = { 0, 0 }; |
1568 | 3.22k | int limitAngle[2]; |
1569 | 9.66k | for (int i = 0; i < 2; i++) |
1570 | 6.44k | limitAngle[i] = (angle[i] < 0) ? int(angle[i]/90)-1 : int(angle[i]/90); |
1571 | 59.8k | for (int bord = limitAngle[0]; bord <= limitAngle[1]+1; bord++) { |
1572 | 56.6k | float ang = (bord == limitAngle[0]) ? float(angle[0]) : |
1573 | 56.6k | (bord == limitAngle[1]+1) ? float(angle[1]) : float(90 * bord); |
1574 | 56.6k | ang *= float(M_PI/180.); |
1575 | 56.6k | float const actVal[2] = { std::cos(ang), -std::sin(ang)}; |
1576 | 56.6k | if (actVal[0] < minVal[0]) minVal[0] = actVal[0]; |
1577 | 52.0k | else if (actVal[0] > maxVal[0]) maxVal[0] = actVal[0]; |
1578 | 56.6k | if (actVal[1] < minVal[1]) minVal[1] = actVal[1]; |
1579 | 53.0k | else if (actVal[1] > maxVal[1]) maxVal[1] = actVal[1]; |
1580 | 56.6k | } |
1581 | 3.22k | MWAWBox2f circleBox(orig,end); |
1582 | | // we have the shape box, we need to reconstruct the circle box |
1583 | 3.22k | if (maxVal[0]>minVal[0] && maxVal[1]>minVal[1]) { |
1584 | 2.92k | float const scaling[2]= { (box[1][0]-box[0][0])/(maxVal[0]-minVal[0]), |
1585 | 2.92k | (box[1][1]-box[0][1])/(maxVal[1]-minVal[1]) |
1586 | 2.92k | }; |
1587 | 2.92k | float const constant[2]= { box[0][0]-minVal[0] *scaling[0], box[0][1]-minVal[1] *scaling[1]}; |
1588 | 2.92k | circleBox=MWAWBox2f(MWAWVec2f(constant[0]-scaling[0], constant[1]-scaling[1]), |
1589 | 2.92k | MWAWVec2f(constant[0]+scaling[0], constant[1]+scaling[1])); |
1590 | 2.92k | } |
1591 | 3.22k | if (graphic.m_style.hasSurface()) |
1592 | 48 | shape = MWAWGraphicShape::pie(box, circleBox, MWAWVec2f(float(angle[0]),float(angle[1]))); |
1593 | 3.17k | else |
1594 | 3.17k | shape = MWAWGraphicShape::arc(box, circleBox, MWAWVec2f(float(angle[0]),float(angle[1]))); |
1595 | 3.22k | break; |
1596 | 658 | } |
1597 | 717 | case 7: |
1598 | 717 | shape=MWAWGraphicShape::circle(MWAWBox2f(orig,end)); |
1599 | 717 | break; |
1600 | 590 | case 8: |
1601 | 590 | if (graphic.m_flag&0x20) |
1602 | 543 | shape=MWAWGraphicShape::rectangle(MWAWBox2f(orig,end), 0.2f*pos.size()); |
1603 | 47 | else |
1604 | 47 | shape=MWAWGraphicShape::rectangle(MWAWBox2f(orig,end)); |
1605 | 590 | break; |
1606 | 9.46k | case 9: { |
1607 | 9.46k | if (graphic.m_vertices.empty()) { |
1608 | 2.15k | MWAW_DEBUG_MSG(("WingzGraph::sendPageGraphics: oops, can not find any vertices\n")); |
1609 | 2.15k | return false; |
1610 | 2.15k | } |
1611 | 7.31k | auto size=pos.size(); |
1612 | 7.31k | if (graphic.m_flag&2) { // smooth |
1613 | 2.85k | shape.m_bdBox=MWAWBox2f(orig,end); |
1614 | 2.85k | shape.m_type=MWAWGraphicShape::Path; |
1615 | 2.85k | shape.m_path.push_back(MWAWGraphicShape::PathData('M', MWAWVec2f(orig[0]+graphic.m_vertices[0][0]*size[0],orig[1]+graphic.m_vertices[0][1]*size[1]))); |
1616 | 20.2k | for (size_t i=1; i+1<graphic.m_vertices.size(); ++i) { |
1617 | 17.4k | MWAWVec2f pt=MWAWVec2f(orig[0]+graphic.m_vertices[i][0]*size[0], |
1618 | 17.4k | orig[1]+graphic.m_vertices[i][1]*size[1]); |
1619 | 17.4k | MWAWVec2f dir=graphic.m_vertices[i+1]-graphic.m_vertices[i-1]; |
1620 | 17.4k | shape.m_path.push_back(MWAWGraphicShape::PathData('S', pt, pt-0.1f*MWAWVec2f(dir[0]*size[0],dir[1]*size[1]))); |
1621 | 17.4k | } |
1622 | 2.85k | if (graphic.m_vertices.size()>1) |
1623 | 2.35k | shape.m_path.push_back(MWAWGraphicShape::PathData('L', MWAWVec2f(orig[0]+graphic.m_vertices.back()[0]*size[0],orig[1]+graphic.m_vertices.back()[1]*size[1]))); |
1624 | 2.85k | if (graphic.m_flag&1) |
1625 | 538 | shape.m_path.push_back(MWAWGraphicShape::PathData('Z')); |
1626 | 2.85k | break; |
1627 | 2.85k | } |
1628 | 4.45k | if (graphic.m_flag&1) |
1629 | 263 | shape=MWAWGraphicShape::polygon(MWAWBox2f(orig,end)); |
1630 | 4.19k | else |
1631 | 4.19k | shape=MWAWGraphicShape::polyline(MWAWBox2f(orig,end)); |
1632 | 4.45k | for (auto const &pt : graphic.m_vertices) |
1633 | 17.2k | shape.m_vertices.push_back(MWAWVec2f(orig[0]+pt[0]*size[0],orig[1]+pt[1]*size[1])); |
1634 | 4.45k | break; |
1635 | 7.31k | } |
1636 | 0 | default: |
1637 | 0 | shape=MWAWGraphicShape::rectangle(MWAWBox2f(orig,end)); |
1638 | 0 | break; |
1639 | 14.6k | } |
1640 | 12.4k | listener->insertShape(pos, shape, graphic.m_style); |
1641 | 12.4k | return true; |
1642 | 14.6k | } |
1643 | | |
1644 | | bool WingzGraph::sendText(WingzGraphInternal::Graphic const &graphic) |
1645 | 60.5k | { |
1646 | 60.5k | MWAWListenerPtr listener=m_parserState->getMainListener(); |
1647 | 60.5k | if (!listener) { |
1648 | 0 | MWAW_DEBUG_MSG(("WingzGraph::sendText: listener is not set\n")); |
1649 | 0 | return false; |
1650 | 0 | } |
1651 | 60.5k | auto input=m_parserState->m_input; |
1652 | | |
1653 | 60.5k | bool first=true; |
1654 | 181k | for (int i=0; i<2; ++i) { |
1655 | 121k | if (!graphic.m_entry[i].valid()) continue; |
1656 | 65.1k | if (!first) listener->insertEOL(); |
1657 | 65.1k | listener->setFont(graphic.m_font[graphic.m_textType==1 ? 0 : 1]); |
1658 | 65.1k | input->seek(graphic.m_entry[i].begin(), librevenge::RVNG_SEEK_SET); |
1659 | 1.50M | for (long l=graphic.m_entry[i].length(); l>0; --l) { |
1660 | 1.44M | auto c=static_cast<unsigned char>(input->readULong(1)); |
1661 | 1.44M | if (c==0x9) |
1662 | 11.3k | listener->insertTab(); |
1663 | 1.42M | else if (c==0xd) |
1664 | 42.6k | listener->insertEOL(); |
1665 | 1.38M | else |
1666 | 1.38M | listener->insertCharacter(c); |
1667 | 1.44M | } |
1668 | 65.1k | first=false; |
1669 | 65.1k | } |
1670 | | |
1671 | 60.5k | if (!graphic.m_textEntry.valid()) |
1672 | 36.6k | return true; |
1673 | 23.9k | if (!first) listener->insertEOL(); |
1674 | 23.9k | listener->setParagraph(graphic.m_paragraph); |
1675 | 23.9k | input->seek(graphic.m_textEntry.begin(), librevenge::RVNG_SEEK_SET); |
1676 | 2.18M | for (long l=0; l<graphic.m_textEntry.length(); ++l) { |
1677 | 2.16M | if (graphic.m_posToFontId.find(int(l))!=graphic.m_posToFontId.end()) { |
1678 | 11.0k | auto fId=graphic.m_posToFontId.find(int(l))->second; |
1679 | 11.0k | if (fId<graphic.m_fontList.size()) |
1680 | 11.0k | listener->setFont(graphic.m_fontList[fId]); |
1681 | 11.0k | } |
1682 | 2.16M | auto c=static_cast<unsigned char>(input->readULong(1)); |
1683 | 2.16M | if (c==0x9) |
1684 | 26.5k | listener->insertTab(); |
1685 | 2.13M | else if (c==0xd) |
1686 | 43.3k | listener->insertEOL(); |
1687 | 2.09M | else |
1688 | 2.09M | listener->insertCharacter(c); |
1689 | 2.16M | } |
1690 | 23.9k | return true; |
1691 | 60.5k | } |
1692 | | |
1693 | | bool WingzGraph::sendPageGraphics() |
1694 | 2.61k | { |
1695 | 2.61k | if (!m_state->m_groupStack.empty()) { |
1696 | 401 | MWAW_DEBUG_MSG(("WingzGraph::sendPageGraphics: oops, some groups are not closed\n")); |
1697 | 401 | } |
1698 | 2.61k | MWAWListenerPtr listener=m_parserState->getMainListener(); |
1699 | 2.61k | if (!listener) { |
1700 | 0 | MWAW_DEBUG_MSG(("WingzGraph::sendPageGraphics: listener is not set\n")); |
1701 | 0 | return false; |
1702 | 0 | } |
1703 | 2.61k | MWAWPosition pos(MWAWVec2f(0,0), MWAWVec2f(0,0), librevenge::RVNG_POINT); |
1704 | 2.61k | pos.m_anchorTo=MWAWPosition::Page; |
1705 | | |
1706 | 71.1k | for (auto const &graph : m_state->m_pictureList) { |
1707 | 71.1k | if (graph) sendGraphic(*graph, pos); |
1708 | 71.1k | } |
1709 | 2.61k | return true; |
1710 | 2.61k | } |
1711 | | // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: |