/src/libstaroffice/src/lib/StarObjectPageStyle.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 <set> |
39 | | #include <sstream> |
40 | | |
41 | | #include <librevenge/librevenge.h> |
42 | | |
43 | | #include "StarObjectPageStyle.hxx" |
44 | | |
45 | | #include "STOFFListener.hxx" |
46 | | #include "STOFFPageSpan.hxx" |
47 | | |
48 | | #include "StarAttribute.hxx" |
49 | | #include "StarFormatManager.hxx" |
50 | | #include "StarItemPool.hxx" |
51 | | #include "StarObject.hxx" |
52 | | #include "StarState.hxx" |
53 | | #include "StarWriterStruct.hxx" |
54 | | #include "StarZone.hxx" |
55 | | #include "SWFieldManager.hxx" |
56 | | |
57 | | /** Internal: the structures of a StarObjectPageStyle */ |
58 | | namespace StarObjectPageStyleInternal |
59 | | { |
60 | | /** \brief structure to store a endnote/footnote page description |
61 | | */ |
62 | | struct NoteDesc { |
63 | | public: |
64 | | //! constructor |
65 | | explicit NoteDesc(bool isFootnote) |
66 | 1.92k | : m_isFootnote(isFootnote) |
67 | 1.92k | , m_adjust(0) |
68 | 1.92k | , m_penWidth(0) |
69 | 1.92k | , m_color(STOFFColor::black()) |
70 | 1.92k | { |
71 | 7.71k | for (float &distance : m_distances) distance=0; |
72 | 1.92k | } |
73 | | //! operator<< |
74 | | friend std::ostream &operator<<(std::ostream &o, NoteDesc const &desc); |
75 | | //! try to read a noteDesc: '1' or '2' |
76 | | bool read(StarZone &zone); |
77 | | //! a flag to know if this corresponds to a footnote or a endnote |
78 | | bool m_isFootnote; |
79 | | //! the width/height/topDist/bottomDist |
80 | | float m_distances[4]; |
81 | | //! the adjust |
82 | | int m_adjust; |
83 | | //! the pen's width |
84 | | int m_penWidth; |
85 | | //! the color |
86 | | STOFFColor m_color; |
87 | | }; |
88 | | |
89 | | bool NoteDesc::read(StarZone &zone) |
90 | 1.92k | { |
91 | 1.92k | STOFFInputStreamPtr input=zone.input(); |
92 | 1.92k | libstoff::DebugFile &ascFile=zone.ascii(); |
93 | 1.92k | libstoff::DebugStream f; |
94 | 1.92k | long pos=input->tell(); |
95 | 1.92k | unsigned char type; |
96 | 1.92k | if (input->peek()!=(m_isFootnote ? '1' : '2') || !zone.openSWRecord(type)) { |
97 | 40 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
98 | 40 | STOFF_DEBUG_MSG(("StarObjectPageStyleInternal::NoteDesc::read: can not read a noteDesc\n")); |
99 | 40 | return false; |
100 | 40 | } |
101 | | // sw_sw3page.cxx InPageFtnInfo |
102 | 1.88k | f << "Entries(StarNoteDesc)[" << zone.getRecordLevel() << "]:"; |
103 | 7.55k | for (int i=1; i<4; ++i) m_distances[i]=float(input->readLong(4)); |
104 | 1.88k | m_adjust=int(input->readLong(2)); |
105 | 1.88k | long dim[2]; |
106 | 3.77k | for (long &i : dim) i=long(input->readLong(4)); |
107 | 1.88k | if (!dim[1]) { |
108 | 7 | STOFF_DEBUG_MSG(("StarObjectPageStyleInternal::NoteDesc::read: can not find the width deminator\n")); |
109 | 7 | } |
110 | 1.88k | else |
111 | 1.88k | m_distances[0]=float(dim[0])/float(dim[1]); |
112 | 1.88k | m_penWidth=int(input->readLong(2)); |
113 | 1.88k | if (!input->readColor(m_color)) { |
114 | 44 | STOFF_DEBUG_MSG(("StarObjectPageStyleInternal::NoteDesc::read: can not read a color\n")); |
115 | 44 | f << "###color,"; |
116 | 44 | } |
117 | 1.88k | f << *this; |
118 | 1.88k | ascFile.addPos(pos); |
119 | 1.88k | ascFile.addNote(f.str().c_str()); |
120 | 1.88k | zone.closeSWRecord(type, "StarNoteDesc"); |
121 | 1.88k | return true; |
122 | 1.92k | } |
123 | | |
124 | | std::ostream &operator<<(std::ostream &o, NoteDesc const &desc) |
125 | 0 | { |
126 | 0 | if (desc.m_isFootnote) |
127 | 0 | o << "footnote,"; |
128 | 0 | else |
129 | 0 | o << "endnote,"; |
130 | 0 | for (int i=0; i<4; ++i) { |
131 | 0 | if (desc.m_distances[i]>=0 && desc.m_distances[i]<=0) continue; |
132 | 0 | char const *wh[]= {"width", "height", "top[dist]", "bottom[dist]"}; |
133 | 0 | o << wh[i] << "=" << desc.m_distances[i] << ","; |
134 | 0 | } |
135 | 0 | if (desc.m_adjust) o << "adjust=" << desc.m_adjust << ","; |
136 | 0 | if (desc.m_penWidth) o << "penWidth=" << desc.m_penWidth << ","; |
137 | 0 | if (!desc.m_color.isBlack()) o << "color=" << desc.m_color << ","; |
138 | 0 | return o; |
139 | 0 | } |
140 | | |
141 | | /** \brief structure to store a page description |
142 | | */ |
143 | | struct PageDesc { |
144 | | public: |
145 | | //! constructor |
146 | | explicit PageDesc() |
147 | 2.20k | : m_name("") |
148 | 2.20k | , m_follow("") |
149 | 2.20k | , m_landscape(false) |
150 | 2.20k | , m_poolId(0) |
151 | 2.20k | , m_numType(0) |
152 | 2.20k | , m_usedOn(3) |
153 | 2.20k | , m_regCollIdx(0xFFFF) |
154 | 2.20k | { |
155 | 2.20k | } |
156 | | //! destructor |
157 | | ~PageDesc() |
158 | 4.70k | { |
159 | 4.70k | } |
160 | | //! update pagespan properties |
161 | | void updatePageSpan(StarState &state) const; |
162 | | /** try to update the section*/ |
163 | | bool updateState(StarState &state) const; |
164 | | //! operator<< |
165 | | friend std::ostream &operator<<(std::ostream &o, PageDesc const &desc); |
166 | | //! try to read a pageDesc: 'p' |
167 | | bool read(StarZone &zone, StarObject &object); |
168 | | //! the name |
169 | | librevenge::RVNGString m_name; |
170 | | //! the follow |
171 | | librevenge::RVNGString m_follow; |
172 | | //! is the page a lanscape |
173 | | bool m_landscape; |
174 | | //! the poolId |
175 | | int m_poolId; |
176 | | //! the number's type |
177 | | int m_numType; |
178 | | //! the page where is it used ? |
179 | | int m_usedOn; |
180 | | //! the coll idx |
181 | | int m_regCollIdx; |
182 | | //! the foot and page foot desc |
183 | | std::shared_ptr<NoteDesc> m_noteDesc[2]; |
184 | | //! the master and left attributes lists |
185 | | std::vector<StarWriterStruct::Attribute> m_attributes[2]; |
186 | | }; |
187 | | |
188 | | void PageDesc::updatePageSpan(StarState &state) const |
189 | 1.68k | { |
190 | 1.68k | updateState(state); |
191 | 1.68k | auto &page=state.m_global->m_page; |
192 | 1.68k | if (m_landscape && page.m_propertiesList[0]["fo:page-height"] && page.m_propertiesList[0]["fo:page-width"] && |
193 | 78 | page.m_propertiesList[0]["fo:page-height"]->getInt() > page.m_propertiesList[0]["fo:page-width"]->getInt()) { |
194 | | // we must inverse fo:page-height and fo:page-width |
195 | 46 | auto height=page.m_propertiesList[0]["fo:page-height"]->getStr(); |
196 | 46 | page.m_propertiesList[0].insert("fo:page-height", page.m_propertiesList[0]["fo:page-width"]); |
197 | 46 | page.m_propertiesList[0].insert("fo:page-width", height); |
198 | 46 | page.m_propertiesList[0].insert("style:print-orientation", "landscape"); |
199 | 46 | } |
200 | 1.68k | } |
201 | | |
202 | | bool PageDesc::updateState(StarState &state) const |
203 | 1.68k | { |
204 | 3.36k | for (const auto &attribute : m_attributes) { |
205 | 7.88k | for (auto &attr : attribute) { |
206 | 7.88k | if (attr.m_attribute) |
207 | 7.76k | attr.m_attribute->addTo(state); |
208 | 7.88k | } |
209 | 3.36k | } |
210 | 1.68k | return true; |
211 | 1.68k | } |
212 | | |
213 | | bool PageDesc::read(StarZone &zone, StarObject &object) |
214 | 2.20k | { |
215 | 2.20k | STOFFInputStreamPtr input=zone.input(); |
216 | 2.20k | libstoff::DebugFile &ascFile=zone.ascii(); |
217 | 2.20k | libstoff::DebugStream f; |
218 | 2.20k | long pos=input->tell(); |
219 | 2.20k | unsigned char type; |
220 | 2.20k | if (input->peek()!='p' || !zone.openSWRecord(type)) { |
221 | 176 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
222 | 176 | STOFF_DEBUG_MSG(("StarObjectPageStyleInternal::PageDesc::read: can not read a pageDesc\n")); |
223 | 176 | return false; |
224 | 176 | } |
225 | | // sw_sw3page.cxx InPageDesc |
226 | 2.03k | f << "Entries(StarPageDesc)[" << type << "-" << zone.getRecordLevel() << "]:"; |
227 | 2.03k | int fl=zone.openFlagZone(); |
228 | 2.03k | if (fl&0x10) m_landscape=true; |
229 | 2.03k | if (fl&0xf0) f << "fl=" << (fl>>4) << ","; |
230 | 2.03k | auto val=int(input->readULong(2)); |
231 | 2.03k | if (!zone.getPoolName(val, m_name)) { |
232 | 352 | STOFF_DEBUG_MSG(("StarObjectPageStyleInternal::PageDesc::read: can not find a pool name\n")); |
233 | 352 | f << "###nameId=" << val << ","; |
234 | 352 | } |
235 | 2.03k | val=int(input->readULong(2)); |
236 | 2.03k | if (!zone.getPoolName(val, m_follow)) { |
237 | 355 | STOFF_DEBUG_MSG(("StarObjectPageStyleInternal::PageDesc::read: can not find a pool name\n")); |
238 | 355 | f << "###followId=" << val << ","; |
239 | 355 | } |
240 | 2.03k | m_poolId=int(input->readULong(2)); |
241 | 2.03k | m_numType=int(input->readULong(1)); |
242 | 2.03k | m_usedOn=int(input->readULong(2)); |
243 | 2.03k | if (zone.isCompatibleWith(0x16,0x22, 0x101)) |
244 | 1.63k | m_regCollIdx=int(input->readULong(2)); |
245 | 2.03k | zone.closeFlagZone(); |
246 | 2.03k | f << *this; |
247 | 2.03k | ascFile.addPos(pos); |
248 | 2.03k | ascFile.addNote(f.str().c_str()); |
249 | | |
250 | 2.03k | long lastPos=zone.getRecordLastPosition(); |
251 | 2.03k | int whichAttrib=0; |
252 | 7.04k | while (input->tell() < lastPos) { |
253 | 5.75k | pos=input->tell(); |
254 | 5.75k | int rType=input->peek(); |
255 | 5.75k | bool done=false; |
256 | 5.75k | switch (rType) { |
257 | 3.16k | case 'S': { |
258 | 3.16k | std::vector<StarWriterStruct::Attribute> attributeList; |
259 | 3.16k | done=StarWriterStruct::Attribute::readList(zone, attributeList, object); |
260 | 3.16k | if (!done) break; |
261 | 2.75k | if (whichAttrib<2) // first master, second left |
262 | 2.74k | m_attributes[whichAttrib++]=attributeList; |
263 | 4 | else { |
264 | 4 | STOFF_DEBUG_MSG(("StarObjectPageStyleInternal::PageDesc::read: unexpected attribute list\n")); |
265 | 4 | } |
266 | 2.75k | break; |
267 | 3.16k | } |
268 | 98 | case '1': // foot info |
269 | 1.92k | case '2': { // page foot info |
270 | 1.92k | std::shared_ptr<NoteDesc> desc(new NoteDesc(rType=='1')); |
271 | 1.92k | done=desc->read(zone); |
272 | 1.92k | if (done) |
273 | 1.88k | m_noteDesc[rType=='1' ? 0 : 1]=desc; |
274 | 1.92k | break; |
275 | 98 | } |
276 | 665 | default: |
277 | 665 | break; |
278 | 5.75k | } |
279 | 5.75k | if (done) continue; |
280 | 1.11k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
281 | 1.11k | f.str(""); |
282 | 1.11k | if (!zone.openSWRecord(type)) { |
283 | 745 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
284 | 745 | break; |
285 | 745 | } |
286 | 370 | f << "StarPageDesc[" << type << "-" << zone.getRecordLevel() << "]:"; |
287 | 370 | STOFF_DEBUG_MSG(("StarObjectPageStyleInternal::PageDesc::read: find unknown type\n")); |
288 | 370 | f << "###type,"; |
289 | 370 | ascFile.addPos(pos); |
290 | 370 | ascFile.addNote(f.str().c_str()); |
291 | 370 | zone.closeSWRecord(type, "StarPageDesc"); |
292 | 370 | } |
293 | 2.03k | zone.closeSWRecord('p', "StarPageDesc"); |
294 | 2.03k | return true; |
295 | 2.03k | } |
296 | | |
297 | | std::ostream &operator<<(std::ostream &o, PageDesc const &desc) |
298 | 0 | { |
299 | 0 | o << desc.m_name.cstr() << ","; |
300 | 0 | if (!desc.m_follow.empty()) o << "follow=" << desc.m_follow.cstr() << ","; |
301 | 0 | if (desc.m_landscape) o << "landscape,"; |
302 | 0 | if (desc.m_poolId) o << "poolId=" << desc.m_poolId << ","; |
303 | 0 | if (desc.m_numType) o << "numType=" << desc.m_numType << ","; |
304 | 0 | switch (desc.m_usedOn&3) { |
305 | 0 | case 1: |
306 | 0 | o << "left,"; |
307 | 0 | break; |
308 | 0 | case 2: |
309 | 0 | o << "right,"; |
310 | 0 | break; |
311 | 0 | case 3: |
312 | 0 | o << "all,"; |
313 | 0 | break; |
314 | 0 | case 0: // internal |
315 | 0 | default: |
316 | 0 | break; |
317 | 0 | } |
318 | 0 | if (desc.m_usedOn&0x40) o << "header[share],"; |
319 | 0 | if (desc.m_usedOn&0x80) o << "footer[share],"; |
320 | 0 | if (desc.m_usedOn&0x100) o << "first[share],"; |
321 | 0 | if (desc.m_usedOn&0xFE3C) o << "usedOn=" << std::hex << (desc.m_usedOn&0xFE3C) << std::dec << ","; |
322 | 0 | if (desc.m_regCollIdx!=0xFFFF) o << "regCollIdx=" << desc.m_regCollIdx << ","; |
323 | 0 | return o; |
324 | 0 | } |
325 | | |
326 | | //////////////////////////////////////// |
327 | | //! Internal: the state of a StarObjectPageStyle |
328 | | struct State { |
329 | | //! constructor |
330 | | State() |
331 | 4.76k | : m_pageList() |
332 | 4.76k | , m_nameToPageIdMap() |
333 | 4.76k | , m_simplifyNameToPageIdMap() |
334 | 4.76k | { |
335 | 4.76k | } |
336 | | //! list of pages |
337 | | std::vector<PageDesc> m_pageList; |
338 | | //! map name to id |
339 | | std::map<librevenge::RVNGString, size_t> m_nameToPageIdMap; |
340 | | //! map simplify name to id |
341 | | std::map<librevenge::RVNGString, size_t> m_simplifyNameToPageIdMap; |
342 | | }; |
343 | | |
344 | | } |
345 | | |
346 | | //////////////////////////////////////////////////////////// |
347 | | // constructor/destructor, ... |
348 | | //////////////////////////////////////////////////////////// |
349 | | StarObjectPageStyle::StarObjectPageStyle(StarObject const &orig, bool duplicateState) |
350 | 4.76k | : StarObject(orig, duplicateState) |
351 | 4.76k | , m_pageStyleState(new StarObjectPageStyleInternal::State) |
352 | 4.76k | { |
353 | 4.76k | } |
354 | | |
355 | | StarObjectPageStyle::~StarObjectPageStyle() |
356 | 4.76k | { |
357 | 4.76k | } |
358 | | |
359 | | //////////////////////////////////////////////////////////// |
360 | | // send data |
361 | | //////////////////////////////////////////////////////////// |
362 | | bool StarObjectPageStyle::updatePageSpan(librevenge::RVNGString const &name, StarState &state) |
363 | 2.19k | { |
364 | 2.19k | auto &ps=state.m_global->m_page; |
365 | 2.19k | ps=STOFFPageSpan(); |
366 | 2.19k | size_t id=0; |
367 | 2.19k | if (m_pageStyleState->m_nameToPageIdMap.find(name) != m_pageStyleState->m_nameToPageIdMap.end()) |
368 | 228 | id=m_pageStyleState->m_nameToPageIdMap.find(name)->second; |
369 | 1.96k | else { |
370 | 1.96k | auto simpName=libstoff::simplifyString(name); |
371 | 1.96k | if (m_pageStyleState->m_simplifyNameToPageIdMap.find(simpName)!=m_pageStyleState->m_simplifyNameToPageIdMap.end()) |
372 | 14 | id=m_pageStyleState->m_simplifyNameToPageIdMap.find(simpName)->second; |
373 | 1.95k | else if (!name.empty()) { |
374 | 159 | STOFF_DEBUG_MSG(("StarObjectPageStyle::updatePageSpan: can not find page %s\n", name.cstr())); |
375 | 159 | } |
376 | 1.96k | } |
377 | 2.19k | if (id>=m_pageStyleState->m_pageList.size()) |
378 | 614 | return false; |
379 | 1.58k | size_t listIds[3]; |
380 | 1.58k | std::string listOccurence[3]; |
381 | 1.58k | std::set<librevenge::RVNGString> seen; |
382 | 1.58k | int numPages=0; |
383 | 1.70k | for (int i=0; i<3; ++i) { |
384 | 1.68k | auto const &page=m_pageStyleState->m_pageList[id]; |
385 | 1.68k | listIds[i]=id; |
386 | 1.68k | numPages=i+1; |
387 | 1.68k | if ((page.m_usedOn&3)==3) { |
388 | 1.41k | if (i==1) listOccurence[0]="first"; |
389 | 1.41k | listOccurence[i]="all"; |
390 | 1.41k | break; |
391 | 1.41k | } |
392 | 267 | listOccurence[i]=(page.m_usedOn&1) ? "left" : "right"; |
393 | 267 | seen.insert(page.m_name); |
394 | 267 | auto const &follow=page.m_follow; |
395 | 267 | if (follow.empty() || seen.find(follow)!=seen.end()) |
396 | 112 | break; |
397 | 155 | if (m_pageStyleState->m_nameToPageIdMap.find(follow) != m_pageStyleState->m_nameToPageIdMap.end()) |
398 | 37 | id=m_pageStyleState->m_nameToPageIdMap.find(follow)->second; |
399 | 118 | else { |
400 | 118 | auto simpName=libstoff::simplifyString(follow); |
401 | 118 | if (m_pageStyleState->m_simplifyNameToPageIdMap.find(simpName)!=m_pageStyleState->m_simplifyNameToPageIdMap.end()) |
402 | 91 | id=m_pageStyleState->m_simplifyNameToPageIdMap.find(simpName)->second; |
403 | 27 | else { |
404 | 27 | STOFF_DEBUG_MSG(("StarObjectPageStyle::updatePageSpan: can not find page %s\n", follow.cstr())); |
405 | 27 | break; |
406 | 27 | } |
407 | 118 | } |
408 | 128 | if (id>=m_pageStyleState->m_pageList.size()) |
409 | 0 | break; |
410 | 128 | } |
411 | 1.58k | if (numPages==3) listOccurence[0]="first"; |
412 | 3.26k | for (int p=numPages-1; p>=0; --p) { // invert so that section correspond to the first page |
413 | 1.68k | ps.m_section=STOFFSection(); |
414 | 1.68k | state.m_global->m_pageOccurence=listOccurence[p]; |
415 | 1.68k | m_pageStyleState->m_pageList[listIds[p]].updatePageSpan(state); |
416 | 1.68k | } |
417 | 1.58k | return true; |
418 | 2.19k | } |
419 | | |
420 | | bool StarObjectPageStyle::updatePageSpans |
421 | | (std::vector<librevenge::RVNGString> const &listNames, std::vector<STOFFPageSpan> &pageSpan, int &number) |
422 | 2.12k | { |
423 | 2.12k | librevenge::RVNGString lastPageName(""); |
424 | 2.12k | int numPage=0; |
425 | 2.12k | number=0; |
426 | 2.12k | auto pool=findItemPool(StarItemPool::T_WriterPool, false); |
427 | 2.12k | StarState state(pool.get(), *this); |
428 | 2.12k | auto &ps=state.m_global->m_page; |
429 | 3.78k | for (size_t i=0; i<=listNames.size(); ++i) { |
430 | 3.78k | bool newPage=(i==listNames.size()) || (lastPageName!="" && listNames[i]!="" && lastPageName!=listNames[i]); |
431 | 3.78k | if (!newPage) { |
432 | 1.59k | if (lastPageName.empty()) lastPageName=listNames[i]; |
433 | 1.59k | ++numPage; |
434 | 1.59k | continue; |
435 | 1.59k | } |
436 | 2.19k | if (i==listNames.size()) |
437 | 2.12k | numPage=10000; // be sure to allow enough page |
438 | 2.19k | if (numPage) { |
439 | 2.19k | updatePageSpan(lastPageName, state); |
440 | 2.19k | ps.m_pageSpan=numPage; |
441 | 2.19k | pageSpan.push_back(ps); |
442 | 2.19k | number+=numPage; |
443 | 2.19k | } |
444 | 2.19k | if (i==listNames.size()) break; |
445 | 74 | numPage=1; |
446 | 74 | lastPageName=listNames[i]; |
447 | 74 | } |
448 | 2.12k | return number!=0; |
449 | 2.12k | } |
450 | | |
451 | | //////////////////////////////////////////////////////////// |
452 | | // the parser |
453 | | //////////////////////////////////////////////////////////// |
454 | | bool StarObjectPageStyle::read(StarZone &zone) |
455 | 4.76k | try |
456 | 4.76k | { |
457 | 4.76k | STOFFInputStreamPtr input=zone.input(); |
458 | 4.76k | if (!zone.readSWHeader()) { |
459 | 2.52k | STOFF_DEBUG_MSG(("StarObjectPageStyle::read: can not read the header\n")); |
460 | 2.52k | return false; |
461 | 2.52k | } |
462 | 2.23k | zone.readStringsPool(); |
463 | 2.23k | SWFieldManager fieldManager; |
464 | 8.96k | while (fieldManager.readField(zone,'Y')) |
465 | 6.73k | ; |
466 | 2.23k | std::vector<StarWriterStruct::Bookmark> markList; |
467 | 2.23k | StarWriterStruct::Bookmark::readList(zone, markList); |
468 | 2.23k | std::vector<std::vector<StarWriterStruct::Redline> > redlineListList; |
469 | 2.23k | StarWriterStruct::Redline::readListList(zone, redlineListList); |
470 | 2.23k | getFormatManager()->readSWNumberFormatterList(zone); |
471 | | // sw_sw3page.cxx Sw3IoImp::InPageDesc |
472 | 2.23k | libstoff::DebugFile &ascFile=zone.ascii(); |
473 | 4.73k | while (!input->isEnd()) { |
474 | 4.68k | long pos=input->tell(); |
475 | 4.68k | unsigned char type; |
476 | 4.68k | if (!zone.openSWRecord(type)) { |
477 | 868 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
478 | 868 | break; |
479 | 868 | } |
480 | 3.82k | libstoff::DebugStream f; |
481 | 3.82k | f << "StarPageStyleSheets[" << type << "]:"; |
482 | 3.82k | bool done=false; |
483 | 3.82k | switch (type) { |
484 | 1.72k | case 'P': { |
485 | 1.72k | zone.openFlagZone(); |
486 | 1.72k | auto N=int(input->readULong(2)); |
487 | 1.72k | f << "N=" << N << ","; |
488 | 1.72k | zone.closeFlagZone(); |
489 | 3.75k | for (int i=0; i<N; ++i) { |
490 | 2.20k | StarObjectPageStyleInternal::PageDesc desc; |
491 | | // read will check that we can read the data, .... |
492 | 2.20k | if (!desc.read(zone, *this)) |
493 | 176 | break; |
494 | 2.03k | if (m_pageStyleState->m_nameToPageIdMap.find(desc.m_name)!=m_pageStyleState->m_nameToPageIdMap.end()) { |
495 | 94 | STOFF_DEBUG_MSG(("StarObjectPageStyle::read: oops page with name=%s already exists\n", desc.m_name.cstr())); |
496 | 94 | } |
497 | 1.93k | else { |
498 | 1.93k | m_pageStyleState->m_nameToPageIdMap[desc.m_name]=m_pageStyleState->m_pageList.size(); |
499 | 1.93k | auto simpName=libstoff::simplifyString(desc.m_name); |
500 | 1.93k | if (m_pageStyleState->m_simplifyNameToPageIdMap.find(simpName)==m_pageStyleState->m_simplifyNameToPageIdMap.end()) |
501 | 1.92k | m_pageStyleState->m_simplifyNameToPageIdMap[simpName]=m_pageStyleState->m_pageList.size(); |
502 | 1.93k | } |
503 | 2.03k | m_pageStyleState->m_pageList.push_back(desc); |
504 | 2.03k | } |
505 | 1.72k | break; |
506 | 0 | } |
507 | 1.31k | case 'Z': |
508 | 1.31k | done=true; |
509 | 1.31k | break; |
510 | 777 | default: |
511 | 777 | STOFF_DEBUG_MSG(("StarObjectPageStyle::read: find unknown data\n")); |
512 | 777 | f << "###"; |
513 | 777 | break; |
514 | 3.82k | } |
515 | 3.82k | if (!zone.closeSWRecord(type, "StarPageStyleSheets")) { |
516 | 0 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
517 | 0 | break; |
518 | 0 | } |
519 | 3.82k | ascFile.addPos(pos); |
520 | 3.82k | ascFile.addNote(f.str().c_str()); |
521 | | |
522 | 3.82k | if (done) |
523 | 1.31k | break; |
524 | 3.82k | } |
525 | | |
526 | 2.23k | if (!input->isEnd()) { |
527 | 874 | STOFF_DEBUG_MSG(("StarObjectPageStyle::read: find extra data\n")); |
528 | 874 | ascFile.addPos(input->tell()); |
529 | 874 | ascFile.addNote("StarPageStyleSheets:##extra"); |
530 | 874 | } |
531 | | |
532 | 2.23k | return true; |
533 | 2.23k | } |
534 | 4.76k | catch (...) |
535 | 4.76k | { |
536 | 14 | return false; |
537 | 14 | } |
538 | | |
539 | | // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: |