Coverage Report

Created: 2026-06-13 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libmwaw/src/lib/FullWrtGraph.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 <cmath>
35
#include <iomanip>
36
#include <iostream>
37
#include <limits>
38
#include <map>
39
#include <sstream>
40
41
#include <librevenge/librevenge.h>
42
43
#include "MWAWTextListener.hxx"
44
#include "MWAWPictData.hxx"
45
#include "MWAWPosition.hxx"
46
#include "MWAWSubDocument.hxx"
47
48
#include "FullWrtParser.hxx"
49
#include "FullWrtStruct.hxx"
50
51
#include "FullWrtGraph.hxx"
52
53
/** Internal: the structures of a FullWrtGraph */
54
namespace FullWrtGraphInternal
55
{
56
////////////////////////////////////////
57
//! Internal: the sidebar of a FullWrtGraph
58
struct SideBar final : public FullWrtStruct::ZoneHeader {
59
  //! constructor
60
8.76k
  explicit SideBar(FullWrtStruct::ZoneHeader const &header): FullWrtStruct::ZoneHeader(header), m_box(), m_page(0), m_borderId(0), m_parsed(false)
61
8.76k
  {
62
8.76k
  }
63
  //! destructor
64
  ~SideBar() final;
65
  //! the position (in point)
66
  MWAWBox2f m_box;
67
  //! the page
68
  int m_page;
69
  //! the border id
70
  int m_borderId;
71
  //! a flag to know if the sidebar is send to the listener
72
  mutable bool m_parsed;
73
};
74
75
SideBar::~SideBar()
76
8.76k
{
77
8.76k
}
78
79
////////////////////////////////////////
80
//! Internal: the state of a FullWrtGraph
81
struct State {
82
  //! constructor
83
  State()
84
56.2k
    : m_version(-1)
85
56.2k
    , m_sidebarList()
86
56.2k
    , m_graphicMap()
87
56.2k
    , m_borderList()
88
56.2k
    , m_numPages(-1) { }
89
90
  //! the file version
91
  mutable int m_version;
92
  //! the sidebar list
93
  std::vector<std::shared_ptr<SideBar> > m_sidebarList;
94
  //! zoneId -> graphic entry
95
  std::multimap<int, FullWrtStruct::EntryPtr > m_graphicMap;
96
  //! a list of border
97
  std::vector<FullWrtStruct::Border> m_borderList;
98
  int m_numPages /* the number of pages */;
99
};
100
101
////////////////////////////////////////
102
//! Internal: the subdocument of a FullWrtGraph
103
class SubDocument final : public MWAWSubDocument
104
{
105
public:
106
  //! constructor
107
  SubDocument(FullWrtGraph &pars, int id, MWAWColor fontColor)
108
4.93k
    : MWAWSubDocument(pars.m_mainParser, MWAWInputStreamPtr(), MWAWEntry())
109
4.93k
    , m_graphParser(&pars)
110
4.93k
    , m_id(id)
111
4.93k
    , m_fontColor(fontColor) {}
112
113
  //! destructor
114
0
  ~SubDocument() final {}
115
116
  //! operator!=
117
  bool operator!=(MWAWSubDocument const &doc) const final;
118
119
  //! the parser function
120
  void parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType type) final;
121
122
protected:
123
  /** the graph parser */
124
  FullWrtGraph *m_graphParser;
125
  //! the zone file id
126
  int m_id;
127
  //! the default font color
128
  MWAWColor m_fontColor;
129
130
private:
131
  SubDocument(SubDocument const &orig) = delete;
132
  SubDocument &operator=(SubDocument const &orig) = delete;
133
};
134
135
void SubDocument::parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType /*type*/)
136
4.93k
{
137
4.93k
  if (!listener.get()) {
138
0
    MWAW_DEBUG_MSG(("FullWrtGraphInternal::SubDocument::parse: no listener\n"));
139
0
    return;
140
0
  }
141
4.93k
  if (!m_graphParser) {
142
0
    MWAW_DEBUG_MSG(("FullWrtGraphInternal::SubDocument::parse: no graph parser\n"));
143
0
    return;
144
0
  }
145
4.93k
  m_graphParser->send(m_id, m_fontColor);
146
4.93k
}
147
148
bool SubDocument::operator!=(MWAWSubDocument const &doc) const
149
0
{
150
0
  if (MWAWSubDocument::operator!=(doc)) return true;
151
0
  auto const *sDoc = dynamic_cast<SubDocument const *>(&doc);
152
0
  if (!sDoc) return true;
153
0
  if (m_graphParser != sDoc->m_graphParser) return true;
154
0
  if (m_id != sDoc->m_id) return true;
155
0
  if (m_fontColor != sDoc->m_fontColor) return true;
156
0
  return false;
157
0
}
158
}
159
160
////////////////////////////////////////////////////////////
161
// constructor/destructor, ...
162
////////////////////////////////////////////////////////////
163
FullWrtGraph::FullWrtGraph(FullWrtParser &parser)
164
56.2k
  : m_parserState(parser.getParserState())
