/src/libstaroffice/src/lib/StarObjectText.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 | | /* libstaroffice |
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 <cstring> |
35 | | #include <iomanip> |
36 | | #include <iostream> |
37 | | #include <limits> |
38 | | #include <memory> |
39 | | #include <sstream> |
40 | | |
41 | | #include <librevenge/librevenge.h> |
42 | | |
43 | | #include "STOFFList.hxx" |
44 | | #include "STOFFOLEParser.hxx" |
45 | | #include "STOFFPageSpan.hxx" |
46 | | #include "STOFFParagraph.hxx" |
47 | | #include "STOFFSection.hxx" |
48 | | #include "STOFFSubDocument.hxx" |
49 | | #include "STOFFTextListener.hxx" |
50 | | |
51 | | #include "SWFieldManager.hxx" |
52 | | |
53 | | #include "StarAttribute.hxx" |
54 | | #include "StarFormatManager.hxx" |
55 | | #include "StarObject.hxx" |
56 | | #include "StarFileManager.hxx" |
57 | | #include "StarGraphicStruct.hxx" |
58 | | #include "StarItemPool.hxx" |
59 | | #include "StarLayout.hxx" |
60 | | #include "StarObjectChart.hxx" |
61 | | #include "StarObjectMath.hxx" |
62 | | #include "StarObjectModel.hxx" |
63 | | #include "StarObjectNumericRuler.hxx" |
64 | | #include "StarObjectPageStyle.hxx" |
65 | | #include "StarObjectSpreadsheet.hxx" |
66 | | #include "StarState.hxx" |
67 | | #include "StarTable.hxx" |
68 | | #include "StarWriterStruct.hxx" |
69 | | #include "StarZone.hxx" |
70 | | |
71 | | #include "StarObjectText.hxx" |
72 | | |
73 | | /** Internal: the structures of a StarObjectText */ |
74 | | namespace StarObjectTextInternal |
75 | | { |
76 | | //////////////////////////////////////// |
77 | | //! Internal: the subdocument of a StarObjectSpreadsheet |
78 | | class SubDocument final : public STOFFSubDocument |
79 | | { |
80 | | public: |
81 | | explicit SubDocument(StarObjectTextInternal::Content const &content, StarState &state) : |
82 | 113 | STOFFSubDocument(nullptr, STOFFInputStreamPtr(), STOFFEntry()), m_content(content), m_state(state) {} |
83 | | |
84 | | //! destructor |
85 | 0 | ~SubDocument() final {} |
86 | | |
87 | | //! operator!= |
88 | | bool operator!=(STOFFSubDocument const &doc) const final |
89 | 0 | { |
90 | 0 | if (STOFFSubDocument::operator!=(doc)) return true; |
91 | 0 | auto const *sDoc = dynamic_cast<SubDocument const *>(&doc); |
92 | 0 | if (!sDoc) return true; |
93 | 0 | if (&m_content != &sDoc->m_content) return true; |
94 | 0 | return false; |
95 | 0 | } |
96 | | |
97 | | //! the parser function |
98 | | void parse(STOFFListenerPtr &listener, libstoff::SubDocumentType type) final; |
99 | | |
100 | | protected: |
101 | | //! the content |
102 | | StarObjectTextInternal::Content const &m_content; |
103 | | //! the state |
104 | | StarState &m_state; |
105 | | private: |
106 | | SubDocument(SubDocument const &); |
107 | | SubDocument &operator=(SubDocument const &); |
108 | | }; |
109 | | |
110 | | void SubDocument::parse(STOFFListenerPtr &listener, libstoff::SubDocumentType /*type*/) |
111 | 113 | { |
112 | 113 | if (!listener.get()) { |
113 | 0 | STOFF_DEBUG_MSG(("StarObjectSpreadsheetInternal::SubDocument::parse: no listener\n")); |
114 | 0 | return; |
115 | 0 | } |
116 | 113 | m_content.send(listener, m_state); |
117 | 113 | } |
118 | | |
119 | | //////////////////////////////////////// |
120 | | // Zone, Content function |
121 | | Zone::~Zone() |
122 | 177k | { |
123 | 177k | } |
124 | | |
125 | | Content::~Content() |
126 | 36.8k | { |
127 | 36.8k | } |
128 | | |
129 | | void Content::inventoryPages(StarState &state) const |
130 | 5.42k | { |
131 | 5.42k | if (!state.m_global->m_pool) { |
132 | 3.39k | STOFF_DEBUG_MSG(("StarObjectTextInternal::Content::inventoryPages: can not find the pool\n")); |
133 | 3.39k | return; |
134 | 3.39k | } |
135 | 27.1k | for (auto &z : m_zoneList) { |
136 | 27.1k | if (z) |
137 | 27.1k | z->inventoryPage(state); |
138 | 27.1k | if (state.m_global->m_pageNameList.empty()) |
139 | 1.88k | state.m_global->m_pageNameList.push_back(""); |
140 | 27.1k | } |
141 | 2.02k | } |
142 | | |
143 | | //////////////////////////////////////// |
144 | | //! Internal: a formatZone of StarObjectTextInteral |
145 | | struct FormatZone final : public Zone { |
146 | | //! constructor |
147 | | explicit FormatZone(std::shared_ptr<StarFormatManagerInternal::FormatDef> &format) |
148 | 1.03k | : Zone() |
149 | 1.03k | , m_format(format) |
150 | 1.03k | { |
151 | 1.03k | } |
152 | | //! try to send the data to a listener |
153 | | bool send(STOFFListenerPtr &listener, StarState &state) const final; |
154 | | //! the format |
155 | | std::shared_ptr<StarFormatManagerInternal::FormatDef> m_format; |
156 | | }; |
157 | | |
158 | | bool FormatZone::send(STOFFListenerPtr &listener, StarState &state) const |
159 | 236 | { |
160 | 236 | if (!listener) { |
161 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::FormatZone::send: call without listener\n")); |
162 | 0 | return false; |
163 | 0 | } |
164 | 236 | if (!m_format) { |
165 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::FormatZone::send: can not find the format\n")); |
166 | 0 | return false; |
167 | 0 | } |
168 | 236 | StarState cState(*state.m_global); |
169 | 236 | return m_format->send(listener, cState); |
170 | 236 | } |
171 | | |
172 | | //////////////////////////////////////// |
173 | | //! Internal: a graphZone of StarObjectTextInteral |
174 | | struct GraphZone final : public Zone { |
175 | | //! constructor |
176 | | explicit GraphZone(std::shared_ptr<STOFFOLEParser> &oleParser) |
177 | 3.15k | : Zone() |
178 | 3.15k | , m_oleParser(oleParser) |
179 | 3.15k | , m_attributeList() |
180 | 3.15k | , m_contour() |
181 | 3.15k | { |
182 | 3.15k | } |
183 | | //! try to send the data to a listener |
184 | | bool send(STOFFListenerPtr &listener, StarState &state) const final; |
185 | | //! the ole parser |
186 | | std::shared_ptr<STOFFOLEParser> m_oleParser; |
187 | | //! the graph name, the fltName, the replace text |
188 | | librevenge::RVNGString m_names[3]; |
189 | | //! the attributes list |
190 | | std::vector<StarWriterStruct::Attribute> m_attributeList; |
191 | | //! the contour(useme) |
192 | | StarGraphicStruct::StarPolygon m_contour; |
193 | | }; |
194 | | |
195 | | bool GraphZone::send(STOFFListenerPtr &listener, StarState &state) const |
196 | 1.82k | { |
197 | 1.82k | if (!listener) { |
198 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::GraphZone::send: call without listener\n")); |
199 | 0 | return false; |
200 | 0 | } |
201 | 1.82k | if (m_names[0].empty()) { |
202 | 294 | STOFF_DEBUG_MSG(("StarObjectTextInternal::GraphZone::send: can not find the graph name\n")); |
203 | 294 | return false; |
204 | 294 | } |
205 | 1.53k | STOFFEmbeddedObject localPicture; |
206 | 1.53k | if (!m_oleParser || !StarFileManager::readEmbeddedPicture(m_oleParser, m_names[0].cstr(), localPicture) || localPicture.isEmpty()) { |
207 | 1.26k | STOFF_DEBUG_MSG(("StarObjectTextInternal: sorry, can not find object %s\n", m_names[0].cstr())); |
208 | 1.26k | return false; |
209 | 1.26k | } |
210 | 268 | STOFFGraphicStyle style=state.m_graphic; |
211 | 268 | state.m_frame.addTo(style.m_propertyList); |
212 | 268 | listener->insertPicture(state.m_frame, localPicture, style); |
213 | 268 | return true; |
214 | 1.53k | } |
215 | | |
216 | | //////////////////////////////////////// |
217 | | //! Internal: a OLEZone of StarObjectTextInteral |
218 | | struct OLEZone final : public Zone { |
219 | | //! constructor |
220 | | OLEZone() |
221 | 35.9k | : Zone() |
222 | 35.9k | , m_name("") |
223 | 35.9k | , m_replaceText("") |
224 | 35.9k | , m_oleParser() |
225 | 35.9k | { |
226 | 35.9k | } |
227 | | //! try to send the data to a listener |
228 | | bool send(STOFFListenerPtr &listener, StarState &state) const final; |
229 | | //! the OLE name |
230 | | librevenge::RVNGString m_name; |
231 | | //! the replacement text |
232 | | librevenge::RVNGString m_replaceText; |
233 | | //! the ole parser |
234 | | std::shared_ptr<STOFFOLEParser> m_oleParser; |
235 | | }; |
236 | | |
237 | | bool OLEZone::send(STOFFListenerPtr &listener, StarState &state) const |
238 | 6.43k | { |
239 | 6.43k | if (!listener) { |
240 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::OLEZone::send: call without listener\n")); |
241 | 0 | return false; |
242 | 0 | } |
243 | 6.43k | if (m_name.empty()) { |
244 | 72 | STOFF_DEBUG_MSG(("StarObjectTextInternal::OLEZone::send: call without object name\n")); |
245 | 72 | return false; |
246 | 72 | } |
247 | 6.36k | if (!m_oleParser) { |
248 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::OLEZone::send: call without ole parser\n")); |
249 | 0 | return false; |
250 | 0 | } |
251 | 6.36k | STOFFEmbeddedObject localPicture; |
252 | 6.36k | std::shared_ptr<StarObject> localObj; |
253 | 6.36k | auto dir=m_oleParser->getDirectory(m_name.cstr()); |
254 | 6.36k | STOFFGraphicStyle style=state.m_graphic; |
255 | 6.36k | state.m_frame.addTo(style.m_propertyList); |
256 | 6.36k | if (!dir || !StarFileManager::readOLEDirectory(m_oleParser, dir, localPicture, localObj) || localPicture.isEmpty()) { |
257 | 5.75k | if (!localObj) { |
258 | 1.26k | STOFF_DEBUG_MSG(("StarObjectTextInternal::OLEZone::send: sorry, can not find object %s\n", m_name.cstr())); |
259 | 1.26k | return false; |
260 | 1.26k | } |
261 | 4.49k | auto chart=std::dynamic_pointer_cast<StarObjectChart>(localObj); |
262 | 4.49k | if (chart && chart->send(listener, state.m_frame, style)) |
263 | 0 | return true; |
264 | 4.49k | auto math=std::dynamic_pointer_cast<StarObjectMath>(localObj); |
265 | 4.49k | if (math && math->send(listener, state.m_frame, style)) |
266 | 556 | return true; |
267 | 3.93k | if (std::dynamic_pointer_cast<StarObjectText>(localObj)) { |
268 | 3.83k | STOFF_DEBUG_MSG(("StarObjectTextInternal::OLEZone::send: sorry, unsure how to send a text object %s\n", m_name.cstr())); |
269 | 3.83k | } |
270 | 102 | else { |
271 | 102 | STOFF_DEBUG_MSG(("StarObjectTextInternal::OLEZone::send: sorry, find unexpected object for %s\n", m_name.cstr())); |
272 | 102 | } |
273 | 3.93k | return false; |
274 | 4.49k | } |
275 | 610 | listener->insertPicture(state.m_frame, localPicture, style); |
276 | | |
277 | 610 | return true; |
278 | 6.36k | } |
279 | | |
280 | | //////////////////////////////////////// |
281 | | //! Internal: a sectionZone of StarObjectTextInteral |
282 | | struct SectionZone final : public Zone { |
283 | | //! constructor |
284 | | SectionZone() |
285 | 20.9k | : Zone() |
286 | 20.9k | , m_name("") |
287 | 20.9k | , m_condition("") |
288 | 20.9k | , m_linkName("") |
289 | 20.9k | , m_type(0) |
290 | 20.9k | , m_flags(0) |
291 | 20.9k | , m_format() |
292 | 20.9k | , m_content() |
293 | 20.9k | { |
294 | 20.9k | } |
295 | | //! try to send the data to a listener |
296 | | bool send(STOFFListenerPtr &listener, StarState &state) const final; |
297 | | //! the section name |
298 | | librevenge::RVNGString m_name; |
299 | | //! the section condition |
300 | | librevenge::RVNGString m_condition; |
301 | | //! the section link name |
302 | | librevenge::RVNGString m_linkName; |
303 | | //! the section type |
304 | | int m_type; |
305 | | //! the section flag |
306 | | int m_flags; |
307 | | //! the format |
308 | | std::shared_ptr<StarFormatManagerInternal::FormatDef> m_format; |
309 | | //! the content |
310 | | std::shared_ptr<Content> m_content; |
311 | | }; |
312 | | |
313 | | bool SectionZone::send(STOFFListenerPtr &listener, StarState &state) const |
314 | 3.34k | { |
315 | 3.34k | if (!listener) { |
316 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::SectionZone::send: call without listener\n")); |
317 | 0 | return false; |
318 | 0 | } |
319 | | // checkme: do we need to create a new section here |
320 | 3.34k | if (m_content) |
321 | 174 | m_content->send(listener, state); |
322 | 3.16k | else { |
323 | 3.16k | STOFF_DEBUG_MSG(("StarObjectTextInternal::SectionZone::send: call without content\n")); |
324 | 3.16k | } |
325 | 3.34k | return true; |
326 | 3.34k | } |
327 | | |
328 | | //////////////////////////////////////// |
329 | | //! Internal: a textZone of StarObjectTextInteral |
330 | | struct TextZone final : public Zone { |
331 | | //! constructor |
332 | | TextZone() |
333 | 110k | : Zone() |
334 | 110k | , m_text() |
335 | 110k | , m_textSourcePosition() |
336 | 110k | , m_styleName("") |
337 | 110k | , m_level(-1) |
338 | 110k | , m_charAttributeList() |
339 | 110k | , m_formatList() |
340 | 110k | , m_list() |
341 | 110k | , m_markList() |
342 | 110k | { |
343 | 110k | } |
344 | | //! try to inventory the different pages |
345 | | void inventoryPage(StarState &state) const final; |
346 | | //! try to send the data to a listener |
347 | | bool send(STOFFListenerPtr &listener, StarState &state) const final; |
348 | | //! the text |
349 | | std::vector<uint32_t> m_text; |
350 | | //! the text initial position |
351 | | std::vector<size_t> m_textSourcePosition; |
352 | | //! the style name |
353 | | librevenge::RVNGString m_styleName; |
354 | | //! the level -1=none, 200: keep in list with no bullet |
355 | | int m_level; |
356 | | //! the character item list |
357 | | std::vector<StarWriterStruct::Attribute> m_charAttributeList; |
358 | | //! the format |
359 | | std::vector<std::shared_ptr<StarFormatManagerInternal::FormatDef> > m_formatList; |
360 | | //! the list (if defined) |
361 | | std::shared_ptr<STOFFList> m_list; |
362 | | //! the mark |
363 | | std::vector<StarWriterStruct::Mark> m_markList; |
364 | | }; |
365 | | |
366 | | void TextZone::inventoryPage(StarState &state) const |
367 | 23.2k | { |
368 | 23.2k | size_t numPages=state.m_global->m_pageNameList.size(); |
369 | 23.2k | if (state.m_styleName!=m_styleName) { |
370 | 6.62k | state.reinitializeLineData(); |
371 | 6.62k | state.m_styleName=m_styleName; |
372 | 6.62k | if (state.m_global->m_pool && !m_styleName.empty()) { // checkme |
373 | 6.09k | auto const *style=state.m_global->m_pool->findStyleWithFamily(m_styleName, StarItemStyle::F_Paragraph); |
374 | 6.09k | if (style) { |
375 | 15.2k | for (auto it : style->m_itemSet.m_whichToItemMap) { |
376 | 15.2k | if (it.second && it.second->m_attribute) |
377 | 14.4k | it.second->m_attribute->addTo(state); |
378 | 15.2k | } |
379 | 3.09k | } |
380 | 2.99k | else { |
381 | 2.99k | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::inventoryPage: can not find style %s\n", m_styleName.cstr())); |
382 | 2.99k | } |
383 | 6.09k | } |
384 | 6.62k | } |
385 | 23.2k | StarState lineState(state); |
386 | 49.6k | for (auto const &attrib : m_charAttributeList) { |
387 | 49.6k | if ((attrib.m_position[1]<0 && attrib.m_position[0]>0) || attrib.m_position[0]>0) |
388 | 7.44k | continue; |
389 | 42.1k | if (!attrib.m_attribute) |
390 | 604 | continue; |
391 | 41.5k | attrib.m_attribute->addTo(lineState); |
392 | 41.5k | } |
393 | 23.2k | if (lineState.m_global->m_pageNameList.size()!=state.m_global->m_pageNameList.size()) { |
394 | 0 | state.m_global->m_pageName=lineState.m_global->m_pageName; |
395 | 0 | state.m_global->m_pageNameList.push_back(state.m_global->m_pageName); |
396 | 0 | } |
397 | 23.2k | else if (lineState.m_global->m_pageNameList.size()==numPages && lineState.m_break==4) |
398 | 98 | state.m_global->m_pageNameList.push_back(""); |
399 | 23.2k | } |
400 | | |
401 | | bool TextZone::send(STOFFListenerPtr &listener, StarState &state) const |
402 | 72.8k | { |
403 | 72.8k | if (!listener || !listener->canWriteText()) { |
404 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: call without listener\n")); |
405 | 0 | return false; |
406 | 0 | } |
407 | | |
408 | 72.8k | if (m_list) state.m_global->m_list=listener->getListManager()->addList(m_list); |
409 | 72.8k | size_t numPages=state.m_global->m_pageNameList.size(); |
410 | 72.8k | if (state.m_styleName!=m_styleName) { |
411 | 25.0k | state.reinitializeLineData(); |
412 | 25.0k | state.m_paragraph=STOFFParagraph(); |
413 | 25.0k | state.m_styleName=m_styleName; |
414 | 25.0k | if (state.m_global->m_pool && !m_styleName.empty()) { // checkme |
415 | 18.7k | StarItemStyle const *style=state.m_global->m_pool->findStyleWithFamily(m_styleName, StarItemStyle::F_Paragraph); |
416 | 18.7k | if (style) { |
417 | 9.06k | if (style->m_outlineLevel>=0 && style->m_outlineLevel<20) { |
418 | 502 | state.m_paragraph.m_outline=true; |
419 | 502 | state.m_paragraph.m_listLevelIndex=style->m_outlineLevel+1; |
420 | 502 | } |
421 | 52.5k | for (auto it : style->m_itemSet.m_whichToItemMap) { |
422 | 52.5k | if (it.second && it.second->m_attribute) |
423 | 50.9k | it.second->m_attribute->addTo(state); |
424 | 52.5k | } |
425 | | #if 0 |
426 | | std::cerr << "Para[" << m_styleName.cstr() << "]:" << style->m_itemSet.printChild() << "\n"; |
427 | | #endif |
428 | 9.06k | } |
429 | 9.64k | else { |
430 | 9.64k | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: can not find style %s\n", m_styleName.cstr())); |
431 | 9.64k | } |
432 | 18.7k | } |
433 | 25.0k | } |
434 | 72.8k | STOFFFont mainFont=state.m_font; |
435 | 72.8k | listener->setFont(mainFont); |
436 | 72.8k | if (!m_markList.empty()) { |
437 | 1.12k | static bool first=true; |
438 | 1.12k | if (first) { |
439 | 1 | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: sorry mark are not implemented\n")); |
440 | 1 | first=false; |
441 | 1 | } |
442 | 1.12k | } |
443 | 72.8k | if (state.m_flyCnt || state.m_footnote || state.m_field) { |
444 | 451 | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: find a data in mainFont\n")); |
445 | 451 | } |
446 | 72.8k | if (!state.m_link.empty()) { |
447 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: find a link in mainFont\n")); |
448 | 0 | } |
449 | 72.8k | if (!state.m_refMark.empty()) { |
450 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: find a refMark in mainFont\n")); |
451 | 0 | } |
452 | 72.8k | std::set<size_t> modPosSet; |
453 | 72.8k | modPosSet.insert(0); |
454 | 119k | for (auto const &attrib : m_charAttributeList) { |
455 | 119k | if (attrib.m_position[0]>0) |
456 | 13.7k | modPosSet.insert(size_t(attrib.m_position[0])); |
457 | 119k | if (attrib.m_position[1]>0) |
458 | 5.65k | modPosSet.insert(size_t(attrib.m_position[1])); |
459 | 119k | } |
460 | 72.8k | std::multimap<size_t, std::shared_ptr<StarFormatManagerInternal::FormatDef> > posToFormat; |
461 | 72.8k | for (auto const &c : m_formatList) { |
462 | 1.82k | if (!c) continue; |
463 | | // either a paragraph anchor or a "at char" anchor |
464 | 1.82k | StarState fState(state); |
465 | 1.82k | c->updateState(fState); |
466 | 1.82k | size_t lastIndex=m_textSourcePosition.empty() ? 0 : m_textSourcePosition.back(); |
467 | 1.82k | size_t cPos=fState.m_frame.m_anchorIndex<0 ? 0 : fState.m_frame.m_anchorIndex>int(lastIndex) ? lastIndex : |
468 | 104 | size_t(fState.m_frame.m_anchorIndex); |
469 | 1.82k | posToFormat.insert(std::multimap<size_t, std::shared_ptr<StarFormatManagerInternal::FormatDef> >::value_type(cPos, c)); |
470 | 1.82k | } |
471 | 72.8k | auto posSetIt=modPosSet.begin(); |
472 | 72.8k | int endLinkPos=-1, endRefMarkPos=-1; |
473 | 72.8k | librevenge::RVNGString refMarkString; |
474 | 72.8k | StarState lineState(state); |
475 | 72.8k | state.m_break=0; |
476 | 72.8k | bool newPage=false; |
477 | 13.2M | for (size_t c=0; c<= m_text.size(); ++c) { |
478 | 13.2M | bool fontChange=false; |
479 | 13.2M | size_t srcPos=c<m_textSourcePosition.size() ? m_textSourcePosition[c] : m_textSourcePosition.empty() ? 0 : 10000; |
480 | 13.3M | while (posSetIt!=modPosSet.end() && *posSetIt <= srcPos) { |
481 | 89.5k | ++posSetIt; |
482 | 89.5k | fontChange=true; |
483 | 89.5k | } |
484 | 13.2M | std::shared_ptr<StarAttribute> flyCnt; |
485 | 13.2M | std::shared_ptr<StarAttribute> footnote; |
486 | 13.2M | std::shared_ptr<SWFieldManagerInternal::Field> field; |
487 | 13.2M | librevenge::RVNGString linkString; |
488 | 13.2M | bool startRefMark=false; |
489 | 13.2M | bool softHyphen=false; |
490 | 13.2M | bool hardBlank=false; |
491 | 13.2M | if (fontChange) { |
492 | 89.3k | lineState.reinitializeLineData(); |
493 | 89.3k | lineState.m_font=mainFont; |
494 | 89.3k | STOFFFont &font=lineState.m_font; |
495 | 257k | for (auto const &attrib : m_charAttributeList) { |
496 | 257k | if ((attrib.m_position[1]<0 && attrib.m_position[0]>=0 && attrib.m_position[0]!=int(srcPos)) || |
497 | 184k | (attrib.m_position[0]>=0 && attrib.m_position[0]>int(srcPos)) || |
498 | 174k | (attrib.m_position[1]>=0 && attrib.m_position[1]<=int(srcPos))) |
499 | 96.7k | continue; |
500 | 160k | if (!attrib.m_attribute) |
501 | 3.69k | continue; |
502 | 156k | attrib.m_attribute->addTo(lineState); |
503 | 156k | if (!footnote && lineState.m_footnote) |
504 | 3.32k | footnote=attrib.m_attribute; |
505 | 156k | if (!flyCnt && lineState.m_flyCnt) |
506 | 2.18k | flyCnt=attrib.m_attribute; |
507 | 156k | if (c==0) { |
508 | 103k | switch (lineState.m_break) { |
509 | 102k | case 0: |
510 | 102k | break; |
511 | 63 | case 1: |
512 | 63 | listener->insertBreak(STOFFListener::ColumnBreak); |
513 | 63 | break; |
514 | 320 | case 4: |
515 | 320 | newPage=true; |
516 | 320 | listener->insertBreak(STOFFListener::PageBreak); |
517 | 320 | if (state.m_global->m_pageNameList.size()==numPages) |
518 | 256 | state.m_global->m_pageNameList.push_back(""); |
519 | 320 | break; |
520 | 49 | default: { |
521 | 49 | static bool first=true; |
522 | 49 | if (first) { |
523 | 1 | first=false; |
524 | 1 | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: unexpected break\n")); |
525 | 1 | } |
526 | 49 | break; |
527 | 0 | } |
528 | 103k | } |
529 | 103k | lineState.m_break=0; |
530 | 103k | } |
531 | 156k | if (lineState.m_field) { |
532 | 581 | if (int(srcPos)==attrib.m_position[0]) |
533 | 555 | field=lineState.m_field; |
534 | 581 | lineState.m_field.reset(); |
535 | 581 | } |
536 | 156k | if (!lineState.m_link.empty()) { |
537 | 411 | if (endLinkPos<0) { |
538 | 384 | linkString=lineState.m_link; |
539 | 384 | endLinkPos=int(attrib.m_position[1]<0 ? attrib.m_position[0] : attrib.m_position[1]); |
540 | 384 | } |
541 | 411 | lineState.m_link.clear(); |
542 | 411 | } |
543 | 156k | if (!lineState.m_refMark.empty()) { |
544 | 31 | if (endRefMarkPos<0) { |
545 | 24 | refMarkString=lineState.m_refMark; |
546 | 24 | endRefMarkPos=int(attrib.m_position[1]<0 ? attrib.m_position[0] : attrib.m_position[1]); |
547 | 24 | startRefMark=true; |
548 | 24 | } |
549 | 7 | else { |
550 | 7 | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: multiple refmark is not implemented\n")); |
551 | 7 | } |
552 | 31 | lineState.m_refMark.clear(); |
553 | 31 | } |
554 | 156k | } |
555 | 89.3k | softHyphen=font.m_softHyphen; |
556 | 89.3k | hardBlank=font.m_hardBlank; |
557 | 89.3k | listener->setFont(font); |
558 | 89.3k | if (c==0) { |
559 | 72.8k | int level=m_level; |
560 | 72.8k | if (level==200) { |
561 | 0 | level=state.m_global->m_listLevel; |
562 | 0 | lineState.m_paragraph.m_bulletVisible=true; // useMe |
563 | 0 | } |
564 | 72.8k | if (!lineState.m_paragraph.m_outline) { |
565 | 72.0k | if (level>=0 && (!state.m_global->m_list || state.m_global->m_list->numLevels()<=int(level))) { |
566 | 2.11k | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: oops can not find the list\n")); |
567 | 2.11k | level=-1; |
568 | 2.11k | } |
569 | 72.0k | if (level>=0) { |
570 | 5.17k | lineState.m_paragraph.m_listLevel = state.m_global->m_list->getLevel(level); |
571 | 5.17k | lineState.m_paragraph.m_listId = state.m_global->m_list->getId(); |
572 | 5.17k | lineState.m_paragraph.m_listLevelIndex = level+1; |
573 | 5.17k | } |
574 | 66.8k | else |
575 | 66.8k | lineState.m_paragraph.m_listLevelIndex=0; |
576 | 72.0k | } |
577 | 72.8k | listener->setParagraph(lineState.m_paragraph); |
578 | 72.8k | } |
579 | 89.3k | static bool first=true; |
580 | 89.3k | if (first && lineState.m_content) { |
581 | 1 | first=false; |
582 | 1 | STOFF_DEBUG_MSG(("StarObjectTextInternal::TextZone::send: find unexpected content zone\n")); |
583 | 1 | } |
584 | 89.3k | } |
585 | 13.2M | if (c==0 && !newPage && numPages && numPages!=lineState.m_global->m_pageNameList.size()) |
586 | 61 | listener->insertBreak(STOFFListener::SoftPageBreak); |
587 | 13.2M | for (auto it=posToFormat.lower_bound(srcPos); it!=posToFormat.upper_bound(srcPos); ++it) { |
588 | 1.81k | StarState cState(*lineState.m_global); |
589 | 1.81k | it->second->send(listener, cState); |
590 | 1.81k | } |
591 | | |
592 | 13.2M | if (!linkString.empty()) { |
593 | 384 | STOFFLink link; |
594 | 384 | link.m_HRef=linkString.cstr(); |
595 | 384 | listener->openLink(link); |
596 | 384 | } |
597 | 13.2M | if (!refMarkString.empty() && startRefMark) { |
598 | 24 | STOFFField cField; |
599 | 24 | cField.m_propertyList.insert("librevenge:field-type", "text:reference-mark-start"); |
600 | 24 | cField.m_propertyList.insert("text:name", refMarkString); |
601 | 24 | listener->insertField(cField); |
602 | 24 | } |
603 | 13.2M | if (endLinkPos>=0 && int(c)==endLinkPos) { |
604 | 183 | listener->closeLink(); |
605 | 183 | endLinkPos=-1; |
606 | 183 | } |
607 | 13.2M | if (endRefMarkPos>=0 && int(c)==endRefMarkPos) { |
608 | 9 | STOFFField cField; |
609 | 9 | cField.m_propertyList.insert("librevenge:field-type", "text:reference-mark-end"); |
610 | 9 | cField.m_propertyList.insert("text:name", refMarkString); |
611 | 9 | listener->insertField(cField); |
612 | 9 | endRefMarkPos=-1; |
613 | 9 | } |
614 | 13.2M | if (footnote) { |
615 | 3.32k | StarState cState(*state.m_global); |
616 | 3.32k | footnote->send(listener, cState); |
617 | 3.32k | } |
618 | 13.2M | else if (flyCnt) { |
619 | 2.18k | StarState cState(*state.m_global); |
620 | 2.18k | flyCnt->send(listener, cState); |
621 | 2.18k | } |
622 | 13.2M | else if (field) { |
623 | 555 | StarState cState(*state.m_global); |
624 | 555 | field->send(listener, cState); |
625 | 555 | } |
626 | 13.2M | else if (c==m_text.size()) |
627 | 72.6k | break; |
628 | 13.1M | else if (hardBlank) |
629 | 60 | listener->insertUnicode(0xa0); |
630 | 13.1M | else if (softHyphen) |
631 | 5.28k | listener->insertUnicode(0xad); |
632 | 13.1M | else if (m_text[c]==0x9) |
633 | 55.9k | listener->insertTab(); |
634 | 13.1M | else if (m_text[c]==0xa) |
635 | 46.3k | listener->insertEOL(true); |
636 | 13.0M | else |
637 | 13.0M | listener->insertUnicode(m_text[c]); |
638 | 13.2M | } |
639 | 72.8k | if (endLinkPos>=0) // check that not link is opened |
640 | 193 | listener->closeLink(); |
641 | 72.8k | if (endRefMarkPos>=0) { // check that not refMark is opened |
642 | 15 | STOFFField cField; |
643 | 15 | cField.m_propertyList.insert("librevenge:field-type", "text:reference-mark-end"); |
644 | 15 | cField.m_propertyList.insert("text:name", refMarkString); |
645 | 15 | listener->insertField(cField); |
646 | 15 | } |
647 | 72.8k | return true; |
648 | 72.8k | } |
649 | | |
650 | | //! Internal: a table of StarObjectTextInteral |
651 | | struct Table final : public Zone { |
652 | | //! constructor |
653 | | Table() |
654 | 5.81k | : Zone() |
655 | 5.81k | , m_table() |
656 | 5.81k | { |
657 | 5.81k | } |
658 | | //! try to send the data to a listener |
659 | | bool send(STOFFListenerPtr &listener, StarState &state) const final; |
660 | | //! the table |
661 | | std::shared_ptr<StarTable> m_table; |
662 | | }; |
663 | | |
664 | | bool Table::send(STOFFListenerPtr &listener, StarState &state) const |
665 | 4.32k | { |
666 | 4.32k | if (!listener) { |
667 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::Table::send: call without listener\n")); |
668 | 0 | return false; |
669 | 0 | } |
670 | 4.32k | if (!m_table) { |
671 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::Table::send: can not find the table\n")); |
672 | 0 | return false; |
673 | 0 | } |
674 | 4.32k | return m_table->send(listener, state); |
675 | 4.32k | } |
676 | | |
677 | | bool Content::send(STOFFListenerPtr &listener, StarState &state, bool isFlyer) const |
678 | 30.2k | { |
679 | 30.2k | if (!listener) { |
680 | 0 | STOFF_DEBUG_MSG(("StarObjectTextInternal::Content::send: call without listener\n")); |
681 | 0 | return false; |
682 | 0 | } |
683 | 30.2k | if (isFlyer) { |
684 | | // check if we need to create a textbox |
685 | 6.82k | for (size_t t=0; t<m_zoneList.size(); ++t) { |
686 | 3.45k | if (!std::dynamic_pointer_cast<TextZone>(m_zoneList[t])) |
687 | 3.33k | continue; |
688 | 113 | StarState cState(state.m_global); |
689 | 113 | auto subDoc = std::make_shared<SubDocument>(*this, cState); |
690 | 113 | STOFFGraphicStyle style=cState.m_graphic; |
691 | 113 | state.m_frame.addTo(style.m_propertyList); |
692 | 113 | listener->insertTextBox(state.m_frame, subDoc, style); |
693 | 113 | return true; |
694 | 3.45k | } |
695 | 3.49k | } |
696 | 30.1k | StarState cState(state.m_global); |
697 | 30.1k | cState.m_frame=state.m_frame; |
698 | 119k | for (size_t t=0; t<m_zoneList.size(); ++t) { |
699 | 89.0k | if (m_zoneList[t]) |
700 | 89.0k | m_zoneList[t]->send(listener, cState); |
701 | 89.0k | if (t+1!=m_zoneList.size()) |
702 | 59.7k | listener->insertEOL(); |
703 | 89.0k | } |
704 | 30.1k | return true; |
705 | 30.2k | } |
706 | | |
707 | | //////////////////////////////////////// |
708 | | //! Internal: the state of a StarObjectText |
709 | | struct State { |
710 | | //! constructor |
711 | | State() |
712 | 37.0k | : m_numPages(0) |
713 | 37.0k | , m_numGraphicPages(0) |
714 | 37.0k | , m_mainContent() |
715 | 37.0k | , m_flyList() |
716 | 37.0k | , m_numericRuler() |
717 | 37.0k | , m_pageStyle() |
718 | 37.0k | , m_model() |
719 | 37.0k | { |
720 | 37.0k | } |
721 | | //! the number of pages |
722 | | int m_numPages; |
723 | | //! the graphic number of pages |
724 | | int m_numGraphicPages; |
725 | | //! the main content |
726 | | std::shared_ptr<Content> m_mainContent; |
727 | | //! the list of fly zone |
728 | | std::vector<std::shared_ptr<StarFormatManagerInternal::FormatDef> > m_flyList; |
729 | | //! the numeric ruler |
730 | | std::shared_ptr<StarObjectNumericRuler> m_numericRuler; |
731 | | //! the page style |
732 | | std::shared_ptr<StarObjectPageStyle> m_pageStyle; |
733 | | //! the drawing model |
734 | | std::shared_ptr<StarObjectModel> m_model; |
735 | | }; |
736 | | |
737 | | } |
738 | | |
739 | | //////////////////////////////////////////////////////////// |
740 | | // constructor/destructor, ... |
741 | | //////////////////////////////////////////////////////////// |
742 | | StarObjectText::StarObjectText(StarObject const &orig, bool duplicateState) |
743 | 37.0k | : StarObject(orig, duplicateState) |
744 | 37.0k | , m_textState(new StarObjectTextInternal::State) |
745 | 37.0k | { |
746 | 37.0k | } |
747 | | |
748 | | StarObjectText::~StarObjectText() |
749 | 37.0k | { |
750 | 37.0k | cleanPools(); |
751 | 37.0k | } |
752 | | |
753 | | //////////////////////////////////////////////////////////// |
754 | | // send the data |
755 | | //////////////////////////////////////////////////////////// |
756 | | bool StarObjectText::updatePageSpans(std::vector<STOFFPageSpan> &pageSpan, int &numPages) |
757 | 18.8k | { |
758 | 18.8k | numPages=0; |
759 | | |
760 | 18.8k | auto pool=findItemPool(StarItemPool::T_WriterPool, false); |
761 | 18.8k | StarState state(pool.get(), *this); |
762 | 18.8k | state.m_global->m_objectModel=m_textState->m_model; |
763 | 18.8k | if (m_textState->m_mainContent) |
764 | 5.42k | m_textState->m_mainContent->inventoryPages(state); |
765 | 18.8k | if (m_textState->m_pageStyle) |
766 | 1.47k | m_textState->m_pageStyle->updatePageSpans(state.m_global->m_pageNameList, pageSpan, numPages); |
767 | 17.4k | else { |
768 | 17.4k | numPages=1000; |
769 | 17.4k | STOFFPageSpan ps; |
770 | 17.4k | ps.m_pageSpan=numPages; |
771 | 17.4k | pageSpan.clear(); |
772 | 17.4k | pageSpan.push_back(ps); |
773 | 17.4k | } |
774 | 18.8k | m_textState->m_numPages=numPages; |
775 | 18.8k | if (m_textState->m_model) { |
776 | 604 | std::vector<STOFFPageSpan> modelPageSpan; |
777 | 604 | m_textState->m_model->updatePageSpans(modelPageSpan, m_textState->m_numGraphicPages); |
778 | 604 | } |
779 | 18.8k | return numPages>0; |
780 | 18.8k | } |
781 | | |
782 | | bool StarObjectText::sendPages(STOFFTextListenerPtr &listener) |
783 | 18.8k | { |
784 | 18.8k | if (!listener) { |
785 | 0 | STOFF_DEBUG_MSG(("StarObjectText::sendPages: can not find the listener\n")); |
786 | 0 | return false; |
787 | 0 | } |
788 | 18.8k | if (!m_textState->m_mainContent) { |
789 | 13.4k | STOFF_DEBUG_MSG(("StarObjectText::sendPages: can not find any content\n")); |
790 | 13.4k | return true; |
791 | 13.4k | } |
792 | | /* |
793 | | if (m_textState->m_model) { |
794 | | // send the graphics which are in the model |
795 | | for (int i=0; i<=m_textState->m_numGraphicPages; ++i) |
796 | | m_textState->m_model->sendPage(i, listener); |
797 | | } |
798 | | */ |
799 | 5.42k | auto pool=findItemPool(StarItemPool::T_WriterPool, false); |
800 | | // then send the frames relative to the page |
801 | 5.42k | for (auto fly : m_textState->m_flyList) { |
802 | 1.42k | if (!fly) continue; |
803 | 1.42k | StarState state(pool.get(), *this); |
804 | 1.42k | state.m_global->m_objectModel=m_textState->m_model; |
805 | 1.42k | fly->send(listener, state); |
806 | 1.42k | } |
807 | | // finally send the text content |
808 | 5.42k | StarState state(pool.get(), *this); |
809 | 5.42k | state.m_global->m_objectModel=m_textState->m_model; |
810 | 5.42k | state.m_global->m_numericRuler=m_textState->m_numericRuler; |
811 | 5.42k | STOFFListenerPtr basicListener(listener); |
812 | 5.42k | m_textState->m_mainContent->send(basicListener, state); |
813 | 5.42k | return true; |
814 | 18.8k | } |
815 | | |
816 | | //////////////////////////////////////////////////////////// |
817 | | // the parser |
818 | | //////////////////////////////////////////////////////////// |
819 | | bool StarObjectText::parse() |
820 | 22.7k | { |
821 | 22.7k | if (!getOLEDirectory() || !getOLEDirectory()->m_input) { |
822 | 0 | STOFF_DEBUG_MSG(("StarObjectText::parser: error, incomplete document\n")); |
823 | 0 | return false; |
824 | 0 | } |
825 | 22.7k | auto &directory=*getOLEDirectory(); |
826 | 22.7k | StarObject::parse(); |
827 | 22.7k | auto unparsedOLEs=directory.getUnparsedOles(); |
828 | 22.7k | STOFFInputStreamPtr input=directory.m_input; |
829 | 22.7k | StarFileManager fileManager; |
830 | 22.7k | STOFFInputStreamPtr mainOle; // let store the StarWriterDocument to read it in last position |
831 | 22.7k | std::string mainName; |
832 | 97.9k | for (auto const &name : unparsedOLEs) { |
833 | 97.9k | STOFFInputStreamPtr ole = input->getSubStreamByName(name.c_str()); |
834 | 97.9k | if (!ole.get()) { |
835 | 30.6k | STOFF_DEBUG_MSG(("StarObjectText::parse: error: can not find OLE part: \"%s\"\n", name.c_str())); |
836 | 30.6k | continue; |
837 | 30.6k | } |
838 | | |
839 | 67.3k | auto pos = name.find_last_of('/'); |
840 | 67.3k | std::string base; |
841 | 67.3k | if (pos == std::string::npos) base = name; |
842 | 1 | else if (pos == 0) base = name.substr(1); |
843 | 1 | else |
844 | 1 | base = name.substr(pos+1); |
845 | 67.3k | ole->setReadInverted(true); |
846 | 67.3k | if (base=="SwNumRules") { |
847 | 1.07k | try { |
848 | 1.07k | StarZone zone(ole, name, "StarNumericList", getPassword()); |
849 | 1.07k | std::shared_ptr<StarObjectNumericRuler> numericRuler(new StarObjectNumericRuler(*this,true)); |
850 | 1.07k | if (numericRuler->read(zone)) |
851 | 779 | m_textState->m_numericRuler=numericRuler; |
852 | 1.07k | } |
853 | 1.07k | catch (...) { |
854 | 0 | } |
855 | 1.07k | continue; |
856 | 1.07k | } |
857 | 66.2k | if (base=="SwPageStyleSheets") { |
858 | 2.73k | try { |
859 | 2.73k | StarZone zone(ole, name, "StarPageStyleSheets", getPassword()); |
860 | 2.73k | std::shared_ptr<StarObjectPageStyle> pageStyle(new StarObjectPageStyle(*this,true)); |
861 | 2.73k | if (pageStyle->read(zone)) |
862 | 1.56k | m_textState->m_pageStyle=pageStyle; |
863 | 2.73k | } |
864 | 2.73k | catch (...) { |
865 | 0 | } |
866 | 2.73k | continue; |
867 | 2.73k | } |
868 | | |
869 | 63.5k | if (base=="DrawingLayer") { |
870 | 7.18k | readDrawingLayer(ole,name); |
871 | 7.18k | continue; |
872 | 7.18k | } |
873 | 56.3k | if (base=="SfxStyleSheets") { |
874 | 19.4k | readSfxStyleSheets(ole,name); |
875 | 19.4k | continue; |
876 | 19.4k | } |
877 | 36.8k | if (base=="StarWriterDocument") { |
878 | 22.9k | mainOle=ole; |
879 | 22.9k | mainName=name; |
880 | 22.9k | continue; |
881 | 22.9k | } |
882 | 13.9k | if (base!="BasicManager2") { |
883 | 12.8k | STOFF_DEBUG_MSG(("StarObjectText::parse: find unexpected ole %s\n", name.c_str())); |
884 | 12.8k | } |
885 | 13.9k | libstoff::DebugFile asciiFile(ole); |
886 | 13.9k | asciiFile.open(name); |
887 | | |
888 | 13.9k | libstoff::DebugStream f; |
889 | 13.9k | f << "Entries(" << base << "):"; |
890 | 13.9k | asciiFile.addPos(0); |
891 | 13.9k | asciiFile.addNote(f.str().c_str()); |
892 | 13.9k | asciiFile.reset(); |
893 | 13.9k | } |
894 | 22.7k | if (!mainOle) { |
895 | 0 | STOFF_DEBUG_MSG(("StarObjectText::parser: can not find the main writer document\n")); |
896 | 0 | return false; |
897 | 0 | } |
898 | 22.7k | readWriterDocument(mainOle,mainName); |
899 | 22.7k | return true; |
900 | 22.7k | } |
901 | | |
902 | | bool StarObjectText::readSfxStyleSheets(STOFFInputStreamPtr input, std::string const &name) |
903 | 19.4k | { |
904 | 19.4k | StarZone zone(input, name, "SfxStyleSheets", getPassword()); |
905 | 19.4k | input->seek(0, librevenge::RVNG_SEEK_SET); |
906 | 19.4k | libstoff::DebugFile &ascFile=zone.ascii(); |
907 | 19.4k | ascFile.open(name); |
908 | | |
909 | 19.4k | if (getDocumentKind()!=STOFFDocument::STOFF_K_TEXT) { |
910 | 0 | STOFF_DEBUG_MSG(("StarObjectText::readSfxStyleSheets: called with unexpected document\n")); |
911 | 0 | ascFile.addPos(0); |
912 | 0 | ascFile.addNote("Entries(SfxStyleSheets)"); |
913 | 0 | return false; |
914 | 0 | } |
915 | | // sd_sdbinfilter.cxx SdBINFilter::Import: one pool followed by a pool style |
916 | | // chart sch_docshell.cxx SchChartDocShell::Load |
917 | 19.4k | auto pool=getNewItemPool(StarItemPool::T_WriterPool); |
918 | 19.4k | auto mainPool=pool; |
919 | 21.5k | while (!input->isEnd()) { |
920 | | // REMOVEME: remove this loop, when creation of secondary pool is checked |
921 | 21.5k | long pos=input->tell(); |
922 | 21.5k | bool extraPool=false; |
923 | 21.5k | if (!pool) { |
924 | 2.08k | extraPool=true; |
925 | 2.08k | pool=getNewItemPool(StarItemPool::T_Unknown); |
926 | 2.08k | } |
927 | 21.5k | if (pool && pool->read(zone)) { |
928 | 2.08k | if (extraPool) { |
929 | 3 | STOFF_DEBUG_MSG(("StarObjectText::readSfxStyleSheets: create extra pool of type %d\n", int(pool->getType()))); |
930 | 3 | } |
931 | 2.08k | if (!mainPool) mainPool=pool; |
932 | 2.08k | pool.reset(); |
933 | 2.08k | continue; |
934 | 2.08k | } |
935 | 19.4k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
936 | 19.4k | break; |
937 | 21.5k | } |
938 | 19.4k | if (input->isEnd()) return true; |
939 | 19.4k | long pos=input->tell(); |
940 | 19.4k | if (!mainPool || !mainPool->readStyles(zone, *this)) { |
941 | 134 | STOFF_DEBUG_MSG(("StarObjectText::readSfxStyleSheets: can not read a style pool\n")); |
942 | 134 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
943 | 134 | } |
944 | 19.4k | mainPool->updateStyles(); |
945 | 19.4k | if (!input->isEnd()) { |
946 | 3.03k | STOFF_DEBUG_MSG(("StarObjectText::readSfxStyleSheets: find extra data\n")); |
947 | 3.03k | ascFile.addPos(input->tell()); |
948 | 3.03k | ascFile.addNote("Entries(SfxStyleSheets):###extra"); |
949 | 3.03k | } |
950 | 19.4k | return true; |
951 | 19.4k | } |
952 | | |
953 | | //////////////////////////////////////////////////////////// |
954 | | // |
955 | | // Intermediate level |
956 | | // |
957 | | //////////////////////////////////////////////////////////// |
958 | | bool StarObjectText::readSWContent(StarZone &zone, std::shared_ptr<StarObjectTextInternal::Content> &content) |
959 | 74.9k | { |
960 | 74.9k | STOFFInputStreamPtr input=zone.input(); |
961 | 74.9k | libstoff::DebugFile &ascFile=zone.ascii(); |
962 | 74.9k | unsigned char type; |
963 | 74.9k | long pos=input->tell(); |
964 | 74.9k | if (input->peek()!='N' || !zone.openSWRecord(type)) { |
965 | 10.0k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
966 | 10.0k | return false; |
967 | 10.0k | } |
968 | | // sw_sw3sectn.cxx: InContents |
969 | 64.9k | if (content) { |
970 | 28.0k | STOFF_DEBUG_MSG(("StarObjectText::readSWContent: oops, the content zone is already created\n")); |
971 | 28.0k | } |
972 | 36.8k | else |
973 | 36.8k | content.reset(new StarObjectTextInternal::Content); |
974 | 64.9k | libstoff::DebugStream f; |
975 | 64.9k | f << "Entries(SWContent)[" << zone.getRecordLevel() << "]:"; |
976 | 64.9k | if (zone.isCompatibleWith(5)) |
977 | 64.8k | zone.openFlagZone(); |
978 | 64.9k | int nNodes; |
979 | 64.9k | if (zone.isCompatibleWith(0x201)) |
980 | 38.1k | nNodes=int(input->readULong(4)); |
981 | 26.7k | else { |
982 | 26.7k | if (zone.isCompatibleWith(5)) { |
983 | 26.6k | auto id=int(input->readULong(2)); |
984 | | // dummy sectid, so probably ok if we do not find the pool name |
985 | 26.6k | if (id>=zone.getNumPoolNames() || !zone.getPoolName(id, content->m_sectionName)) |
986 | 20.7k | f << "#sectId=" << id << ","; |
987 | 5.91k | else |
988 | 5.91k | f << "section[name]=" << content->m_sectionName.cstr() << ","; |
989 | 26.6k | } |
990 | 26.7k | nNodes=int(input->readULong(2)); |
991 | 26.7k | } |
992 | 64.9k | f << "N=" << nNodes << ","; |
993 | 64.9k | if (zone.isCompatibleWith(5)) |
994 | 64.8k | zone.closeFlagZone(); |
995 | 64.9k | ascFile.addPos(pos); |
996 | 64.9k | ascFile.addNote(f.str().c_str()); |
997 | | |
998 | 64.9k | long lastPos=zone.getRecordLastPosition(); |
999 | 307k | for (int i=0; i<nNodes; ++i) { |
1000 | 280k | if (input->tell()>=lastPos) break; |
1001 | 278k | pos=input->tell(); |
1002 | 278k | int cType=input->peek(); |
1003 | 278k | bool done=false; |
1004 | 278k | switch (cType) { |
1005 | 6.38k | case 'E': { |
1006 | 6.38k | std::shared_ptr<StarTable> table(new StarTable); |
1007 | 6.38k | done=table->read(zone, *this); |
1008 | 6.38k | if (done) { |
1009 | 5.81k | std::shared_ptr<StarObjectTextInternal::Table> tableZone(new StarObjectTextInternal::Table); |
1010 | 5.81k | tableZone->m_table=table; |
1011 | 5.81k | content->m_zoneList.push_back(tableZone); |
1012 | 5.81k | } |
1013 | 6.38k | break; |
1014 | 0 | } |
1015 | 3.43k | case 'G': { |
1016 | 3.43k | std::shared_ptr<StarObjectTextInternal::GraphZone> graph; |
1017 | 3.43k | done=readSWGraphNode(zone, graph); |
1018 | 3.43k | if (done && graph) |
1019 | 3.15k | content->m_zoneList.push_back(graph); |
1020 | 3.43k | break; |
1021 | 0 | } |
1022 | 21.3k | case 'I': { |
1023 | 21.3k | std::shared_ptr<StarObjectTextInternal::SectionZone> section; |
1024 | 21.3k | done=readSWSection(zone, section); |
1025 | 21.3k | if (done && section) |
1026 | 20.9k | content->m_zoneList.push_back(section); |
1027 | 21.3k | break; |
1028 | 0 | } |
1029 | 36.6k | case 'O': { |
1030 | 36.6k | std::shared_ptr<StarObjectTextInternal::OLEZone> ole; |
1031 | 36.6k | done=readSWOLENode(zone, ole); |
1032 | 36.6k | if (done && ole) |
1033 | 35.9k | content->m_zoneList.push_back(ole); |
1034 | 36.6k | break; |
1035 | 0 | } |
1036 | 111k | case 'T': { |
1037 | 111k | std::shared_ptr<StarObjectTextInternal::TextZone> text; |
1038 | 111k | done=readSWTextZone(zone, text); |
1039 | 111k | if (done && text) |
1040 | 110k | content->m_zoneList.push_back(text); |
1041 | 111k | break; |
1042 | 0 | } |
1043 | 1.02k | case 'l': // related to link |
1044 | 1.75k | case 'o': { // format: safe to ignore |
1045 | 1.75k | std::shared_ptr<StarFormatManagerInternal::FormatDef> format; |
1046 | 1.75k | done=getFormatManager()->readSWFormatDef(zone,static_cast<unsigned char>(cType),format, *this); |
1047 | 1.75k | if (done && format) { |
1048 | 1.03k | std::shared_ptr<StarObjectTextInternal::FormatZone> formatZone; |
1049 | 1.03k | formatZone.reset(new StarObjectTextInternal::FormatZone(format)); |
1050 | 1.03k | content->m_zoneList.push_back(formatZone); |
1051 | 1.03k | } |
1052 | 1.75k | break; |
1053 | 1.02k | } |
1054 | 408 | case 'v': { |
1055 | 408 | StarWriterStruct::NodeRedline redline; |
1056 | 408 | done=redline.read(zone); |
1057 | 408 | break; |
1058 | 1.02k | } |
1059 | 97.2k | default: |
1060 | 97.2k | break; |
1061 | 278k | } |
1062 | 278k | if (done) continue; |
1063 | 100k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1064 | 100k | if (!zone.openSWRecord(type)) { |
1065 | 36.1k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1066 | 36.1k | break; |
1067 | 36.1k | } |
1068 | 64.3k | f.str(""); |
1069 | 64.3k | f << "SWContent[" << type << "-" << zone.getRecordLevel() << "]:"; |
1070 | 64.3k | switch (cType) { |
1071 | 2.36k | case 'i': |
1072 | | // sw_sw3node.cxx InRepTxtNode |
1073 | 2.36k | f << "repTxtNode,"; |
1074 | 2.36k | f << "rep=" << input->readULong(4) << ","; |
1075 | 2.36k | break; |
1076 | 61.9k | default: |
1077 | 61.9k | STOFF_DEBUG_MSG(("StarObjectText::readSWContent: find unexpected type\n")); |
1078 | 61.9k | f << "###"; |
1079 | 64.3k | } |
1080 | 64.3k | ascFile.addPos(pos); |
1081 | 64.3k | ascFile.addNote(f.str().c_str()); |
1082 | 64.3k | zone.closeSWRecord(type, "SWContent"); |
1083 | 64.3k | } |
1084 | 64.9k | zone.closeSWRecord('N', "SWContent"); |
1085 | 64.9k | return true; |
1086 | 64.9k | } |
1087 | | |
1088 | | bool StarObjectText::readSWGraphNode(StarZone &zone, std::shared_ptr<StarObjectTextInternal::GraphZone> &graphZone) |
1089 | 3.43k | { |
1090 | 3.43k | STOFFInputStreamPtr input=zone.input(); |
1091 | 3.43k | libstoff::DebugFile &ascFile=zone.ascii(); |
1092 | 3.43k | unsigned char type; |
1093 | 3.43k | long pos=input->tell(); |
1094 | 3.43k | if (input->peek()!='G' || !zone.openSWRecord(type)) { |
1095 | 286 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1096 | 286 | return false; |
1097 | 286 | } |
1098 | | // sw_sw3nodes.cxx: InGrfNode |
1099 | 3.15k | libstoff::DebugStream f; |
1100 | 3.15k | f << "Entries(SWGraphNode)[" << zone.getRecordLevel() << "]:"; |
1101 | 3.15k | graphZone.reset(new StarObjectTextInternal::GraphZone(m_oleParser)); |
1102 | 3.15k | std::vector<uint32_t> text; |
1103 | 3.15k | int fl=zone.openFlagZone(); |
1104 | 3.15k | if (fl&0x10) f << "link,"; |
1105 | 3.15k | if (fl&0x20) f << "empty,"; |
1106 | 3.15k | if (fl&0x40) f << "serverMap,"; |
1107 | 3.15k | zone.closeFlagZone(); |
1108 | 8.28k | for (int i=0; i<2; ++i) { |
1109 | 5.76k | if (!zone.readString(text)) { |
1110 | 634 | STOFF_DEBUG_MSG(("StarObjectText::readSWGraphNode: can not read a string\n")); |
1111 | 634 | f << "###string"; |
1112 | 634 | ascFile.addPos(pos); |
1113 | 634 | ascFile.addNote(f.str().c_str()); |
1114 | 634 | zone.closeSWRecord('G', "SWGraphNode"); |
1115 | 634 | return true; |
1116 | 634 | } |
1117 | 5.13k | if (!text.empty()) { |
1118 | 2.95k | graphZone->m_names[i]=libstoff::getString(text); |
1119 | 2.95k | f << (i==0 ? "grfName" : "fltName") << "=" << graphZone->m_names[i].cstr() << ","; |
1120 | 2.95k | } |
1121 | 5.13k | } |
1122 | 2.51k | if (zone.isCompatibleWith(0x101)) { |
1123 | 1.64k | if (!zone.readString(text)) { |
1124 | 164 | STOFF_DEBUG_MSG(("StarObjectText::readSWGraphNode: can not read a objName\n")); |
1125 | 164 | f << "###textRepl"; |
1126 | 164 | ascFile.addPos(pos); |
1127 | 164 | ascFile.addNote(f.str().c_str()); |
1128 | 164 | zone.closeSWRecord('G', "SWGraphNode"); |
1129 | 164 | return true; |
1130 | 164 | } |
1131 | 1.48k | if (!text.empty()) { |
1132 | 252 | graphZone->m_names[2]=libstoff::getString(text); |
1133 | 252 | f << "textRepl=" << graphZone->m_names[2].cstr() << ","; |
1134 | 252 | } |
1135 | 1.48k | } |
1136 | 2.35k | ascFile.addPos(pos); |
1137 | 2.35k | ascFile.addNote(f.str().c_str()); |
1138 | 2.35k | long lastPos=zone.getRecordLastPosition(); |
1139 | 3.39k | while (input->tell() < lastPos) { |
1140 | 1.38k | pos=input->tell(); |
1141 | 1.38k | bool done=false; |
1142 | 1.38k | int rType=input->peek(); |
1143 | | |
1144 | 1.38k | switch (rType) { |
1145 | 912 | case 'S': |
1146 | 912 | done=StarWriterStruct::Attribute::readList(zone, graphZone->m_attributeList, *this); |
1147 | 912 | break; |
1148 | 117 | case 'X': // store me |
1149 | 117 | done=readSWImageMap(zone); |
1150 | 117 | break; |
1151 | 355 | default: |
1152 | 355 | break; |
1153 | 1.38k | } |
1154 | 1.38k | if (done) |
1155 | 1.00k | continue; |
1156 | 377 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1157 | 377 | if (!zone.openSWRecord(type)) { |
1158 | 346 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1159 | 346 | break; |
1160 | 346 | } |
1161 | 31 | f.str(""); |
1162 | 31 | f << "SWGraphNode[" << type << "-" << zone.getRecordLevel() << "]:"; |
1163 | 31 | switch (type) { |
1164 | 0 | case 'k': { |
1165 | | // sw_sw3nodes.cxx InContour |
1166 | 0 | int polyFl=zone.openFlagZone(); |
1167 | 0 | zone.closeFlagZone(); |
1168 | 0 | if (polyFl&0x10) { |
1169 | | // poly2.cxx operator>> |
1170 | 0 | auto numPoly=int(input->readULong(2)); |
1171 | 0 | for (int i=0; i<numPoly; ++i) { |
1172 | 0 | f << "poly" << i << "=["; |
1173 | | // poly.cxx operator>> |
1174 | 0 | auto numPoints=int(input->readULong(2)); |
1175 | 0 | if (input->tell()+8*numPoints>lastPos) { |
1176 | 0 | STOFF_DEBUG_MSG(("StarObjectText::readSWGraphNode: can not read a polygon\n")); |
1177 | 0 | f << "###poly"; |
1178 | 0 | break; |
1179 | 0 | } |
1180 | 0 | for (int p=0; p<numPoints; ++p) { |
1181 | 0 | int dim[2]; |
1182 | 0 | for (int &j : dim) j=int(input->readLong(4)); |
1183 | 0 | graphZone->m_contour.m_points.push_back(StarGraphicStruct::StarPolygon::Point(STOFFVec2i(dim[0],dim[1]))); |
1184 | 0 | f << STOFFVec2i(dim[0],dim[1]) << ","; |
1185 | 0 | } |
1186 | 0 | f << "],"; |
1187 | 0 | } |
1188 | 0 | } |
1189 | 0 | break; |
1190 | 0 | } |
1191 | 31 | default: |
1192 | 31 | STOFF_DEBUG_MSG(("StarObjectText::readSWGraphNode: find unexpected type\n")); |
1193 | 31 | f << "###"; |
1194 | 31 | break; |
1195 | 31 | } |
1196 | 31 | ascFile.addPos(pos); |
1197 | 31 | ascFile.addNote(f.str().c_str()); |
1198 | 31 | zone.closeSWRecord(type, "SWGraphNode"); |
1199 | 31 | } |
1200 | | |
1201 | 2.35k | zone.closeSWRecord('G', "SWGraphNode"); |
1202 | 2.35k | return true; |
1203 | 2.35k | } |
1204 | | |
1205 | | bool StarObjectText::readSWImageMap(StarZone &zone) |
1206 | 203 | { |
1207 | 203 | STOFFInputStreamPtr input=zone.input(); |
1208 | 203 | libstoff::DebugFile &ascFile=zone.ascii(); |
1209 | 203 | unsigned char type; |
1210 | 203 | long pos=input->tell(); |
1211 | 203 | if (input->peek()!='X' || !zone.openSWRecord(type)) { |
1212 | 94 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1213 | 94 | return false; |
1214 | 94 | } |
1215 | | |
1216 | 109 | libstoff::DebugStream f; |
1217 | 109 | f << "Entries(SWImageMap)[" << zone.getRecordLevel() << "]:"; |
1218 | | // sw_sw3nodes.cxx InImageMap |
1219 | 109 | int flag=zone.openFlagZone(); |
1220 | 109 | if (flag&0xF0) f << "fl=" << flag << ","; |
1221 | 109 | zone.closeFlagZone(); |
1222 | 109 | std::vector<uint32_t> string; |
1223 | 109 | if (!zone.readString(string)) { |
1224 | 18 | STOFF_DEBUG_MSG(("StarObjectText::readSWImageMap: can not read url\n")); |
1225 | 18 | f << "###url"; |
1226 | 18 | ascFile.addPos(pos); |
1227 | 18 | ascFile.addNote(f.str().c_str()); |
1228 | | |
1229 | 18 | zone.closeSWRecord('X', "SWImageMap"); |
1230 | 18 | return true; |
1231 | 18 | } |
1232 | 91 | if (!string.empty()) |
1233 | 74 | f << "url=" << libstoff::getString(string).cstr() << ","; |
1234 | 91 | if (zone.isCompatibleWith(0x11,0x22, 0x101)) { |
1235 | 162 | for (int i=0; i<2; ++i) { |
1236 | 119 | if (!zone.readString(string)) { |
1237 | 23 | STOFF_DEBUG_MSG(("StarObjectText::readSWImageMap: can not read string\n")); |
1238 | 23 | f << "###string"; |
1239 | 23 | ascFile.addPos(pos); |
1240 | 23 | ascFile.addNote(f.str().c_str()); |
1241 | | |
1242 | 23 | zone.closeSWRecord('X', "SWImageMap"); |
1243 | 23 | return true; |
1244 | 23 | } |
1245 | 96 | if (string.empty()) continue; |
1246 | 34 | f << (i==0 ? "target" : "dummy") << "=" << libstoff::getString(string).cstr() << ","; |
1247 | 34 | } |
1248 | 66 | } |
1249 | 68 | if (flag&0x20) { |
1250 | | // svt_imap.cxx: ImageMap::Read |
1251 | 56 | std::string cMagic(""); |
1252 | 392 | for (int i=0; i<6; ++i) cMagic+=char(input->readULong(1)); |
1253 | 56 | if (cMagic!="SDIMAP") { |
1254 | 38 | STOFF_DEBUG_MSG(("StarObjectText::readSWImageMap: cMagic is bad\n")); |
1255 | 38 | f << "###cMagic=" << cMagic << ","; |
1256 | 38 | } |
1257 | 18 | else { |
1258 | 18 | input->seek(2, librevenge::RVNG_SEEK_CUR); |
1259 | 47 | for (int i=0; i<3; ++i) { |
1260 | 40 | if (!zone.readString(string)) { |
1261 | 11 | STOFF_DEBUG_MSG(("StarObjectText::readSWImageMap: can not read string\n")); |
1262 | 11 | f << "###string"; |
1263 | 11 | ascFile.addPos(pos); |
1264 | 11 | ascFile.addNote(f.str().c_str()); |
1265 | | |
1266 | 11 | zone.closeSWRecord('X', "SWImageMap"); |
1267 | 11 | return true; |
1268 | 11 | } |
1269 | 29 | if (!string.empty()) |
1270 | 8 | f << (i==0 ? "target" : i==1 ? "dummy1" : "dummy2") << "=" << libstoff::getString(string).cstr() << ","; |
1271 | 29 | if (i==1) |
1272 | 8 | f << "nCount=" << input->readULong(2) << ","; |
1273 | 29 | } |
1274 | 7 | if (input->tell()<zone.getRecordLastPosition()) { |
1275 | 0 | STOFF_DEBUG_MSG(("StarObjectText::readSWImageMap: find imapCompat data, not implemented\n")); |
1276 | | // svt_imap3.cxx IMapCompat::IMapCompat |
1277 | 0 | ascFile.addPos(input->tell()); |
1278 | 0 | ascFile.addNote("SWImageMap:###IMapCompat"); |
1279 | 0 | input->seek(zone.getRecordLastPosition(), librevenge::RVNG_SEEK_SET); |
1280 | 0 | } |
1281 | 7 | } |
1282 | 56 | } |
1283 | 57 | ascFile.addPos(pos); |
1284 | 57 | ascFile.addNote(f.str().c_str()); |
1285 | 57 | zone.closeSWRecord('X', "SWImageMap"); |
1286 | 57 | return true; |
1287 | 68 | } |
1288 | | |
1289 | | bool StarObjectText::readSWJobSetUp(StarZone &zone) |
1290 | 2.40k | { |
1291 | 2.40k | STOFFInputStreamPtr input=zone.input(); |
1292 | 2.40k | libstoff::DebugFile &ascFile=zone.ascii(); |
1293 | 2.40k | unsigned char type; |
1294 | 2.40k | long pos=input->tell(); |
1295 | 2.40k | if (input->peek()!='J' || !zone.openSWRecord(type)) { |
1296 | 100 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1297 | 100 | return false; |
1298 | 100 | } |
1299 | | |
1300 | 2.30k | libstoff::DebugStream f; |
1301 | 2.30k | zone.openFlagZone(); |
1302 | 2.30k | zone.closeFlagZone(); |
1303 | 2.30k | if (input->tell()==zone.getRecordLastPosition()) // empty |
1304 | 8 | f << "Entries(JobSetUp)[" << zone.getRecordLevel() << "]:"; |
1305 | 2.29k | else { |
1306 | 2.29k | f << "JobSetUp[container-" << zone.getRecordLevel() << "]:"; |
1307 | 2.29k | StarFileManager fileManager; |
1308 | 2.29k | fileManager.readJobSetUp(zone, false); |
1309 | 2.29k | } |
1310 | 2.30k | ascFile.addPos(pos); |
1311 | 2.30k | ascFile.addNote(f.str().c_str()); |
1312 | | |
1313 | 2.30k | zone.closeSWRecord(type, "JobSetUp[container]"); |
1314 | 2.30k | return true; |
1315 | 2.40k | } |
1316 | | |
1317 | | bool StarObjectText::readSWOLENode(StarZone &zone, std::shared_ptr<StarObjectTextInternal::OLEZone> &ole) |
1318 | 36.6k | { |
1319 | 36.6k | STOFFInputStreamPtr input=zone.input(); |
1320 | 36.6k | libstoff::DebugFile &ascFile=zone.ascii(); |
1321 | 36.6k | unsigned char type; |
1322 | 36.6k | long pos=input->tell(); |
1323 | 36.6k | if (input->peek()!='O' || !zone.openSWRecord(type)) { |
1324 | 313 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1325 | 313 | return false; |
1326 | 313 | } |
1327 | | // sw_sw3nodes.cxx: InOLENode |
1328 | 36.3k | libstoff::DebugStream f; |
1329 | 36.3k | f << "Entries(SWOLENode)[" << zone.getRecordLevel() << "]:"; |
1330 | | |
1331 | 36.3k | std::vector<uint32_t> text; |
1332 | 36.3k | if (!zone.readString(text)) { |
1333 | 350 | STOFF_DEBUG_MSG(("StarObjectText::readSWOLENode: can not read a objName\n")); |
1334 | 350 | f << "###objName"; |
1335 | 350 | ascFile.addPos(pos); |
1336 | 350 | ascFile.addNote(f.str().c_str()); |
1337 | 350 | zone.closeSWRecord('O', "SWOLENode"); |
1338 | 350 | return true; |
1339 | 350 | } |
1340 | 35.9k | ole.reset(new StarObjectTextInternal::OLEZone); |
1341 | 35.9k | ole->m_oleParser=m_oleParser; |
1342 | 35.9k | if (!text.empty()) { |
1343 | 35.9k | ole->m_name=libstoff::getString(text); |
1344 | 35.9k | f << "objName=" << ole->m_name.cstr() << ","; |
1345 | 35.9k | } |
1346 | 35.9k | if (zone.isCompatibleWith(0x101)) { |
1347 | 30.3k | if (!zone.readString(text)) { |
1348 | 19.3k | STOFF_DEBUG_MSG(("StarObjectText::readSWOLENode: can not read a objName\n")); |
1349 | 19.3k | f << "###textRepl"; |
1350 | 19.3k | ascFile.addPos(pos); |
1351 | 19.3k | ascFile.addNote(f.str().c_str()); |
1352 | 19.3k | zone.closeSWRecord('O', "SWOLENode"); |
1353 | 19.3k | return true; |
1354 | 19.3k | } |
1355 | 10.9k | if (!text.empty()) { |
1356 | 5.88k | ole->m_replaceText=libstoff::getString(text); |
1357 | 5.88k | f << "textRepl=" << ole->m_replaceText.cstr() << ","; |
1358 | 5.88k | } |
1359 | 10.9k | } |
1360 | 16.5k | ascFile.addPos(pos); |
1361 | 16.5k | ascFile.addNote(f.str().c_str()); |
1362 | 16.5k | zone.closeSWRecord('O', "SWOLENode"); |
1363 | 16.5k | return true; |
1364 | 35.9k | } |
1365 | | |
1366 | | bool StarObjectText::readSWSection(StarZone &zone, std::shared_ptr<StarObjectTextInternal::SectionZone> §ion) |
1367 | 21.3k | { |
1368 | 21.3k | STOFFInputStreamPtr input=zone.input(); |
1369 | 21.3k | libstoff::DebugFile &ascFile=zone.ascii(); |
1370 | 21.3k | unsigned char type; |
1371 | 21.3k | long pos=input->tell(); |
1372 | 21.3k | if (input->peek()!='I' || !zone.openSWRecord(type)) { |
1373 | 429 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1374 | 429 | return false; |
1375 | 429 | } |
1376 | | // sw_sw3sectn.cxx: InSection |
1377 | 20.9k | libstoff::DebugStream f; |
1378 | 20.9k | f << "Entries(SWSection)[" << zone.getRecordLevel() << "]:"; |
1379 | 20.9k | section.reset(new StarObjectTextInternal::SectionZone); |
1380 | 20.9k | std::vector<uint32_t> text; |
1381 | 53.6k | for (int i=0; i<2; ++i) { |
1382 | 39.9k | if (!zone.readString(text)) { |
1383 | 7.29k | STOFF_DEBUG_MSG(("StarObjectText::readSWSection: can not read a string\n")); |
1384 | 7.29k | f << "###string"; |
1385 | 7.29k | ascFile.addPos(pos); |
1386 | 7.29k | ascFile.addNote(f.str().c_str()); |
1387 | 7.29k | zone.closeSWRecord('I', "SWSection"); |
1388 | 7.29k | return true; |
1389 | 7.29k | } |
1390 | 32.6k | if (text.empty()) continue; |
1391 | 21.9k | if (i==0) |
1392 | 13.1k | section->m_name=libstoff::getString(text); |
1393 | 8.74k | else |
1394 | 8.74k | section->m_condition=libstoff::getString(text); |
1395 | 21.9k | f << (i==0 ? "name" : "cond") << "=" << libstoff::getString(text).cstr() << ","; |
1396 | 21.9k | } |
1397 | 13.6k | int fl=section->m_flags=zone.openFlagZone(); |
1398 | 13.6k | if (fl&0x10) f << "hidden,"; |
1399 | 13.6k | if (fl&0x20) f << "protect,"; |
1400 | 13.6k | if (fl&0x40) f << "condHidden,"; |
1401 | 13.6k | if (fl&0x80) f << "connectFlag,"; |
1402 | 13.6k | section->m_type=int(input->readULong(2)); |
1403 | 13.6k | if (section->m_type) f << "nType=" << section->m_type << ","; |
1404 | 13.6k | zone.closeFlagZone(); |
1405 | 13.6k | long lastPos=zone.getRecordLastPosition(); |
1406 | 17.1k | while (input->tell()<lastPos) { |
1407 | 5.46k | long actPos=input->tell(); |
1408 | 5.46k | int c=input->peek(); |
1409 | 5.46k | bool done=false; |
1410 | 5.46k | switch (c) { // checkme: unsure which data can be found here |
1411 | 2.69k | case 's': |
1412 | 2.69k | done=getFormatManager()->readSWFormatDef(zone,'s', section->m_format, *this); |
1413 | 2.69k | break; |
1414 | 1.42k | case 'N': |
1415 | 1.42k | done=readSWContent(zone, section->m_content); |
1416 | 1.42k | break; |
1417 | 1.34k | default: |
1418 | 1.34k | break; |
1419 | 5.46k | } |
1420 | 5.46k | if (!done || input->tell()<=actPos || input->tell()>lastPos) { |
1421 | 1.99k | input->seek(actPos, librevenge::RVNG_SEEK_SET); |
1422 | 1.99k | break; |
1423 | 1.99k | } |
1424 | 5.46k | } |
1425 | 13.6k | if (zone.isCompatibleWith(0xd)) { |
1426 | 13.3k | if (!zone.readString(text)) { |
1427 | 4.69k | STOFF_DEBUG_MSG(("StarObjectText::readSWSection: can not read a linkName\n")); |
1428 | 4.69k | f << "###linkName"; |
1429 | 4.69k | ascFile.addPos(pos); |
1430 | 4.69k | ascFile.addNote(f.str().c_str()); |
1431 | 4.69k | zone.closeSWRecord('I', "SWSection"); |
1432 | 4.69k | return true; |
1433 | 4.69k | } |
1434 | 8.67k | else if (!text.empty()) { |
1435 | 2.66k | section->m_linkName=libstoff::getString(text); |
1436 | 2.66k | f << "linkName=" << section->m_linkName.cstr() << ","; |
1437 | 2.66k | } |
1438 | 13.3k | } |
1439 | 8.98k | ascFile.addPos(pos); |
1440 | 8.98k | ascFile.addNote(f.str().c_str()); |
1441 | 8.98k | zone.closeSWRecord('I', "SWSection"); |
1442 | 8.98k | return true; |
1443 | 13.6k | } |
1444 | | |
1445 | | bool StarObjectText::readSWTextZone(StarZone &zone, std::shared_ptr<StarObjectTextInternal::TextZone> &textZone) |
1446 | 111k | { |
1447 | 111k | STOFFInputStreamPtr input=zone.input(); |
1448 | 111k | libstoff::DebugFile &ascFile=zone.ascii(); |
1449 | 111k | unsigned char type; |
1450 | 111k | long pos=input->tell(); |
1451 | 111k | if (input->peek()!='T' || !zone.openSWRecord(type)) { |
1452 | 823 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1453 | 823 | return false; |
1454 | 823 | } |
1455 | | // sw_sw3nodes.cxx: InTxtNode |
1456 | 110k | libstoff::DebugStream f; |
1457 | 110k | f << "Entries(SWText)[" << zone.getRecordLevel() << "]:"; |
1458 | 110k | textZone.reset(new StarObjectTextInternal::TextZone); |
1459 | 110k | int fl=zone.openFlagZone(); |
1460 | 110k | auto poolId=int(input->readULong(2)); |
1461 | 110k | if (!zone.getPoolName(poolId, textZone->m_styleName)) |
1462 | 60.1k | f << "###nPoolId=" << poolId << ","; |
1463 | 50.3k | else |
1464 | 50.3k | f << textZone->m_styleName.cstr() << ","; |
1465 | 110k | if (fl&0x10 && !zone.isCompatibleWith(0x201)) { |
1466 | 4.38k | auto val=int(input->readULong(1)); |
1467 | 4.38k | if (val==200 && zone.isCompatibleWith(0xf,0x101) && input->tell() < zone.getFlagLastPosition()) |
1468 | 4 | val=int(input->readULong(1)); |
1469 | 4.38k | if (val!=200) { |
1470 | 4.36k | textZone->m_level=val&0x1f; |
1471 | 4.36k | f << "nLevel=" << val << ","; |
1472 | 4.36k | } |
1473 | 4.38k | } |
1474 | 110k | if (zone.isCompatibleWith(0x19,0x22, 0x101)) |
1475 | 77.4k | f << "nCondColl=" << input->readULong(2) << ","; |
1476 | 110k | zone.closeFlagZone(); |
1477 | | |
1478 | 110k | if (!zone.readString(textZone->m_text, textZone->m_textSourcePosition, -1, true)) { |
1479 | 14.2k | STOFF_DEBUG_MSG(("StarObjectText::readSWTextZone: can not read main text\n")); |
1480 | 14.2k | f << "###text"; |
1481 | 14.2k | ascFile.addPos(pos); |
1482 | 14.2k | ascFile.addNote(f.str().c_str()); |
1483 | 14.2k | zone.closeSWRecord('T', "SWText"); |
1484 | 14.2k | return true; |
1485 | 14.2k | } |
1486 | 96.3k | else if (!textZone->m_text.empty()) |
1487 | 72.5k | f << libstoff::getString(textZone->m_text).cstr(); |
1488 | | |
1489 | 96.3k | ascFile.addPos(pos); |
1490 | 96.3k | ascFile.addNote(f.str().c_str()); |
1491 | | |
1492 | 96.3k | long lastPos=zone.getRecordLastPosition(); |
1493 | 183k | while (input->tell()<lastPos) { |
1494 | 98.5k | pos=input->tell(); |
1495 | | |
1496 | 98.5k | bool done=false; |
1497 | 98.5k | int rType=input->peek(); |
1498 | | |
1499 | 98.5k | switch (rType) { |
1500 | 19.2k | case 'A': { |
1501 | 19.2k | StarWriterStruct::Attribute attrib; |
1502 | 19.2k | done=attrib.read(zone, *this); |
1503 | 19.2k | if (done) |
1504 | 18.1k | textZone->m_charAttributeList.push_back(attrib); |
1505 | 19.2k | break; |
1506 | 0 | } |
1507 | 2.20k | case 'K': { |
1508 | 2.20k | StarWriterStruct::Mark mark; |
1509 | 2.20k | done=mark.read(zone); |
1510 | 2.20k | if (done) textZone->m_markList.push_back(mark); |
1511 | 2.20k | break; |
1512 | 0 | } |
1513 | 278 | case '0': |
1514 | 3.53k | case 'R': { |
1515 | 3.53k | std::shared_ptr<STOFFList> list; |
1516 | 3.53k | done=StarObjectNumericRuler::readList(zone,list); |
1517 | 3.53k | if (done && list) textZone->m_list=list; |
1518 | 3.53k | break; |
1519 | 278 | } |
1520 | 50.3k | case 'S': |
1521 | 50.3k | done=StarWriterStruct::Attribute::readList(zone, textZone->m_charAttributeList, *this); |
1522 | 50.3k | break; |
1523 | 1.54k | case 'l': { // related to link |
1524 | 1.54k | std::shared_ptr<StarFormatManagerInternal::FormatDef> format; |
1525 | 1.54k | done=getFormatManager()->readSWFormatDef(zone,'l', format, *this); |
1526 | 1.54k | if (done && format) |
1527 | 1.49k | textZone->m_formatList.push_back(format); |
1528 | 1.54k | break; |
1529 | 278 | } |
1530 | 924 | case 'o': { // |
1531 | 924 | std::shared_ptr<StarFormatManagerInternal::FormatDef> format; |
1532 | 924 | done=getFormatManager()->readSWFormatDef(zone,'o', format, *this); |
1533 | 924 | if (done && format) |
1534 | 327 | textZone->m_formatList.push_back(format); |
1535 | 924 | break; |
1536 | 278 | } |
1537 | 115 | case 'v': { |
1538 | 115 | StarWriterStruct::NodeRedline redline; |
1539 | 115 | done=redline.read(zone); |
1540 | 115 | break; |
1541 | 278 | } |
1542 | 20.6k | default: |
1543 | 20.6k | break; |
1544 | 98.5k | } |
1545 | 98.5k | if (done) |
1546 | 74.8k | continue; |
1547 | 23.7k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1548 | 23.7k | if (!zone.openSWRecord(type)) { |
1549 | 11.5k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1550 | 11.5k | break; |
1551 | 11.5k | } |
1552 | 12.2k | f.str(""); |
1553 | 12.2k | f << "SWText[" << type << "-" << zone.getRecordLevel() << "]:"; |
1554 | 12.2k | switch (type) { |
1555 | 3.41k | case '3': { |
1556 | | // sw_sw3num InNodeNum |
1557 | 3.41k | f << "nodeNum,"; |
1558 | 3.41k | int cFlag=zone.openFlagZone(); |
1559 | 3.41k | auto nLevel=int(input->readULong(1)); |
1560 | 3.41k | if (nLevel!=201) { |
1561 | 3.41k | int level=(nLevel&0x1f); |
1562 | 3.41k | if (level>=10) { |
1563 | 82 | level=9; |
1564 | 82 | if (nLevel&0x20) level |= 0x20; |
1565 | 82 | } |
1566 | 3.41k | textZone->m_level=level; |
1567 | 3.41k | f << "nLevel=" << level<< ","; |
1568 | 3.41k | } |
1569 | 3.41k | if (cFlag&0x20) f << "nSetValue=" << input->readULong(2) << ","; |
1570 | 3.41k | zone.closeFlagZone(); |
1571 | 3.41k | if (nLevel!=201) { |
1572 | 3.41k | int N=int(zone.getRecordLastPosition()-input->tell())/2; |
1573 | 3.41k | f << "level=["; |
1574 | 7.61k | for (int i=0; i<N; ++i) |
1575 | 4.20k | f << input->readULong(2) << ","; |
1576 | 3.41k | f << "],"; |
1577 | 3.41k | } |
1578 | 3.41k | break; |
1579 | 0 | } |
1580 | 6.97k | case 'w': { // wrong list |
1581 | | // sw_sw3nodes.cxx in text node |
1582 | 6.97k | f << "wrongList,"; |
1583 | 6.97k | int cFlag=zone.openFlagZone(); |
1584 | 6.97k | if (cFlag&0xf0) f << "flag=" << (cFlag>>4) << ","; |
1585 | 6.97k | f << "nBeginInv=" << input->readULong(2) << ","; |
1586 | 6.97k | f << "nEndInc=" << input->readULong(2) << ","; |
1587 | 6.97k | zone.closeFlagZone(); |
1588 | 6.97k | auto N =int(input->readULong(2)); |
1589 | 6.97k | if (input->tell()+4*N>zone.getRecordLastPosition()) { |
1590 | 60 | STOFF_DEBUG_MSG(("StarObjectText::readSWTextZone: find bad count\n")); |
1591 | 60 | f << "###N=" << N << ","; |
1592 | 60 | break; |
1593 | 60 | } |
1594 | 6.91k | f << "nWrong=["; |
1595 | 24.6k | for (int i=0; i<N; ++i) f << input->readULong(4) << ","; |
1596 | 6.91k | f << "],"; |
1597 | 6.91k | break; |
1598 | 6.97k | } |
1599 | 1.83k | default: |
1600 | 1.83k | STOFF_DEBUG_MSG(("StarObjectText::readSWTextZone: find unexpected type\n")); |
1601 | 1.83k | f << "###"; |
1602 | 12.2k | } |
1603 | 12.2k | ascFile.addPos(pos); |
1604 | 12.2k | ascFile.addNote(f.str().c_str()); |
1605 | 12.2k | zone.closeSWRecord(type, "SWText"); |
1606 | 12.2k | } |
1607 | 96.3k | zone.closeSWRecord('T', "SWText"); |
1608 | 96.3k | return true; |
1609 | 96.3k | } |
1610 | | |
1611 | | //////////////////////////////////////////////////////////// |
1612 | | // drawing layer |
1613 | | //////////////////////////////////////////////////////////// |
1614 | | bool StarObjectText::readDrawingLayer(STOFFInputStreamPtr input, std::string const &name) |
1615 | 7.18k | try |
1616 | 7.18k | { |
1617 | 7.18k | StarZone zone(input, name, "DrawingLayer", getPassword()); |
1618 | 7.18k | input->seek(0, librevenge::RVNG_SEEK_SET); |
1619 | 7.18k | libstoff::DebugFile &ascFile=zone.ascii(); |
1620 | 7.18k | ascFile.open(name); |
1621 | | // sw_sw3imp.cxx Sw3IoImp::LoadDrawingLayer |
1622 | | |
1623 | | // create this pool from the main's SWG pool |
1624 | 7.18k | auto pool=getNewItemPool(StarItemPool::T_XOutdevPool); |
1625 | 7.18k | pool->setRelativeUnit(0.05); |
1626 | 7.18k | pool->addSecondaryPool(getNewItemPool(StarItemPool::T_EditEnginePool)); |
1627 | | |
1628 | 7.93k | while (!input->isEnd()) { |
1629 | | // REMOVEME: remove this loop, when creation of secondary pool is checked |
1630 | 7.93k | long pos=input->tell(); |
1631 | 7.93k | bool extraPool=false; |
1632 | 7.93k | if (!pool) { |
1633 | 747 | extraPool=true; |
1634 | 747 | pool=getNewItemPool(StarItemPool::T_Unknown); |
1635 | 747 | } |
1636 | 7.93k | if (pool && pool->read(zone)) { |
1637 | 747 | if (extraPool) { |
1638 | 0 | STOFF_DEBUG_MSG(("StarObjectText::readDrawingLayer: create extra pool for %d of type %d\n", |
1639 | 0 | int(getDocumentKind()), int(pool->getType()))); |
1640 | 0 | } |
1641 | 747 | pool.reset(); |
1642 | 747 | continue; |
1643 | 747 | } |
1644 | 7.18k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1645 | 7.18k | break; |
1646 | 7.93k | } |
1647 | 7.18k | long pos=input->tell(); |
1648 | 7.18k | std::shared_ptr<StarObjectModel> model(new StarObjectModel(*this, true)); |
1649 | 7.18k | if (!model->read(zone)) { |
1650 | 6.51k | STOFF_DEBUG_MSG(("StarObjectText::readDrawingLayer: can not read the drawing model\n")); |
1651 | 6.51k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1652 | 6.51k | ascFile.addPos(input->tell()); |
1653 | 6.51k | ascFile.addNote("Entries(DrawingLayer):###extra"); |
1654 | 6.51k | return true; |
1655 | 6.51k | } |
1656 | 674 | if (m_textState->m_model) { |
1657 | 0 | STOFF_DEBUG_MSG(("StarObjectText::readDrawingLayer: oops the drawing model is already defined\n")); |
1658 | 0 | } |
1659 | 674 | else |
1660 | 674 | m_textState->m_model=model; |
1661 | 674 | if (input->isEnd()) return true; |
1662 | 674 | pos=input->tell(); |
1663 | 674 | uint16_t nSign; |
1664 | 674 | *input >> nSign; |
1665 | 674 | libstoff::DebugStream f; |
1666 | 674 | f << "Entries(DrawingLayer):"; |
1667 | 674 | bool ok=true; |
1668 | 674 | std::set<long> ids; |
1669 | 674 | if (nSign!=0x444D && nSign!=0) // 0 seems ok if followed by 0 |
1670 | 225 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1671 | 449 | else { |
1672 | 449 | uint16_t n; |
1673 | 449 | *input >> n; |
1674 | 449 | if (pos+4+4*long(n)>input->size()) { |
1675 | 28 | STOFF_DEBUG_MSG(("StarObjectText::readDrawingLayer: bad n frame\n")); |
1676 | 28 | f << "###pos"; |
1677 | 28 | ok=false; |
1678 | 28 | } |
1679 | 421 | else { |
1680 | 421 | f << "framePos=["; |
1681 | 2.73k | for (uint16_t i=0; i<n; ++i) { |
1682 | 2.31k | auto id=long(input->readULong(4)); |
1683 | 2.31k | ids.insert(id); |
1684 | 2.31k | f << id << ","; |
1685 | 2.31k | } |
1686 | 421 | f << "],"; |
1687 | 421 | } |
1688 | 449 | } |
1689 | 674 | if (ok && input->tell()+4==input->size()) |
1690 | 103 | f << "num[hidden]=" << input->readULong(4) << ","; |
1691 | 674 | if (ok && !input->isEnd()) { |
1692 | 287 | STOFF_DEBUG_MSG(("StarObjectText::readDrawingLayer: find extra data\n")); |
1693 | 287 | f << "###extra"; |
1694 | 287 | } |
1695 | 674 | model->updateObjectIds(ids); |
1696 | 674 | ascFile.addPos(pos); |
1697 | 674 | ascFile.addNote(f.str().c_str()); |
1698 | 674 | return true; |
1699 | 674 | } |
1700 | 7.18k | catch (...) |
1701 | 7.18k | { |
1702 | 0 | return false; |
1703 | 0 | } |
1704 | | |
1705 | | //////////////////////////////////////////////////////////// |
1706 | | // main zone |
1707 | | //////////////////////////////////////////////////////////// |
1708 | | bool StarObjectText::readWriterDocument(STOFFInputStreamPtr input, std::string const &name) |
1709 | 22.7k | try |
1710 | 22.7k | { |
1711 | 22.7k | StarZone zone(input, name, "SWWriterDocument", getPassword()); |
1712 | 22.7k | if (!zone.readSWHeader()) { |
1713 | 12.0k | STOFF_DEBUG_MSG(("StarObjectText::readWriterDocument: can not read the header\n")); |
1714 | 12.0k | return false; |
1715 | 12.0k | } |
1716 | 10.6k | libstoff::DebugFile &ascFile=zone.ascii(); |
1717 | | // sw_sw3doc.cxx Sw3IoImp::LoadDocContents |
1718 | 10.6k | SWFieldManager fieldManager; |
1719 | 10.6k | StarFileManager fileManager; |
1720 | 127k | while (!input->isEnd()) { |
1721 | 126k | long pos=input->tell(); |
1722 | 126k | int rType=input->peek(); |
1723 | 126k | bool done=false; |
1724 | 126k | switch (rType) { |
1725 | 6.27k | case '!': |
1726 | 6.27k | done=zone.readStringsPool(); |
1727 | 6.27k | break; |
1728 | 890 | case 'R': |
1729 | 6.12k | case '0': { // Outline |
1730 | 6.12k | std::shared_ptr<STOFFList> list; |
1731 | 6.12k | done=StarObjectNumericRuler::readList(zone,list); |
1732 | 6.12k | break; |
1733 | 890 | } |
1734 | 7.38k | case '1': { |
1735 | 7.38k | StarWriterStruct::NoteInfo info(true); |
1736 | 7.38k | done=info.read(zone); |
1737 | 7.38k | break; |
1738 | 890 | } |
1739 | 1.94k | case '4': { |
1740 | 1.94k | StarWriterStruct::NoteInfo info(false); |
1741 | 1.94k | done=info.read(zone); |
1742 | 1.94k | break; |
1743 | 890 | } |
1744 | 202 | case '8': { |
1745 | 202 | StarWriterStruct::PrintData info; |
1746 | 202 | done=info.read(zone); |
1747 | 202 | break; |
1748 | 890 | } |
1749 | 6.29k | case 'D': { |
1750 | 6.29k | StarWriterStruct::DatabaseName dbase; |
1751 | 6.29k | done=dbase.read(zone); |
1752 | 6.29k | break; |
1753 | 890 | } |
1754 | 1.79k | case 'F': |
1755 | 1.79k | done=getFormatManager()->readSWFlyFrameList(zone, *this, m_textState->m_flyList); |
1756 | 1.79k | break; |
1757 | 2.40k | case 'J': |
1758 | 2.40k | done=readSWJobSetUp(zone); |
1759 | 2.40k | break; |
1760 | 32 | case 'M': { |
1761 | 32 | std::vector<StarWriterStruct::Macro> macroList; |
1762 | 32 | done=StarWriterStruct::Macro::readList(zone, macroList); |
1763 | 32 | break; |
1764 | 890 | } |
1765 | 39.7k | case 'N': |
1766 | 39.7k | done=readSWContent(zone, m_textState->m_mainContent); |
1767 | 39.7k | break; |
1768 | 1.25k | case 'U': { // layout info, no code, ignored by LibreOffice |
1769 | 1.25k | StarLayout layout; |
1770 | 1.25k | done=layout.read(zone, *this); |
1771 | 1.25k | break; |
1772 | 890 | } |
1773 | 33 | case 'V': { |
1774 | 33 | std::vector<std::vector<StarWriterStruct::Redline> > redlineListList; |
1775 | 33 | done=StarWriterStruct::Redline::readListList(zone, redlineListList); |
1776 | 33 | break; |
1777 | 890 | } |
1778 | 9.22k | case 'Y': |
1779 | 9.22k | done=bool(fieldManager.readField(zone,'Y')); |
1780 | 9.22k | break; |
1781 | 505 | case 'a': { |
1782 | 505 | std::vector<StarWriterStruct::Bookmark> markList; |
1783 | 505 | done=StarWriterStruct::Bookmark::readList(zone, markList); |
1784 | 505 | break; |
1785 | 890 | } |
1786 | 4.69k | case 'd': { |
1787 | 4.69k | StarWriterStruct::DocStats stats; |
1788 | 4.69k | done=stats.read(zone); |
1789 | 4.69k | break; |
1790 | 890 | } |
1791 | 1.88k | case 'j': { |
1792 | 1.88k | StarWriterStruct::Dictionary dico; |
1793 | 1.88k | done=dico.read(zone); |
1794 | 1.88k | break; |
1795 | 890 | } |
1796 | 353 | case 'q': |
1797 | 353 | done=getFormatManager()->readSWNumberFormatterList(zone); |
1798 | 353 | break; |
1799 | 516 | case 'u': { |
1800 | 516 | std::vector<StarWriterStruct::TOX> toxList; |
1801 | 516 | done=StarWriterStruct::TOX::readList(zone, toxList, *this); |
1802 | 516 | break; |
1803 | 890 | } |
1804 | 650 | case 'y': { |
1805 | 650 | std::vector<StarWriterStruct::TOX51> toxList; |
1806 | 650 | done=StarWriterStruct::TOX51::readList(zone, toxList, *this); |
1807 | 650 | break; |
1808 | 890 | } |
1809 | 35.6k | default: |
1810 | 35.6k | break; |
1811 | 126k | } |
1812 | 126k | if (done) |
1813 | 87.8k | continue; |
1814 | | |
1815 | 39.1k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1816 | 39.1k | unsigned char type; |
1817 | 39.1k | if (!zone.openSWRecord(type)) { |
1818 | 9.47k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
1819 | 9.47k | break; |
1820 | 9.47k | } |
1821 | 29.6k | libstoff::DebugStream f; |
1822 | 29.6k | f << "SWWriterDocument[" << type << "]:"; |
1823 | 29.6k | long lastPos=zone.getRecordLastPosition(); |
1824 | 29.6k | bool endZone=false; |
1825 | 29.6k | std::vector<uint32_t> string; |
1826 | 29.6k | switch (type) { |
1827 | 1.11k | case '$': // unknown, seems to store an object name |
1828 | 1.11k | f << "dollarZone,"; |
1829 | 1.11k | if (input->tell()+7>lastPos) { |
1830 | 937 | STOFF_DEBUG_MSG(("StarObjectText::readWriterDocument: zone seems to short\n")); |
1831 | 937 | break; |
1832 | 937 | } |
1833 | 1.09k | for (int i=0; i<5; ++i) { // f0=f1=1 |
1834 | 910 | auto val=int(input->readULong(1)); |
1835 | 910 | if (val) f << "f" << i << "=" << val << ","; |
1836 | 910 | } |
1837 | 182 | if (!zone.readString(string)) { |
1838 | 44 | STOFF_DEBUG_MSG(("StarObjectText::readWriterDocument: can not read main string\n")); |
1839 | 44 | f << "###string"; |
1840 | 44 | break; |
1841 | 44 | } |
1842 | 138 | else if (!string.empty()) |
1843 | 123 | f << libstoff::getString(string).cstr(); |
1844 | 138 | break; |
1845 | 2.98k | case '5': { |
1846 | | // sw_sw3misc.cxx InLineNumberInfo |
1847 | 2.98k | int fl=zone.openFlagZone(); |
1848 | 2.98k | if (fl&0xf0) f << "fl=" << (fl>>4) << ","; |
1849 | 2.98k | f << "linenumberInfo=" << input->readULong(1) << ","; |
1850 | 2.98k | f << "nPos=" << input->readULong(1) << ","; |
1851 | 2.98k | f << "nChrIdx=" << input->readULong(2) << ","; |
1852 | 2.98k | f << "nPosFromLeft=" << input->readULong(2) << ","; |
1853 | 2.98k | f << "nCountBy=" << input->readULong(2) << ","; |
1854 | 2.98k | f << "nDividerCountBy=" << input->readULong(2) << ","; |
1855 | 2.98k | zone.closeFlagZone(); |
1856 | 2.98k | if (!zone.readString(string)) { |
1857 | 493 | STOFF_DEBUG_MSG(("StarObjectText::readWriterDocument: can not read sDivider string\n")); |
1858 | 493 | f << "###sDivider"; |
1859 | 493 | break; |
1860 | 493 | } |
1861 | 2.48k | else if (!string.empty()) |
1862 | 203 | f << libstoff::getString(string).cstr(); |
1863 | 2.48k | break; |
1864 | 2.98k | } |
1865 | 2.48k | case '6': |
1866 | | // sw_sw3misc.cxx InDocDummies |
1867 | 1.84k | f << "docDummies,"; |
1868 | 1.84k | f << "n1=" << input->readULong(4) << ","; |
1869 | 1.84k | f << "n2=" << input->readULong(4) << ","; |
1870 | 1.84k | f << "n3=" << input->readULong(1) << ","; |
1871 | 1.84k | f << "n4=" << input->readULong(1) << ","; |
1872 | 5.40k | for (int i=0; i<2; ++i) { |
1873 | 3.65k | if (!zone.readString(string)) { |
1874 | 88 | STOFF_DEBUG_MSG(("StarObjectText::readWriterDocument: can not read a string\n")); |
1875 | 88 | f << "###string"; |
1876 | 88 | break; |
1877 | 88 | } |
1878 | 3.56k | else if (!string.empty()) |
1879 | 213 | f << (i==0 ? "sAutoMarkURL" : "s2") << "=" << libstoff::getString(string).cstr() << ","; |
1880 | 3.65k | } |
1881 | 1.84k | break; |
1882 | 728 | case '7': { // config, ignored by LibreOffice, and find no code |
1883 | 728 | f << "config,"; |
1884 | 728 | auto fl=int(zone.openFlagZone()); |
1885 | 728 | if (fl&0xf0) f << "fl=" << (fl>>4) << ","; |
1886 | 728 | f << "f0=" << input->readULong(1) << ","; // 1 |
1887 | 4.36k | for (int i=0; i<5; ++i) // e,1,5,1,5 |
1888 | 3.64k | f << "f" << i+1 << "=" << input->readULong(2) << ","; |
1889 | 728 | zone.closeFlagZone(); |
1890 | 728 | break; |
1891 | 2.98k | } |
1892 | 5.00k | case 'C': { // ignored by LibreOffice |
1893 | 5.00k | std::string comment(""); |
1894 | 101k | while (lastPos && input->tell()<lastPos) comment+=char(input->readULong(1)); |
1895 | 5.00k | f << "comment=" << comment << ","; |
1896 | 5.00k | break; |
1897 | 2.98k | } |
1898 | 90 | case 'P': // password |
1899 | | // sw_sw3misc.cxx: InPasswd |
1900 | 90 | f << "passwd,"; |
1901 | 90 | if (zone.isCompatibleWith(0x6)) { |
1902 | 86 | f << "cType=" << input->readULong(1) << ","; |
1903 | 86 | if (!zone.readString(string)) { |
1904 | 24 | STOFF_DEBUG_MSG(("StarObjectText::readWriterDocument: can not read passwd string\n")); |
1905 | 24 | f << "###passwd"; |
1906 | 24 | } |
1907 | 62 | else |
1908 | 62 | f << "cryptedPasswd=" << libstoff::getString(string).cstr() << ","; |
1909 | 86 | } |
1910 | 90 | break; |
1911 | 1.13k | case 'Z': |
1912 | 1.13k | endZone=true; |
1913 | 1.13k | break; |
1914 | 16.7k | default: |
1915 | 16.7k | STOFF_DEBUG_MSG(("StarObjectText::readWriterDocument: find unexpected type\n")); |
1916 | 16.7k | f << "###type,"; |
1917 | 29.6k | } |
1918 | 29.6k | ascFile.addPos(pos); |
1919 | 29.6k | ascFile.addNote(f.str().c_str()); |
1920 | 29.6k | zone.closeSWRecord(type, "SWWriterDocument"); |
1921 | 29.6k | if (endZone) |
1922 | 1.13k | break; |
1923 | 29.6k | } |
1924 | 10.6k | if (!input->isEnd()) { |
1925 | 9.52k | STOFF_DEBUG_MSG(("StarObjectText::readWriterDocument: find extra data\n")); |
1926 | 9.52k | ascFile.addPos(input->tell()); |
1927 | 9.52k | ascFile.addNote("SWWriterDocument:##extra"); |
1928 | 9.52k | } |
1929 | 10.6k | return true; |
1930 | 10.6k | } |
1931 | 22.7k | catch (...) |
1932 | 22.7k | { |
1933 | 46 | return false; |
1934 | 46 | } |
1935 | | //////////////////////////////////////////////////////////// |
1936 | | // |
1937 | | // Low level |
1938 | | // |
1939 | | //////////////////////////////////////////////////////////// |
1940 | | |
1941 | | |
1942 | | // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: |