/src/libmwaw/src/lib/ClarisWksStruct.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */ |
2 | | |
3 | | /* libmwaw |
4 | | * Version: MPL 2.0 / LGPLv2+ |
5 | | * |
6 | | * The contents of this file are subject to the Mozilla Public License Version |
7 | | * 2.0 (the "License"); you may not use this file except in compliance with |
8 | | * the License or as specified alternatively below. You may obtain a copy of |
9 | | * the License at http://www.mozilla.org/MPL/ |
10 | | * |
11 | | * Software distributed under the License is distributed on an "AS IS" basis, |
12 | | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
13 | | * for the specific language governing rights and limitations under the |
14 | | * License. |
15 | | * |
16 | | * Major Contributor(s): |
17 | | * Copyright (C) 2002 William Lachance (wrlach@gmail.com) |
18 | | * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net) |
19 | | * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch) |
20 | | * Copyright (C) 2006, 2007 Andrew Ziem |
21 | | * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr) |
22 | | * |
23 | | * |
24 | | * All Rights Reserved. |
25 | | * |
26 | | * For minor contributions see the git repository. |
27 | | * |
28 | | * Alternatively, the contents of this file may be used under the terms of |
29 | | * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"), |
30 | | * in which case the provisions of the LGPLv2+ are applicable |
31 | | * instead of those above. |
32 | | */ |
33 | | |
34 | | #include <string.h> |
35 | | |
36 | | #include <algorithm> |
37 | | #include <iomanip> |
38 | | #include <iostream> |
39 | | #include <sstream> |
40 | | |
41 | | #include <librevenge/librevenge.h> |
42 | | |
43 | | #include "MWAWDebug.hxx" |
44 | | #include "MWAWInputStream.hxx" |
45 | | #include "MWAWParser.hxx" |
46 | | |
47 | | #include "ClarisWksStruct.hxx" |
48 | | |
49 | | namespace ClarisWksStruct |
50 | | { |
51 | | |
52 | | static const int MAX_PAGES = 1 << 16; |
53 | | |
54 | | std::ostream &operator<<(std::ostream &o, Struct const &z) |
55 | 0 | { |
56 | 0 | o << "sz=" << z.m_size << ","; |
57 | 0 | if (z.m_numData>0) { |
58 | 0 | o << "N=" << z.m_numData << ","; |
59 | 0 | o << "data[sz]=" << z.m_dataSize << ","; |
60 | 0 | } |
61 | 0 | if (z.m_headerSize>0) |
62 | 0 | o << "header[sz]=" << z.m_headerSize << ","; |
63 | 0 | if (z.m_type>0) |
64 | 0 | o << "type=" << z.m_type << ","; |
65 | 0 | for (int i=0; i<2; ++i) { |
66 | 0 | if (z.m_values[i]) |
67 | 0 | o << "f" << i << "=" << z.m_values[i] << ","; |
68 | 0 | } |
69 | 0 | return o; |
70 | 0 | } |
71 | | |
72 | | bool Struct::readHeader(MWAWInputStreamPtr input, bool strict) |
73 | 8.92M | { |
74 | 8.92M | *this=Struct(); |
75 | 8.92M | long pos=input->tell(); |
76 | 8.92M | if (!input->checkPosition(pos+4)) |
77 | 1.52M | return false; |
78 | 7.39M | m_size=input->readLong(4); |
79 | 7.39M | if (m_size==0) |
80 | 2.62M | return true; |
81 | 4.76M | if (m_size<12 || !input->checkPosition(pos+4+m_size)) |
82 | 1.72M | return false; |
83 | | |
84 | 3.03M | m_numData =int(input->readULong(2)); |
85 | 3.03M | m_type = int(input->readLong(2)); |
86 | 3.03M | m_values[0] = int(input->readLong(2)); |
87 | 3.03M | m_dataSize = long(input->readULong(2)); |
88 | 3.03M | m_headerSize = long(input->readULong(2)); |
89 | 3.03M | m_values[1] = int(input->readLong(2)); |
90 | 3.03M | if (m_numData && m_dataSize>10000) return false; // too big to be honetx |
91 | 2.97M | long expectedLength = 12+m_headerSize; |
92 | 2.97M | if (m_numData>0) expectedLength+=long(m_numData)*m_dataSize; |
93 | 2.97M | if (expectedLength>m_size || (strict && expectedLength != m_size)) |
94 | 238k | return false; |
95 | 2.73M | return true; |
96 | 2.97M | } |
97 | | |
98 | | // try to read a list of structured zone |
99 | | bool readIntZone(MWAWParserState &parserState, char const *zoneName, bool hasEntete, int intSz, std::vector<int> &res) |
100 | 2.38M | { |
101 | 2.38M | res.resize(0); |
102 | 2.38M | if (intSz != 1 && intSz != 2 && intSz != 4) { |
103 | 0 | MWAW_DEBUG_MSG(("ClarisWksStruct::readIntZone: unknown int size: %d\n", intSz)); |
104 | 0 | return false; |
105 | 0 | } |
106 | | |
107 | 2.38M | MWAWInputStreamPtr input = parserState.m_input; |
108 | 2.38M | long pos = input->tell(); |
109 | 2.38M | Struct zone; |
110 | 2.38M | if (!zone.readHeader(input,true)) { |
111 | 1.72M | MWAW_DEBUG_MSG(("ClarisWksStruct::readIntZone: can not header of %s\n", zoneName ? zoneName : "unamed")); |
112 | 1.72M | } |
113 | 2.38M | libmwaw::DebugStream f; |
114 | 2.38M | libmwaw::DebugFile &ascFile=parserState.m_asciiFile; |
115 | 2.38M | if (zoneName && strlen(zoneName)) |
116 | 2.38M | f << "Entries(" << zoneName << "):"; |
117 | 2.38M | long endPos = pos+4+zone.m_size; |
118 | | |
119 | 2.38M | if (zone.m_size==0) { |
120 | 2.04M | if (hasEntete) { |
121 | 0 | ascFile.addPos(pos-4); |
122 | 0 | ascFile.addNote(f.str().c_str()); |
123 | 0 | } |
124 | 2.04M | else { |
125 | 2.04M | ascFile.addPos(pos); |
126 | 2.04M | ascFile.addNote("NOP"); |
127 | 2.04M | } |
128 | 2.04M | return true; |
129 | 2.04M | } |
130 | | |
131 | 347k | if (zone.m_dataSize != intSz) { |
132 | 140k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
133 | 140k | MWAW_DEBUG_MSG(("ClarisWksStruct::readIntZone: unexpected field size\n")); |
134 | 140k | return false; |
135 | 140k | } |
136 | | |
137 | 206k | f << zone; |
138 | 206k | if (zone.m_headerSize) { |
139 | 24.4k | ascFile.addDelimiter(input->tell(), '|'); |
140 | 24.4k | input->seek(zone.m_headerSize, librevenge::RVNG_SEEK_CUR); |
141 | 24.4k | } |
142 | 206k | if (zone.m_numData) ascFile.addDelimiter(input->tell(), '|'); |
143 | 206k | f << "["; |
144 | 2.14G | for (long i = 0; i < zone.m_numData; i++) { |
145 | 2.14G | auto val = int(input->readLong(intSz)); |
146 | 2.14G | res.push_back(val); |
147 | 2.14G | if (val>1000) f << "0x" << std::hex << val << std::dec << ","; |
148 | 2.02G | else f << val << ","; |
149 | 2.14G | } |
150 | 206k | f << "]"; |
151 | | |
152 | 206k | ascFile.addPos(hasEntete ? pos-4 : pos); |
153 | 206k | ascFile.addNote(f.str().c_str()); |
154 | | |
155 | 206k | input->seek(endPos,librevenge::RVNG_SEEK_SET); |
156 | 206k | return true; |
157 | 347k | } |
158 | | |
159 | | /////////////////////////////////////////////////////////// |
160 | | // try to read a unknown structured zone |
161 | | //////////////////////////////////////////////////////////// |
162 | | bool readStructZone(MWAWParserState &parserState, char const *zoneName, bool hasEntete) |
163 | 1.44M | { |
164 | 1.44M | MWAWInputStreamPtr input = parserState.m_input; |
165 | 1.44M | long pos = input->tell(); |
166 | 1.44M | Struct zone; |
167 | 1.44M | if (!zone.readHeader(input,false) || (zone.m_size && zone.m_dataSize<=0)) { |
168 | 319k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
169 | 319k | MWAW_DEBUG_MSG(("ClarisWksStruct::readStructZone: can not read header for %s\n", zoneName)); |
170 | 319k | return false; |
171 | 319k | } |
172 | 1.12M | libmwaw::DebugFile &ascFile= parserState.m_asciiFile; |
173 | 1.12M | libmwaw::DebugStream f; |
174 | 1.12M | f << "Entries(" << zoneName << "):"; |
175 | | |
176 | 1.12M | if (zone.m_size == 0) { |
177 | 785k | if (hasEntete) { |
178 | 0 | ascFile.addPos(pos-4); |
179 | 0 | ascFile.addNote(f.str().c_str()); |
180 | 0 | } |
181 | 785k | else { |
182 | 785k | ascFile.addPos(pos); |
183 | 785k | ascFile.addNote("NOP"); |
184 | 785k | } |
185 | 785k | return true; |
186 | 785k | } |
187 | 344k | long endPos=pos+4+zone.m_size; |
188 | 344k | f << zone; |
189 | 344k | if (zone.m_headerSize) { |
190 | 23.9k | ascFile.addDelimiter(input->tell(), '|'); |
191 | 23.9k | input->seek(zone.m_headerSize, librevenge::RVNG_SEEK_CUR); |
192 | 23.9k | } |
193 | 344k | ascFile.addPos(hasEntete ? pos-4 : pos); |
194 | 344k | ascFile.addNote(f.str().c_str()); |
195 | | |
196 | 344k | pos=input->tell(); |
197 | 458k | for (long i = 0; i < zone.m_numData; i++) { |
198 | 114k | f.str(""); |
199 | 114k | f << zoneName << "-" << i << ":"; |
200 | | |
201 | 114k | ascFile.addPos(pos); |
202 | 114k | ascFile.addNote(f.str().c_str()); |
203 | 114k | pos += zone.m_dataSize; |
204 | 114k | } |
205 | 344k | if (pos!=endPos) { |
206 | 14.7k | MWAW_DEBUG_MSG(("ClarisWksStruct::readStructZone: find extra data for %s\n", zoneName)); |
207 | 14.7k | f.str(""); |
208 | 14.7k | f << zoneName << ":###extra"; |
209 | 14.7k | ascFile.addPos(pos); |
210 | 14.7k | ascFile.addNote(f.str().c_str()); |
211 | 14.7k | } |
212 | 344k | input->seek(endPos,librevenge::RVNG_SEEK_SET); |
213 | 344k | return true; |
214 | 1.12M | } |
215 | | |
216 | | //------------------------------------------------------------ |
217 | | // DSET |
218 | | //------------------------------------------------------------ |
219 | | MWAWBox2i DSET::getUnionChildBox() const |
220 | 50.7k | { |
221 | 50.7k | MWAWBox2f res; |
222 | 50.7k | long maxX=1000; |
223 | 5.07M | for (auto const &child : m_childs) { |
224 | | // highly spurious, better to ignore |
225 | 5.07M | if (long(child.m_box[1][0])>3*maxX) |
226 | 443k | continue; |
227 | 4.62M | if (long(child.m_box[1][0])>maxX) |
228 | 28.6k | maxX=long(child.m_box[1][0]); |
229 | 4.62M | res=child.m_box.getUnion(res); |
230 | 4.62M | } |
231 | 50.7k | return MWAWBox2i(res); |
232 | 50.7k | } |
233 | | |
234 | | void DSET::removeChild(int cId) |
235 | 14.1k | { |
236 | 14.1k | removeChild(cId, std::find(m_otherChilds.begin(), m_otherChilds.end(), cId)==m_otherChilds.end()); |
237 | 14.1k | } |
238 | | |
239 | | void DSET::removeChild(int cId, bool normalChild) |
240 | 3.77M | { |
241 | 3.77M | if (normalChild) { |
242 | 943M | for (auto it=m_childs.begin(); it!=m_childs.end(); ++it) { |
243 | 943M | if (it->m_type != C_Zone || it->m_id != cId) continue; |
244 | 864k | m_childs.erase(it); |
245 | 864k | return; |
246 | 943M | } |
247 | 864k | } |
248 | 2.90M | else { |
249 | 197M | for (auto it=m_otherChilds.begin(); it!=m_otherChilds.end(); ++it) { |
250 | 197M | if (*it != cId) continue; |
251 | 2.90M | m_otherChilds.erase(it); |
252 | 2.90M | return; |
253 | 197M | } |
254 | 2.90M | } |
255 | 139 | MWAW_DEBUG_MSG(("ClarisWksStruct::DSET::removeChild can not detach %d\n", cId)); |
256 | 139 | } |
257 | | |
258 | | |
259 | | void DSET::updateChildPositions(MWAWVec2f const &pageDim, float formLength, int numHorizontalPages) |
260 | 1.15M | { |
261 | 1.15M | float const &textWidth=pageDim[0]; |
262 | 1.15M | float textHeight=pageDim[1]; |
263 | 1.15M | if (float(m_pageDimension[1])>0.5f*formLength && float(m_pageDimension[1])<formLength) |
264 | 8.27k | textHeight=float(m_pageDimension[1]); |
265 | 1.15M | if (textHeight<=0) { |
266 | 2.07k | MWAW_DEBUG_MSG(("ClarisWksStruct::DSET::updateChildPositions: the height can not be null\n")); |
267 | 2.07k | return; |
268 | 2.07k | } |
269 | 1.15M | if (numHorizontalPages>1 && textWidth<=0) { |
270 | 1.56k | MWAW_DEBUG_MSG(("ClarisWksStruct::DSET::updateChildPositions: the width can not be null\n")); |
271 | 1.56k | numHorizontalPages=1; |
272 | 1.56k | } |
273 | 1.15M | MWAWBox2f groupBox; |
274 | 1.15M | int groupPage=-1; |
275 | 1.15M | bool firstGroupFound=false; |
276 | 76.1M | for (auto &child : m_childs) { |
277 | 76.1M | MWAWBox2f childBdBox=child.getBdBox(); |
278 | 76.1M | auto pageY=int(float(childBdBox[1].y())/textHeight); |
279 | 76.1M | if (pageY < 0) |
280 | 914k | continue; |
281 | 75.2M | if (++pageY > 1) { |
282 | 12.6M | MWAWVec2f orig = child.m_box[0]; |
283 | 12.6M | MWAWVec2f sz = child.m_box.size(); |
284 | 12.6M | orig[1]-=float(pageY-1)*textHeight; |
285 | 12.6M | if (orig[1] < 0) { |
286 | 5.80M | if (orig[1]>=-textHeight*0.1f) |
287 | 15.8k | orig[1]=0; |
288 | 5.78M | else if (orig[1]>-1.1f*textHeight) { |
289 | 155k | orig[1]+=textHeight; |
290 | 155k | if (orig[1]<0) orig[1]=0; |
291 | 155k | pageY--; |
292 | 155k | } |
293 | 5.62M | else { |
294 | | // can happen in a drawing document if a form is on several vertical page |
295 | 5.62M | if (m_position!=P_Main) { // can be normal, if this corresponds to the mainZone |
296 | 4.40M | MWAW_DEBUG_MSG(("ClarisWksStruct::DSET::updateChildPositions: data on several vertical page(move it on the first page)\n")); |
297 | 4.40M | } |
298 | | // better to move it on the first page, ie. if the position is problematic, we do no create a big number of empty page |
299 | 5.62M | pageY=int(float(childBdBox[0].y())/textHeight); |
300 | 5.62M | if (++pageY<0) pageY=0; |
301 | 5.62M | if (sz[1]>textHeight) { |
302 | 5.62M | orig[1]=0; |
303 | 5.62M | sz[1]=textHeight; |
304 | 5.62M | } |
305 | 1.46k | else |
306 | 1.46k | orig[1]=textHeight-sz[1]; |
307 | 5.62M | } |
308 | 5.80M | } |
309 | 12.6M | child.m_box = MWAWBox2f(orig, orig+sz); |
310 | 12.6M | } |
311 | 75.2M | int pageX=1; |
312 | 75.2M | if (numHorizontalPages>1) { |
313 | 2.02M | pageX=int(float(childBdBox[1].x())/textWidth); |
314 | 2.02M | MWAWVec2f orig = child.m_box[0]; |
315 | 2.02M | MWAWVec2f sz = child.m_box.size(); |
316 | 2.02M | orig[0]-=float(pageX)*textWidth; |
317 | 2.02M | if (orig[0] < 0) { |
318 | 610k | if (orig[0]>=-textWidth*0.1f) |
319 | 40.6k | orig[0]=0; |
320 | 569k | else if (orig[0]>-1.1f*textWidth) { |
321 | 40.7k | orig[0]+=textWidth; |
322 | 40.7k | if (orig[0]<0) orig[0]=0; |
323 | 40.7k | pageX--; |
324 | 40.7k | } |
325 | 528k | else { |
326 | | // can happen if a form is on several horizontal page |
327 | 528k | MWAW_DEBUG_MSG(("ClarisWksStruct::DSET::updateChildPositions: data on several horizontal page(move it on the first page)\n")); |
328 | | // better to move it on the first page, ie. if the position is problematic, we do no create a big number of empty page |
329 | 528k | pageX=int(float(childBdBox[0].x())/textWidth); |
330 | 528k | if (pageX<0) pageX=0; |
331 | 528k | if (sz[0]>textWidth) { |
332 | 528k | orig[0]=0; |
333 | 528k | sz[0]=textWidth; |
334 | 528k | } |
335 | 206 | else |
336 | 206 | orig[0]=textWidth-sz[0]; |
337 | 528k | } |
338 | 610k | } |
339 | 2.02M | child.m_box = MWAWBox2f(orig, orig+sz); |
340 | 2.02M | pageX++; |
341 | 2.02M | } |
342 | 75.2M | int64_t newPage = pageX+int64_t(pageY-1)*numHorizontalPages; |
343 | 75.2M | if (newPage > MAX_PAGES) |
344 | 117k | continue; |
345 | 75.1M | int page = int(newPage); |
346 | 75.1M | if (!firstGroupFound) { |
347 | 617k | groupPage=page; |
348 | 617k | groupBox=child.getBdBox(); |
349 | 617k | firstGroupFound=true; |
350 | 617k | } |
351 | 74.5M | else if (groupPage==page) |
352 | 56.1M | groupBox=groupBox.getUnion(child.getBdBox()); |
353 | 18.3M | else |
354 | 18.3M | groupPage=-1; |
355 | 75.1M | child.m_page = page; |
356 | 75.1M | } |
357 | 1.15M | if (groupPage>=0) { |
358 | 469k | m_page=groupPage; |
359 | 469k | m_box=groupBox; |
360 | 469k | } |
361 | 1.15M | } |
362 | | |
363 | | void DSET::findForbiddenPagesBreaking(float pageDim, float formDim, int dim, MWAWVariable<int> &lastPage) const |
364 | 534k | { |
365 | 534k | if (isHeaderFooter() || m_position==P_Frame) |
366 | 46.7k | return; |
367 | | |
368 | 487k | if (dim<0||dim>1) { |
369 | 0 | MWAW_DEBUG_MSG(("ClarisWksStruct::DSET::findForbiddenPagesBreaking: the height can not be null\n")); |
370 | 0 | return; |
371 | 0 | } |
372 | 487k | float length=pageDim; |
373 | 487k | if (float(m_pageDimension[dim])>0.5f*formDim && float(m_pageDimension[dim])<formDim) |
374 | 3.76k | length=float(m_pageDimension[dim]); |
375 | 487k | if (length<=0) { |
376 | 2.37k | MWAW_DEBUG_MSG(("ClarisWksStruct::DSET::findForbiddenPagesBreaking: the length can not be null\n")); |
377 | 2.37k | return; |
378 | 2.37k | } |
379 | 485k | float const eps=0.1f*length; |
380 | 25.5M | for (auto const &child : m_childs) { |
381 | 25.5M | MWAWBox2f childBdBox=child.getBdBox(); |
382 | | // as the recomputation of page position is not accurate, just ignore the small size |
383 | 25.5M | if (childBdBox.size()[dim]<=length) |
384 | 18.5M | continue; |
385 | 6.99M | auto pageMax=int(float(childBdBox[1][dim])/length); |
386 | 6.99M | if (pageMax <= 0) |
387 | 680k | continue; |
388 | 6.31M | float diff = child.m_box[1][dim]-float(pageMax)*length; |
389 | 6.31M | if (diff <= eps) |
390 | 3.29M | --pageMax; |
391 | 6.31M | if (!lastPage.isSet() || pageMax > *lastPage) |
392 | 153k | lastPage = pageMax; |
393 | 6.31M | } |
394 | 485k | } |
395 | | |
396 | | std::ostream &operator<<(std::ostream &o, DSET const &doc) |
397 | 0 | { |
398 | 0 | switch (doc.m_position) { |
399 | 0 | case DSET::P_Unknown: |
400 | 0 | break; |
401 | 0 | case DSET::P_Frame: |
402 | 0 | o << "frame,"; |
403 | 0 | break; |
404 | 0 | case DSET::P_Header: |
405 | 0 | o << "header,"; |
406 | 0 | break; |
407 | 0 | case DSET::P_Footer: |
408 | 0 | o << "footer,"; |
409 | 0 | break; |
410 | 0 | case DSET::P_Footnote: |
411 | 0 | o << "footnote,"; |
412 | 0 | break; |
413 | 0 | case DSET::P_Main: |
414 | 0 | o << "main,"; |
415 | 0 | break; |
416 | 0 | case DSET::P_GraphicMaster: |
417 | 0 | o << "graphic[master],"; |
418 | 0 | break; |
419 | 0 | case DSET::P_Slide: |
420 | 0 | o << "slide,"; |
421 | 0 | break; |
422 | 0 | case DSET::P_SlideMaster: |
423 | 0 | o << "slide[master],"; |
424 | 0 | break; |
425 | 0 | case DSET::P_SlideNote: |
426 | 0 | o << "slide[note],"; |
427 | 0 | break; |
428 | 0 | case DSET::P_SlideThumbnail: |
429 | 0 | o << "slide[thumbnail],"; |
430 | 0 | break; |
431 | 0 | case DSET::P_Table: |
432 | 0 | o << "table,"; |
433 | 0 | break; |
434 | | #if !defined(__clang__) |
435 | | default: |
436 | | o << "#position=" << doc.m_position << ","; |
437 | | break; |
438 | | #endif |
439 | 0 | } |
440 | 0 | switch (doc.m_fileType) { |
441 | 0 | case 0: |
442 | 0 | o << "normal,"; |
443 | 0 | break; |
444 | 0 | case 1: |
445 | 0 | o << "text"; |
446 | 0 | if (doc.m_textType==0xFF) |
447 | 0 | o << "*,"; |
448 | 0 | else if (doc.m_textType==0xa) // appear in graphic file |
449 | 0 | o << "[textbox],"; |
450 | 0 | else if (doc.m_textType) |
451 | 0 | o << "[#type=" << std::hex << doc.m_textType<< std::dec << "],"; |
452 | 0 | else |
453 | 0 | o << ","; |
454 | 0 | break; |
455 | 0 | case 2: |
456 | 0 | o << "spreadsheet,"; |
457 | 0 | break; |
458 | 0 | case 3: |
459 | 0 | o << "database,"; |
460 | 0 | break; |
461 | 0 | case 4: |
462 | 0 | o << "bitmap,"; |
463 | 0 | break; |
464 | 0 | case 5: |
465 | 0 | o << "presentation,"; |
466 | 0 | break; |
467 | 0 | case 6: |
468 | 0 | o << "table,"; |
469 | 0 | break; |
470 | 0 | default: |
471 | 0 | o << "#type=" << doc.m_fileType << ","; |
472 | 0 | break; |
473 | 0 | } |
474 | 0 | if (doc.m_page>= 0) o << "pg=" << doc.m_page << ","; |
475 | 0 | if (doc.m_box.size()[0]>0||doc.m_box.size()[1]>0) |
476 | 0 | o << "box=" << doc.m_box << ","; |
477 | 0 | if (doc.m_pageDimension[0]>0 || doc.m_pageDimension[1]>0) |
478 | 0 | o << "zone[dim]=" << doc.m_pageDimension << ","; |
479 | 0 | o << "id=" << doc.m_id << ","; |
480 | 0 | if (!doc.m_fathersList.empty()) { |
481 | 0 | o << "fathers=["; |
482 | 0 | for (auto id : doc.m_fathersList) |
483 | 0 | o << id << ","; |
484 | 0 | o << "],"; |
485 | 0 | } |
486 | 0 | o << "N=" << doc.m_numData << ","; |
487 | 0 | if (doc.m_dataSz >=0) o << "dataSz=" << doc.m_dataSz << ","; |
488 | 0 | if (doc.m_headerSz >= 0) o << "headerSz=" << doc.m_headerSz << ","; |
489 | 0 | if (doc.m_beginSelection) o << "begSel=" << doc.m_beginSelection << ","; |
490 | 0 | if (doc.m_endSelection >= 0) o << "endSel=" << doc.m_endSelection << ","; |
491 | 0 | for (int i = 0; i < 4; i++) { |
492 | 0 | if (doc.m_flags[i]) |
493 | 0 | o << "fl" << i << "=" << std::hex << doc.m_flags[i] << std::dec << ","; |
494 | 0 | } |
495 | 0 | for (size_t i = 0; i < doc.m_childs.size(); i++) |
496 | 0 | o << "child" << i << "=[" << doc.m_childs[i] << "],"; |
497 | 0 | for (size_t i = 0; i < doc.m_otherChilds.size(); i++) |
498 | 0 | o << "otherChild" << i << "=" << doc.m_otherChilds[i] << ","; |
499 | 0 | return o; |
500 | 0 | } |
501 | | |
502 | | } |
503 | | // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: |