165
56.2k
  , m_state(new FullWrtGraphInternal::State)
166
56.2k
  , m_mainParser(&parser)
167
56.2k
{
168
56.2k
}
169
170
FullWrtGraph::~FullWrtGraph()
171
56.2k
{
172
56.2k
}
173
174
int FullWrtGraph::version() const
175
128k
{
176
128k
  if (m_state->m_version < 0)
177
15.8k
    m_state->m_version = m_parserState->m_version;
178
128k
  return m_state->m_version;
179
128k
}
180
181
int FullWrtGraph::numPages() const
182
22.6k
{
183
22.6k
  if (m_state->m_numPages > 0)
184
996
    return m_state->m_numPages;
185
21.6k
  int nPage=0;
186
21.6k
  for (auto const &sidebar : m_state->m_sidebarList) {
187
4.93k
    if (!sidebar)
188
0
      continue;
189
4.93k
    if (sidebar->m_page>nPage)
190
2.30k
      nPage=sidebar->m_page;
191
4.93k
  }
192
21.6k
  return (m_state->m_numPages=nPage);
193
22.6k
}
194
195
bool FullWrtGraph::getBorder(int bId, FullWrtStruct::Border &border) const
196
3.00k
{
197
3.00k
  if (bId < 0 || bId>= int(m_state->m_borderList.size())) {
198
3.00k
    MWAW_DEBUG_MSG(("FullWrtGraph::getBorder: can not find border %d\n", bId));
199
3.00k
    border=FullWrtStruct::Border();
200
3.00k
    return false;
201
3.00k
  }
202
0
  border=m_state->m_borderList[size_t(bId)];
203
0
  return true;
204
3.00k
}
205
206
bool FullWrtGraph::send(int fileId, MWAWColor const &fontColor)
207
4.93k
{
208
4.93k
  return m_mainParser->send(fileId, fontColor);
209
4.93k
}
210
211
////////////////////////////////////////////////////////////
212
//
213
// Intermediate level
214
//
215
////////////////////////////////////////////////////////////
216
217
////////////////////////////////////////////////////////////
218
// low level
219
////////////////////////////////////////////////////////////
220
221
////////////////////////////////////////////////////////////
222
// border
223
bool FullWrtGraph::readBorderDocInfo(FullWrtStruct::EntryPtr zone)
224
243
{
225
243
  MWAWInputStreamPtr input = zone->m_input;
226
243
  libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
227
243
  libmwaw::DebugStream f;
228
243
  long pos = input->tell();
229
243
  if (input->readULong(4)!=0x626f7264 || input->readULong(1)) {
230
0
    input->seek(pos, librevenge::RVNG_SEEK_SET);
231
0
    return false;
232
0
  }
233
234
243
  long blckSz = input->readLong(4);
235
243
  long endData = pos+9+blckSz;
236
243
  auto num = static_cast<int>(input->readULong(2));
237
243
  int const fSz = 26;
238
243
  f << "Entries(Border):N=" << num << ",";
239
243
  if (blckSz < 2 || blckSz != 2 + num*fSz || endData > zone->end()) {
240
65
    MWAW_DEBUG_MSG(("FullWrtGraph::readBorderDocInfo: problem reading the data block or the number of data\n"));
241
65
    f << "###";
242
65
    asciiFile.addPos(pos);
243
65
    asciiFile.addNote(f.str().c_str());
244
65
    if (endData <= zone->end()) {
245
49
      input->seek(endData, librevenge::RVNG_SEEK_SET);
246
49
      return true;
247
49
    }
248
16
    input->seek(pos, librevenge::RVNG_SEEK_SET);
249
16
    return false;
250
65
  }
251
252
178
  asciiFile.addPos(pos);
253
178
  asciiFile.addNote(f.str().c_str());
254
255
178
  m_state->m_borderList.push_back(FullWrtStruct::Border());
256
178
  for (int i = 0; i < num; i++) {
257
0
    pos = input->tell();
258
0
    FullWrtStruct::Border mod;
259
0
    f.str("");
260
0
    f << "Border-B" << i << ":";
261
0
    if (!mod.read(zone, fSz))
262
0
      f << "###";
263
0
    else
264
0
      f << mod;
265
0
    m_state->m_borderList.push_back(mod);
266
0
    asciiFile.addPos(pos);
267
0
    asciiFile.addNote(f.str().c_str());
268
0
    input->seek(pos+fSz, librevenge::RVNG_SEEK_SET);
269
0
  }
270
178
  return true;
271
243
}
272
273
////////////////////////////////////////////////////////////
274
// side bar
275
std::shared_ptr<FullWrtStruct::ZoneHeader> FullWrtGraph::readSideBar(FullWrtStruct::EntryPtr zone, FullWrtStruct::ZoneHeader const &doc)
276
8.76k
{
277
8.76k
  std::shared_ptr<FullWrtGraphInternal::SideBar> sidebar;
278
8.76k
  if (doc.m_type != 0x13 && doc.m_type != 0x14) {
279
0
    MWAW_DEBUG_MSG(("FullWrtGraph::readSideBar: find unexpected type\n"));
280
0
    return sidebar;
281
0
  }
282
8.76k
  MWAWInputStreamPtr input = zone->m_input;
283
8.76k
  long pos = input->tell();
284
8.76k
  sidebar.reset(new FullWrtGraphInternal::SideBar(doc));
285
8.76k
  if (!sidebar->read(zone)) {
286
2.53k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
287
2.53k
    sidebar.reset();
288
2.53k
    return sidebar;
289
2.53k
  }
290
291
6.23k
  int val;
292
6.23k
  if (input->tell()+12 > zone->end()) {
293
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
294
1
    sidebar.reset();
295
1
    return sidebar;
296
1
  }
297
298
6.23k
  libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
299
6.23k
  libmwaw::DebugStream f;
300
6.23k
  f << "Entries(SideBar):" << *sidebar;
301
6.23k
  asciiFile.addPos(pos);
302
6.23k
  asciiFile.addNote(f.str().c_str());
303
304
22.9k
  for (int i=0; i<3; ++i) {
305
18.0k
    pos = input->tell();
306
18.0k
    bool ok=false;
307
18.0k
    switch (i) {
308
6.23k
    case 0:
309
6.23k
      ok=readSideBarPosition(zone, *sidebar);
310
6.23k
      break;
311
6.04k
    case 1:
312
6.04k
      ok=readSideBarFormat(zone, *sidebar);
313
6.04k
      break;
314
5.78k
    case 2:
315
5.78k
      ok=readSideBarUnknown(zone, *sidebar);
316
5.78k
      break;
317
0
    default:
318
0
      break;
319
18.0k
    }
320
18.0k
    if (ok) continue;
321
1.29k
    MWAW_DEBUG_MSG(("FullWrtGraph::readSideBar: pb reading the zone %d\n", i));
322
1.29k
    f.str("");
323
1.29k
    static char const* const wh[]= {"position","format","unknown"};
324
1.29k
    f << "SideBar[" << wh[i] << ":###";
325
1.29k
    asciiFile.addPos(pos);
326
1.29k
    asciiFile.addNote(f.str().c_str());
327
328
1.29k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
329
1.29k
    return sidebar;
330
18.0k
  }
331
332
  // checkme: can this exist for a sidebar ?
333
4.93k
  val = int(input->readLong(1));
334
4.93k
  if (val==1) {
335
45
    pos = input->tell();
336
45
    auto sz = long(input->readULong(4));
337
45
    if (sz && input->tell()+sz <= zone->end()) {
338
8
      f.str("");
339
8
      f << "SideBar[end]:";
340
8
      asciiFile.addPos(pos);
341
8
      asciiFile.addNote(f.str().c_str());
342
8
      input->seek(sz, librevenge::RVNG_SEEK_CUR);
343
8
    }
344
37
    else {
345
37
      MWAW_DEBUG_MSG(("FullWrtGraph::readSideBar: find bad end data\n"));
346
37
      input->seek(pos, librevenge::RVNG_SEEK_SET);
347
37
    }
348
45
  }
349
4.89k
  else if (val) {
350
307
    MWAW_DEBUG_MSG(("FullWrtGraph::readSideBar: find bad end data(II)\n"));
351
307
  }
352
4.93k
  m_state->m_sidebarList.push_back(sidebar);
353
4.93k
  return sidebar;
354
6.23k
}
355
356
bool FullWrtGraph::readSideBarPosition(FullWrtStruct::EntryPtr zone, FullWrtGraphInternal::SideBar &frame)
357
6.23k
{
358
6.23k
  MWAWInputStreamPtr input = zone->m_input;
359
6.23k
  long pos = input->tell();
360
6.23k
  libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
361
6.23k
  libmwaw::DebugStream f;
362
363
6.23k
  auto sz = long(input->readULong(4));
364
6.23k
  if (sz < 0 || pos+sz+4 > zone->end())
365
188
    return false;
366
6.04k
  f << "SideBar[pos]:";
367
368
6.04k
  if (sz < 28) {
369
137
    MWAW_DEBUG_MSG(("FullWrtGraph::readSideBarPosition: the size seems bad\n"));
370
137
    f << "###";
371
137
    input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
372
137
    asciiFile.addPos(pos);
373
137
    asciiFile.addNote(f.str().c_str());
374
137
    return true;
375
137
  }
376
377
5.90k
  int dim[4];
378
23.6k
  for (auto &d : dim) d=int(input->readLong(2));
379
5.90k
  frame.m_box=MWAWBox2f(MWAWVec2f(float(dim[1]),float(dim[0])),MWAWVec2f(float(dim[3]),float(dim[2])));
380
5.90k
  f << "pos=" << frame.m_box << ",";
381
5.90k
  auto val=int(input->readLong(2));
382
5.90k
  if (val) f << "w[wrap]=" << val << "pt,";
383
5.90k
  f << "ptr?=[" << std::hex;
384
17.7k
  for (int i = 0; i < 2; i++) // two big number
385
11.8k
    f << input->readULong(4) << ",";
386
5.90k
  f << std::dec << "],";
387
5.90k
  val = int(input->readLong(2)); // seems related to floating point position
388
5.90k
  if (val) f << "unkn=" << std::hex << val << std::dec << ",";// 0|441|442|f91|16ac
389
5.90k
  val = int(input->readLong(2)); // always 0?
390
5.90k
  if (val) f << "f0=" << val << ",";
391
5.90k
  frame.m_page = int(input->readLong(2));
392
5.90k
  if (frame.m_page) f << "page=" << frame.m_page << ",";
393
5.90k
  val = int(input->readLong(2)); // number of point in the left part
394
5.90k
  if (val) f << "N[left]?=" << val << ",";
395
5.90k
  auto N=static_cast<int>(input->readLong(2));
396
5.90k
  if (N*4+28 > sz) {
397
133
    f << "#N=" << N << ",";
398
133
    N=0;
399
133
  }
400
5.77k
  else
401
5.77k
    f << "N=" << N << ",";
402
403
  /* probably first the left margin: (x_i,n): meaning to add n times
404
     a point at x, then the same thing for the right margins
405
     -16000/16000=no point (left/right)
406
  */
407
5.90k
  f << "mask=[";
408
38.9k
  for (int i = 0; i < N; i++) {
409
33.0k
    auto x = int(input->readLong(2));
410
33.0k
    auto n = int(input->readLong(2));
411
33.0k
    f << x << ":" << n << ",";
412
33.0k
  }
413
5.90k
  f << "],";
414
5.90k
  if (input->tell() != pos+4+sz) {
415
241
    asciiFile.addDelimiter(input->tell(),'|');
416
241
    input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
417
241
  }
418
5.90k
  asciiFile.addPos(pos);
419
5.90k
  asciiFile.addNote(f.str().c_str());
420
5.90k
  return true;
421
6.04k
}
422
423
bool FullWrtGraph::readSideBarFormat(FullWrtStruct::EntryPtr zone, FullWrtGraphInternal::SideBar &frame)
424
6.04k
{
425
6.04k
  int const vers=version();
426
6.04k
  MWAWInputStreamPtr input = zone->m_input;
427
6.04k
  long pos = input->tell();
428
6.04k
  libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
429
6.04k
  libmwaw::DebugStream f;
430
431
6.04k
  auto sz = long(input->readULong(4));
432
6.04k
  if (sz < 0 || pos+sz+4 > zone->end())
433
257
    return false;
434
5.78k
  f << "SideBar[format]:";
435
5.78k
  if ((vers==1&&sz!=0x3a)||(vers==2&&sz!=0x38)) {
436
174
    MWAW_DEBUG_MSG(("FullWrtGraph::readSideBarFormat: the size seems bad\n"));
437
174
    f << "###";
438
174
    input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
439
174
    asciiFile.addPos(pos);
440
174
    asciiFile.addNote(f.str().c_str());
441
174
    return true;
442
174
  }
443
5.61k
  f << "PTR=" << std::hex << input->readLong(4) << std::dec << ",";
444
5.61k
  auto N=static_cast<int>(input->readLong(1));
445
5.61k
  int val;
446
5.61k
  if (N) {
447
450
    f << "N=" << N << ",";
448
450
    val=static_cast<int>(input->readLong(1));
449
450
    if (val) f << "#f0=" << val << ",";
450
    /* now probably N*[unknData],
451
       find for N=1 005f000000b201d2001600f40f94020004100001009700000000000000000000
452
     */
453
450
  }
454
5.61k
  input->seek(pos+42, librevenge::RVNG_SEEK_SET);
455
5.61k
  float dim[2];
456
11.2k
  for (auto &d : dim) d=float(input->readLong(4))/65536.f;
457
5.61k
  f << "dim?=" << dim[1] << "x" << dim[0] << ",";
458
5.61k
  val=static_cast<int>(input->readULong(2)); // another dim with a flag?
459
5.61k
  if (val&0x8000) f << "f1[high],";
460
5.61k
  if (val&0x7FFF) f << "f1=" << (val&0x7FFF) << ",";
461
5.61k
  float w=float(input->readLong(4))/65536.f;
462
5.61k
  f << "w[wrap]=" << w << "pt,";
463
5.61k
  frame.m_borderId=static_cast<int>(input->readLong(2));
464
5.61k
  if (frame.m_borderId)
465
870
    f << "B" << frame.m_borderId-1 << ",";
466
5.61k
  if (vers==1) {
467
5.61k
    val=static_cast<int>(input->readLong(2)); // 0|1|4|b|20|..f0
468
5.61k
    if (val) f << "f2=" << val << ",";
469
5.61k
  }
470
5.61k
  val=static_cast<int>(input->readLong(2)); // always 0
471
5.61k
  if (val)
472
188
    f << "f3=" << val << ",";
473
474
5.61k
  if (input->tell() != pos+4+sz) {
475
0
    asciiFile.addDelimiter(input->tell(),'|');
476
0
    input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
477
0
  }
478
5.61k
  asciiFile.addPos(pos);
479
5.61k
  asciiFile.addNote(f.str().c_str());
480
5.61k
  return true;
481
5.78k
}
482
483
bool FullWrtGraph::readSideBarUnknown(FullWrtStruct::EntryPtr zone, FullWrtGraphInternal::SideBar &/*frame*/)
484
5.78k
{
485
5.78k
  MWAWInputStreamPtr input = zone->m_input;
486
5.78k
  long pos = input->tell();
487
5.78k
  libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
488
5.78k
  libmwaw::DebugStream f;
489
490
5.78k
  auto sz = long(input->readULong(4));
491
5.78k
  if (sz < 0 || pos+sz+4 > zone->end())
492
852
    return false;
493
4.93k
  f << "SideBar[unknown]:";
494
4.93k
  if (sz!=0x30) {
495
352
    MWAW_DEBUG_MSG(("FullWrtGraph::readSideBarUnknown: the size seems bad\n"));
496
352
    f << "###";
497
352
    input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
498
352
    asciiFile.addPos(pos);
499
352
    asciiFile.addNote(f.str().c_str());
500
352
    return true;
501
352
  }
502
4.58k
  auto val = static_cast<int>(input->readLong(2));
503
4.58k
  if (val!=-1)
504
5
    f << "f0=" << val << ",";
505
4.58k
  val = static_cast<int>(input->readLong(2));
506
4.58k
  if (val!=1)
507
11
    f << "f1=" << val << ",";
508
4.58k
  val = static_cast<int>(input->readULong(2)); // maybe a color?
509
4.58k
  if (val)
510
2.40k
    f << "f2=" << std::hex << val << std::dec << ",";
511
13.7k
  for (int i=0; i<2; ++i) { // f3=1|2, f4=small numer 0..ff
512
9.16k
    val = static_cast<int>(input->readULong(2));
513
9.16k
    if (val)
514
6.94k
      f << "f" << i+3 << "=" << val << ",";
515
9.16k
  }
516
91.6k
  for (int i=0; i<19; ++i) { // g0,g1,g17,g18: in form xyxy, other 0
517
87.0k
    val = static_cast<int>(input->readULong(2));
518
87.0k
    if (val)
519
3.56k
      f << "g" << i << "=" << std::hex << val << std::dec << ",";
520
87.0k
  }
521
4.58k
  if (input->tell() != pos+4+sz) {
522
0
    asciiFile.addDelimiter(input->tell(),'|');
523
0
    input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
524
0
  }
525
4.58k
  asciiFile.addPos(pos);
526
4.58k
  asciiFile.addNote(f.str().c_str());
527
4.58k
  return true;
528
4.93k
}
529
530
bool FullWrtGraph::sendSideBar(FullWrtGraphInternal::SideBar const &frame)
531
4.93k
{
532
4.93k
  MWAWTextListenerPtr listener=m_parserState->m_textListener;
533
4.93k
  if (!listener) {
534
0
    MWAW_DEBUG_MSG(("FullWrtGraph::sendSideBar can not find the listener\n"));
535
0
    return true;
536
0
  }
537
538
4.93k
  frame.m_parsed=true;
539
4.93k
  MWAWPosition pos(frame.m_box[0]+72.f *m_mainParser->getPageLeftTop(),
540
4.93k
                   frame.m_box.size(),librevenge::RVNG_POINT);
541
4.93k
  pos.setPage(frame.m_page>0 ? frame.m_page : 1);
542
4.93k
  pos.setRelativePosition(MWAWPosition::Page);
543
4.93k
  pos.m_wrapping=(frame.m_wrapping==3) ?
544
4.93k
                 MWAWPosition::WBackground : MWAWPosition::WDynamic;
545
4.93k
  FullWrtStruct::Border border;
546
4.93k
  MWAWGraphicStyle style;
547
4.93k
  if (frame.m_borderId && getBorder(frame.m_borderId, border))
548
0
    border.addTo(style);
549
4.93k
  MWAWSubDocumentPtr doc(new FullWrtGraphInternal::SubDocument(*this,frame.m_fileId,border.m_frontColor));
550
4.93k
  listener->insertTextBox(pos, doc, style);
551
4.93k
  return true;
552
4.93k
}
553
554
////////////////////////////////////////////////////////////
555
// graphic: data +
556
std::shared_ptr<FullWrtStruct::ZoneHeader> FullWrtGraph::readGraphicData(FullWrtStruct::EntryPtr zone, FullWrtStruct::ZoneHeader &doc)
557
10.3k
{
558
10.3k
  std::shared_ptr<FullWrtStruct::ZoneHeader> graphData;
559
10.3k
  if (doc.m_type != 0x15) {
560
0
    MWAW_DEBUG_MSG(("FullWrtGraph::readGraphicData: find unexpected type\n"));
561
0
    return graphData;
562
0
  }
563
10.3k
  MWAWInputStreamPtr input = zone->m_input;
564
10.3k
  long pos = input->tell();
565
10.3k
  if (!doc.read(zone)) {
566
3.58k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
567
3.58k
    return graphData;
568
3.58k
  }
569
570
6.75k
  int const vers = version();
571
6.75k
  libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
572
6.75k
  libmwaw::DebugStream f;
573
574
6.75k
  if (input->tell()+(vers==2?14:2) > zone->end()) {
575
9
    input->seek(pos, librevenge::RVNG_SEEK_SET);
576
9
    return graphData;
577
9
  }
578
579
6.74k
  graphData.reset(new FullWrtStruct::ZoneHeader(doc));
580
6.74k
  f.str("");
581
6.74k
  f << "Entries(GraphData):" << doc;
582
6.74k
  asciiFile.addPos(pos);
583
6.74k
  asciiFile.addNote(f.str().c_str());
584
6.74k
  if (vers == 2) {
585
252
    pos = input->tell();
586
252
    f.str("");
587
252
    f << "GraphData[1]:";
588
252
    int dim[4];
589
1.00k
    for (auto &d : dim) d=int(input->readLong(2));
590
252
    f << "box=" << dim[1] << "x" << dim[0] << "<->" << dim[3] << "x" << dim[2] << ",";
591
756
    for (int i = 0; i < 2; i++) { // always 0 ?
592
504
      auto val = int(input->readLong(2));
593
504
      if (val)
594
232
        f << "f" << i << "=" << val << "c";
595
504
    }
596
252
    asciiFile.addPos(pos);
597
252
    asciiFile.addNote(f.str().c_str());
598
252
  }
599
600
6.74k
  f.str("");
601
6.74k
  auto nextData = int(input->readULong(1));
602
6.74k
  pos = input->tell();
603
6.74k
  if (nextData==1) {
604
219
    f << "GraphData[2]:";
605
219
    auto sz = long(input->readULong(4));
606
219
    if (sz < 0 || pos+4+sz > zone->end()) {
607
17
      f << "#sz=" << sz << ",";
608
17
      input->seek(pos, librevenge::RVNG_SEEK_SET);
609
17
    }
610
202
    else if (sz) {   // a serie of doc id ( normally 1e )
611
178
      f << "docId[type1e?]=[";
612
5.75k
      for (long i = 0; i < sz/2; i++) {
613
5.57k
        auto id = int(input->readLong(2));
614
5.57k
        std::string type=m_mainParser->getDocumentTypeName(id);
615
5.57k
        if (type.empty())
616
1.89k
          f << "#" << id << ",";
617
3.68k
        else
618
3.68k
          f << id << "[" << type << "],";
619
5.57k
      }
620
178
      f << "],";
621
178
      input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
622
178
    }
623
219
  }
624
6.52k
  else if (nextData) f << "GraphData[2]:#" << nextData;
625
626
6.74k
  input->seek(1, librevenge::RVNG_SEEK_CUR);
627
6.74k
  if (f.str().length()) {
628
0
    asciiFile.addPos(pos);
629
0
    asciiFile.addNote(f.str().c_str());
630
0
  }
631
632
6.74k
  return graphData;
633
6.75k
}
634
635
bool FullWrtGraph::readGraphic(FullWrtStruct::EntryPtr zone)
636
115k
{
637
115k
  int vers = version();
638
639
115k
  MWAWInputStreamPtr input = zone->m_input;
640
115k
  libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
641
115k
  libmwaw::DebugStream f;
642
643
115k
  long pos = zone->begin();
644
115k
  input->seek(pos, librevenge::RVNG_SEEK_SET);
645
115k
  auto sz = long(input->readULong(4));
646
115k
  int expectedSz = vers==1 ? 0x5c : 0x54;
647
115k
  if (sz != expectedSz || pos+sz > zone->end()) return false;
648
4.23k
  input->seek(sz, librevenge::RVNG_SEEK_CUR);
649
4.23k
  f << "Entries(Graphic)";
650
4.23k
  f << "|" << *zone << ":";
651
4.23k
  if (zone->m_fileType >= 0)
652
1.31k
    f << "type=" << std::hex << zone->m_fileType << std::dec << ",";
653
4.23k
  asciiFile.addPos(pos);
654
4.23k
  asciiFile.addNote(f.str().c_str());
655
656
4.23k
  pos = input->tell();
657
4.23k
  sz = long(input->readULong(4));
658
4.23k
  if (!sz || pos+4+sz > zone->end()) {
659
995
    MWAW_DEBUG_MSG(("FullWrtGraph::readGraphic: can not read graphic size\n"));
660
995
    return false;
661
995
  }
662
3.23k
  f.str("");
663
3.23k
  f << "Graphic:sz=" << std::hex << sz << std::dec << ",";
664
3.23k
  asciiFile.addPos(pos);
665
3.23k
  asciiFile.addNote(f.str().c_str());
666
3.23k
  asciiFile.skipZone(pos+4, pos+4+sz-1);
667
3.23k
  input->seek(sz, librevenge::RVNG_SEEK_CUR);
668
669
3.23k
  m_state->m_graphicMap.insert
670
3.23k
  (std::multimap<int, FullWrtStruct::EntryPtr >::value_type(zone->id(), zone));
671
672
3.23k
  pos = input->tell();
673
3.23k
  if (pos == zone->end())
674
379
    return true;
675
676
2.85k
  sz = long(input->readULong(4));
677
2.85k
  if (sz)
678
1.92k
    input->seek(sz, librevenge::RVNG_SEEK_CUR);
679
2.85k
  if (pos+4+sz!=zone->end()) {
680
1.69k
    MWAW_DEBUG_MSG(("FullWrtGraph::readGraphic: end graphic seems odds\n"));
681
1.69k
  }
682
2.85k
  asciiFile.addPos(pos);
683
2.85k
  asciiFile.addNote("Graphic-A");
684
685
2.85k
  asciiFile.addPos(input->tell());
686
2.85k
  asciiFile.addNote("_");
687
688
2.85k
  return true;
689
3.23k
}
690
691
////////////////////////////////////////////////////////////
692
// send data
693
////////////////////////////////////////////////////////////
694
bool FullWrtGraph::sendGraphic(int fId)
695
90.6k
{
696
90.6k
  auto it = m_state->m_graphicMap.find(fId);
697
90.6k
  if (it == m_state->m_graphicMap.end() || !it->second) {
698
89.9k
    MWAW_DEBUG_MSG(("FullWrtGraph::sendGraphic: can not find graphic %d\n", fId));
699
89.9k
    return false;
700
89.9k
  }
701
718
  auto zone = it->second;
702
718
  MWAWInputStreamPtr input = zone->m_input;
703
718
  long pos = input->tell();
704
718
  bool ok=sendGraphic(zone);
705
718
  input->seek(pos, librevenge::RVNG_SEEK_SET);
706
718
  return ok;
707
90.6k
}
708
709
bool FullWrtGraph::sendGraphic(FullWrtStruct::EntryPtr zone)
710
3.23k
{
711
3.23k
  MWAWTextListenerPtr listener=m_parserState->m_textListener;
712
3.23k
  if (!listener) {
713
0
    MWAW_DEBUG_MSG(("FullWrtGraph::sendGraphic can not find the listener\n"));
714
0
    return true;
715
0
  }
716
3.23k
  zone->setParsed(true);
717
718
3.23k
  MWAWInputStreamPtr input = zone->m_input;
719
720
3.23k
  long pos = zone->begin();
721
3.23k
  input->seek(pos, librevenge::RVNG_SEEK_SET);
722
3.23k
  auto sz = static_cast<int>(input->readULong(4));
723
3.23k
  input->seek(sz, librevenge::RVNG_SEEK_CUR);
724
725
  // header
726
3.23k
  pos = input->tell();
727
3.23k
  sz = static_cast<int>(input->readULong(4));
728
729
#ifdef DEBUG_WITH_FILES
730
  if (1) {
731
    librevenge::RVNGBinaryData file;
732
    input->seek(pos+4, librevenge::RVNG_SEEK_SET);
733
    input->readDataBlock(sz, file);
734
    static int volatile pictName = 0;
735
    libmwaw::DebugStream f;
736
    f << "DATA-" << ++pictName;
737
    libmwaw::Debug::dumpFile(file, f.str().c_str());
738
  }
739
#endif
740
741
3.23k
  input->seek(pos+4, librevenge::RVNG_SEEK_SET);
742
3.23k
  MWAWBox2f box;
743
3.23k
  auto res = MWAWPictData::check(input, sz, box);
744
3.23k
  if (res == MWAWPict::MWAW_R_BAD) {
745
1.19k
    MWAW_DEBUG_MSG(("FullWrtGraph::sendGraphic: can not find the picture\n"));
746
1.19k
    return false;
747
1.19k
  }
748
749
2.04k
  MWAWVec2f actualSize, naturalSize;
750
2.04k
  if (box.size().x() > 0 && box.size().y()  > 0) {
751
1.86k
    actualSize = naturalSize = box.size();
752
1.86k
  }
753
183
  else if (actualSize.x() <= 0 || actualSize.y() <= 0) {
754
183
    MWAW_DEBUG_MSG(("FullWrtGraph::sendGraphic: can not find the picture size\n"));
755
183
    actualSize = naturalSize = MWAWVec2f(100,100);
756
183
  }
757
2.04k
  MWAWPosition pictPos=MWAWPosition(MWAWVec2f(0,0),actualSize, librevenge::RVNG_POINT);
758
2.04k
  pictPos.setRelativePosition(MWAWPosition::Char);
759
2.04k
  pictPos.setNaturalSize(naturalSize);
760
761
2.04k
  input->seek(pos+4, librevenge::RVNG_SEEK_SET);
762
2.04k
  std::shared_ptr<MWAWPict> pict(MWAWPictData::get(input, sz));
763
2.04k
  if (pict) {
764
2.03k
    MWAWEmbeddedObject picture;
765
2.03k
    if (pict->getBinary(picture)) {
766
2.03k
      listener->insertPicture(pictPos, picture);
767
2.03k
      return true;
768
2.03k
    }
769
2.03k
  }
770
771
4
  return true;
772
2.04k
}
773
774
bool FullWrtGraph::sendPageGraphics()
775
21.6k
{
776
21.6k
  for (auto const &frame : m_state->m_sidebarList) {
777
4.93k
    if (!frame)
778
0
      continue;
779
4.93k
    if (!frame->m_parsed)
780
4.93k
      sendSideBar(*frame);
781
4.93k
  }
782
21.6k
  return true;
783
21.6k
}
784
785
void FullWrtGraph::flushExtra()
786
21.6k
{
787
21.6k
  for (auto const &it : m_state->m_graphicMap) {
788
3.20k
    FullWrtStruct::EntryPtr const &zone = it.second;
789
3.20k
    if (!zone || zone->isParsed())
790
689
      continue;
791
2.51k
    sendGraphic(zone);
792
2.51k
  }
793
21.6k
}
794
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: