Coverage Report

Created: 2026-03-12 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwps/src/lib/WPS8Graph.cpp
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2
/* libwps
3
 * Version: MPL 2.0 / LGPLv2.1+
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * Major Contributor(s):
10
 * Copyright (C) 2009, 2011 Alonso Laurent (alonso@loria.fr)
11
 * Copyright (C) 2006, 2007 Andrew Ziem
12
 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
13
 * Copyright (C) 2004 Marc Maurer (uwog@uwog.net)
14
 * Copyright (C) 2003-2005 William Lachance (william.lachance@sympatico.ca)
15
 *
16
 * For minor contributions see the git repository.
17
 *
18
 * Alternatively, the contents of this file may be used under the terms
19
 * of the GNU Lesser General Public License Version 2.1 or later
20
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
21
 * applicable instead of those above.
22
 *
23
 * For further information visit http://libwps.sourceforge.net
24
 */
25
26
#include <string.h>
27
28
#include <iomanip>
29
#include <iostream>
30
31
#include <librevenge/librevenge.h>
32
33
#include "WPSContentListener.h"
34
#include "WPSEntry.h"
35
#include "WPSFont.h"
36
#include "WPSOLEObject.h"
37
#include "WPSOLEParser.h"
38
#include "WPSParagraph.h"
39
#include "WPSPosition.h"
40
#include "WPSStream.h"
41
42
#include "WPS8.h"
43
44
#include "WPS8Graph.h"
45
46
47
/** Internal: the structures of a WPS8Graph */
48
namespace WPS8GraphInternal
49
{
50
/** Internal: a complex border picture
51
 *
52
 * It consists in series of at most 8 pictures which forms the border */
53
struct Border
54
{
55
  //! constructor
56
  Border()
57
0
    : m_name("")
58
0
    , m_pictList()
59
0
    , m_parsed(false)
60
0
  {
61
0
    for (int &i : m_borderSize) i = -1;
62
0
    for (int &i : m_borderId) i = -1;
63
0
  }
64
65
  //! Internal: the border name
66
  std::string m_name;
67
  /** three value to stored the border's sizes
68
   *
69
   * Checkme: corner size, following by horizontal, vertical size in points?
70
   */
71
  int m_borderSize[3];
72
  //! the picture uses to draw TopLeft corner, Top border, TopRight corner, Right border...
73
  int m_borderId[8];
74
  //! the border's pictures: 1 to 8 pictures..
75
  std::vector<WPSEmbeddedObject> m_pictList;
76
  //! flag to know if the border was sent to the listener
77
  bool m_parsed;
78
};
79
80
//! Internal: the state of a WPS8Graph
81
struct State
82
{
83
  State()
84
6.71k
    : m_version(-1)
85
6.71k
    , m_numPages(0)
86
6.71k
    , m_borderMap()
87
6.71k
    , m_ibgfMap()
88
6.71k
    , m_pictMap()
89
6.71k
    , m_oleMap() {}
90
  //! the version
91
  int m_version;
92
  //! the number page
93
  int m_numPages;
94
  //! a map id -> border
95
  std::map<int, Border> m_borderMap;
96
  //! a map id -> ibgf entry (background picture entry)
97
  std::map<int, WPSEntry> m_ibgfMap;
98
  //! a map id -> pictData
99
  std::map<int, WPSEmbeddedObject> m_pictMap;
100
  //! a map id -> OleData
101
  std::map<int, WPSEmbeddedObject> m_oleMap;
102
};
103
}
104
105
////////////////////////////////////////////////////////////
106
// constructor/destructor
107
////////////////////////////////////////////////////////////
108
WPS8Graph::WPS8Graph(WPS8Parser &parser)
109
6.71k
  : m_listener()
110
6.71k
  , m_mainParser(parser)
111
6.71k
  , m_state()
112
6.71k
  , m_asciiFile(parser.ascii())
113
6.71k
{
114
6.71k
  m_state.reset(new WPS8GraphInternal::State);
115
6.71k
}
116
117
WPS8Graph::~WPS8Graph()
118
6.71k
{ }
119
120
////////////////////////////////////////////////////////////
121
// update the positions and send data to the listener
122
////////////////////////////////////////////////////////////
123
int WPS8Graph::version() const
124
0
{
125
0
  if (m_state->m_version <= 0)
126
0
    m_state->m_version = m_mainParser.version();
127
0
  return m_state->m_version;
128
0
}
129
130
int WPS8Graph::numPages() const
131
5.58k
{
132
5.58k
  return m_state->m_numPages;
133
5.58k
}
134
135
////////////////////////////////////////////////////////////
136
// update the positions and send data to the listener
137
////////////////////////////////////////////////////////////
138
void WPS8Graph::computePositions() const
139
5.58k
{
140
5.58k
  m_state->m_numPages = (m_state->m_pictMap.size() || m_state->m_oleMap.size()) ? 1 : 0;
141
5.58k
}
142
143
void WPS8Graph::storeObjects(std::map<int,WPSEmbeddedObject> const &objectsMap)
144
6.71k
{
145
6.71k
  m_state->m_oleMap=objectsMap;
146
6.71k
}
147
148
////////////////////////////////////////////////////////////
149
// find all structures which correspond to the picture
150
////////////////////////////////////////////////////////////
151
bool WPS8Graph::readStructures(RVNGInputStreamPtr const &input)
152
5.58k
{
153
5.58k
  auto const &nameTable = m_mainParser.getNameEntryMap();
154
155
  // contains a text and 8 borders cells?
156
5.58k
  auto pos = nameTable.lower_bound("BDR ");
157
262k
  while (nameTable.end() != pos)
158
262k
  {
159
262k
    WPSEntry const &entry = pos++->second;
160
262k
    if (!entry.hasName("BDR ")) break;
161
256k
    if (!entry.hasType("WBDR")) continue;
162
0
    readBDR(input, entry);
163
0
  }
164
165
  // read IBGF zone : picture type (image background f...? )
166
5.58k
  pos = nameTable.lower_bound("IBGF");
167
172k
  while (pos != nameTable.end())
168
172k
  {
169
172k
    WPSEntry const &entry = pos++->second;
170
172k
    if (!entry.hasName("IBGF")) break;
171
167k
    if (!entry.hasType("IBGF")) continue;
172
173
87.5k
    readIBGF(input, entry);
174
87.5k
  }
175
176
5.58k
  pos = nameTable.lower_bound("PICT");
177
135k
  while (pos != nameTable.end())
178
135k
  {
179
135k
    WPSEntry const &entry = pos++->second;
180
135k
    if (!entry.hasName("PICT")) break;
181
182
129k
    readPICT(input, entry);
183
129k
  }
184
185
5.58k
  return true;
186
5.58k
}
187
188
////////////////////////////////////////////////////////////
189
// different function to send data to a listener
190
////////////////////////////////////////////////////////////
191
bool WPS8Graph::sendObject(WPSPosition const &posi, int id, bool ole)
192
10.9k
{
193
10.9k
  if (m_listener.get() == nullptr)
194
0
  {
195
0
    WPS_DEBUG_MSG(("WPS8Graph::sendObject: listener is not set\n"));
196
0
    return false;
197
0
  }
198
10.9k
  auto &map = ole ? m_state->m_oleMap : m_state->m_pictMap;
199
200
10.9k
  auto pos = map.find(id);
201
10.9k
  if (pos == map.end())
202
10.7k
  {
203
10.7k
    WPS_DEBUG_MSG(("WPS8Graph::sendObject: can not find %dth object\n", id));
204
10.7k
    return false;
205
10.7k
  }
206
113
  auto &pict = pos->second;
207
113
  pict.m_sent = true;
208
209
113
  Vec2f size(posi.size()), naturalSize;
210
113
  if (size.x() <= 0 || size.y()<=0)
211
3
  {
212
3
    size=pict.m_size;
213
3
    if (size.x() <= 0 || size.y()<=0)
214
3
    {
215
3
      WPS_DEBUG_MSG(("WPS8Graph::sendObject: can not find object size\n"));
216
3
      size=Vec2f(0.5,0.5);
217
3
    }
218
3
  }
219
110
  else if (pict.m_size.x() > 0 && pict.m_size.y() > 0)
220
2
    naturalSize = pict.m_size;
221
113
  WPSPosition finalPos(posi);
222
113
  finalPos.setSize(size);
223
113
  finalPos.setNaturalSize(naturalSize);
224
113
  m_listener->insertObject(finalPos, pict);
225
113
  return true;
226
10.9k
}
227
228
bool WPS8Graph::sendIBGF(WPSPosition const &posi, int ibgfId)
229
0
{
230
0
  auto pos = m_state->m_ibgfMap.find(ibgfId);
231
0
  if (pos == m_state->m_ibgfMap.end())
232
0
  {
233
0
    WPS_DEBUG_MSG(("WPS8Graph::sendIBGF: can not find background\n"));
234
0
    return false;
235
0
  }
236
237
0
  WPSEntry const &ent = pos->second;
238
0
  if (!ent.hasName("PICT"))
239
0
  {
240
0
    WPS_DEBUG_MSG(("WPS8Graph::sendIBGF: unknown ibgf type\n"));
241
0
    return false;
242
0
  }
243
0
  return sendObject(posi, ent.id(), false);
244
0
}
245
246
void WPS8Graph::sendObjects(int page, int)
247
16.8k
{
248
16.8k
  if (page != -1) return;
249
0
  if (m_listener.get() == nullptr)
250
0
  {
251
0
    WPS_DEBUG_MSG(("WPS8Graph::sendObjects: listener is not set\n"));
252
0
    return;
253
0
  }
254
255
#ifdef DEBUG
256
  bool firstSend = false;
257
#endif
258
0
  for (int st = 0; st < 2; st++)
259
0
  {
260
0
    auto &map = (st == 0) ? m_state->m_pictMap : m_state->m_oleMap;
261
0
    auto pos = map.begin();
262
263
0
    while (pos != map.end())
264
0
    {
265
0
      auto &pict = pos++->second;
266
0
      if (pict.m_sent) continue;
267
268
#ifdef DEBUG
269
      if (!firstSend)
270
      {
271
        firstSend = true;
272
        WPS_DEBUG_MSG(("WPS8Graph::sendObjects: find some extra pictures\n"));
273
        m_listener->setFont(WPSFont::getDefault());
274
        m_listener->setParagraph(WPSParagraph());
275
        m_listener->insertEOL();
276
        librevenge::RVNGString message = "--------- The original document has some extra pictures: -------- ";
277
        m_listener->insertUnicodeString(message);
278
        m_listener->insertEOL();
279
      }
280
#endif
281
282
0
      pict.m_sent = true;
283
0
      Vec2f size=pict.m_size;
284
      // if we do not have the size of the data, we insert small picture
285
0
      if (size.x() <= 0 || size.y() <= 0) size.set(1.0, 1.0);
286
0
      WPSPosition position(Vec2f(),size);
287
0
      position.setNaturalSize(pict.m_size);
288
0
      position.setRelativePosition(WPSPosition::CharBaseLine);
289
0
      position.m_wrapping = WPSPosition::WDynamic;
290
0
      m_listener->insertObject(position, pict);
291
0
    }
292
0
  }
293
294
#ifdef DEBUG
295
  // check the border
296
  for (auto const &pos : m_state->m_borderMap)
297
  {
298
    int id = pos.first;
299
    bool parsed = pos.second.m_parsed;
300
    if (parsed) continue;
301
    if (!firstSend)
302
    {
303
      firstSend = true;
304
      m_listener->setFont(WPSFont::getDefault());
305
      m_listener->setParagraph(WPSParagraph());
306
      m_listener->insertEOL();
307
      librevenge::RVNGString message;
308
      message = "--------- The original document used some complex border: -------- ";
309
      m_listener->insertUnicodeString(message);
310
      m_listener->insertEOL();
311
    }
312
    sendBorder(id);
313
  }
314
#endif
315
0
}
316
317
void WPS8Graph::sendBorder(int borderId)
318
0
{
319
0
  if (!m_listener || m_state->m_borderMap.find(borderId) == m_state->m_borderMap.end()) return;
320
321
0
  auto &border = m_state->m_borderMap[borderId];
322
0
  if (border.m_parsed) return;
323
324
0
  border.m_parsed = true;
325
326
0
  m_listener->setFont(WPSFont::getDefault());
327
0
  m_listener->setParagraph(WPSParagraph());
328
0
  librevenge::RVNGString message("-------");
329
0
  message.append(border.m_name.c_str());
330
0
  message.append("---------");
331
0
  m_listener->insertUnicodeString(message);
332
333
0
  WPSPosition pos(Vec2f(),Vec2f(0.5,0.5));
334
0
  pos.setRelativePosition(WPSPosition::CharBaseLine);
335
0
  pos.m_wrapping = WPSPosition::WDynamic;
336
0
  for (int i = 0; i < 8; i++)
337
0
  {
338
0
    if (i == 0 || i == 3 || i == 5) m_listener->insertEOL();
339
0
    static int const wh[8] = {0, 1, 2, 7, 3, 6, 5, 4 };
340
0
    auto id = size_t(border.m_borderId[wh[i]]);
341
0
    if (border.m_pictList[id].m_size.x() > 0 &&
342
0
            border.m_pictList[id].m_size.y() > 0)
343
0
      pos.setSize(border.m_pictList[id].m_size);
344
0
    m_listener->insertObject(pos, border.m_pictList[id]);
345
0
    if (i == 3)
346
0
    {
347
0
      message = librevenge::RVNGString("-----");
348
0
      m_listener->insertUnicodeString(message);
349
0
    }
350
0
  }
351
0
}
352
353
////////////////////////////////////////////////////////////
354
//
355
//  low level
356
//
357
////////////////////////////////////////////////////////////
358
359
// Read a PICT/MEF4 entry :  read uncompressed picture of sx*sy of rgb
360
bool WPS8Graph::readPICT(RVNGInputStreamPtr const &input, WPSEntry const &entry)
361
129k
{
362
129k
  long page_offset = entry.begin();
363
129k
  long length = entry.length();
364
129k
  long endPos = entry.end();
365
366
129k
  WPSEmbeddedObject pict;
367
368
  // too small, we return 0
369
129k
  if (length < 24) return false;
370
371
48.0k
  if (!entry.hasType("MEF4"))
372
48.0k
  {
373
48.0k
    WPS_DEBUG_MSG(("WPS8Graph::readPICT: warning: PICT name=%s, type=%s\n",
374
48.0k
                   entry.name().c_str(), entry.type().c_str()));
375
48.0k
    return false;
376
48.0k
  }
377
378
0
  input->seek(page_offset, librevenge::RVNG_SEEK_SET);
379
0
  std::string name;
380
0
  for (int i = 0; i < 4; i++) name += char(libwps::readU8(input));
381
0
  if (strncmp("MEF4", name.c_str(), 4))
382
0
  {
383
0
    WPS_DEBUG_MSG(("WPS8Graph::readPICT: warning: PICT unknown header=%s\n",
384
0
                   name.c_str()));
385
0
    return false;
386
0
  }
387
388
0
  libwps::DebugStream f;
389
0
  f << "Header:";
390
  // unkn0, unkn1 : always 0 ?
391
0
  for (int i = 0; i < 2; i++)
392
0
  {
393
0
    auto val = long(libwps::readU32(input)); // is one the number of meta file ?
394
0
    if (val) f << "unknA" << i << "=" << std::hex << val << std::dec << ",";
395
0
  }
396
0
  pict.m_size.setX(float(libwps::readU32(input))/914400.f);
397
0
  pict.m_size.setY(float(libwps::readU32(input))/914400.f);
398
0
  f << "pSz(inches)=" << pict.m_size << ",";
399
400
0
  ascii().addPos(page_offset);
401
0
  ascii().addNote(f.str().c_str());
402
0
  entry.setParsed();
403
404
0
  auto stream=std::make_shared<WPSStream>(input, ascii());
405
0
  bool ok=WPSOLEObject::readWMF(stream, pict, endPos); // we may also want to check if this is a emf file
406
0
  if (ok)
407
0
  {
408
0
    if (m_state->m_pictMap.find(entry.id()) != m_state->m_pictMap.end())
409
0
      WPS_DEBUG_MSG(("WPS8Graph::readPICT: Pict entry %d already exists\n",  entry.id()));
410
0
    else
411
0
      m_state->m_pictMap[entry.id()] = pict;
412
0
  }
413
0
  else
414
0
    input->seek(page_offset+24, librevenge::RVNG_SEEK_SET);
415
416
0
  if (input->tell() != endPos)
417
0
  {
418
0
    ascii().addPos(input->tell());
419
0
    ascii().addNote("PICT###");
420
0
  }
421
422
423
0
  return ok;
424
0
}
425
426
427
// reads a IBGF zone
428
// Warning: only seems very simple IBGF, complex may differ
429
bool WPS8Graph::readIBGF(RVNGInputStreamPtr const &input, WPSEntry const &entry)
430
87.5k
{
431
87.5k
  libwps::DebugStream f;
432
87.5k
  if (!entry.hasType(entry.name()))
433
0
  {
434
0
    WPS_DEBUG_MSG(("WPS8Graph::readIBGF: warning: IBGF name=%s, type=%s\n",
435
0
                   entry.name().c_str(), entry.type().c_str()));
436
0
    return false;
437
0
  }
438
439
87.5k
  long page_offset = entry.begin();
440
87.5k
  long length = entry.length();
441
442
87.5k
  if (length != 26)
443
47.9k
  {
444
47.9k
    WPS_DEBUG_MSG(("WPS8Graph::readIBGF: IBGF length=0x%lx\n", static_cast<unsigned long>(length)));
445
47.9k
    return false;
446
47.9k
  }
447
448
39.5k
  entry.setParsed();
449
39.5k
  input->seek(page_offset, librevenge::RVNG_SEEK_SET);
450
39.5k
  std::string name;
451
120k
  for (int i = 0; i < 4; i++)
452
111k
  {
453
111k
    auto val = char(libwps::readU8(input));
454
111k
    if (val >= '0' && val <= 'z')
455
81.2k
    {
456
81.2k
      name+=val;
457
81.2k
      continue;
458
81.2k
    }
459
30.6k
    WPS_DEBUG_MSG(("WPS8Graph::readIBGF: invalid name %s\n", name.c_str()));
460
30.6k
    return false;
461
111k
  }
462
463
8.97k
  auto id = int(libwps::read16(input));
464
465
8.97k
  WPSEntry res;
466
8.97k
  res.setName(name);
467
8.97k
  res.setId(id);
468
469
  // name = PICT ?
470
8.97k
  f << "indexEntry='" << name << "':" << id;
471
472
98.6k
  for (int i = 0; i < 10; i++)
473
89.7k
  {
474
89.7k
    auto val = libwps::read16(input);
475
89.7k
    if (val) f << ", f"<<i <<"=" << val;
476
89.7k
  }
477
478
8.97k
  ascii().addPos(page_offset);
479
8.97k
  ascii().addNote(f.str().c_str());
480
481
8.97k
  if (m_state->m_ibgfMap.find(entry.id()) != m_state->m_ibgfMap.end())
482
8.95k
    WPS_DEBUG_MSG(("WPS8Graph::readIBGF: warning: IBGF entry %d already exists\n",
483
8.95k
                   entry.id()));
484
16
  else
485
16
    m_state->m_ibgfMap[entry.id()] = res;
486
487
8.97k
  return true;
488
39.5k
}
489
490
// BDR/WBDR Code : read a BDR Code
491
bool WPS8Graph::readBDR(RVNGInputStreamPtr const &input, WPSEntry const &entry)
492
0
{
493
0
  long page_offset = entry.begin();
494
0
  long length = entry.length();
495
0
  long endPos = entry.end();
496
497
  // too small, we return 0
498
0
  if (length < 20)
499
0
  {
500
0
    WPS_DEBUG_MSG(("WPS8Graph::readBDR: length=%ld is too short\n", length));
501
0
    return false;
502
0
  }
503
504
0
  if (!entry.hasType("WBDR"))
505
0
  {
506
0
    WPS_DEBUG_MSG(("WPS8Graph::readBDR: warning: BDR name=%s, type=%s\n",
507
0
                   entry.name().c_str(), entry.type().c_str()));
508
0
    return false;
509
0
  }
510
511
0
  entry.setParsed();
512
0
  input->seek(page_offset, librevenge::RVNG_SEEK_SET);
513
514
0
  WPS8GraphInternal::Border border;
515
0
  border.m_name = entry.extra();
516
0
  libwps::DebugStream f;
517
0
  if (!border.m_name.empty()) f << "Header:borderName='"<<border.m_name << "',";
518
519
  // 1, unk? = ~ 1/20*following size ?
520
0
  for (int i = 0; i < 2; i++) f << libwps::read16(input) << ",";
521
  // 3*size (corner size, following by x/y steps) in points?
522
0
  f << "sizes=(";
523
0
  for (int &i : border.m_borderSize)
524
0
  {
525
0
    i = libwps::read16(input);
526
0
    f << i << ",";
527
0
  }
528
0
  f << "),";
529
530
0
  bool ok = true;
531
  // ids of picture which corresponds to the frame borders:
532
  // TL, T, TR, R, BR, B, BL, L ?
533
0
  f << "id=(";
534
0
  for (int &i : border.m_borderId)
535
0
  {
536
0
    auto id = int(libwps::read8(input));
537
0
    if (id < 0 || id> 8)
538
0
    {
539
0
      ok = false;
540
0
      break;
541
0
    }
542
0
    i = id;
543
0
    f << id << ",";
544
0
  }
545
0
  f << "),";
546
0
  auto N = int(libwps::read8(input));
547
0
  f << "Nbdr="<<N << ",";
548
0
  auto unkn = int(libwps::read8(input));
549
0
  if (unkn) f << "###unkn=" << unkn << ",";
550
551
0
  if (!ok || N < 0 || N > 8 || 20+N*4 > length)
552
0
  {
553
0
    WPS_DEBUG_MSG(("WPS8Graph::readBDR: can not read the pictures\n"));
554
0
    f << "###";
555
0
    ascii().addPos(page_offset);
556
0
    ascii().addNote(f.str().c_str());
557
0
    return false;
558
0
  }
559
560
0
  long debPos = page_offset+4*N+20;
561
0
  f << "ptr(" << std::hex;
562
563
0
  std::vector<long> listPtrs;
564
0
  listPtrs.push_back(debPos);
565
566
0
  for (int i = 0; i < N; i++)
567
0
  {
568
0
    f << debPos << ",";
569
0
    auto sz = long(libwps::readU32(input));
570
0
    debPos += sz;
571
0
    if (sz < 0 || debPos > endPos)
572
0
    {
573
0
      ok = false;
574
0
      break;
575
0
    }
576
0
    listPtrs.push_back(debPos);
577
0
  }
578
0
  f << debPos << ")," << std::dec;
579
580
0
  ascii().addPos(page_offset);
581
0
  ascii().addNote(f.str().c_str());
582
0
  if (!ok) return false;
583
584
0
  if (listPtrs[size_t(N)] != endPos)
585
0
  {
586
0
    ascii().addPos(listPtrs[size_t(N)]);
587
0
    ascii().addNote("###BDR");
588
0
  }
589
590
0
  auto stream=std::make_shared<WPSStream>(input, ascii());
591
0
  for (size_t bd = 0; bd < size_t(N); bd++)
592
0
  {
593
0
    long debP = listPtrs[bd];
594
0
    long endP = listPtrs[bd+1];
595
596
0
    input->seek(debP, librevenge::RVNG_SEEK_SET);
597
0
    f.str("");
598
0
    f << "BDR(" << bd << "):";
599
600
0
    if (debP+12 > endP || libwps::readU32(input) != 0x4154454d)   // META
601
0
    {
602
0
      WPS_DEBUG_MSG(("WPS8Graph::readBDR: unknown type can not read the picture %d\n", int(bd)));
603
0
      f << "###";
604
0
      ascii().addPos(debP);
605
0
      ascii().addNote(f.str().c_str());
606
0
      ok = false;
607
0
      continue;
608
0
    }
609
610
0
    WPSEmbeddedObject pict;
611
0
    int dim[4];
612
0
    for (int &i : dim)
613
0
    {
614
0
      i = int(libwps::read16(input));
615
0
      f << i << ",";
616
0
    }
617
    // final picture size
618
0
    pict.m_size.set(float(dim[2]-dim[0])/1440.f, float(dim[3]-dim[1])/1440.f);
619
0
    bool correct=WPSOLEObject::readWMF(stream, pict, endP);
620
0
    if (!correct) f << "###";
621
0
    ascii().addPos(debP);
622
0
    ascii().addNote(f.str().c_str());
623
624
0
    if (!correct)
625
0
    {
626
0
      ok = false;
627
0
      continue;
628
0
    }
629
630
0
    if (ok) border.m_pictList.push_back(pict);
631
0
  }
632
633
0
  if (!ok) return false;
634
0
  m_state->m_borderMap[entry.id()] = border;
635
0
  return true;
636
0
}
637
638
/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */