Coverage Report

Created: 2026-10-28 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libstaroffice/src/lib/StarObjectSmallGraphic.cxx
Line
Count
Source
1
/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2
3
/* libstaroffice
4
* Version: MPL 2.0 / LGPLv2+
5
*
6
* The contents of this file are subject to the Mozilla Public License Version
7
* 2.0 (the "License"); you may not use this file except in compliance with
8
* the License or as specified alternatively below. You may obtain a copy of
9
* the License at http://www.mozilla.org/MPL/
10
*
11
* Software distributed under the License is distributed on an "AS IS" basis,
12
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
* for the specific language governing rights and limitations under the
14
* License.
15
*
16
* Major Contributor(s):
17
* Copyright (C) 2002 William Lachance (wrlach@gmail.com)
18
* Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
19
* Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
20
* Copyright (C) 2006, 2007 Andrew Ziem
21
* Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
22
*
23
*
24
* All Rights Reserved.
25
*
26
* For minor contributions see the git repository.
27
*
28
* Alternatively, the contents of this file may be used under the terms of
29
* the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
30
* in which case the provisions of the LGPLv2+ are applicable
31
* instead of those above.
32
*/
33
34
#include <cstring>
35
#include <iomanip>
36
#include <iostream>
37
#include <limits>
38
#include <memory>
39
#include <sstream>
40
41
#include <librevenge/librevenge.h>
42
43
#include "STOFFGraphicShape.hxx"
44
#include "STOFFGraphicStyle.hxx"
45
#include "STOFFListener.hxx"
46
#include "STOFFSubDocument.hxx"
47
#include "STOFFTextListener.hxx"
48
49
#include "StarAttribute.hxx"
50
#include "StarBitmap.hxx"
51
#include "StarFileManager.hxx"
52
#include "StarGraphicStruct.hxx"
53
#include "StarObject.hxx"
54
#include "StarObjectChart.hxx"
55
#include "StarObjectMath.hxx"
56
#include "StarObjectSmallText.hxx"
57
#include "StarObjectText.hxx"
58
#include "StarItemPool.hxx"
59
#include "StarState.hxx"
60
#include "StarZone.hxx"
61
62
#include "StarObjectSmallGraphic.hxx"
63
64
/** Internal: the structures of a StarObjectSmallGraphic */
65
namespace StarObjectSmallGraphicInternal
66
{
67
////////////////////////////////////////
68
//! Internal: virtual class to store a glue point
69
class GluePoint
70
{
71
public:
72
  //! constructor
73
  GluePoint(int x=0, int y=0)
74
3.34k
    : m_dimension(x, y)
75
3.34k
    , m_direction(0)
76
3.34k
    , m_id(0)
77
3.34k
    , m_align(0)
78
3.34k
    , m_percent(false)
79
3.34k
  {
80
3.34k
  }
81
  //! operator<<
82
  friend std::ostream &operator<<(std::ostream &o, GluePoint const &pt)
83
0
  {
84
0
    o << "dim=" << pt.m_dimension << ",";
85
0
    if (pt.m_direction) o << "escDir=" << pt.m_direction << ",";
86
0
    if (pt.m_id) o << "id=" << pt.m_id << ",";
87
0
    if (pt.m_align) o << "align=" << pt.m_align << ",";
88
0
    if (pt.m_percent) o << "percent,";
89
0
    return o;
90
0
  }
91
  //! the dimension
92
  STOFFVec2i m_dimension;
93
  //! the esc direction
94
  int m_direction;
95
  //! the id
96
  int m_id;
97
  //! the alignment
98
  int m_align;
99
  //! a flag to know if this is percent
100
  bool m_percent;
101
};
102
////////////////////////////////////////
103
//! Internal: virtual class to store a outliner paragraph object
104
class OutlinerParaObject
105
{
106
public:
107
  //! small struct use to define a Zone: v<=3
108
  struct Zone {
109
    //! constructor
110
    Zone()
111
538
      : m_text()
112
538
      , m_depth(0)
113
538
      , m_backgroundColor(STOFFColor::white())
114
538
      , m_background()
115
538
      , m_colorName("")
116
538
    {
117
538
    }
118
    //! operator<<
119
    friend std::ostream &operator<<(std::ostream &o, Zone const &zone)
120
0
    {
121
0
      if (!zone.m_text) o << "noText,";
122
0
      if (zone.m_depth) o << "depth=" << zone.m_depth << ",";
123
0
      if (!zone.m_backgroundColor.isWhite()) o << "color=" << zone.m_backgroundColor << ",";
124
0
      if (!zone.m_background.isEmpty()) o << "hasBitmap,";
125
0
      if (!zone.m_colorName.empty()) o << "color[name]=" << zone.m_colorName.cstr() << ",";
126
0
      return o;
127
0
    }
128
    //! the text
129
    std::shared_ptr<StarObjectSmallText> m_text;
130
    //! the depth
131
    int m_depth;
132
    //! the background color
133
    STOFFColor m_backgroundColor;
134
    //! the background bitmap
135
    STOFFEmbeddedObject m_background;
136
    //! the color name
137
    librevenge::RVNGString m_colorName;
138
  };
139
  //! constructor
140
  OutlinerParaObject()
141
68.3k
    : m_version(0)
142
68.3k
    , m_zones()
143
68.3k
    , m_textZone()
144
68.3k
    , m_depthList()
145
68.3k
    , m_isEditDoc(false)
146
68.3k
  {
147
68.3k
  }
148
  //! operator<<
149
  friend std::ostream &operator<<(std::ostream &o, OutlinerParaObject const &obj)
150
0
  {
151
0
    o << "version=" << obj.m_version << ",";
152
0
    if (!obj.m_zones.empty()) {
153
0
      o << "zones=[";
154
0
      for (auto const &z : obj.m_zones)
155
0
        o << "[" << z << "],";
156
0
      o << "],";
157
0
    }
158
0
    if (obj.m_textZone) o << "hasTextZone,";
159
0
    if (!obj.m_depthList.empty()) {
160
0
      o << "depth=[";
161
0
      for (auto d : obj.m_depthList)
162
0
        o << d << ",";
163
0
      o << "],";
164
0
    }
165
0
    if (obj.m_isEditDoc) o << "isEditDoc,";
166
0
    return o;
167
0
  }
168
  //! try to send the text to the listener
169
  bool send(STOFFListenerPtr &listener)
170
14.8k
  {
171
14.8k
    if (!listener) {
172
0
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::OutlinerParaObject::send: no listener\n"));
173
0
      return false;
174
0
    }
175
14.8k
    if (m_textZone)
176
14.5k
      m_textZone->send(listener);
177
307
    else {
178
307
      bool first=true;
179
307
      for (auto const &z : m_zones) {
180
104
        if (first)
181
104
          first=false;
182
0
        else
183
0
          listener->insertEOL();
184
104
        if (z.m_text)
185
104
          z.m_text->send(listener, z.m_depth);
186
104
      }
187
307
    }
188
14.8k
    return true;
189
14.8k
  }
190
  //! the version
191
  int m_version;
192
  //! the list of zones: version<=3
193
  std::vector<Zone> m_zones;
194
  //! list of text zone: version==4
195
  std::shared_ptr<StarObjectSmallText> m_textZone;
196
  //! list of depth data
197
  std::vector<int> m_depthList;
198
  //! true if the object is a edit document
199
  bool m_isEditDoc;
200
};
201
202
////////////////////////////////////////
203
//! Internal: the subdocument of a StarObjectSmallGraphic
204
class SubDocument final : public STOFFSubDocument
205
{
206
public:
207
  explicit SubDocument(std::shared_ptr<OutlinerParaObject> &text)
208
17.8k
    : STOFFSubDocument(nullptr, STOFFInputStreamPtr(), STOFFEntry())
209
17.8k
    , m_text(text) {}
210
211
  //! destructor
212
17.8k
  ~SubDocument() final {}
213
214
  //! operator!=
215
  bool operator!=(STOFFSubDocument const &doc) const final
216
0
  {
217
0
    if (STOFFSubDocument::operator!=(doc)) return true;
218
0
    auto const *sDoc = dynamic_cast<SubDocument const *>(&doc);
219
0
    if (!sDoc) return true;
220
0
    if (m_text.get() != sDoc->m_text.get()) return true;
221
0
    return false;
222
0
  }
223
224
  //! the parser function
225
  void parse(STOFFListenerPtr &listener, libstoff::SubDocumentType type) final;
226
227
protected:
228
  //! the text
229
  std::shared_ptr<OutlinerParaObject> m_text;
230
};
231
232
void SubDocument::parse(STOFFListenerPtr &listener, libstoff::SubDocumentType /*type*/)
233
17.8k
{
234
17.8k
  if (!listener.get()) {
235
0
    STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SubDocument::parse: no listener\n"));
236
0
    return;
237
0
  }
238
17.8k
  if (!m_text)
239
3.03k
    listener->insertChar(' ');
240
14.8k
  else
241
14.8k
    m_text->send(listener);
242
17.8k
}
243
244
/////////////////////////////////////////////////////////////
245
246
////////////////////////////////////////
247
//! Internal: virtual class to store a graphic
248
class Graphic
249
{
250
public:
251
  //! constructor
252
  explicit Graphic(int id)
253
338k
    : m_identifier(id)
254
338k
  {
255
338k
  }
256
  //! destructor
257
  virtual ~Graphic();
258
  //! basic print function
259
  virtual std::string print() const
260
0
  {
261
0
    return getName();
262
0
  }
263
  //! return the object name
264
  virtual std::string getName() const = 0;
265
  //! try to send the graphic to the listener
266
  virtual bool send(STOFFListenerPtr &/*listener*/, STOFFFrameStyle const &/*pos*/, StarObject &/*object*/, bool /*inMasterPage*/)
267
23.3k
  {
268
23.3k
    static bool first=true;
269
23.3k
    if (first) {
270
4
      first=false;
271
4
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::Graphic::send: not implemented for identifier %d\n", m_identifier));
272
4
    }
273
23.3k
    return false;
274
23.3k
  }
275
  //! the type
276
  int m_identifier;
277
};
278
279
Graphic::~Graphic()
280
338k
{
281
338k
}
282
283
284
////////////////////////////////////////
285
//! Internal: virtual class to store a Sdr graphic
286
class SdrGraphic : public Graphic
287
{
288
public:
289
  //! constructor
290
  explicit SdrGraphic(int id)
291
217k
    : Graphic(id)
292
217k
    , m_bdbox()
293
217k
    , m_layerId(-1)
294
217k
    , m_anchorPosition(0,0)
295
217k
    , m_polygon()
296
217k
    , m_userDataList()
297
217k
  {
298
1.30M
    for (bool &flag : m_flags) flag=false;
299
217k
  }
300
  //! destructor
301
  ~SdrGraphic() override;
302
  //! return the object name
303
  std::string getName() const override
304
0
  {
305
0
    if (m_identifier>0 && m_identifier<=32) {
306
0
      char const *wh[]= {"none", "group", "line", "rect", "circle",
307
0
                         "sector", "arc", "ccut", "poly", "polyline",
308
0
                         "pathline", "pathfill", "freeline", "freefill", "splineline",
309
0
                         "splinefill", "text", "textextended", "fittext", "fitalltext",
310
0
                         "titletext", "outlinetext", "graf", "ole2", "edge",
311
0
                         "caption", "pathpoly", "pathpline", "page", "measure",
312
0
                         "dummy","frame", "uno"
313
0
                        };
314
0
      return wh[m_identifier];
315
0
    }
316
0
    std::stringstream s;
317
0
    s << "###type=" << m_identifier << ",";
318
0
    return s.str();
319
0
  }
320
  //! return a pool corresponding to an object
321
  StarState getState(StarObject &object, STOFFListenerPtr listener, STOFFFrameStyle const &/*pos*/) const
322
111k
  {
323
111k
    auto pool=object.findItemPool(StarItemPool::T_XOutdevPool, false);
324
111k
    StarState state(pool.get(), object);
325
111k
    if (std::dynamic_pointer_cast<STOFFTextListener>(listener))
326
1.59k
      state.m_global->m_offset=state.convertVectorInPoint(STOFFVec2f(-float(m_anchorPosition[0]),-float(m_anchorPosition[1])));
327
111k
    return state;
328
111k
  }
329
  //! try to update the graphic style
330
  void updateStyle(StarState &state, STOFFListenerPtr /*listener*/) const
331
98.2k
  {
332
98.2k
    state.m_frame.addStyleTo(state.m_graphic.m_propertyList);
333
98.2k
    if (m_flags[0] && m_flags[1])
334
36.3k
      state.m_graphic.m_propertyList.insert("style:protect", "position size");
335
61.9k
    else if (m_flags[0])
336
1.23k
      state.m_graphic.m_propertyList.insert("style:protect", "position");
337
60.6k
    else if (m_flags[1])
338
1.11k
      state.m_graphic.m_propertyList.insert("style:protect", "size");
339
98.2k
    state.m_graphic.m_propertyList.insert("style:print-content", !m_flags[2]);
340
    // todo noVisible as master ie hide in master
341
98.2k
  }
342
  //! basic print function
343
  std::string print() const override
344
0
  {
345
0
    std::stringstream s;
346
0
    s << *this << ",";
347
0
    return s.str();
348
0
  }
349
  //! print object data
350
  friend std::ostream &operator<<(std::ostream &o, SdrGraphic const &graph)
351
0
  {
352
0
    o << graph.getName() << ",";
353
0
    o << "bdbox=" << graph.m_bdbox << ",";
354
0
    if (graph.m_layerId>=0) o << "layer[id]=" << graph.m_layerId << ",";
355
0
    if (graph.m_anchorPosition!=STOFFVec2i(0,0)) o << "anchor[pos]=" << graph.m_anchorPosition << ",";
356
0
    for (int i=0; i<6; ++i) {
357
0
      if (!graph.m_flags[i]) continue;
358
0
      char const *wh[]= {"move[protected]", "size[protected]", "print[no]", "mark[protected]", "empty", "notVisibleAsMaster"};
359
0
      o << wh[i] << ",";
360
0
    }
361
0
    if (!graph.m_polygon.empty()) {
362
0
      o << "poly=[";
363
0
      for (const auto &i : graph.m_polygon)
364
0
        o << i << ",";
365
0
      o << "],";
366
0
    }
367
0
    return o;
368
0
  }
369
  //! the bdbox
370
  STOFFBox2i m_bdbox;
371
  //! the layer id
372
  int m_layerId;
373
  //! the anchor position
374
  STOFFVec2i m_anchorPosition;
375
  //! a polygon
376
  std::vector<GluePoint> m_polygon;
377
  //! a list of flag
378
  bool m_flags[6];
379
  //! the user data list
380
  std::vector<std::shared_ptr<StarObjectSmallGraphicInternal::SDRUserData> > m_userDataList;
381
};
382
383
SdrGraphic::~SdrGraphic()
384
217k
{
385
217k
}
386
////////////////////////////////////////
387
//! Internal: virtual class to store a Sdr graphic attribute
388
class SdrGraphicAttribute : public SdrGraphic
389
{
390
public:
391
  //! constructor
392
  explicit SdrGraphicAttribute(int id)
393
145k
    : SdrGraphic(id)
394
145k
    , m_itemList()
395
145k
    , m_sheetStyle("")
396
145k
  {
397
145k
  }
398
  //! destructor
399
  ~SdrGraphicAttribute() override;
400
  //! basic print function
401
  std::string print() const override
402
0
  {
403
0
    std::stringstream s;
404
0
    s << SdrGraphic::print() << *this << ",";
405
0
    return s.str();
406
0
  }
407
  //! try to update the style
408
  void updateStyle(StarState &state, STOFFListenerPtr listener) const
409
98.2k
  {
410
98.2k
    SdrGraphic::updateStyle(state, listener);
411
98.2k
    if (state.m_global->m_pool && !m_sheetStyle.empty()) {
412
30.9k
      auto const *mStyle=state.m_global->m_pool->findStyleWithFamily(m_sheetStyle, StarItemStyle::F_Paragraph);
413
30.9k
      if (mStyle && !mStyle->m_names[0].empty()) {
414
10.9k
        if (listener) state.m_global->m_pool->defineGraphicStyle(listener, mStyle->m_names[0], state.m_global->m_object);
415
10.9k
        state.m_graphic.m_propertyList.insert("librevenge:parent-display-name", mStyle->m_names[0]);
416
10.9k
      }
417
20.0k
      else if (mStyle) {
418
0
        for (auto it : mStyle->m_itemSet.m_whichToItemMap) {
419
0
          if (it.second && it.second->m_attribute)
420
0
            it.second->m_attribute->addTo(state);
421
0
        }
422
0
      }
423
30.9k
    }
424
581k
    for (auto &item : m_itemList) {
425
581k
      if (item && item->m_attribute)
426
369k
        item->m_attribute->addTo(state);
427
581k
    }
428
98.2k
  }
429
  //! print object data
430
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicAttribute const &graph)
431
0
  {
432
0
    o << graph.getName() << ",";
433
0
    for (auto &item : graph.m_itemList) {
434
0
      if (!item || !item->m_attribute) continue;
435
0
      libstoff::DebugStream f;
436
0
      item->m_attribute->printData(f);
437
0
      o << "[" << f.str() << "],";
438
0
    }
439
0
    if (!graph.m_sheetStyle.empty()) o << "sheetStyle[name]=" << graph.m_sheetStyle.cstr() << ",";
440
0
    return o;
441
0
  }
442
  //! the list of star item
443
  std::vector<std::shared_ptr<StarItem> > m_itemList;
444
  //! the sheet style name
445
  librevenge::RVNGString m_sheetStyle;
446
};
447
448
SdrGraphicAttribute::~SdrGraphicAttribute()
449
145k
{
450
145k
}
451
452
////////////////////////////////////////
453
//! Internal: virtual class to store a Sdr graphic group
454
class SdrGraphicGroup final : public SdrGraphic
455
{
456
public:
457
  //! constructor
458
  explicit SdrGraphicGroup(int id)
459
17.1k
    : SdrGraphic(id)
460
17.1k
    , m_groupName()
461
17.1k
    , m_child()
462
17.1k
    , m_refPoint()
463
17.1k
    , m_hasRefPoint(false)
464
17.1k
    , m_groupDrehWink(0)
465
17.1k
    , m_groupShearWink(0)
466
17.1k
  {
467
17.1k
  }
468
  //! destructor
469
  ~SdrGraphicGroup() final;
470
  //! basic print function
471
  std::string print() const final
472
0
  {
473
0
    std::stringstream s;
474
0
    s << SdrGraphic::print() << *this << ",";
475
0
    return s.str();
476
0
  }
477
  //! try to send the graphic to the listener
478
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool inMasterPage) final
479
13.2k
  {
480
13.2k
    if (!listener) {
481
0
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicGroup::send: unexpected listener\n"));
482
0
      return false;
483
0
    }
484
13.2k
    STOFFFrameStyle finalPos(pos);
485
13.2k
    StarState state(getState(object, listener, finalPos));
486
13.2k
    finalPos.m_position.m_offset=state.m_global->m_offset;
487
    //finalPos.m_position.m_offset=true;
488
13.2k
    listener->openGroup(pos);
489
60.5k
    for (auto &child : m_child) {
490
60.5k
      if (child)
491
60.5k
        child->send(listener, finalPos, object, inMasterPage);
492
60.5k
    }
493
13.2k
    listener->closeGroup();
494
13.2k
    return true;
495
13.2k
  }
496
  //! print object data
497
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicGroup const &graph)
498
0
  {
499
0
    o << graph.getName() << ",";
500
0
    if (!graph.m_groupName.empty()) o << graph.m_groupName.cstr() << ",";
501
0
    if (!graph.m_child.empty()) o << "num[child]=" << graph.m_child.size() << ",";
502
0
    if (graph.m_hasRefPoint) o << "refPt=" << graph.m_refPoint << ",";
503
0
    if (graph.m_groupDrehWink) o << "drehWink=" << graph.m_groupDrehWink << ",";
504
0
    if (graph.m_groupShearWink) o << "shearWink=" << graph.m_groupShearWink << ",";
505
0
    return o;
506
0
  }
507
  //! the group name
508
  librevenge::RVNGString m_groupName;
509
  //! the child
510
  std::vector<std::shared_ptr<StarObjectSmallGraphic> > m_child;
511
  //! the ref point
512
  STOFFVec2i m_refPoint;
513
  //! flag to know if we use the ref point
514
  bool m_hasRefPoint;
515
  //! the dreh wink: rotation?
516
  int m_groupDrehWink;
517
  //! the shear wink
518
  int m_groupShearWink;
519
};
520
521
SdrGraphicGroup::~SdrGraphicGroup()
522
17.1k
{
523
17.1k
}
524
525
////////////////////////////////////////
526
//! Internal: virtual class to store a Sdr graphic text
527
class SdrGraphicText : public SdrGraphicAttribute
528
{
529
public:
530
  //! constructor
531
  explicit SdrGraphicText(int id)
532
145k
    : SdrGraphicAttribute(id)
533
145k
    , m_textKind(0)
534
145k
    , m_textRectangle()
535
145k
    , m_textDrehWink(0)
536
145k
    , m_textShearWink(0)
537
145k
    , m_outlinerParaObject()
538
145k
    , m_textBound()
539
145k
  {
540
145k
  }
541
  //! destructor
542
  ~SdrGraphicText() override;
543
  //! try to update the transformation
544
  void updateTransformProperties(librevenge::RVNGPropertyList &list, double relUnit) const
545
69.7k
  {
546
69.7k
    if (m_textDrehWink) {
547
      // rotation around the first point, let do that by hand
548
16.9k
      librevenge::RVNGString transform;
549
16.9k
      if (m_textRectangle[0]==STOFFVec2i(0,0))
550
12.0k
        transform.sprintf("rotate(%f)", m_textDrehWink/100.*M_PI/180.);
551
4.91k
      else {
552
4.91k
        STOFFVec2f center=STOFFVec2f(m_textRectangle[0]);
553
4.91k
        transform.sprintf("translate(%fpt %fpt) rotate(%f) translate(%fpt %fpt)",
554
4.91k
                          -relUnit*center[0],-relUnit*center[1],
555
4.91k
                          m_textDrehWink/100.*M_PI/180., // gradient
556
4.91k
                          relUnit*center[0],relUnit*center[1]);
557
4.91k
      }
558
16.9k
      list.insert("draw:transform", transform);
559
16.9k
    }
560
69.7k
  }
561
  //! basic print function
562
  std::string print() const override
563
0
  {
564
0
    std::stringstream s;
565
0
    s << SdrGraphicAttribute::print() << *this << ",";
566
0
    return s.str();
567
0
  }
568
  //! try to send the text zone to the listener
569
  bool sendTextZone(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object)
570
18.0k
  {
571
    // for basic text zone, we use the real textbox, for other zones (text link to a shape) we use the shape box
572
18.0k
    STOFFBox2f const &box=(m_identifier!=3 && m_identifier!=16 && m_identifier!=17 && m_identifier!=20 && m_identifier!=21) ? m_bdbox : m_textRectangle;
573
18.0k
    if (!listener || box.size()[0]<=0 || box.size()[1]<=0) {
574
141
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicText::sendTextZone: can not send a shape\n"));
575
141
      return false;
576
141
    }
577
17.8k
    StarState state(getState(object, listener, pos));
578
17.8k
    STOFFFrameStyle frame=pos;
579
17.8k
    STOFFPosition &position=frame.m_position;
580
17.8k
    position.setOrigin(state.convertPointInPoint(box[0]));
581
17.8k
    position.setSize(state.convertVectorInPoint(box.size()));
582
17.8k
    if (position.m_anchorTo==STOFFPosition::Unknown)
583
20
      position.setAnchor(STOFFPosition::Page);
584
17.8k
    updateStyle(state, listener);
585
    // if (!state.m_graphic.m_hasBackground) state.m_graphic.m_propertyList.insert("draw:fill", "none"); checkme
586
17.8k
    state.m_graphic.m_propertyList.insert("draw:fill", "none");
587
17.8k
    state.m_graphic.m_propertyList.insert("draw:shadow", "hidden"); // the text is not shadowed
588
17.8k
    if (m_textDrehWink) {
589
      // checkme: this can not work for a text listener. We must create a rectangle with text instead
590
3.85k
      STOFFVec2f const &orig=position.m_origin;
591
3.85k
      state.m_graphic.m_propertyList.insert("librevenge:rotate-cx", orig[0], librevenge::RVNG_POINT);
592
3.85k
      state.m_graphic.m_propertyList.insert("librevenge:rotate-cy", orig[1], librevenge::RVNG_POINT);
593
3.85k
      state.m_graphic.m_propertyList.insert("librevenge:rotate", -(m_textDrehWink/100.), librevenge::RVNG_GENERIC);
594
3.85k
    }
595
17.8k
    std::shared_ptr<SubDocument> doc(new SubDocument(m_outlinerParaObject));
596
17.8k
    listener->insertTextBox(frame, doc, state.m_graphic);
597
17.8k
    return true;
598
18.0k
  }
599
  //! print object data
600
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicText const &graph)
601
0
  {
602
0
    o << graph.getName() << ",";
603
0
    o << "textKind=" << graph.m_textKind << ",";
604
0
    o << "rect=" << graph.m_textRectangle << ",";
605
0
    if (graph.m_textDrehWink) o << "drehWink=" << graph.m_textDrehWink << ",";
606
0
    if (graph.m_textShearWink) o << "shearWink=" << graph.m_textShearWink << ",";
607
0
    if (graph.m_outlinerParaObject) o << "outliner=[" << *graph.m_outlinerParaObject << "],";
608
0
    if (graph.m_textBound.size()!=STOFFVec2i(0,0)) o << "bound=" << graph.m_textBound << ",";
609
0
    return o;
610
0
  }
611
  //! the text kind
612
  int m_textKind;
613
  //! the text rectangle
614
  STOFFBox2i m_textRectangle;
615
  //! the dreh wink: rotation?
616
  int m_textDrehWink;
617
  //! the shear wink
618
  int m_textShearWink;
619
  //! the outliner object
620
  std::shared_ptr<OutlinerParaObject> m_outlinerParaObject;
621
  //! the text bound
622
  STOFFBox2i m_textBound;
623
};
624
625
SdrGraphicText::~SdrGraphicText()
626
145k
{
627
145k
}
628
629
////////////////////////////////////////
630
//! Internal: virtual class to store a Sdr graphic rectangle
631
class SdrGraphicRect : public SdrGraphicText
632
{
633
public:
634
  //! constructor
635
  explicit SdrGraphicRect(int id)
636
96.5k
    : SdrGraphicText(id)
637
96.5k
    , m_eckRag(0)
638
96.5k
  {
639
96.5k
  }
640
  //! destructor
641
  ~SdrGraphicRect() override;
642
  //! try to send the graphic to the listener
643
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool inMasterPage) override
644
52.4k
  {
645
52.4k
    if (!listener || m_textRectangle.size()[0]<=0 || m_textRectangle.size()[1]<=0) {
646
2.62k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicText::send: can not send a shape\n"));
647
2.62k
      return false;
648
2.62k
    }
649
49.8k
    if (inMasterPage && (m_identifier==20 || m_identifier==21))
650
2.23k
      return false;
651
47.6k
    if (m_identifier!=16 && m_identifier!=17 && m_identifier!=20 && m_identifier!=21) { // basic rect
652
34.2k
      StarState state(getState(object, listener, pos));
653
34.2k
      STOFFGraphicShape shape;
654
34.2k
      shape.m_command=STOFFGraphicShape::C_Rectangle;
655
34.2k
      shape.m_bdbox=STOFFBox2f(state.convertPointInPoint(m_textRectangle[0]), state.convertPointInPoint(m_textRectangle[1]));
656
34.2k
      updateTransformProperties(shape.m_propertyList, state.m_global->m_relativeUnit);
657
34.2k
      updateStyle(state, listener);
658
34.2k
      listener->insertShape(pos, shape, state.m_graphic);
659
34.2k
      if (m_outlinerParaObject)
660
3.75k
        sendTextZone(listener, pos, object);
661
34.2k
    }
662
13.3k
    else
663
13.3k
      sendTextZone(listener, pos, object);
664
47.6k
    return true;
665
49.8k
  }
666
  //! basic print function
667
  std::string print() const override
668
0
  {
669
0
    std::stringstream s;
670
0
    s << SdrGraphicText::print() << *this << ",";
671
0
    return s.str();
672
0
  }
673
  //! print object data
674
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicRect const &graph)
675
0
  {
676
0
    o << graph.getName() << ",";
677
0
    if (graph.m_eckRag) o << "eckRag=" << graph.m_eckRag << ",";
678
0
    return o;
679
0
  }
680
  //! the eckRag?
681
  int m_eckRag;
682
};
683
684
SdrGraphicRect::~SdrGraphicRect()
685
{
686
}
687
688
////////////////////////////////////////
689
//! Internal: virtual class to store a Sdr graphic caption
690
class SdrGraphicCaption final : public SdrGraphicRect
691
{
692
public:
693
  //! constructor
694
706
  SdrGraphicCaption() : SdrGraphicRect(25), m_captionPolygon(), m_captionItem()
695
706
  {
696
706
  }
697
  //! destructor
698
  ~SdrGraphicCaption() final;
699
  //! basic print function
700
  std::string print() const final
701
0
  {
702
0
    std::stringstream s;
703
0
    s << SdrGraphicRect::print() << *this << ",";
704
0
    return s.str();
705
0
  }
706
  //! print object data
707
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicCaption const &graph)
708
0
  {
709
0
    o << graph.getName() << ",";
710
0
    if (!graph.m_captionPolygon.empty()) {
711
0
      o << "poly=[";
712
0
      for (auto const &p : graph.m_captionPolygon)
713
0
        o << p << ",";
714
0
      o << "],";
715
0
    }
716
0
    if (graph.m_captionItem && graph.m_captionItem->m_attribute) {
717
0
      libstoff::DebugStream f;
718
0
      graph.m_captionItem->m_attribute->printData(f);
719
0
      o << "[" << f.str() << "],";
720
0
    }
721
0
    return o;
722
0
  }
723
  //! try to send the graphic to the listener
724
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool /*inMasterPage*/) final
725
81
  {
726
81
    if (!listener || m_captionPolygon.empty()) {
727
51
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicCaption::send: can not send a shape\n"));
728
51
      return false;
729
51
    }
730
30
    StarState state(getState(object, listener, pos));
731
    // checkme never seen
732
30
    STOFFGraphicShape shape;
733
30
    shape.m_command=STOFFGraphicShape::C_Polyline;
734
30
    StarGraphicStruct::StarPolygon polygon;
735
30
    for (auto const &p : m_captionPolygon)
736
830
      polygon.m_points.push_back(StarGraphicStruct::StarPolygon::Point(p, 0));
737
30
    librevenge::RVNGPropertyListVector path;
738
30
    polygon.addToPath(path, false, state.m_global->m_relativeUnit, state.m_global->m_offset);
739
30
    shape.m_propertyList.insert("svg:d", path);
740
30
    updateTransformProperties(shape.m_propertyList, state.m_global->m_relativeUnit);
741
30
    updateStyle(state, listener);
742
30
    listener->insertShape(pos, shape, state.m_graphic);
743
30
    return true;
744
81
  }
745
  //! a polygon
746
  std::vector<STOFFVec2i> m_captionPolygon;
747
  //! the caption attributes
748
  std::shared_ptr<StarItem> m_captionItem;
749
};
750
751
SdrGraphicCaption::~SdrGraphicCaption()
752
706
{
753
706
}
754
////////////////////////////////////////
755
//! Internal: virtual class to store a Sdr graphic circle
756
class SdrGraphicCircle final : public SdrGraphicRect
757
{
758
public:
759
  //! constructor
760
5.85k
  explicit SdrGraphicCircle(int id) : SdrGraphicRect(id), m_circleItem()
761
5.85k
  {
762
5.85k
    m_angles[0]=m_angles[1]=0;
763
5.85k
  }
764
  //! destructor
765
  ~SdrGraphicCircle() final;
766
  //! basic print function
767
  std::string print() const final
768
0
  {
769
0
    std::stringstream s;
770
0
    s << SdrGraphicRect::print() << *this << ",";
771
0
    return s.str();
772
0
  }
773
  //! try to send the graphic to the listener
774
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool /*inMasterPage*/) final
775
2.81k
  {
776
2.81k
    if (!listener || m_textRectangle.size()[0]<=0 || m_textRectangle.size()[1]<=0) {
777
385
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicCircle::send: can not send a shape\n"));
778
385
      return false;
779
385
    }
780
2.43k
    StarState state(getState(object, listener, pos));
781
782
2.43k
    STOFFGraphicShape shape;
783
2.43k
    shape.m_command=STOFFGraphicShape::C_Ellipse;
784
2.43k
    STOFFVec2f center=state.convertPointInPoint(0.5f*STOFFVec2f(m_textRectangle[0]+m_textRectangle[1]));
785
2.43k
    shape.m_propertyList.insert("svg:cx",20*center.x(), librevenge::RVNG_TWIP);
786
2.43k
    shape.m_propertyList.insert("svg:cy",20*center.y(), librevenge::RVNG_TWIP);
787
2.43k
    STOFFVec2f radius=state.convertVectorInPoint(0.5f*STOFFVec2f(m_textRectangle[1]-m_textRectangle[0]));
788
2.43k
    shape.m_propertyList.insert("svg:rx",20*radius.x(), librevenge::RVNG_TWIP);
789
2.43k
    shape.m_propertyList.insert("svg:ry",20*radius.y(), librevenge::RVNG_TWIP);
790
2.43k
    if (m_identifier!=4) {
791
456
      shape.m_propertyList.insert("draw:start-angle", double(m_angles[0]), librevenge::RVNG_GENERIC);
792
456
      shape.m_propertyList.insert("draw:end-angle", double(m_angles[1]), librevenge::RVNG_GENERIC);
793
456
    }
794
2.43k
    if (m_identifier>=4 && m_identifier<=7) {
795
2.40k
      char const *wh[]= {"full", "section", "arc", "cut"};
796
2.40k
      shape.m_propertyList.insert("draw:kind", wh[m_identifier-4]);
797
2.40k
    }
798
2.43k
    updateTransformProperties(shape.m_propertyList, state.m_global->m_relativeUnit);
799
2.43k
    updateStyle(state, listener);
800
2.43k
    listener->insertShape(pos, shape, state.m_graphic);
801
2.43k
    if (m_outlinerParaObject)
802
973
      sendTextZone(listener, pos, object);
803
2.43k
    return true;
804
2.81k
  }
805
  //! try to update the style
806
  void updateStyle(StarState &state, STOFFListenerPtr listener) const
807
2.40k
  {
808
2.40k
    SdrGraphicRect::updateStyle(state, listener);
809
2.40k
    if (m_circleItem && m_circleItem->m_attribute)
810
106
      m_circleItem->m_attribute->addTo(state);
811
2.40k
  }
812
  //! print object data
813
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicCircle const &graph)
814
0
  {
815
0
    o << graph.getName() << ",";
816
0
    if (graph.m_angles[0]<0||graph.m_angles[0]>0 || graph.m_angles[1]<0||graph.m_angles[1]>0)
817
0
      o << "angles=" << graph.m_angles[0] << "x" << graph.m_angles[1] << ",";
818
0
    if (graph.m_circleItem && graph.m_circleItem->m_attribute) {
819
0
      libstoff::DebugStream f;
820
0
      graph.m_circleItem->m_attribute->printData(f);
821
0
      o << "[" << f.str() << "],";
822
0
    }
823
0
    return o;
824
0
  }
825
  //! the two angles
826
  float m_angles[2];
827
  //! the circle attributes
828
  std::shared_ptr<StarItem> m_circleItem;
829
};
830
831
SdrGraphicCircle::~SdrGraphicCircle()
832
5.85k
{
833
5.85k
}
834
////////////////////////////////////////
835
//! Internal: virtual class to store a Sdr graphic edge
836
class SdrGraphicEdge final : public SdrGraphicText
837
{
838
public:
839
  //! the information record
840
  struct Information {
841
    //! constructor
842
    Information()
843
6.69k
      : m_orthoForm(0)
844
6.69k
    {
845
6.69k
      m_angles[0]=m_angles[1]=0;
846
20.0k
      for (int &i : m_n) i=0;
847
6.69k
    }
848
    //! operator=
849
    friend std::ostream &operator<<(std::ostream &o, Information const &info)
850
0
    {
851
0
      o << "pts=[";
852
0
      for (auto point : info.m_points) o << point << ",";
853
0
      o << "],";
854
0
      o << "angles=" << info.m_angles[0] << "x" << info.m_angles[1] << ",";
855
0
      for (int i=0; i<3; ++i) {
856
0
        if (info.m_n[i]) o << "n" << i << "=" << info.m_n[i] << ",";
857
0
      }
858
0
      if (info.m_orthoForm) o << "orthoForm=" << info.m_orthoForm << ",";
859
0
      return o;
860
0
    }
861
    //! some points: obj1Line2, obj1Line3, obj2Line2, obj2Line3, middleLine
862
    STOFFVec2i m_points[5];
863
    //! two angles
864
    int m_angles[2];
865
    //! some values: nObj1Lines, nObj2Lines, middleLines
866
    int m_n[3];
867
    //! orthogonal form
868
    int m_orthoForm;
869
  };
870
  //! constructor
871
6.69k
  SdrGraphicEdge() : SdrGraphicText(24), m_edgePolygon(), m_edgePolygonFlags(), m_edgeItem(), m_info()
872
6.69k
  {
873
6.69k
  }
874
  //! destructor
875
  ~SdrGraphicEdge() final;
876
  //! basic print function
877
  std::string print() const final
878
0
  {
879
0
    std::stringstream s;
880
0
    s << SdrGraphicText::print() << *this << ",";
881
0
    return s.str();
882
0
  }
883
  //! print object data
884
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicEdge const &graph)
885
0
  {
886
0
    o << graph.getName() << ",";
887
0
    if (!graph.m_edgePolygon.empty()) {
888
0
      if (graph.m_edgePolygon.size()==graph.m_edgePolygonFlags.size()) {
889
0
        o << "poly=[";
890
0
        for (size_t i=0; i<graph.m_edgePolygon.size(); ++i)
891
0
          o << graph.m_edgePolygon[i] << ":" << graph.m_edgePolygonFlags[i] << ",";
892
0
        o << "],";
893
0
      }
894
0
      else {
895
0
        STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicEdge::operator<<: unexpected number of flags\n"));
896
0
        o << "###poly,";
897
0
      }
898
0
    }
899
0
    if (graph.m_edgeItem && graph.m_edgeItem->m_attribute) {
900
0
      libstoff::DebugStream f;
901
0
      graph.m_edgeItem->m_attribute->printData(f);
902
0
      o << "[" << f.str() << "],";
903
0
    }
904
0
    return o;
905
0
  }
906
  //! try to send the graphic to the listener
907
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool /*inMasterPage*/) final
908
4.53k
  {
909
4.53k
    if (!listener || m_edgePolygon.empty()) {
910
278
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicEdge::send: can not send a shape\n"));
911
278
      return false;
912
278
    }
913
4.25k
    StarState state(getState(object, listener, pos));
914
4.25k
    STOFFGraphicShape shape;
915
4.25k
    shape.m_command=STOFFGraphicShape::C_Connector;
916
4.25k
    size_t numFlags=m_edgePolygonFlags.size();
917
4.25k
    StarGraphicStruct::StarPolygon polygon;
918
21.2k
    for (size_t p=0; p<m_edgePolygon.size(); ++p)
919
16.9k
      polygon.m_points.push_back(StarGraphicStruct::StarPolygon::Point(m_edgePolygon[p], p<numFlags ? m_edgePolygonFlags[p] : 0));
920
4.25k
    librevenge::RVNGPropertyListVector path;
921
4.25k
    polygon.addToPath(path, false, state.m_global->m_relativeUnit, state.m_global->m_offset);
922
4.25k
    shape.m_propertyList.insert("svg:d", path);
923
4.25k
    updateTransformProperties(shape.m_propertyList, state.m_global->m_relativeUnit);
924
4.25k
    updateStyle(state, listener);
925
4.25k
    listener->insertShape(pos, shape, state.m_graphic);
926
4.25k
    return true;
927
4.53k
  }
928
  //! the edge polygon
929
  std::vector<STOFFVec2i> m_edgePolygon;
930
  //! the edge polygon flags
931
  std::vector<int> m_edgePolygonFlags;
932
  // TODO: store the connector
933
  //! the edge attributes
934
  std::shared_ptr<StarItem> m_edgeItem;
935
  //! the information record
936
  Information m_info;
937
};
938
939
SdrGraphicEdge::~SdrGraphicEdge()
940
6.69k
{
941
6.69k
}
942
////////////////////////////////////////
943
//! Internal: virtual class to store a Sdr graphic graph
944
class SdrGraphicGraph final : public SdrGraphicRect
945
{
946
public:
947
  //! constructor
948
  SdrGraphicGraph()
949
3.59k
    : SdrGraphicRect(22)
950
3.59k
    , m_graphic()
951
3.59k
    , m_graphRectangle()
952
3.59k
    , m_mirrored(false)
953
3.59k
    , m_hasGraphicLink(false)
954
3.59k
    , m_graphItem()
955
3.59k
  {
956
3.59k
  }
957
  //! destructor
958
  ~SdrGraphicGraph() override;
959
  //! basic print function
960
  std::string print() const final
961
0
  {
962
0
    std::stringstream s;
963
0
    s << SdrGraphicRect::print() << *this << ",";
964
0
    return s.str();
965
0
  }
966
  //! try to send the graphic to the listener
967
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool inMasterPage) final
968
1.16k
  {
969
1.16k
    if (!listener || m_bdbox.size()[0]<=0 || m_bdbox.size()[1]<=0) {
970
142
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicGraph::send: can not send a shape\n"));
971
142
      return false;
972
142
    }
973
1.02k
    if ((!m_graphic || m_graphic->m_object.isEmpty()) && m_graphNames[1].empty()) {
974
464
      static bool first=true;
975
464
      if (first) {
976
4
        first=false;
977
4
        STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicGraph::send: sorry, can not find some graphic representation\n"));
978
4
      }
979
464
      return SdrGraphicRect::send(listener, pos, object, inMasterPage);
980
464
    }
981
560
    StarState state(getState(object, listener, pos));
982
560
    auto frame=pos;
983
560
    STOFFPosition &position=frame.m_position;
984
560
    position.setOrigin(state.convertPointInPoint(m_bdbox[0]));
985
560
    position.setSize(state.convertVectorInPoint(m_bdbox.size()));
986
560
    updateStyle(state, listener);
987
560
    if (!m_graphic || m_graphic->m_object.isEmpty()) {
988
      // CHECKME: we need probably correct the filename, transform ":" in "/", ...
989
23
      STOFFEmbeddedObject link;
990
23
      link.m_filenameLink=m_graphNames[1];
991
23
      listener->insertPicture(frame, link, state.m_graphic);
992
23
    }
993
537
    else
994
537
      listener->insertPicture(frame, m_graphic->m_object, state.m_graphic);
995
996
560
    return true;
997
1.02k
  }
998
  //! try to update the style
999
  void updateStyle(StarState &state, STOFFListenerPtr listener) const
1000
556
  {
1001
556
    SdrGraphicRect::updateStyle(state, listener);
1002
556
    if (m_graphItem && m_graphItem->m_attribute)
1003
370
      m_graphItem->m_attribute->addTo(state);
1004
556
  }
1005
  //! print object data
1006
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicGraph const &graph)
1007
0
  {
1008
0
    o << graph.getName() << ",";
1009
0
    if (graph.m_graphic) {
1010
0
      if (!graph.m_graphic->m_object.isEmpty())
1011
0
        o << "hasObject,";
1012
0
      else if (graph.m_graphic->m_bitmap)
1013
0
        o << "hasBitmap,";
1014
0
    }
1015
0
    if (graph.m_graphRectangle.size()[0] || graph.m_graphRectangle.size()[1]) o << "rect=" << graph.m_graphRectangle << ",";
1016
0
    for (int i=0; i<3; ++i) {
1017
0
      if (graph.m_graphNames[i].empty()) continue;
1018
0
      o << (i==0 ? "name" : i==1 ? "file[name]" : "filter[name]") << "=" << graph.m_graphNames[i].cstr() << ",";
1019
0
    }
1020
0
    if (graph.m_mirrored) o << "mirrored,";
1021
0
    if (graph.m_hasGraphicLink) o << "hasGraphicLink,";
1022
0
    if (graph.m_graphItem && graph.m_graphItem->m_attribute) {
1023
0
      libstoff::DebugStream f;
1024
0
      graph.m_graphItem->m_attribute->printData(f);
1025
0
      o << "[" << f.str() << "],";
1026
0
    }
1027
0
    return o;
1028
0
  }
1029
  //! the graphic
1030
  std::shared_ptr<StarGraphicStruct::StarGraphic> m_graphic;
1031
  //! the rectangle
1032
  STOFFBox2i m_graphRectangle;
1033
  //! the name, filename, the filtername
1034
  librevenge::RVNGString m_graphNames[3];
1035
  //! flag to know if the image is mirrored
1036
  bool m_mirrored;
1037
  //! flag to know if the image has a graphic link
1038
  bool m_hasGraphicLink;
1039
  //! the graph attributes
1040
  std::shared_ptr<StarItem> m_graphItem;
1041
};
1042
1043
SdrGraphicGraph::~SdrGraphicGraph()
1044
3.59k
{
1045
3.59k
}
1046
1047
////////////////////////////////////////
1048
//! Internal: virtual class to store a Sdr graphic edge
1049
class SdrGraphicMeasure final : public SdrGraphicText
1050
{
1051
public:
1052
  //! constructor
1053
  SdrGraphicMeasure()
1054
1.44k
    : SdrGraphicText(29)
1055
1.44k
    , m_overwritten(false)
1056
1.44k
    , m_measureItem()
1057
1.44k
  {
1058
1.44k
  }
1059
  //! destructor
1060
  ~SdrGraphicMeasure() final;
1061
  //! basic print function
1062
  std::string print() const final
1063
0
  {
1064
0
    std::stringstream s;
1065
0
    s << SdrGraphicText::print() << *this << ",";
1066
0
    return s.str();
1067
0
  }
1068
  //! try to send the graphic to the listener
1069
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool /*inMasterPage*/) final
1070
340
  {
1071
340
    STOFFGraphicShape shape;
1072
340
    StarState state(getState(object, listener, pos));
1073
340
    updateStyle(state, listener);
1074
340
    librevenge::RVNGPropertyListVector vect;
1075
340
    shape.m_command=STOFFGraphicShape::C_Polyline;
1076
340
    shape.m_propertyList.insert("draw:show-unit", true);
1077
340
    librevenge::RVNGPropertyList list;
1078
680
    for (auto &measurePoint : m_measurePoints) {
1079
680
      auto measure=state.convertPointInPoint(measurePoint);
1080
680
      list.insert("svg:x",measure[0], librevenge::RVNG_POINT);
1081
680
      list.insert("svg:y",measure[1], librevenge::RVNG_POINT);
1082
680
      vect.append(list);
1083
680
    }
1084
340
    shape.m_propertyList.insert("svg:points", vect);
1085
340
    updateTransformProperties(shape.m_propertyList, state.m_global->m_relativeUnit);
1086
340
    listener->insertShape(pos, shape, state.m_graphic);
1087
340
    return true;
1088
340
  }
1089
  //! try to update the style
1090
  void updateStyle(StarState &state, STOFFListenerPtr listener) const
1091
340
  {
1092
340
    SdrGraphicText::updateStyle(state, listener);
1093
340
    if (m_measureItem && m_measureItem->m_attribute)
1094
55
      m_measureItem->m_attribute->addTo(state);
1095
340
  }
1096
  //! print object data
1097
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicMeasure const &graph)
1098
0
  {
1099
0
    o << graph.getName() << ",";
1100
0
    if (graph.m_overwritten) o << "overwritten,";
1101
0
    o << "pts=[";
1102
0
    for (auto measurePoint : graph.m_measurePoints) o << measurePoint << ",";
1103
0
    o << "],";
1104
0
    if (graph.m_measureItem && graph.m_measureItem->m_attribute) {
1105
0
      libstoff::DebugStream f;
1106
0
      graph.m_measureItem->m_attribute->printData(f);
1107
0
      o << "[" << f.str() << "],";
1108
0
    }
1109
0
    return o;
1110
0
  }
1111
  //! the points
1112
  STOFFVec2i m_measurePoints[2];
1113
  //! overwritten flag
1114
  bool m_overwritten;
1115
  //! the measure attributes
1116
  std::shared_ptr<StarItem> m_measureItem;
1117
};
1118
1119
SdrGraphicMeasure::~SdrGraphicMeasure()
1120
1.44k
{
1121
1.44k
}
1122
////////////////////////////////////////
1123
//! Internal: virtual class to store a Sdr graphic OLE
1124
class SdrGraphicOLE final : public SdrGraphicRect
1125
{
1126
public:
1127
  //! constructor
1128
  explicit SdrGraphicOLE(int id)
1129
12.6k
    : SdrGraphicRect(id)
1130
12.6k
    , m_graphic()
1131
12.6k
    , m_oleParser()
1132
12.6k
  {
1133
12.6k
  }
1134
  //! destructor
1135
  ~SdrGraphicOLE() final;
1136
  //! basic print function
1137
  std::string print() const final
1138
0
  {
1139
0
    std::stringstream s;
1140
0
    s << SdrGraphicRect::print() << *this << ",";
1141
0
    return s.str();
1142
0
  }
1143
  //! try to send the graphic to the listener
1144
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool inMasterPage) final
1145
10.8k
  {
1146
10.8k
    if (!listener || m_bdbox.size()[0]<=0 || m_bdbox.size()[1]<=0) {
1147
833
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicOLE::send: can not send a shape\n"));
1148
833
      return false;
1149
833
    }
1150
9.97k
    StarState state(getState(object, listener, pos));
1151
9.97k
    STOFFPosition &position=state.m_frame.m_position;
1152
9.97k
    position=pos.m_position;
1153
9.97k
    position.setOrigin(state.convertPointInPoint(m_bdbox[0]));
1154
9.97k
    position.setSize(state.convertVectorInPoint(m_bdbox.size()));
1155
9.97k
    updateStyle(state, listener);
1156
9.97k
    STOFFEmbeddedObject localPicture;
1157
9.97k
    if (!m_oleNames[0].empty() && m_oleParser) {
1158
8.38k
      auto dir=m_oleParser->getDirectory(m_oleNames[0].cstr());
1159
8.38k
      std::shared_ptr<StarObject> localObj;
1160
8.38k
      if (!dir || !StarFileManager::readOLEDirectory(m_oleParser, dir, localPicture, localObj) || localPicture.isEmpty()) {
1161
8.02k
        if (localObj) {
1162
4.49k
          STOFFOLEParser::OleDirectoryInUse inUse(dir);
1163
4.49k
          auto chart=std::dynamic_pointer_cast<StarObjectChart>(localObj);
1164
4.49k
          if (chart && chart->send(listener, state.m_frame, state.m_graphic)) {
1165
2.72k
            if (m_graphic && !m_graphic->m_object.isEmpty()) {
1166
0
              STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicOLE::send: find extra graphic for chart %s\n", m_oleNames[0].cstr()));
1167
0
            }
1168
2.72k
            return true;
1169
2.72k
          }
1170
1.76k
          auto math=std::dynamic_pointer_cast<StarObjectMath>(localObj);
1171
1.76k
          if (math && math->send(listener, state.m_frame, state.m_graphic)) {
1172
1.01k
            if (m_graphic && !m_graphic->m_object.isEmpty()) {
1173
0
              STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicOLE::send: find extra graphic for math %s\n", m_oleNames[0].cstr()));
1174
0
            }
1175
1.01k
            return true;
1176
1.01k
          }
1177
751
          if (std::dynamic_pointer_cast<StarObjectText>(localObj)) {
1178
0
            STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicOLE::send: sorry, unsure how to send a text object %s\n", m_oleNames[0].cstr()));
1179
0
          }
1180
751
          else {
1181
751
            STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicOLE::send: sorry, unexpected type for object %s\n", m_oleNames[0].cstr()));
1182
751
          }
1183
751
        }
1184
3.53k
        else {
1185
3.53k
          STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicOLE::send: sorry, can not find object %s\n", m_oleNames[0].cstr()));
1186
3.53k
        }
1187
8.02k
      }
1188
8.38k
    }
1189
6.23k
    if (m_graphic && !m_graphic->m_object.isEmpty()) {
1190
147
      size_t numTypes=m_graphic->m_object.m_typeList.size();
1191
294
      for (size_t i=0; i<m_graphic->m_object.m_dataList.size(); ++i) {
1192
147
        if (m_graphic->m_object.m_dataList[i].empty())
1193
0
          continue;
1194
147
        if (i<numTypes)
1195
147
          localPicture.add(m_graphic->m_object.m_dataList[i], m_graphic->m_object.m_typeList[i]);
1196
0
        else
1197
0
          localPicture.add(m_graphic->m_object.m_dataList[i]);
1198
147
      }
1199
147
    }
1200
6.23k
    if (localPicture.isEmpty()) {
1201
5.71k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicOLE::send: sorry, can not find some graphic representation\n"));
1202
5.71k
      return SdrGraphicRect::send(listener, pos, object, inMasterPage);
1203
5.71k
    }
1204
521
    listener->insertPicture(state.m_frame, localPicture, state.m_graphic);
1205
1206
521
    return true;
1207
6.23k
  }
1208
  //! print object data
1209
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicOLE const &graph)
1210
0
  {
1211
0
    o << graph.getName() << ",";
1212
0
    for (int i=0; i<2; ++i) {
1213
0
      if (!graph.m_oleNames[i].empty())
1214
0
        o << (i==0 ? "persist" : "program") << "[name]=" << graph.m_oleNames[i].cstr() << ",";
1215
0
    }
1216
0
    if (graph.m_graphic) {
1217
0
      if (!graph.m_graphic->m_object.isEmpty())
1218
0
        o << "hasObject,";
1219
0
      else if (graph.m_graphic->m_bitmap)
1220
0
        o << "hasBitmap,";
1221
0
    }
1222
0
    return o;
1223
0
  }
1224
  //! the persist and the program name
1225
  librevenge::RVNGString m_oleNames[2];
1226
  //! the graphic
1227
  std::shared_ptr<StarGraphicStruct::StarGraphic> m_graphic;
1228
  //! the ole parser
1229
  std::shared_ptr<STOFFOLEParser> m_oleParser;
1230
};
1231
1232
SdrGraphicOLE::~SdrGraphicOLE()
1233
12.6k
{
1234
12.6k
}
1235
////////////////////////////////////////
1236
//! Internal: virtual class to store a Sdr graphic page
1237
class SdrGraphicPage final : public SdrGraphic
1238
{
1239
public:
1240
  //! constructor
1241
  SdrGraphicPage()
1242
12.9k
    : SdrGraphic(28)
1243
12.9k
    , m_page(0)
1244
12.9k
  {
1245
12.9k
  }
1246
  //! destructor
1247
  ~SdrGraphicPage() override;
1248
  //! basic print function
1249
  std::string print() const final
1250
0
  {
1251
0
    std::stringstream s;
1252
0
    s << SdrGraphic::print() << *this << ",";
1253
0
    return s.str();
1254
0
  }
1255
  //! try to send the graphic to the listener
1256
  bool send(STOFFListenerPtr &/*listener*/, STOFFFrameStyle const &/*pos*/, StarObject &/*object*/, bool /*inMasterPage*/) final
1257
172
  {
1258
172
    STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicPage::send: unexpected call\n"));
1259
172
    return false;
1260
172
  }
1261
  //! print object data
1262
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicPage const &graph)
1263
0
  {
1264
0
    if (graph.m_page>=0) o << "page=" << graph.m_page << ",";
1265
0
    return o;
1266
0
  }
1267
  //! the page
1268
  int m_page;
1269
};
1270
1271
SdrGraphicPage::~SdrGraphicPage()
1272
{
1273
}
1274
////////////////////////////////////////
1275
//! Internal: virtual class to store a Sdr graphic path
1276
class SdrGraphicPath final : public SdrGraphicText
1277
{
1278
public:
1279
  //! constructor
1280
  explicit SdrGraphicPath(int id)
1281
41.2k
    : SdrGraphicText(id)
1282
41.2k
    , m_pathPolygons()
1283
41.2k
  {
1284
41.2k
  }
1285
  //! try to send the graphic to the listener
1286
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool /*inMasterPage*/) final;
1287
  //! basic print function
1288
  std::string print() const final
1289
0
  {
1290
0
    std::stringstream s;
1291
0
    s << SdrGraphicText::print() << *this << ",";
1292
0
    return s.str();
1293
0
  }
1294
  //! print object data
1295
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicPath const &graph)
1296
0
  {
1297
0
    o << graph.getName() << ",";
1298
0
    if (!graph.m_pathPolygons.empty()) {
1299
0
      for (size_t p=0; p<graph.m_pathPolygons.size(); ++p)
1300
0
        o << "poly" << p << "=[" << graph.m_pathPolygons[p] << "],";
1301
0
    }
1302
0
    return o;
1303
0
  }
1304
  //! the path polygon
1305
  std::vector<StarGraphicStruct::StarPolygon> m_pathPolygons;
1306
};
1307
1308
bool SdrGraphicPath::send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool inMasterPage)
1309
30.0k
{
1310
30.0k
  if (!listener || m_pathPolygons.empty() || m_pathPolygons[0].empty()) {
1311
1.47k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicPath::send: can not send a shape\n"));
1312
1.47k
    return false;
1313
1.47k
  }
1314
1315
28.5k
  STOFFGraphicShape shape;
1316
28.5k
  StarState state(getState(object, listener, pos));
1317
28.5k
  updateStyle(state, listener);
1318
28.5k
  librevenge::RVNGPropertyListVector vect;
1319
28.5k
  bool isClosed=false;
1320
28.5k
  switch (m_identifier) {
1321
20.7k
  case 2: // line
1322
20.7k
    if (m_pathPolygons.size()==2) {
1323
      // version <6 : two poly, one for each arrow?
1324
48
      static bool first=true;
1325
48
      if (first) {
1326
2
        STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicPath::send: find a line defined by two polygons, unsure\n"));
1327
2
        first=false;
1328
2
      }
1329
48
      if (m_pathPolygons[0].empty() || m_pathPolygons[1].empty()) {
1330
45
        STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicPath::send: the number of points is bad for a line\n"));
1331
45
        return false;
1332
45
      }
1333
3
      shape.m_command=STOFFGraphicShape::C_Polyline;
1334
9
      for (size_t i=0; i<2; ++i) {
1335
6
        librevenge::RVNGPropertyList list;
1336
6
        auto pt=state.convertPointInPoint(m_pathPolygons[i].m_points[0].m_point);
1337
6
        list.insert("svg:x",pt[0], librevenge::RVNG_POINT);
1338
6
        list.insert("svg:y",pt[1], librevenge::RVNG_POINT);
1339
6
        vect.append(list);
1340
6
      }
1341
3
      shape.m_propertyList.insert("svg:points", vect);
1342
3
      updateTransformProperties(shape.m_propertyList, state.m_global->m_relativeUnit);
1343
3
      listener->insertShape(pos, shape, state.m_graphic);
1344
3
      if (m_outlinerParaObject)
1345
0
        sendTextZone(listener, pos, object);
1346
3
      return true;
1347
48
    }
1348
20.6k
    if (m_pathPolygons[0].size()!=2) {
1349
62
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicPath::send: the number of points is bad for a line\n"));
1350
62
      return false;
1351
62
    }
1352
20.5k
    break;
1353
20.5k
  case 8: // polygon
1354
7.22k
  case 11: // pathfill
1355
7.29k
  case 13: // freefill
1356
7.29k
  case 15: // splinefill
1357
7.37k
  case 26: // pathpoly
1358
7.37k
    isClosed=true;
1359
7.37k
    break;
1360
200
  case 9: // polyline
1361
362
  case 10: // pathline
1362
419
  case 12: // freeline
1363
419
  case 14: // splineline
1364
499
  case 27: // pathpline
1365
499
    break;
1366
0
  default:
1367
0
    STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SdrGraphicPath::send: find unexpected identifier %d\n", m_identifier));
1368
0
    return SdrGraphicText::send(listener, pos, object, inMasterPage);
1369
28.5k
  }
1370
1371
  // first check if we have some spline, bezier flags
1372
28.4k
  bool hasSpecialPoint=false;
1373
29.6k
  for (auto const &poly : m_pathPolygons) {
1374
29.6k
    if (poly.hasSpecialPoints()) {
1375
7.56k
      hasSpecialPoint=true;
1376
7.56k
      break;
1377
7.56k
    }
1378
29.6k
  }
1379
28.4k
  if (!hasSpecialPoint && m_pathPolygons.size()==1) {
1380
20.7k
    shape.m_command=isClosed ? STOFFGraphicShape::C_Polygon : STOFFGraphicShape::C_Polyline;
1381
20.7k
    librevenge::RVNGPropertyList list;
1382
66.6k
    for (size_t i=0; i<m_pathPolygons[0].size(); ++i) {
1383
45.8k
      auto pt=state.convertPointInPoint(m_pathPolygons[0].m_points[i].m_point);
1384
45.8k
      list.insert("svg:x",pt[0], librevenge::RVNG_POINT);
1385
45.8k
      list.insert("svg:y",pt[1], librevenge::RVNG_POINT);
1386
45.8k
      vect.append(list);
1387
45.8k
    }
1388
20.7k
    shape.m_propertyList.insert("svg:points", vect);
1389
20.7k
  }
1390
7.68k
  else {
1391
7.68k
    shape.m_command=STOFFGraphicShape::C_Path;
1392
7.68k
    librevenge::RVNGPropertyListVector path;
1393
7.68k
    for (auto const &poly : m_pathPolygons)
1394
9.06k
      poly.addToPath(path, isClosed, state.m_global->m_relativeUnit, state.m_global->m_offset);
1395
7.68k
    shape.m_propertyList.insert("svg:d", path);
1396
7.68k
  }
1397
28.4k
  updateTransformProperties(shape.m_propertyList, state.m_global->m_relativeUnit);
1398
28.4k
  listener->insertShape(pos, shape, state.m_graphic);
1399
28.4k
  if (m_outlinerParaObject)
1400
0
    sendTextZone(listener, pos, object);
1401
28.4k
  return true;
1402
28.5k
}
1403
1404
////////////////////////////////////////
1405
//! Internal: virtual class to store a Sdr graphic uno
1406
class SdrGraphicUno final : public SdrGraphicRect
1407
{
1408
public:
1409
  //! constructor
1410
  SdrGraphicUno()
1411
913
    : SdrGraphicRect(32)
1412
913
    , m_unoName()
1413
913
  {
1414
913
  }
1415
  //! destructor
1416
  ~SdrGraphicUno() final;
1417
  //! basic print function
1418
  std::string print() const final
1419
0
  {
1420
0
    std::stringstream s;
1421
0
    s << SdrGraphicRect::print() << *this << ",";
1422
0
    return s.str();
1423
0
  }
1424
  //! print object data
1425
  friend std::ostream &operator<<(std::ostream &o, SdrGraphicUno const &graph)
1426
0
  {
1427
0
    o << graph.getName() << ",";
1428
0
    if (!graph.m_unoName.empty()) o << graph.m_unoName.cstr() << ",";
1429
0
    return o;
1430
0
  }
1431
  //! the uno name
1432
  librevenge::RVNGString m_unoName;
1433
};
1434
1435
SdrGraphicUno::~SdrGraphicUno()
1436
913
{
1437
913
}
1438
1439
////////////////////////////////////////
1440
//! Internal: virtual class to store a user data
1441
class SDRUserData : public Graphic
1442
{
1443
public:
1444
  // constructor
1445
  explicit SDRUserData(int id=-1)
1446
121k
    : Graphic(id)
1447
121k
  {
1448
121k
  }
1449
  //! return the object name
1450
  std::string getName() const override
1451
0
  {
1452
0
    return "userData";
1453
0
  }
1454
  //! basic print function
1455
  std::string print() const override;
1456
};
1457
1458
std::string SDRUserData::print() const
1459
0
{
1460
0
  return "unknown";
1461
0
}
1462
////////////////////////////////////////
1463
//! Internal: virtual class to store a SCHU graphic
1464
class SCHUGraphic final : public SDRUserData
1465
{
1466
public:
1467
  //! constructor
1468
  explicit SCHUGraphic(int id)
1469
114k
    : SDRUserData(id)
1470
114k
    , m_id(0)
1471
114k
    , m_adjust(0)
1472
114k
    , m_orientation(0)
1473
114k
    , m_column(0)
1474
114k
    , m_row(0)
1475
114k
    , m_factor(0)
1476
114k
    , m_group()
1477
114k
  {
1478
114k
  }
1479
  //! destructor
1480
  ~SCHUGraphic() final;
1481
  //! return the object name
1482
  std::string getName() const final
1483
0
  {
1484
0
    if (m_identifier>0 && m_identifier<=7) {
1485
0
      char const *wh[]= {"none", "group",  "objectId", "objectAdjustId", "dataRowId",
1486
0
                         "dataPointId", "lightfactorId", "axisId"
1487
0
                        };
1488
0
      return wh[m_identifier];
1489
0
    }
1490
0
    std::stringstream s;
1491
0
    s << "###type=" << m_identifier << "[SCHU],";
1492
0
    return s.str();
1493
0
  }
1494
  //! basic print function
1495
  std::string print() const final
1496
0
  {
1497
0
    std::stringstream s;
1498
0
    s << *this << ",";
1499
0
    return s.str();
1500
0
  }
1501
  //! try to send the graphic to the listener
1502
  bool send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool inMasterPage) final
1503
12.0k
  {
1504
12.0k
    if (m_identifier && m_group)
1505
11.7k
      return m_group->send(listener, pos, object, inMasterPage);
1506
295
    static bool first=true;
1507
295
    if (first) {
1508
3
      first=false;
1509
3
      STOFF_DEBUG_MSG(("StarObjectSmallGraphicInternal::SCHUGraphic::send: not implemented for identifier %d\n", m_identifier));
1510
3
    }
1511
295
    return false;
1512
12.0k
  }
1513
  //! print object data
1514
  friend std::ostream &operator<<(std::ostream &o, SCHUGraphic const &graph)
1515
0
  {
1516
0
    o << graph.getName() << ",";
1517
0
    switch (graph.m_identifier) {
1518
0
    case 2:
1519
0
    case 7:
1520
0
      o << "id=" << graph.m_id << ",";
1521
0
      break;
1522
0
    case 3:
1523
0
      o << "adjust=" << graph.m_adjust << ",";
1524
0
      if (graph.m_orientation)
1525
0
        o << "orientation=" << graph.m_orientation << ",";
1526
0
      break;
1527
0
    case 4:
1528
0
      o << "row=" << graph.m_row << ",";
1529
0
      break;
1530
0
    case 5:
1531
0
      o << "column=" << graph.m_column << ",";
1532
0
      o << "row=" << graph.m_row << ",";
1533
0
      break;
1534
0
    case 6:
1535
0
      o << "factor=" << graph.m_factor << ",";
1536
0
      break;
1537
0
    default:
1538
0
      break;
1539
0
    }
1540
0
    return o;
1541
0
  }
1542
  //! the id
1543
  int m_id;
1544
  //! the adjust data
1545
  int m_adjust;
1546
  //! the orientation
1547
  int m_orientation;
1548
  //! the column
1549
  int m_column;
1550
  //! the row
1551
  int m_row;
1552
  //! the factor
1553
  double m_factor;
1554
  //! the group node
1555
  std::shared_ptr<SdrGraphicGroup> m_group;
1556
};
1557
1558
SCHUGraphic::~SCHUGraphic()
1559
114k
{
1560
114k
}
1561
1562
////////////////////////////////////////
1563
//! Internal: virtual class to store a SDUD graphic
1564
class SDUDGraphic : public SDRUserData
1565
{
1566
public:
1567
  //! constructor
1568
  explicit SDUDGraphic(int id)
1569
5.31k
    : SDRUserData(id)
1570
5.31k
  {
1571
5.31k
  }
1572
  //! destructor
1573
  ~SDUDGraphic() override;
1574
  //! return the object name
1575
  std::string getName() const override
1576
0
  {
1577
0
    if (m_identifier>0 && m_identifier<=2) {
1578
0
      char const *wh[]= {"none", "animationInfo",  "imapInfo" };
1579
0
      return wh[m_identifier];
1580
0
    }
1581
0
    std::stringstream s;
1582
0
    s << "###type=" << m_identifier << "[SDUD],";
1583
0
    return s.str();
1584
0
  }
1585
  //! basic print function
1586
  std::string print() const override
1587
0
  {
1588
0
    std::stringstream s;
1589
0
    s << *this << ",";
1590
0
    return s.str();
1591
0
  }
1592
  //! print object data
1593
  friend std::ostream &operator<<(std::ostream &o, SDUDGraphic const &graph)
1594
0
  {
1595
0
    o << graph.getName() << ",";
1596
0
    return o;
1597
0
  }
1598
};
1599
1600
SDUDGraphic::~SDUDGraphic()
1601
5.31k
{
1602
5.31k
}
1603
////////////////////////////////////////
1604
//! Internal: virtual class to store a SDUD graphic animation
1605
class SDUDGraphicAnimation final : public SDUDGraphic
1606
{
1607
public:
1608
  //! constructor
1609
  SDUDGraphicAnimation()
1610
5.27k
    : SDUDGraphic(1)
1611
5.27k
    , m_polygon()
1612
5.27k
    , m_order(0)
1613
5.27k
  {
1614
42.1k
    for (int &value : m_values) value=0;
1615
10.5k
    for (auto &color : m_colors) color=STOFFColor::white();
1616
15.8k
    for (bool &flag : m_flags) flag=false;
1617
26.3k
    for (bool &boolean : m_booleans) boolean=false;
1618
5.27k
  }
1619
  //! destructor
1620
  ~SDUDGraphicAnimation() override;
1621
  //! basic print function
1622
  std::string print() const override
1623
0
  {
1624
0
    std::stringstream s;
1625
0
    s << *this << ",";
1626
0
    return s.str();
1627
0
  }
1628
  //! print object data
1629
  friend std::ostream &operator<<(std::ostream &o, SDUDGraphicAnimation const &graph)
1630
0
  {
1631
0
    o << graph.getName() << ",";
1632
0
    if (!graph.m_polygon.empty()) {
1633
0
      o << "poly=[";
1634
0
      for (auto const &p : graph.m_polygon)
1635
0
        o << p << ",";
1636
0
      o << "],";
1637
0
    }
1638
0
    if (graph.m_limits[0]!=STOFFVec2i(0,0)) o << "start=" << graph.m_limits[0] << ",";
1639
0
    if (graph.m_limits[1]!=STOFFVec2i(0,0)) o << "end=" << graph.m_limits[1] << ",";
1640
0
    for (int i=0; i<8; ++i) {
1641
0
      if (!graph.m_values[i]) continue;
1642
0
      char const *wh[]= {"pres[effect]", "speed", "clickAction", "pres[effect,second]", "speed[second]",
1643
0
                         "invisible", "verb", "text[effect]"
1644
0
                        };
1645
0
      o << wh[i] << "=" << graph.m_values[i] << ",";
1646
0
    }
1647
0
    for (int i=0; i<3; ++i) {
1648
0
      if (!graph.m_flags[i]) continue;
1649
0
      char const *wh[]= {"active", "dim[previous]", "isMovie"};
1650
0
      o << wh[i] << ",";
1651
0
    }
1652
0
    for (int i=0; i<2; ++i) {
1653
0
      if (!graph.m_colors[i].isWhite())
1654
0
        o << (i==0 ? "blueScreen" : "dim[color]") << "=" << graph.m_colors[i] << ",";
1655
0
    }
1656
0
    for (int i=0; i<3; ++i) {
1657
0
      if (graph.m_names[i].empty()) continue;
1658
0
      char const *wh[]= {"sound[file]", "bookmark", "sound[file,second]"};
1659
0
      o << wh[i] << "=" << graph.m_names[i].cstr() << ",";
1660
0
    }
1661
0
    for (int i=0; i<5; ++i) {
1662
0
      if (!graph.m_booleans[i]) continue;
1663
0
      char const *wh[]= {"hasSound", "playFull","hasSound[second]", "playFull[second]","dim[hide]"};
1664
0
      o << wh[i] << ",";
1665
0
    }
1666
0
    if (graph.m_order) o << "order=" << graph.m_order << ",";
1667
0
    return o;
1668
0
  }
1669
  //! the polygon
1670
  std::vector<STOFFVec2i> m_polygon;
1671
  //! the limits start, end
1672
  STOFFVec2i m_limits[2];
1673
  //! the values: presentation effect, speed, clickAction, presentation effect[second], speed[second], invisible, verb, text effect
1674
  int m_values[8];
1675
  //! the colors
1676
  STOFFColor m_colors[2];
1677
  //! some flags : active, dim[previous], isMovie
1678
  bool m_flags[3];
1679
  //! some bool : hasSound, playFull, sound[second], playFull[second], dim[hide]
1680
  bool m_booleans[5];
1681
  //! the names : sound file, bookmark, sound file[second]
1682
  librevenge::RVNGString m_names[3];
1683
  //! the presentation order
1684
  int m_order;
1685
  // TODO add surrogate
1686
};
1687
1688
SDUDGraphicAnimation::~SDUDGraphicAnimation()
1689
5.27k
{
1690
5.27k
}
1691
////////////////////////////////////////
1692
//! Internal: the state of a StarObjectSmallGraphic
1693
struct State {
1694
  //! constructor
1695
  State()
1696
243k
    : m_graphic()
1697
243k
  {
1698
243k
  }
1699
  //! the graphic object
1700
  std::shared_ptr<Graphic> m_graphic;
1701
};
1702
1703
}
1704
1705
////////////////////////////////////////////////////////////
1706
// constructor/destructor, ...
1707
////////////////////////////////////////////////////////////
1708
StarObjectSmallGraphic::StarObjectSmallGraphic(StarObject const &orig, bool duplicateState)
1709
243k
  : StarObject(orig, duplicateState)
1710
243k
  , m_graphicState(new StarObjectSmallGraphicInternal::State)
1711
243k
{
1712
243k
}
1713
1714
StarObjectSmallGraphic::~StarObjectSmallGraphic()
1715
243k
{
1716
243k
}
1717
1718
std::ostream &operator<<(std::ostream &o, StarObjectSmallGraphic const &graphic)
1719
0
{
1720
0
  if (graphic.m_graphicState->m_graphic)
1721
0
    o << graphic.m_graphicState->m_graphic->print();
1722
0
  return o;
1723
0
}
1724
1725
bool StarObjectSmallGraphic::send(STOFFListenerPtr &listener, STOFFFrameStyle const &pos, StarObject &object, bool inMasterPage)
1726
141k
{
1727
141k
  if (!listener) {
1728
0
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::send: can not find the listener\n"));
1729
0
    return false;
1730
0
  }
1731
141k
  if (!m_graphicState->m_graphic) {
1732
7.90k
    static bool first=true;
1733
7.90k
    if (first) {
1734
4
      first=false;
1735
4
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::send: no object\n"));
1736
4
    }
1737
7.90k
    return false;
1738
7.90k
  }
1739
133k
  return m_graphicState->m_graphic->send(listener, pos, object, inMasterPage);
1740
141k
}
1741
1742
////////////////////////////////////////////////////////////
1743
// the parser
1744
////////////////////////////////////////////////////////////
1745
1746
bool StarObjectSmallGraphic::readSdrObject(StarZone &zone)
1747
243k
{
1748
243k
  STOFFInputStreamPtr input=zone.input();
1749
  // first check magic
1750
243k
  std::string magic("");
1751
243k
  long pos=input->tell();
1752
1.21M
  for (int i=0; i<4; ++i) magic+=char(input->readULong(1));
1753
243k
  input->seek(pos, librevenge::RVNG_SEEK_SET);
1754
243k
  if (magic!="DrOb" || !zone.openSDRHeader(magic)) {
1755
54.7k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1756
54.7k
    return false;
1757
54.7k
  }
1758
1759
188k
  libstoff::DebugFile &ascFile=zone.ascii();
1760
188k
  libstoff::DebugStream f;
1761
188k
  f << "Entries(SdrObject)[" << zone.getRecordLevel() << "]:";
1762
188k
  int version=zone.getHeaderVersion();
1763
188k
  f << magic << ",nVers=" << version << ",";
1764
188k
  ascFile.addPos(pos);
1765
188k
  ascFile.addNote(f.str().c_str());
1766
1767
188k
  long lastPos=zone.getRecordLastPosition();
1768
188k
  if (lastPos==input->tell()) {
1769
91
    zone.closeSDRHeader("SdrObject");
1770
91
    return true;
1771
91
  }
1772
  // svdobj.cxx SdrObjFactory::MakeNewObject
1773
188k
  pos=input->tell();
1774
188k
  f.str("");
1775
188k
  f << "SdrObject:";
1776
188k
  magic="";
1777
944k
  for (int i=0; i<4; ++i) magic+=char(input->readULong(1));
1778
188k
  uint16_t identifier;
1779
188k
  *input>>identifier;
1780
188k
  f << magic << ", ident=" << std::hex << identifier << std::dec << ",";
1781
188k
  bool ok=true;
1782
188k
  std::shared_ptr<StarObjectSmallGraphicInternal::Graphic> graphic;
1783
188k
  if (magic=="SVDr")
1784
164k
    graphic=readSVDRObject(zone, int(identifier));
1785
24.2k
  else if (magic=="SCHU")
1786
15.0k
    graphic=readSCHUObject(zone, int(identifier));
1787
9.24k
  else if (magic=="FM01") // FmFormInventor
1788
421
    graphic=readFmFormObject(zone, int(identifier));
1789
  // to do magic=="E3D1" // E3dInventor
1790
188k
  if (graphic)
1791
178k
    m_graphicState->m_graphic=graphic;
1792
10.0k
  else {
1793
10.0k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSdrObject: can not read an object\n"));
1794
10.0k
    f << "###";
1795
10.0k
    ok=false;
1796
10.0k
  }
1797
188k
  ascFile.addPos(pos);
1798
188k
  ascFile.addNote(f.str().c_str());
1799
188k
  if (ok) {
1800
178k
    pos=input->tell();
1801
178k
    if (pos==lastPos) {
1802
173k
      zone.closeSDRHeader("SdrObject");
1803
173k
      return true;
1804
173k
    }
1805
5.28k
    f.str("");
1806
5.28k
    f << "SVDR:##extra";
1807
5.28k
    static bool first=true;
1808
5.28k
    if (first) {
1809
4
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSdrObject: read object, find extra data\n"));
1810
4
      first=false;
1811
4
    }
1812
5.28k
    f << "##";
1813
5.28k
  }
1814
15.3k
  if (pos!=input->tell())
1815
10.0k
    ascFile.addDelimiter(input->tell(),'|');
1816
1817
15.3k
  input->seek(lastPos, librevenge::RVNG_SEEK_SET);
1818
15.3k
  zone.closeSDRHeader("SdrObject");
1819
15.3k
  return true;
1820
188k
}
1821
1822
////////////////////////////////////////////////////////////
1823
//  SVDR
1824
////////////////////////////////////////////////////////////
1825
std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphic> StarObjectSmallGraphic::readSVDRObject(StarZone &zone, int identifier)
1826
164k
{
1827
164k
  STOFFInputStreamPtr input=zone.input();
1828
164k
  long pos;
1829
1830
164k
  long endPos=zone.getRecordLastPosition();
1831
164k
  libstoff::DebugFile &ascFile=zone.ascii();
1832
164k
  libstoff::DebugStream f;
1833
1834
164k
  bool ok=true;
1835
164k
  std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphic> graphic;
1836
164k
  switch (identifier) {
1837
2.79k
  case 1: { // group
1838
2.79k
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicGroup> graphicGroup(new StarObjectSmallGraphicInternal::SdrGraphicGroup(identifier));
1839
2.79k
    graphic=graphicGroup;
1840
2.79k
    ok=readSVDRObjectGroup(zone, *graphicGroup);
1841
2.79k
    break;
1842
0
  }
1843
30.0k
  case 2: // line
1844
30.9k
  case 8: // poly
1845
31.7k
  case 9: // polyline
1846
32.1k
  case 10: // pathline
1847
39.8k
  case 11: // pathfill
1848
40.2k
  case 12: // freeline
1849
40.3k
  case 13: // freefill
1850
40.6k
  case 26: // pathpoly
1851
41.2k
  case 27: { // pathline
1852
41.2k
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicPath> graphicPath(new StarObjectSmallGraphicInternal::SdrGraphicPath(identifier));
1853
41.2k
    graphic=graphicPath;
1854
41.2k
    ok=readSVDRObjectPath(zone, *graphicPath);
1855
41.2k
    break;
1856
40.6k
  }
1857
3.94k
  case 4: // circle
1858
4.40k
  case 5: // sector
1859
5.44k
  case 6: // arc
1860
5.85k
  case 7: { // cut
1861
5.85k
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicCircle> graphicCircle(new StarObjectSmallGraphicInternal::SdrGraphicCircle(identifier));
1862
5.85k
    graphic=graphicCircle;
1863
5.85k
    ok=readSVDRObjectCircle(zone, *graphicCircle);
1864
5.85k
    break;
1865
5.44k
  }
1866
41.9k
  case 3: // rect
1867
62.0k
  case 16: // text
1868
62.2k
  case 17: // textextended
1869
70.4k
  case 20: // title text
1870
72.7k
  case 21: { // outline text
1871
72.7k
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicRect> graphicRect(new StarObjectSmallGraphicInternal::SdrGraphicRect(identifier));
1872
72.7k
    graphic=graphicRect;
1873
72.7k
    ok=readSVDRObjectRect(zone, *graphicRect);
1874
72.7k
    break;
1875
70.4k
  }
1876
6.69k
  case 24: { // edge
1877
6.69k
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicEdge> graphicEdge(new StarObjectSmallGraphicInternal::SdrGraphicEdge());
1878
6.69k
    graphic=graphicEdge;
1879
6.69k
    ok=readSVDRObjectEdge(zone, *graphicEdge);
1880
6.69k
    break;
1881
70.4k
  }
1882
3.59k
  case 22: { // graph
1883
3.59k
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicGraph> graphicGraph(new StarObjectSmallGraphicInternal::SdrGraphicGraph());
1884
3.59k
    graphic=graphicGraph;
1885
3.59k
    ok=readSVDRObjectGraph(zone, *graphicGraph);
1886
3.59k
    break;
1887
70.4k
  }
1888
12.1k
  case 23: // ole
1889
12.6k
  case 31: { // frame
1890
12.6k
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicOLE> graphicOLE(new StarObjectSmallGraphicInternal::SdrGraphicOLE(identifier));
1891
12.6k
    graphic=graphicOLE;
1892
12.6k
    ok=readSVDRObjectOLE(zone, *graphicOLE);
1893
12.6k
    break;
1894
12.1k
  }
1895
706
  case 25: { // caption
1896
706
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicCaption> graphicCaption(new StarObjectSmallGraphicInternal::SdrGraphicCaption());
1897
706
    graphic=graphicCaption;
1898
706
    ok=readSVDRObjectCaption(zone, *graphicCaption);
1899
706
    break;
1900
12.1k
  }
1901
12.9k
  case 28: { // page
1902
12.9k
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicPage> graphicPage(new StarObjectSmallGraphicInternal::SdrGraphicPage());
1903
12.9k
    graphic=graphicPage;
1904
12.9k
    ok=readSVDRObjectHeader(zone, *graphicPage);
1905
12.9k
    if (!ok) break;
1906
12.6k
    pos=input->tell();
1907
12.6k
    if (!zone.openRecord()) {
1908
1.21k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObject: can not open page record\n"));
1909
1.21k
      input->seek(pos, librevenge::RVNG_SEEK_SET);
1910
1.21k
      ok=false;
1911
1.21k
      break;
1912
1.21k
    }
1913
11.4k
    graphicPage->m_page=int(input->readULong(2));
1914
11.4k
    f << "SVDR[page]:page=" << graphicPage->m_page << ",";
1915
11.4k
    ok=input->tell()<=zone.getRecordLastPosition();
1916
11.4k
    if (!ok)
1917
68
      f << "###";
1918
11.4k
    ascFile.addPos(pos);
1919
11.4k
    ascFile.addNote(f.str().c_str());
1920
11.4k
    zone.closeRecord("SVDR");
1921
11.4k
    break;
1922
12.6k
  }
1923
1.44k
  case 29: { // measure
1924
1.44k
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicMeasure> graphicMeasure(new StarObjectSmallGraphicInternal::SdrGraphicMeasure());
1925
1.44k
    graphic=graphicMeasure;
1926
1.44k
    ok=readSVDRObjectMeasure(zone, *graphicMeasure);
1927
1.44k
    break;
1928
12.6k
  }
1929
622
  case 32: { // uno
1930
622
    std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicUno> graphicUno(new StarObjectSmallGraphicInternal::SdrGraphicUno());
1931
622
    graphic=graphicUno;
1932
622
    ok=readSVDRObjectRect(zone, *graphicUno);
1933
622
    pos=input->tell();
1934
622
    if (!zone.openRecord()) {
1935
290
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObject: can not open uno record\n"));
1936
290
      input->seek(pos, librevenge::RVNG_SEEK_SET);
1937
290
      ok=false;
1938
290
      break;
1939
290
    }
1940
332
    f << "SVDR[uno]:";
1941
    // + SdrUnoObj::ReadData (checkme)
1942
332
    std::vector<uint32_t> string;
1943
332
    if (input->tell()!=zone.getRecordLastPosition() && (!zone.readString(string) || input->tell()>zone.getRecordLastPosition())) {
1944
155
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObject: can not read uno string\n"));
1945
155
      f << "###uno";
1946
155
      ok=false;
1947
155
    }
1948
177
    else if (!string.empty()) {
1949
81
      graphicUno->m_unoName=libstoff::getString(string);
1950
81
      f << graphicUno->m_unoName.cstr() << ",";
1951
81
    }
1952
332
    ascFile.addPos(pos);
1953
332
    ascFile.addNote(f.str().c_str());
1954
332
    zone.closeRecord("SVDR");
1955
332
    break;
1956
622
  }
1957
3.24k
  default:
1958
3.24k
    graphic.reset(new StarObjectSmallGraphicInternal::SdrGraphic(identifier));
1959
3.24k
    ok=readSVDRObjectHeader(zone, *graphic);
1960
3.24k
    break;
1961
164k
  }
1962
164k
  pos=input->tell();
1963
164k
  if (!ok) {
1964
30.5k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObject: can not read some zone\n"));
1965
30.5k
    ascFile.addPos(pos);
1966
30.5k
    ascFile.addNote("Entries(SVDR):###");
1967
30.5k
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1968
30.5k
    graphic.reset(new StarObjectSmallGraphicInternal::SdrGraphic(identifier));
1969
30.5k
    return graphic;
1970
30.5k
  }
1971
134k
  if (input->tell()==endPos)
1972
126k
    return graphic;
1973
7.51k
  graphic.reset(new StarObjectSmallGraphicInternal::SdrGraphic(identifier));
1974
7.51k
  static bool first=true;
1975
7.51k
  if (first) {
1976
7.51k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObject: find unexpected data\n"));
1977
7.51k
  }
1978
7.51k
  if (identifier<=0 || identifier>32) {
1979
1.93k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObject: unknown identifier\n"));
1980
1.93k
    ascFile.addPos(pos);
1981
1.93k
    ascFile.addNote("Entries(SVDR):###");
1982
1.93k
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1983
1.93k
    return graphic;
1984
1.93k
  }
1985
1986
7.45k
  while (input->tell()<endPos) {
1987
6.77k
    pos=input->tell();
1988
6.77k
    f.str("");
1989
6.77k
    f << "SVDR:id=" << identifier << ",###unknown,";
1990
6.77k
    if (!zone.openRecord())
1991
4.89k
      return graphic;
1992
1.87k
    long lastPos=zone.getRecordLastPosition();
1993
1.87k
    ascFile.addPos(pos);
1994
1.87k
    ascFile.addNote(f.str().c_str());
1995
1.87k
    input->seek(lastPos, librevenge::RVNG_SEEK_SET);
1996
1.87k
    zone.closeRecord("SVDR");
1997
1.87k
  }
1998
685
  return graphic;
1999
5.58k
}
2000
2001
bool StarObjectSmallGraphic::readSVDRObjectAttrib(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicAttribute &graphic)
2002
145k
{
2003
145k
  STOFFInputStreamPtr input=zone.input();
2004
145k
  long pos=input->tell();
2005
145k
  if (!readSVDRObjectHeader(zone, graphic)) {
2006
4.26k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2007
4.26k
    return false;
2008
4.26k
  }
2009
141k
  pos=input->tell();
2010
141k
  libstoff::DebugFile &ascFile=zone.ascii();
2011
141k
  libstoff::DebugStream f;
2012
2013
141k
  if (!zone.openRecord()) {
2014
9.47k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectAttrib: can not open record\n"));
2015
9.47k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2016
9.47k
    return false;
2017
9.47k
  }
2018
2019
132k
  long lastPos=zone.getRecordLastPosition();
2020
132k
  auto pool=findItemPool(StarItemPool::T_XOutdevPool, false);
2021
132k
  if (!pool)
2022
40.8k
    pool=getNewItemPool(StarItemPool::T_VCControlPool);
2023
132k
  int vers=zone.getHeaderVersion();
2024
  // svx_svdoattr: SdrAttrObj:ReadData
2025
132k
  bool ok=true;
2026
132k
  f << "[";
2027
912k
  for (int i=0; i<6; ++i) {
2028
783k
    if (vers<11) input->seek(2, librevenge::RVNG_SEEK_CUR);
2029
783k
    uint16_t const what[]= {1017/*XATTRSET_LINE*/, 1047/*XATTRSET_FILL*/, 1066/*XATTRSET_TEXT*/, 1079/*SDRATTRSET_SHADOW*/,
2030
783k
                            1096 /*SDRATTRSET_OUTLINER*/, 1126 /*SDRATTRSET_MISC*/
2031
783k
                           };
2032
783k
    uint16_t nWhich=what[i];
2033
783k
    auto item=pool->loadSurrogate(zone, nWhich, false, f);
2034
783k
    if (input->tell()>lastPos) { // null is ok
2035
1.47k
      f << "###";
2036
1.47k
      ok=false;
2037
1.47k
      break;
2038
1.47k
    }
2039
782k
    if (item)
2040
770k
      graphic.m_itemList.push_back(item);
2041
782k
    if (vers<5 && i==3) break;
2042
780k
    if (vers<6 && i==4) break;
2043
780k
  }
2044
132k
  f << "],";
2045
132k
  std::vector<uint32_t> string;
2046
132k
  if (ok && (!zone.readString(string) || input->tell()>lastPos)) {
2047
7.75k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectAttrib: can not read the sheet style name\n"));
2048
7.75k
    ok=false;
2049
7.75k
  }
2050
124k
  else if (!string.empty()) {
2051
52.3k
    graphic.m_sheetStyle=libstoff::getString(string);
2052
52.3k
    f << "eFamily=" << input->readULong(2) << ",";
2053
52.3k
    if (vers>0 && vers<11) // in this case, we must convert the style name
2054
94
      f << "charSet=" << input->readULong(2) << ",";
2055
52.3k
  }
2056
132k
  if (ok && vers==9 && input->tell()+2==lastPos) // probably a charset even when string.empty()
2057
50
    f << "#charSet?=" << input->readULong(2) << ",";
2058
132k
  if (input->tell()!=lastPos) {
2059
11.6k
    if (ok) {
2060
2.46k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectAttrib: find extra data\n"));
2061
2.46k
      f << "###extra,vers=" << vers;
2062
2.46k
    }
2063
11.6k
    ascFile.addDelimiter(input->tell(),'|');
2064
11.6k
  }
2065
132k
  input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2066
132k
  zone.closeRecord("SVDR");
2067
2068
132k
  std::string extra=f.str();
2069
132k
  f.str("");
2070
132k
  f << "SVDR[" << zone.getRecordLevel() << "]:attrib," << graphic << extra;
2071
132k
  ascFile.addPos(pos);
2072
132k
  ascFile.addNote(f.str().c_str());
2073
132k
  return true;
2074
141k
}
2075
2076
bool StarObjectSmallGraphic::readSVDRObjectCaption(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicCaption &graphic)
2077
706
{
2078
706
  if (!readSVDRObjectRect(zone, graphic))
2079
266
    return false;
2080
440
  STOFFInputStreamPtr input=zone.input();
2081
440
  long pos=input->tell();
2082
440
  libstoff::DebugFile &ascFile=zone.ascii();
2083
440
  libstoff::DebugStream f;
2084
440
  f << "SVDR[" << zone.getRecordLevel() << "]:caption,";
2085
440
  if (!zone.openRecord()) {
2086
129
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectCaption: can not open record\n"));
2087
129
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2088
129
    return false;
2089
129
  }
2090
311
  long lastPos=zone.getRecordLastPosition();
2091
  // svx_svdocapt.cxx SdrCaptionObj::ReadData
2092
311
  bool ok=true;
2093
311
  uint16_t n;
2094
311
  *input >> n;
2095
311
  if (input->tell()+8*n>lastPos) {
2096
110
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectCaption: the number of point seems bad\n"));
2097
110
    f << "###n=" << n << ",";
2098
110
    ok=false;
2099
110
    n=0;
2100
110
  }
2101
1.55k
  for (int pt=0; pt<int(n); ++pt) {
2102
1.24k
    int dim[2];
2103
2.48k
    for (int &i : dim) i=int(input->readLong(4));
2104
1.24k
    graphic.m_captionPolygon.push_back(STOFFVec2i(dim[0],dim[1]));
2105
1.24k
  }
2106
311
  if (ok) {
2107
201
    auto pool=findItemPool(StarItemPool::T_XOutdevPool, false);
2108
201
    if (!pool)
2109
178
      pool=getNewItemPool(StarItemPool::T_XOutdevPool);
2110
201
    uint16_t nWhich=1195; // SDRATTRSET_CAPTION
2111
201
    std::shared_ptr<StarItem> item=pool->loadSurrogate(zone, nWhich, false, f);
2112
201
    if (!item || input->tell()>lastPos)
2113
64
      f << "###";
2114
137
    else
2115
137
      graphic.m_captionItem=item;
2116
201
  }
2117
311
  f << graphic;
2118
311
  if (!ok) {
2119
110
    ascFile.addDelimiter(input->tell(),'|');
2120
110
    input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2121
110
  }
2122
311
  ascFile.addPos(pos);
2123
311
  ascFile.addNote(f.str().c_str());
2124
311
  zone.closeRecord("SVDR");
2125
2126
311
  return true;
2127
440
}
2128
2129
bool StarObjectSmallGraphic::readSVDRObjectCircle(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicCircle &graphic)
2130
5.85k
{
2131
5.85k
  if (!readSVDRObjectRect(zone, graphic))
2132
2.34k
    return false;
2133
3.50k
  int const &id=graphic.m_identifier;
2134
3.50k
  STOFFInputStreamPtr input=zone.input();
2135
3.50k
  long pos=input->tell();
2136
3.50k
  libstoff::DebugFile &ascFile=zone.ascii();
2137
3.50k
  libstoff::DebugStream f;
2138
  // svx_svdocirc SdrCircObj::ReadData
2139
3.50k
  if (!zone.openRecord()) {
2140
430
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectCircle: can not open record\n"));
2141
430
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2142
430
    return false;
2143
430
  }
2144
3.07k
  long lastPos=zone.getRecordLastPosition();
2145
3.07k
  if (id!=4) {
2146
724
    for (float &angle : graphic.m_angles)
2147
1.44k
      angle=float(input->readLong(4))/100.f;
2148
724
  }
2149
3.07k
  if (input->tell()!=lastPos) {
2150
557
    auto pool=findItemPool(StarItemPool::T_XOutdevPool, false);
2151
557
    if (!pool)
2152
323
      pool=getNewItemPool(StarItemPool::T_XOutdevPool);
2153
557
    uint16_t nWhich=1179; // SDRATTRSET_CIRC
2154
557
    std::shared_ptr<StarItem> item=pool->loadSurrogate(zone, nWhich, false, f);
2155
557
    if (!item || input->tell()>lastPos) {
2156
217
      f << "###";
2157
217
    }
2158
340
    else
2159
340
      graphic.m_circleItem=item;
2160
557
  }
2161
3.07k
  zone.closeRecord("SVDR");
2162
2163
3.07k
  std::string extra=f.str();
2164
3.07k
  f.str("");
2165
3.07k
  f << "SVDR[" << zone.getRecordLevel() << "]:" << graphic << extra;
2166
3.07k
  ascFile.addPos(pos);
2167
3.07k
  ascFile.addNote(f.str().c_str());
2168
2169
3.07k
  return true;
2170
3.50k
}
2171
2172
bool StarObjectSmallGraphic::readSVDRObjectEdge(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicEdge &graphic)
2173
6.69k
{
2174
6.69k
  if (!readSVDRObjectText(zone, graphic))
2175
1.16k
    return false;
2176
5.52k
  STOFFInputStreamPtr input=zone.input();
2177
5.52k
  long pos=input->tell();
2178
5.52k
  libstoff::DebugFile &ascFile=zone.ascii();
2179
5.52k
  libstoff::DebugStream f;
2180
5.52k
  f << "SVDR[" << zone.getRecordLevel() << "]:";
2181
  // svx_svdoedge SdrEdgeObj::ReadData
2182
5.52k
  if (!zone.openRecord()) {
2183
222
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectEdge: can not open record\n"));
2184
222
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2185
222
    return false;
2186
222
  }
2187
5.30k
  long lastPos=zone.getRecordLastPosition();
2188
5.30k
  int vers=zone.getHeaderVersion();
2189
5.30k
  bool ok=true;
2190
5.30k
  if (vers<2) {
2191
117
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectEdge: unexpected version\n"));
2192
117
    f << "##badVers,";
2193
117
    ok=false;
2194
117
  }
2195
2196
5.30k
  bool openRec=false;
2197
5.30k
  if (ok && vers>=11) {
2198
5.11k
    openRec=zone.openRecord();
2199
5.11k
    if (!openRec) {
2200
361
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectEdge: can not edgeTrack record\n"));
2201
361
      f << "###record";
2202
361
      ok=false;
2203
361
    }
2204
5.11k
  }
2205
5.30k
  if (ok) {
2206
4.82k
    uint16_t n;
2207
4.82k
    *input >> n;
2208
4.82k
    if (input->tell()+9*n>zone.getRecordLastPosition()) {
2209
151
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectEdge: the number of point seems bad\n"));
2210
151
      f << "###n=" << n << ",";
2211
151
      ok=false;
2212
151
    }
2213
4.67k
    else {
2214
22.9k
      for (int pt=0; pt<int(n); ++pt) {
2215
18.2k
        int dim[2];
2216
36.4k
        for (int &i : dim) i=int(input->readLong(4));
2217
18.2k
        graphic.m_edgePolygon.push_back(STOFFVec2i(dim[0],dim[1]));
2218
18.2k
      }
2219
22.9k
      for (int pt=0; pt<int(n); ++pt) graphic.m_edgePolygonFlags.push_back(int(input->readULong(1)));
2220
4.67k
    }
2221
4.82k
  }
2222
5.30k
  f << graphic;
2223
5.30k
  if (openRec) {
2224
4.74k
    if (!ok) input->seek(zone.getRecordLastPosition(), librevenge::RVNG_SEEK_SET);
2225
4.74k
    zone.closeRecord("SVDR");
2226
4.74k
  }
2227
5.30k
  if (ok && input->tell()<lastPos) {
2228
4.63k
    ascFile.addPos(pos);
2229
4.63k
    ascFile.addNote(f.str().c_str());
2230
4.63k
    f.str("");
2231
4.63k
    f << "SVDR[edgeB]:";
2232
4.63k
    pos=input->tell();
2233
2234
12.8k
    for (int i=0; i<2; ++i) { // TODO: storeme
2235
8.93k
      if (!readSDRObjectConnection(zone)) {
2236
710
        f << "##connector,";
2237
710
        ok=false;
2238
710
        break;
2239
710
      }
2240
8.22k
      pos=input->tell();
2241
8.22k
    }
2242
4.63k
  }
2243
5.30k
  if (ok && input->tell()<lastPos) {
2244
542
    auto pool=findItemPool(StarItemPool::T_XOutdevPool, false);
2245
542
    if (!pool)
2246
390
      pool=getNewItemPool(StarItemPool::T_XOutdevPool);
2247
542
    uint16_t nWhich=1146; // SDRATTRSET_EDGE
2248
542
    auto item=pool->loadSurrogate(zone, nWhich, false, f);
2249
542
    if (!item || input->tell()>lastPos) {
2250
335
      f << "###";
2251
335
    }
2252
207
    else {
2253
207
      graphic.m_edgeItem=item;
2254
207
      if (item->m_attribute)
2255
43
        item->m_attribute->printData(f);
2256
207
    }
2257
542
  }
2258
5.30k
  if (ok && input->tell()<lastPos) {
2259
    // svx_svdoedge.cxx SdrEdgeInfoRec operator>>
2260
237
    if (input->tell()+5*8+2*4+3*2+1>lastPos) {
2261
196
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectEdge: SdrEdgeInfoRec seems too short\n"));
2262
196
      ok=false;
2263
196
    }
2264
41
    else {
2265
41
      auto &info=graphic.m_info;
2266
205
      for (auto &point : info.m_points) {
2267
205
        int dim[2];
2268
410
        for (int &i : dim) i=int(input->readLong(4));
2269
205
        point=STOFFVec2i(dim[0],dim[1]);
2270
205
      }
2271
82
      for (int &angle : info.m_angles) angle=int(input->readLong(4));
2272
123
      for (int &i : info.m_n) i=int(input->readULong(2));
2273
41
      info.m_orthoForm=int(input->readULong(1));
2274
41
      f << "infoRec=[" << info << "],";
2275
41
    }
2276
237
  }
2277
5.30k
  if (input->tell()!=lastPos) {
2278
1.83k
    if (ok) {
2279
342
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectEdge: find extra data\n"));
2280
342
      f << "###extra,vers=" << vers;
2281
342
    }
2282
1.83k
    ascFile.addDelimiter(input->tell(),'|');
2283
1.83k
  }
2284
5.30k
  if (pos!=lastPos) {
2285
1.92k
    ascFile.addPos(pos);
2286
1.92k
    ascFile.addNote(f.str().c_str());
2287
1.92k
  }
2288
5.30k
  input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2289
5.30k
  zone.closeRecord("SVDR");
2290
2291
5.30k
  return true;
2292
5.52k
}
2293
2294
bool StarObjectSmallGraphic::readSVDRObjectHeader(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphic &graphic)
2295
179k
{
2296
179k
  STOFFInputStreamPtr input=zone.input();
2297
179k
  long pos=input->tell();
2298
2299
179k
  libstoff::DebugFile &ascFile=zone.ascii();
2300
179k
  libstoff::DebugStream f;
2301
179k
  f << "Entries(SVDR)[" << zone.getRecordLevel() << "]:header,";
2302
2303
179k
  if (!zone.openRecord()) {
2304
6.10k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectHeader: can not open record\n"));
2305
6.10k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2306
6.10k
    return false;
2307
6.10k
  }
2308
2309
173k
  long lastPos=zone.getRecordLastPosition();
2310
173k
  int vers=zone.getHeaderVersion();
2311
  // svx_svdobj: SdrObject::ReadData
2312
173k
  int dim[4];    // gen.cxx operator>>(Rect) : test compression here
2313
692k
  for (int &i : dim) i=int(input->readLong(4));
2314
173k
  graphic.m_bdbox=STOFFBox2i(STOFFVec2i(dim[0],dim[1]),STOFFVec2i(dim[2],dim[3]));
2315
173k
  graphic.m_layerId=int(input->readULong(2));
2316
519k
  for (int i=0; i<2; ++i) dim[i]=int(input->readLong(4));
2317
173k
  graphic.m_anchorPosition=STOFFVec2i(dim[0],dim[1]);
2318
1.03M
  for (int i=0; i<5; ++i) *input >> graphic.m_flags[i];
2319
173k
  if (vers>=4) *input >> graphic.m_flags[5];
2320
173k
  bool ok=true;
2321
173k
  if (input->tell()>lastPos) {
2322
763
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectHeader: oops read to much data\n"));
2323
763
    f << "###bad,";
2324
763
    ok=false;
2325
763
  }
2326
173k
  if (ok && vers<11) {
2327
    // poly.cxx operator>>(Polygon) : test compression here
2328
4.53k
    uint16_t n;
2329
4.53k
    *input >> n;
2330
4.53k
    if (input->tell()+8*n>lastPos) {
2331
2.17k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectHeader: the number of point seems bad\n"));
2332
2.17k
      f << "###n=" << n << ",";
2333
2.17k
      ok=false;
2334
2.17k
      n=0;
2335
2.17k
    }
2336
7.04k
    for (int pt=0; pt<int(n); ++pt) {
2337
7.52k
      for (int i=0; i<2; ++i) dim[i]=int(input->readLong(4));
2338
2.50k
      graphic.m_polygon.push_back(StarObjectSmallGraphicInternal::GluePoint(dim[0],dim[1]));
2339
2.50k
    }
2340
4.53k
  }
2341
173k
  if (ok && vers>=11) {
2342
167k
    bool bTmp;
2343
167k
    *input >> bTmp;
2344
167k
    if (bTmp) {
2345
5.15k
      ascFile.addPos(pos);
2346
5.15k
      ascFile.addNote(f.str().c_str());
2347
2348
5.15k
      pos=input->tell();
2349
5.15k
      f.str("");
2350
5.15k
      f << "SVDR[headerB]:";
2351
5.15k
      if (!readSDRGluePointList(zone, graphic.m_polygon)) {
2352
4.81k
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectHeader: can not find the gluePoints record\n"));
2353
4.81k
        f << "###gluePoint";
2354
4.81k
        ok=false;
2355
4.81k
      }
2356
331
      else
2357
331
        pos=input->tell();
2358
5.15k
    }
2359
167k
  }
2360
173k
  f << graphic;
2361
173k
  if (ok) {
2362
165k
    bool readUser=true;
2363
165k
    if (vers>=11) *input >> readUser;
2364
165k
    if (readUser) {
2365
81.8k
      ascFile.addPos(pos);
2366
81.8k
      ascFile.addNote(f.str().c_str());
2367
2368
81.8k
      pos=input->tell();
2369
81.8k
      f.str("");
2370
81.8k
      f << "SVDR[headerC]:";
2371
81.8k
      if (!readSDRUserDataList(zone, vers>=11, graphic.m_userDataList)) {
2372
3.62k
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectHeader: can not find the data list record\n"));
2373
3.62k
        f << "###dataList";
2374
3.62k
      }
2375
78.1k
      else
2376
78.1k
        pos=input->tell();
2377
#if 0
2378
      std::cout << graphic.print() << "=>";
2379
      for (auto d : graphic.m_userDataList) {
2380
        if (d) std::cout << "[" << d->print() << "],";
2381
      }
2382
      std::cout << "\n";
2383
#endif
2384
81.8k
    }
2385
165k
  }
2386
2387
173k
  if (input->tell()!=pos) {
2388
86.5k
    if (input->tell()!=lastPos)
2389
3.54k
      ascFile.addDelimiter(input->tell(),'|');
2390
86.5k
    ascFile.addPos(pos);
2391
86.5k
    ascFile.addNote(f.str().c_str());
2392
86.5k
  }
2393
173k
  zone.closeRecord("SVDR");
2394
173k
  return true;
2395
179k
}
2396
2397
bool StarObjectSmallGraphic::readSVDRObjectGraph(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicGraph &graphic)
2398
3.59k
{
2399
3.59k
  if (!readSVDRObjectRect(zone, graphic))
2400
532
    return false;
2401
3.06k
  STOFFInputStreamPtr input=zone.input();
2402
3.06k
  long pos=input->tell();
2403
3.06k
  libstoff::DebugFile &ascFile=zone.ascii();
2404
3.06k
  libstoff::DebugStream f;
2405
3.06k
  f << "SVDR[" << zone.getRecordLevel() << "]:";
2406
  // SdrGrafObj::ReadData
2407
3.06k
  if (!zone.openRecord()) {
2408
124
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGraph: can not open record\n"));
2409
124
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2410
124
    return false;
2411
124
  }
2412
2.94k
  long lastPos=zone.getRecordLastPosition();
2413
2.94k
  int vers=zone.getHeaderVersion();
2414
2.94k
  bool ok=true;
2415
2.94k
  if (vers<11) {
2416
    // ReadDataTilV10
2417
696
    std::shared_ptr<StarGraphicStruct::StarGraphic> smallGraphic(new StarGraphicStruct::StarGraphic);
2418
696
    long begPictPos=input->tell();
2419
696
    if (!smallGraphic->read(zone) || input->tell()>lastPos) {
2420
138
      f << "###graphic";
2421
138
      ok=false;
2422
138
    }
2423
558
    else {
2424
558
      if (smallGraphic->m_object.isEmpty()) {
2425
527
        long endPictPos=input->tell();
2426
        // try to recover can recover here the unknown graphic
2427
527
        input->seek(begPictPos, librevenge::RVNG_SEEK_SET);
2428
527
        librevenge::RVNGBinaryData data;
2429
527
        if (!input->readDataBlock(endPictPos-begPictPos,data)) {
2430
0
          STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGraph: can not retrieve unknown data\n"));
2431
0
        }
2432
527
        else {
2433
527
          smallGraphic->m_object.add(data, "image/pct");
2434
527
          graphic.m_graphic=smallGraphic;
2435
527
        }
2436
527
        input->seek(endPictPos, librevenge::RVNG_SEEK_SET);
2437
527
      }
2438
31
      else
2439
31
        graphic.m_graphic=smallGraphic;
2440
558
    }
2441
696
    if (ok && vers>=6) {
2442
264
      int dim[4];
2443
1.05k
      for (int &i : dim) i=int(input->readLong(4));
2444
264
      graphic.m_graphRectangle=STOFFBox2i(STOFFVec2i(dim[0],dim[1]),STOFFVec2i(dim[2],dim[3]));
2445
264
    }
2446
696
    if (ok && vers>=8) {
2447
259
      std::vector<uint32_t> string;
2448
259
      if (!zone.readString(string) || input->tell()>lastPos) {
2449
119
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGraph: can not read the file name\n"));
2450
119
        f << "###fileName";
2451
119
        ok=false;
2452
119
      }
2453
140
      else
2454
140
        graphic.m_graphNames[1]=libstoff::getString(string);
2455
259
    }
2456
696
    if (ok && vers>=9) {
2457
140
      std::vector<uint32_t> string;
2458
140
      if (!zone.readString(string) || input->tell()>lastPos) {
2459
98
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGraph: can not read the filter name\n"));
2460
98
        f << "###filter";
2461
98
        ok=false;
2462
98
      }
2463
42
      else
2464
42
        graphic.m_graphNames[2]=libstoff::getString(string);
2465
140
    }
2466
696
  }
2467
2.24k
  else {
2468
2.24k
    bool hasGraphic;
2469
2.24k
    *input >> hasGraphic;
2470
2.24k
    if (hasGraphic) {
2471
1.76k
      if (!zone.openRecord()) {
2472
190
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGraph: can not open graphic record\n"));
2473
190
        f << "###graphRecord";
2474
190
        ok=false;
2475
190
      }
2476
1.57k
      else {
2477
1.57k
        f << "graf,";
2478
1.57k
        ascFile.addPos(pos);
2479
1.57k
        ascFile.addNote(f.str().c_str());
2480
1.57k
        std::shared_ptr<StarGraphicStruct::StarGraphic> smallGraphic(new StarGraphicStruct::StarGraphic);
2481
1.57k
        if (!smallGraphic->read(zone, zone.getRecordLastPosition()) || input->tell()>zone.getRecordLastPosition()) {
2482
59
          ascFile.addPos(pos);
2483
59
          ascFile.addNote("SVDR[graph]:##graphic");
2484
59
          input->seek(zone.getRecordLastPosition(), librevenge::RVNG_SEEK_SET);
2485
59
        }
2486
1.51k
        else if (smallGraphic)
2487
1.51k
          graphic.m_graphic=smallGraphic;
2488
1.57k
        pos=input->tell();
2489
1.57k
        f.str("");
2490
1.57k
        f << "SVDR[graph]:";
2491
1.57k
        zone.closeRecord("SVDR");
2492
1.57k
      }
2493
1.76k
    }
2494
2.24k
    if (ok) {
2495
2.05k
      int dim[4];
2496
8.22k
      for (int &i : dim) i=int(input->readLong(4));
2497
2.05k
      graphic.m_graphRectangle=STOFFBox2i(STOFFVec2i(dim[0],dim[1]),STOFFVec2i(dim[2],dim[3]));
2498
2.05k
      *input >> graphic.m_mirrored;
2499
4.69k
      for (auto &graphName : graphic.m_graphNames) {
2500
4.69k
        std::vector<uint32_t> string;
2501
4.69k
        if (!zone.readString(string) || input->tell()>lastPos) {
2502
980
          STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGraph: can not read a string\n"));
2503
980
          f << "###string";
2504
980
          ok=false;
2505
980
          break;
2506
980
        }
2507
3.71k
        graphName=libstoff::getString(string);
2508
3.71k
      }
2509
2.05k
    }
2510
2.24k
    if (ok)
2511
1.07k
      *input >> graphic.m_hasGraphicLink;
2512
2.24k
    if (ok && input->tell()<lastPos) {
2513
1.00k
      auto pool=findItemPool(StarItemPool::T_XOutdevPool, false);
2514
1.00k
      if (!pool)
2515
252
        pool=getNewItemPool(StarItemPool::T_XOutdevPool);
2516
1.00k
      uint16_t nWhich=1243; // SDRATTRSET_GRAF
2517
1.00k
      std::shared_ptr<StarItem> item=pool->loadSurrogate(zone, nWhich, false, f);
2518
1.00k
      if (!item || input->tell()>lastPos) {
2519
103
        f << "###";
2520
103
      }
2521
904
      else
2522
904
        graphic.m_graphItem=item;
2523
1.00k
    }
2524
2.24k
  }
2525
2.94k
  f << graphic;
2526
2.94k
  if (input->tell()!=lastPos) {
2527
2.01k
    if (ok) {
2528
495
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGraphic: find extra data\n"));
2529
495
      f << "###extra";
2530
495
    }
2531
2.01k
    ascFile.addDelimiter(input->tell(),'|');
2532
2.01k
  }
2533
2.94k
  ascFile.addPos(pos);
2534
2.94k
  ascFile.addNote(f.str().c_str());
2535
2.94k
  input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2536
2.94k
  zone.closeRecord("SVDR");
2537
2.94k
  return true;
2538
3.06k
}
2539
2540
bool StarObjectSmallGraphic::readSVDRObjectGroup(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicGroup &graphic)
2541
17.1k
{
2542
17.1k
  if (!readSVDRObjectHeader(zone, graphic))
2543
503
    return false;
2544
16.6k
  STOFFInputStreamPtr input=zone.input();
2545
16.6k
  long pos=input->tell();
2546
16.6k
  libstoff::DebugFile &ascFile=zone.ascii();
2547
16.6k
  libstoff::DebugStream f;
2548
16.6k
  f << "SVDR[" << zone.getRecordLevel() << "]:";
2549
  // svx_svdogrp SdrObjGroup::ReadData
2550
16.6k
  if (!zone.openRecord()) {
2551
753
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGroup: can not open record\n"));
2552
753
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2553
753
    return false;
2554
753
  }
2555
15.8k
  long lastPos=zone.getRecordLastPosition();
2556
15.8k
  int vers=zone.getHeaderVersion();
2557
15.8k
  std::vector<uint32_t> string;
2558
15.8k
  bool ok=true;
2559
15.8k
  if (!zone.readString(string) || input->tell()>lastPos) {
2560
476
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGroup: can not read the name\n"));
2561
476
    ok=false;
2562
476
  }
2563
15.3k
  else if (!string.empty())
2564
1.51k
    graphic.m_groupName=libstoff::getString(string);
2565
15.8k
  if (ok) {
2566
15.3k
    *input >> graphic.m_hasRefPoint;
2567
15.3k
    int dim[2];
2568
30.7k
    for (int &i : dim) i=int(input->readLong(4));
2569
15.3k
    graphic.m_refPoint=STOFFVec2i(dim[0],dim[1]);
2570
15.3k
    if (input->tell()>lastPos) {
2571
136
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGroup: the zone seems too short\n"));
2572
136
      f << "###short";
2573
136
    }
2574
15.3k
  }
2575
15.8k
  f << graphic;
2576
87.0k
  while (ok && input->tell()+4<lastPos) {
2577
86.3k
    ascFile.addPos(pos);
2578
86.3k
    ascFile.addNote(f.str().c_str());
2579
2580
86.3k
    f.str("");
2581
86.3k
    f << "SVDR:group,";
2582
86.3k
    pos=input->tell();
2583
    // check magic
2584
86.3k
    std::string magic("");
2585
431k
    for (int i=0; i<4; ++i) magic+=char(input->readULong(1));
2586
86.3k
    input->seek(-4, librevenge::RVNG_SEEK_CUR);
2587
86.3k
    if (magic=="DrXX" && zone.openSDRHeader(magic)) {
2588
8.72k
      ascFile.addPos(pos);
2589
8.72k
      ascFile.addNote("SVDR:DrXX");
2590
8.72k
      zone.closeSDRHeader("SVDR");
2591
8.72k
      pos=input->tell();
2592
8.72k
      break;
2593
8.72k
    }
2594
77.6k
    if (magic!="DrOb")
2595
5.57k
      break;
2596
72.0k
    std::shared_ptr<StarObjectSmallGraphic> child(new StarObjectSmallGraphic(*this, true));
2597
72.0k
    if (!child->readSdrObject(zone)) {
2598
882
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGroup: can not read an object\n"));
2599
882
      f << "###object";
2600
882
      ok=false;
2601
882
      break;
2602
882
    }
2603
71.2k
    graphic.m_child.push_back(child);
2604
71.2k
  }
2605
15.8k
  if (ok && vers>=2) {
2606
14.3k
    graphic.m_groupDrehWink=int(input->readLong(4));
2607
14.3k
    if (graphic.m_groupDrehWink)
2608
5.45k
      f << "drehWink=" << graphic.m_groupDrehWink << ",";
2609
14.3k
    graphic.m_groupShearWink=int(input->readLong(4));
2610
14.3k
    if (graphic.m_groupShearWink)
2611
5.02k
      f << "shearWink=" << graphic.m_groupShearWink << ",";
2612
14.3k
  }
2613
15.8k
  if (input->tell()!=lastPos) {
2614
7.11k
    if (ok) {
2615
5.75k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectGroup: find extra data\n"));
2616
5.75k
      f << "###extra";
2617
5.75k
    }
2618
7.11k
    if (input->tell()!=pos)
2619
6.13k
      ascFile.addDelimiter(input->tell(),'|');
2620
7.11k
  }
2621
15.8k
  if (pos!=lastPos) {
2622
15.8k
    ascFile.addPos(pos);
2623
15.8k
    ascFile.addNote(f.str().c_str());
2624
15.8k
  }
2625
15.8k
  input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2626
15.8k
  zone.closeRecord("SVDR");
2627
2628
15.8k
  return true;
2629
16.6k
}
2630
2631
bool StarObjectSmallGraphic::readSVDRObjectMeasure(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicMeasure &graphic)
2632
1.44k
{
2633
1.44k
  if (!readSVDRObjectText(zone, graphic))
2634
724
    return false;
2635
725
  STOFFInputStreamPtr input=zone.input();
2636
725
  long pos=input->tell();
2637
725
  libstoff::DebugFile &ascFile=zone.ascii();
2638
725
  libstoff::DebugStream f;
2639
  // svx_svdomeas SdrMeasureObj::ReadData
2640
725
  if (!zone.openRecord()) {
2641
95
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectMeasure: can not open record\n"));
2642
95
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2643
95
    return false;
2644
95
  }
2645
630
  long lastPos=zone.getRecordLastPosition();
2646
1.26k
  for (auto &measurePoint : graphic.m_measurePoints) {
2647
1.26k
    int dim[2];
2648
2.52k
    for (int &i : dim) i=int(input->readLong(4));
2649
1.26k
    measurePoint=STOFFVec2i(dim[0],dim[1]);
2650
1.26k
  }
2651
630
  *input >> graphic.m_overwritten;
2652
630
  auto pool=findItemPool(StarItemPool::T_XOutdevPool, false);
2653
630
  if (!pool)
2654
271
    pool=getNewItemPool(StarItemPool::T_XOutdevPool);
2655
630
  uint16_t nWhich=1171; // SDRATTRSET_MEASURE
2656
630
  auto item=pool->loadSurrogate(zone, nWhich, false, f);
2657
630
  if (!item || input->tell()>lastPos) {
2658
434
    f << "###";
2659
434
  }
2660
196
  else
2661
196
    graphic.m_measureItem=item;
2662
630
  zone.closeRecord("SVDR");
2663
2664
630
  std::string extra=f.str();
2665
630
  f.str("");
2666
630
  f << "SVDR[" << zone.getRecordLevel() << "]:" << graphic << extra;
2667
630
  ascFile.addPos(pos);
2668
630
  ascFile.addNote(f.str().c_str());
2669
2670
630
  return true;
2671
725
}
2672
2673
bool StarObjectSmallGraphic::readSVDRObjectOLE(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicOLE &graphic)
2674
12.6k
{
2675
12.6k
  if (!readSVDRObjectRect(zone, graphic))
2676
1.22k
    return false;
2677
11.4k
  STOFFInputStreamPtr input=zone.input();
2678
11.4k
  long pos=input->tell();
2679
11.4k
  libstoff::DebugFile &ascFile=zone.ascii();
2680
11.4k
  libstoff::DebugStream f;
2681
  // svx_svdoole2 SdrOle2Obj::ReadData
2682
11.4k
  if (!zone.openRecord()) {
2683
189
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectOLE: can not open record\n"));
2684
189
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2685
189
    return false;
2686
189
  }
2687
11.2k
  long lastPos=zone.getRecordLastPosition();
2688
11.2k
  bool ok=true;
2689
21.9k
  for (auto &oleName : graphic.m_oleNames) {
2690
21.9k
    std::vector<uint32_t> string;
2691
21.9k
    if (!zone.readString(string) || input->tell()>lastPos) {
2692
941
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectOLE: can not read a string\n"));
2693
941
      f << "###string";
2694
941
      ok=false;
2695
941
      break;
2696
941
    }
2697
21.0k
    if (!string.empty())
2698
9.82k
      oleName=libstoff::getString(string);
2699
21.0k
  }
2700
11.2k
  if (ok) {
2701
10.2k
    graphic.m_oleParser=m_oleParser;
2702
10.2k
    bool objValid, hasGraphic;
2703
10.2k
    *input >> objValid >> hasGraphic;
2704
10.2k
    if (objValid) f << "obj[refValid],";
2705
10.2k
    if (hasGraphic) {
2706
845
      std::shared_ptr<StarGraphicStruct::StarGraphic> smallGraphic(new StarGraphicStruct::StarGraphic);
2707
845
      long beginPos=input->tell();
2708
845
      if (!smallGraphic->read(zone, lastPos) || input->tell()>lastPos || smallGraphic->m_object.isEmpty()) {
2709
        // try to recover can recover here the unknown graphic
2710
845
        input->seek(beginPos, librevenge::RVNG_SEEK_SET);
2711
845
        librevenge::RVNGBinaryData data;
2712
845
        if (!input->readDataBlock(lastPos-beginPos,data)) {
2713
169
          STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectOLE: can not retrieve unknown data\n"));
2714
169
          f << "###graphic";
2715
169
          ok=false;
2716
169
        }
2717
676
        else {
2718
676
          smallGraphic->m_object.add(data, "image/pct");
2719
676
          graphic.m_graphic=smallGraphic;
2720
676
        }
2721
845
      }
2722
0
      else
2723
0
        graphic.m_graphic=smallGraphic;
2724
845
    }
2725
10.2k
  }
2726
11.2k
  if (input->tell()!=lastPos) {
2727
1.22k
    if (ok) {
2728
116
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectOLE: find extra data\n"));
2729
116
      f << "###extra";
2730
116
    }
2731
1.22k
    ascFile.addDelimiter(input->tell(),'|');
2732
1.22k
  }
2733
11.2k
  input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2734
11.2k
  zone.closeRecord("SVDR");
2735
2736
11.2k
  std::string extra=f.str();
2737
11.2k
  f.str("");
2738
11.2k
  f << "SVDR[" << zone.getRecordLevel() << "]:" << graphic << extra;
2739
11.2k
  ascFile.addPos(pos);
2740
11.2k
  ascFile.addNote(f.str().c_str());
2741
2742
11.2k
  return true;
2743
11.4k
}
2744
2745
bool StarObjectSmallGraphic::readSVDRObjectPath(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicPath &graphic)
2746
41.2k
{
2747
41.2k
  if (!readSVDRObjectText(zone, graphic))
2748
5.34k
    return false;
2749
35.9k
  int const &id=graphic.m_identifier;
2750
35.9k
  STOFFInputStreamPtr input=zone.input();
2751
35.9k
  long pos=input->tell();
2752
35.9k
  int vers=zone.getHeaderVersion();
2753
35.9k
  libstoff::DebugFile &ascFile=zone.ascii();
2754
35.9k
  libstoff::DebugStream f;
2755
35.9k
  f << "SVDR[" << zone.getRecordLevel() << "]:";
2756
  // svx_svdopath SdrPathObj::ReadData
2757
35.9k
  if (!zone.openRecord()) {
2758
1.48k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectPath: can not open record\n"));
2759
1.48k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2760
1.48k
    return false;
2761
1.48k
  }
2762
34.4k
  long lastPos=zone.getRecordLastPosition();
2763
34.4k
  bool ok=true;
2764
34.4k
  findItemPool(StarItemPool::T_XOutdevPool, false); // useme ?
2765
34.4k
  if (vers<=6 && (id==2 || id==8 || id==9)) {
2766
535
    int nPoly=id==2 ? 2 : id==8 ? 1 : int(input->readULong(2));
2767
2.77k
    for (int poly=0; poly<nPoly; ++poly) {
2768
2.59k
      uint16_t n;
2769
2.59k
      *input >> n;
2770
2.59k
      if (input->tell()+8*n>lastPos) {
2771
354
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectPath: the number of point seems bad\n"));
2772
354
        f << "###n=" << n << ",";
2773
354
        ok=false;
2774
354
        break;
2775
354
      }
2776
2.24k
      graphic.m_pathPolygons.push_back(StarGraphicStruct::StarPolygon());
2777
2.24k
      auto &polygon=graphic.m_pathPolygons.back();
2778
8.78k
      for (int pt=0; pt<int(n); ++pt) {
2779
6.54k
        int dim[2];
2780
13.0k
        for (int &i : dim) i=int(input->readLong(4));
2781
6.54k
        polygon.m_points.push_back(StarGraphicStruct::StarPolygon::Point(STOFFVec2i(dim[0],dim[1])));
2782
6.54k
      }
2783
2.24k
    }
2784
535
  }
2785
33.8k
  else {
2786
33.8k
    bool recOpened=false;
2787
33.8k
    if (vers>=11) {
2788
33.6k
      recOpened=zone.openRecord();
2789
33.6k
      if (!recOpened) {
2790
1.20k
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectPath: can not open zone record\n"));
2791
1.20k
        ok=false;
2792
1.20k
      }
2793
33.6k
    }
2794
33.8k
    int nPoly=ok ? int(input->readULong(2)) : 0;
2795
68.4k
    for (int poly=0; poly<nPoly; ++poly) {
2796
35.8k
      uint16_t n;
2797
35.8k
      *input >> n;
2798
35.8k
      if (input->tell()+9*n>lastPos) {
2799
1.29k
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectPath: the number of point seems bad\n"));
2800
1.29k
        f << "###n=" << n << ",";
2801
1.29k
        ok=false;
2802
1.29k
        break;
2803
1.29k
      }
2804
34.5k
      graphic.m_pathPolygons.push_back(StarGraphicStruct::StarPolygon());
2805
34.5k
      auto &polygon=graphic.m_pathPolygons.back();
2806
34.5k
      polygon.m_points.resize(size_t(n));
2807
274k
      for (size_t pt=0; pt<size_t(n); ++pt) {
2808
240k
        int dim[2];
2809
480k
        for (int &i : dim) i=int(input->readLong(4));
2810
240k
        polygon.m_points[pt].m_point=STOFFVec2i(dim[0],dim[1]);
2811
240k
      }
2812
274k
      for (size_t pt=0; pt<size_t(n); ++pt)
2813
240k
        polygon.m_points[pt].m_flags=int(input->readULong(1));
2814
34.5k
    }
2815
33.8k
    if (recOpened) {
2816
32.4k
      if (input->tell()!=zone.getRecordLastPosition()) {
2817
1.22k
        if (ok) {
2818
123
          f << "##";
2819
123
          STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectPath: find extra data\n"));
2820
123
        }
2821
1.22k
        ascFile.addDelimiter(input->tell(),'|');
2822
1.22k
      }
2823
32.4k
      input->seek(zone.getRecordLastPosition(), librevenge::RVNG_SEEK_SET);
2824
32.4k
      zone.closeRecord("SVDR");
2825
32.4k
    }
2826
33.8k
    ok=false;
2827
33.8k
  }
2828
34.4k
  if (!ok) {
2829
34.2k
    ascFile.addDelimiter(input->tell(),'|');
2830
34.2k
    input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2831
34.2k
  }
2832
34.4k
  zone.closeRecord("SVDR");
2833
34.4k
  f << graphic;
2834
34.4k
  ascFile.addPos(pos);
2835
34.4k
  ascFile.addNote(f.str().c_str());
2836
2837
34.4k
  return true;
2838
35.9k
}
2839
2840
bool StarObjectSmallGraphic::readSVDRObjectRect(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicRect &graphic)
2841
96.5k
{
2842
96.5k
  if (!readSVDRObjectText(zone, graphic))
2843
12.4k
    return false;
2844
84.0k
  int const &id=graphic.m_identifier;
2845
84.0k
  STOFFInputStreamPtr input=zone.input();
2846
84.0k
  long pos=input->tell();
2847
84.0k
  int vers=zone.getHeaderVersion();
2848
84.0k
  if (vers<3 && (id==16 || id==17 || id==20 || id==21))
2849
299
    return true;
2850
2851
83.7k
  libstoff::DebugFile &ascFile=zone.ascii();
2852
83.7k
  libstoff::DebugStream f;
2853
83.7k
  f << "SVDR[" << zone.getRecordLevel() << "]:rectZone,";
2854
  // svx_svdorect.cxx SdrRectObj::ReadData
2855
83.7k
  if (!zone.openRecord()) {
2856
4.99k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectRect: can not open record\n"));
2857
4.99k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2858
4.99k
    return false;
2859
4.99k
  }
2860
78.7k
  if (vers<=5) graphic.m_eckRag=int(input->readLong(4));
2861
78.7k
  f << graphic;
2862
78.7k
  ascFile.addPos(pos);
2863
78.7k
  ascFile.addNote(f.str().c_str());
2864
78.7k
  zone.closeRecord("SVDR");
2865
78.7k
  return true;
2866
83.7k
}
2867
2868
bool StarObjectSmallGraphic::readSVDRObjectText(StarZone &zone, StarObjectSmallGraphicInternal::SdrGraphicText &graphic)
2869
145k
{
2870
145k
  if (!readSVDRObjectAttrib(zone, graphic))
2871
13.7k
    return false;
2872
2873
132k
  STOFFInputStreamPtr input=zone.input();
2874
132k
  long pos=input->tell();
2875
132k
  libstoff::DebugFile &ascFile=zone.ascii();
2876
132k
  libstoff::DebugStream f;
2877
132k
  f << "SVDR[" << zone.getRecordLevel() << "]:textZone,";
2878
  // svx_svdotext SdrTextObj::ReadData
2879
132k
  if (!zone.openRecord()) {
2880
5.90k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectText: can not open record\n"));
2881
5.90k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2882
5.90k
    return false;
2883
5.90k
  }
2884
126k
  long lastPos=zone.getRecordLastPosition();
2885
126k
  int vers=zone.getHeaderVersion();
2886
126k
  graphic.m_textKind=int(input->readULong(1));
2887
126k
  int dim[4];
2888
505k
  for (int &i : dim) i=int(input->readLong(4));
2889
126k
  graphic.m_textRectangle=STOFFBox2i(STOFFVec2i(dim[0],dim[1]),STOFFVec2i(dim[2],dim[3]));
2890
126k
  graphic.m_textDrehWink=int(input->readLong(4));
2891
126k
  graphic.m_textShearWink=int(input->readLong(4));
2892
126k
  f << graphic;
2893
126k
  bool paraObjectValid;
2894
126k
  *input >> paraObjectValid;
2895
126k
  bool ok=input->tell()<=lastPos;
2896
126k
  if (paraObjectValid) {
2897
37.4k
    ascFile.addPos(pos);
2898
37.4k
    ascFile.addNote(f.str().c_str());
2899
2900
37.4k
    pos=input->tell();
2901
37.4k
    f.str("");
2902
37.4k
    f << "SVDR:textB";
2903
37.4k
    if (vers>=11 && !zone.openRecord()) {
2904
3.21k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectText: can not open paraObject record\n"));
2905
3.21k
      paraObjectValid=ok=false;
2906
3.21k
      f << "##paraObject";
2907
3.21k
    }
2908
34.1k
    else {
2909
34.1k
      std::shared_ptr<StarObjectSmallGraphicInternal::OutlinerParaObject> paraObject(new StarObjectSmallGraphicInternal::OutlinerParaObject);
2910
34.1k
      if (!readSDROutlinerParaObject(zone, *paraObject)) {
2911
9.42k
        ok=false;
2912
9.42k
        f << "##paraObject";
2913
9.42k
      }
2914
24.7k
      else {
2915
24.7k
        graphic.m_outlinerParaObject=paraObject;
2916
24.7k
        pos=input->tell();
2917
24.7k
      }
2918
34.1k
    }
2919
37.4k
    if (paraObjectValid && vers>=11) {
2920
33.2k
      zone.closeRecord("SdrParaObject");
2921
33.2k
      ok=true;
2922
33.2k
    }
2923
37.4k
  }
2924
126k
  if (ok && vers>=10) {
2925
119k
    bool hasBound;
2926
119k
    *input >> hasBound;
2927
119k
    if (hasBound) {
2928
12.9k
      for (int &i : dim) i=int(input->readLong(4));
2929
3.23k
      graphic.m_textBound=STOFFBox2i(STOFFVec2i(dim[0],dim[1]),STOFFVec2i(dim[2],dim[3]));
2930
3.23k
      f << "bound=" << graphic.m_textBound << ",";
2931
3.23k
    }
2932
119k
    ok=input->tell()<=lastPos;
2933
119k
  }
2934
126k
  if (input->tell()!=lastPos) {
2935
10.6k
    if (ok) {
2936
3.14k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSVDRObjectText: find extra data\n"));
2937
3.14k
      f << "###extra, vers=" << vers;
2938
3.14k
    }
2939
10.6k
    ascFile.addDelimiter(input->tell(),'|');
2940
10.6k
  }
2941
126k
  if (pos!=input->tell()) {
2942
126k
    ascFile.addPos(pos);
2943
126k
    ascFile.addNote(f.str().c_str());
2944
126k
  }
2945
126k
  input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2946
126k
  zone.closeRecord("SVDR");
2947
126k
  return true;
2948
132k
}
2949
2950
bool StarObjectSmallGraphic::readSDRObjectConnection(StarZone &zone)
2951
8.93k
{
2952
8.93k
  STOFFInputStreamPtr input=zone.input();
2953
  // first check magic
2954
8.93k
  std::string magic("");
2955
8.93k
  long pos=input->tell();
2956
44.6k
  for (int i=0; i<4; ++i) magic+=char(input->readULong(1));
2957
8.93k
  input->seek(pos, librevenge::RVNG_SEEK_SET);
2958
8.93k
  if (magic!="DrCn" || !zone.openSDRHeader(magic)) {
2959
710
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2960
710
    return false;
2961
710
  }
2962
8.22k
  libstoff::DebugFile &ascFile=zone.ascii();
2963
8.22k
  libstoff::DebugStream f;
2964
8.22k
  long lastPos=zone.getRecordLastPosition();
2965
8.22k
  f << "Entries(SdrObjConn)[" << zone.getRecordLevel() << "]:";
2966
  // svx_svdoedge.cxx SdrObjConnection::Read
2967
8.22k
  int version=zone.getHeaderVersion();
2968
8.22k
  f << magic << ",nVers=" << version << ",";
2969
8.22k
  if (!readSDRObjectSurrogate(zone)) {
2970
191
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSdrObjectConnection: can not read object surrogate\n"));
2971
191
    f << "###surrogate";
2972
191
    ascFile.addPos(input->tell());
2973
191
    ascFile.addNote("SdrObjConn:###extra");
2974
191
    input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2975
191
    zone.closeSDRHeader("SdrObjConn");
2976
191
    return true;
2977
191
  }
2978
8.03k
  f << "condId=" << input->readULong(2) << ",";
2979
8.03k
  f << "dist=" << input->readLong(4) << "x" << input->readLong(4) << ",";
2980
56.2k
  for (int i=0; i<6; ++i) {
2981
48.1k
    bool val;
2982
48.1k
    *input>>val;
2983
48.1k
    if (!val) continue;
2984
11.3k
    char const *wh[]= {"bestConn", "bestVertex", "xDistOvr", "yDistOvr", "autoVertex", "autoCorner"};
2985
11.3k
    f << wh[i] << ",";
2986
11.3k
  }
2987
8.03k
  input->seek(8, librevenge::RVNG_SEEK_CUR);
2988
8.03k
  ascFile.addPos(pos);
2989
8.03k
  ascFile.addNote(f.str().c_str());
2990
8.03k
  if (input->tell()!=lastPos) {
2991
710
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSdrObjectConnection: find extra data\n"));
2992
710
    ascFile.addPos(input->tell());
2993
710
    ascFile.addNote("SdrObjConn:###extra");
2994
710
    input->seek(lastPos, librevenge::RVNG_SEEK_SET);
2995
710
  }
2996
8.03k
  zone.closeSDRHeader("SdrObjConn");
2997
8.03k
  return true;
2998
8.22k
}
2999
3000
bool StarObjectSmallGraphic::readSDRObjectSurrogate(StarZone &zone)
3001
8.42k
{
3002
8.42k
  STOFFInputStreamPtr input=zone.input();
3003
8.42k
  long pos=input->tell();
3004
8.42k
  long lastPos=zone.getRecordLastPosition();
3005
8.42k
  libstoff::DebugFile &ascFile=zone.ascii();
3006
8.42k
  libstoff::DebugStream f;
3007
8.42k
  f << "Entries(SdrObjSurr):";
3008
  // svx_svdsuro.cxx SdrObjSurrogate::ImpRead
3009
8.42k
  auto id=int(input->readULong(1));
3010
8.42k
  f << "id=" << id << ",";
3011
8.42k
  bool ok=true;
3012
8.42k
  if (id) {
3013
3.67k
    int eid=id&0x1f;
3014
3.67k
    int nBytes=1+(id>>6);
3015
3.67k
    if (nBytes==3) {
3016
72
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSdrObjectConnection: unexpected num bytes\n"));
3017
72
      f << "###nBytes,";
3018
72
      ok=false;
3019
72
    }
3020
3.67k
    if (ok)
3021
3.60k
      f << "val=" << input->readULong(nBytes) << ",";
3022
3.67k
    if (ok && eid>=0x10 && eid<=0x1a)
3023
168
      f << "page=" << input->readULong(2) << ",";
3024
3.67k
    if (ok && id&0x20) {
3025
368
      auto grpLevel=int(input->readULong(2));
3026
368
      f << "nChild=" << grpLevel << ",";
3027
368
      if (input->tell()+nBytes*grpLevel>lastPos) {
3028
127
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSdrObjectConnection: num child is bas\n"));
3029
127
        f << "###";
3030
127
        ok=false;
3031
127
      }
3032
241
      else {
3033
241
        f << "child=[";
3034
1.23k
        for (int i=0; i<grpLevel; ++i)
3035
997
          f << input->readULong(nBytes) << ",";
3036
241
        f << "],";
3037
241
      }
3038
368
    }
3039
3.67k
  }
3040
3041
8.42k
  ascFile.addPos(pos);
3042
8.42k
  ascFile.addNote(f.str().c_str());
3043
8.42k
  return ok && input->tell()<=lastPos;
3044
8.42k
}
3045
3046
bool StarObjectSmallGraphic::readSDROutlinerParaObject(StarZone &zone, StarObjectSmallGraphicInternal::OutlinerParaObject &object)
3047
34.1k
{
3048
34.1k
  object=StarObjectSmallGraphicInternal::OutlinerParaObject();
3049
34.1k
  STOFFInputStreamPtr input=zone.input();
3050
34.1k
  long pos=input->tell();
3051
34.1k
  long lastPos=zone.getRecordLastPosition();
3052
34.1k
  libstoff::DebugFile &ascFile=zone.ascii();
3053
34.1k
  libstoff::DebugStream f;
3054
34.1k
  f << "Entries(SdrParaObject):";
3055
  // svx_outlobj.cxx OutlinerParaObject::Create
3056
34.1k
  auto N=long(input->readULong(4));
3057
34.1k
  f << "N=" << N << ",";
3058
34.1k
  auto syncRef=long(input->readULong(4));
3059
34.1k
  int vers=0;
3060
34.1k
  if (syncRef == 0x12345678)
3061
339
    vers = 1;
3062
33.8k
  else if (syncRef == 0x22345678)
3063
304
    vers = 2;
3064
33.5k
  else if (syncRef == 0x32345678)
3065
247
    vers = 3;
3066
33.3k
  else if (syncRef == 0x42345678)
3067
26.6k
    vers = 4;
3068
6.68k
  else {
3069
6.68k
    f << "##syncRef,";
3070
6.68k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDROutlinerParaObject: can not check the version\n"));
3071
6.68k
    ascFile.addPos(pos);
3072
6.68k
    ascFile.addNote(f.str().c_str());
3073
6.68k
    return N==0;
3074
6.68k
  }
3075
27.5k
  object.m_version=vers;
3076
27.5k
  f << "version=" << vers << ",";
3077
27.5k
  if (vers<=3) {
3078
1.15k
    for (long i=0; i<N; ++i) {
3079
896
      ascFile.addPos(pos);
3080
896
      ascFile.addNote(f.str().c_str());
3081
3082
896
      pos=input->tell();
3083
896
      f.str("");
3084
896
      f << "SdrParaObject:";
3085
896
      std::shared_ptr<StarObjectSmallText> smallText(new StarObjectSmallText(*this, true));
3086
896
      if (!smallText->read(zone, lastPos) || input->tell()>lastPos) {
3087
358
        f << "###editTextObject";
3088
358
        input->seek(pos, librevenge::RVNG_SEEK_SET);
3089
358
        ascFile.addPos(pos);
3090
358
        ascFile.addNote(f.str().c_str());
3091
358
        return false;
3092
358
      }
3093
538
      pos=input->tell();
3094
538
      StarObjectSmallGraphicInternal::OutlinerParaObject::Zone paraZone;
3095
538
      paraZone.m_text=smallText;
3096
538
      f << "sync=" << input->readULong(4) << ",";
3097
538
      paraZone.m_depth=int(input->readULong(2));
3098
538
      bool ok=true;
3099
538
      if (vers==1) {
3100
195
        auto flags=int(input->readULong(2));
3101
195
        if (flags&1) {
3102
42
          StarBitmap bitmap;
3103
42
          librevenge::RVNGBinaryData data;
3104
42
          std::string dType;
3105
42
          if (!bitmap.readBitmap(zone, true, lastPos, data, dType)) {
3106
42
            STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDROutlinerParaObject: can not check the bitmpa\n"));
3107
42
            ok=false;
3108
42
          }
3109
0
          else
3110
0
            paraZone.m_background.add(data, dType);
3111
42
        }
3112
153
        else {
3113
153
          if (!input->readColor(paraZone.m_backgroundColor)) {
3114
45
            STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDROutlinerParaObject: can not find a color\n"));
3115
45
            f << "###aColor,";
3116
45
            ok=false;
3117
45
          }
3118
108
          else
3119
108
            input->seek(16, librevenge::RVNG_SEEK_CUR);
3120
153
          std::vector<uint32_t> string;
3121
153
          if (ok && (!zone.readString(string) || input->tell()>lastPos)) {
3122
78
            STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDROutlinerParaObject: can not find string\n"));
3123
78
            f << "###string,";
3124
78
            ok=false;
3125
78
          }
3126
75
          else
3127
75
            paraZone.m_colorName=libstoff::getString(string);
3128
153
          if (ok)
3129
30
            input->seek(12, librevenge::RVNG_SEEK_CUR);
3130
153
        }
3131
195
        input->seek(8, librevenge::RVNG_SEEK_CUR); // 2 long dummy
3132
195
      }
3133
538
      f << paraZone;
3134
538
      if (input->tell()>lastPos) {
3135
203
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDROutlinerParaObject: we read too much data\n"));
3136
203
        f << "###bad,";
3137
203
        ok=false;
3138
203
      }
3139
538
      if (!ok) {
3140
273
        input->seek(pos, librevenge::RVNG_SEEK_SET);
3141
273
        ascFile.addPos(pos);
3142
273
        ascFile.addNote(f.str().c_str());
3143
273
        return false;
3144
273
      }
3145
265
      object.m_zones.push_back(paraZone);
3146
265
      if (i+1!=N) f << "sync=" << input->readULong(4) << ",";
3147
265
    }
3148
259
    if (vers==3) {
3149
80
      *input >> object.m_isEditDoc;
3150
80
      if (object.m_isEditDoc) f << "isEditDoc,";
3151
80
    }
3152
259
  }
3153
26.6k
  else {
3154
26.6k
    pos=input->tell();
3155
26.6k
    f.str("");
3156
26.6k
    f << "SdrParaObject:";
3157
26.6k
    std::shared_ptr<StarObjectSmallText> smallText(new StarObjectSmallText(*this, true)); // checkme, we must use the text edit pool here
3158
26.6k
    if (!smallText->read(zone, lastPos) || N>(lastPos-input->tell())/2 || input->tell()+N*2>lastPos) {
3159
2.40k
      f << "###editTextObject";
3160
2.40k
      input->seek(pos, librevenge::RVNG_SEEK_SET);
3161
2.40k
      ascFile.addPos(pos);
3162
2.40k
      ascFile.addNote(f.str().c_str());
3163
2.40k
      return false;
3164
2.40k
    }
3165
24.2k
    object.m_textZone=smallText;
3166
24.2k
    pos=input->tell();
3167
24.2k
    f << "depth=[";
3168
68.2k
    for (long i=0; i<N; ++i) {
3169
44.0k
      object.m_depthList.push_back(int(input->readULong(2)));
3170
44.0k
      f << object.m_depthList.back() << ",";
3171
44.0k
    }
3172
24.2k
    f << "],";
3173
24.2k
    *input >> object.m_isEditDoc;
3174
24.2k
    if (object.m_isEditDoc) f << "isEditDoc,";
3175
24.2k
  }
3176
24.4k
  ascFile.addPos(pos);
3177
24.4k
  ascFile.addNote(f.str().c_str());
3178
24.4k
  return true;
3179
27.5k
}
3180
3181
bool StarObjectSmallGraphic::readSDRGluePoint(StarZone &zone, StarObjectSmallGraphicInternal::GluePoint &pt)
3182
417
{
3183
417
  pt=StarObjectSmallGraphicInternal::GluePoint();
3184
417
  STOFFInputStreamPtr input=zone.input();
3185
417
  long pos=input->tell();
3186
417
  if (!zone.openRecord()) {
3187
172
    input->seek(pos, librevenge::RVNG_SEEK_SET);
3188
172
    return false;
3189
172
  }
3190
3191
245
  libstoff::DebugFile &ascFile=zone.ascii();
3192
245
  libstoff::DebugStream f;
3193
245
  f << "Entries(SdrGluePoint):";
3194
  // svx_svdglue_drawdoc.xx: operator>>(SdrGluePoint)
3195
245
  int dim[2];
3196
490
  for (int &i : dim) i=int(input->readULong(2));
3197
245
  pt.m_dimension=STOFFVec2i(dim[0],dim[1]);
3198
245
  pt.m_direction=int(input->readULong(2));
3199
245
  pt.m_id=int(input->readULong(2));
3200
245
  pt.m_align=int(input->readULong(2));
3201
245
  bool noPercent;
3202
245
  *input >> noPercent;
3203
245
  pt.m_percent=!noPercent;
3204
245
  f << "pt,";
3205
245
  ascFile.addPos(pos);
3206
245
  ascFile.addNote(f.str().c_str());
3207
245
  zone.closeRecord("SdrGluePoint");
3208
245
  return true;
3209
417
}
3210
3211
bool StarObjectSmallGraphic::readSDRGluePointList
3212
(StarZone &zone, std::vector<StarObjectSmallGraphicInternal::GluePoint> &listPoints)
3213
5.15k
{
3214
5.15k
  listPoints.clear();
3215
5.15k
  STOFFInputStreamPtr input=zone.input();
3216
5.15k
  long pos=input->tell();
3217
5.15k
  if (!zone.openRecord()) {
3218
4.81k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
3219
4.81k
    return false;
3220
4.81k
  }
3221
331
  long lastPos=zone.getRecordLastPosition();
3222
331
  libstoff::DebugFile &ascFile=zone.ascii();
3223
331
  libstoff::DebugStream f;
3224
331
  f << "Entries(SdrGluePoint)[list]:";
3225
  // svx_svdglue_drawdoc.xx: operator>>(SdrGluePointList)
3226
331
  auto n=int(input->readULong(2));
3227
331
  f << "n=" << n << ",";
3228
331
  ascFile.addPos(pos);
3229
331
  ascFile.addNote(f.str().c_str());
3230
576
  for (int i=0; i<n; ++i) {
3231
417
    pos=input->tell();
3232
417
    StarObjectSmallGraphicInternal::GluePoint pt;
3233
417
    if (!readSDRGluePoint(zone, pt) || input->tell()>lastPos) {
3234
172
      input->seek(pos, librevenge::RVNG_SEEK_SET);
3235
172
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDRGluePointList: can not find a glue point\n"));
3236
172
      break;
3237
172
    }
3238
245
    listPoints.push_back(pt);
3239
245
  }
3240
331
  zone.closeRecord("SdrGluePoint");
3241
331
  return true;
3242
5.15k
}
3243
3244
std::shared_ptr<StarObjectSmallGraphicInternal::SDRUserData> StarObjectSmallGraphic::readSDRUserData(StarZone &zone, bool inRecord)
3245
112k
{
3246
112k
  std::shared_ptr<StarObjectSmallGraphicInternal::SDRUserData> res;
3247
112k
  STOFFInputStreamPtr input=zone.input();
3248
112k
  long pos=input->tell();
3249
112k
  if (inRecord && !zone.openRecord()) {
3250
2.32k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
3251
2.32k
    return res;
3252
2.32k
  }
3253
3254
110k
  libstoff::DebugFile &ascFile=zone.ascii();
3255
110k
  libstoff::DebugStream f;
3256
110k
  f << "Entries(SdrUserData):";
3257
  // svx_svdobj.xx: SdrObject::ReadData
3258
110k
  long lastPos=zone.getRecordLastPosition();
3259
110k
  if (input->tell()+6>lastPos) {
3260
1.86k
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDRUserData: the zone seems too short\n"));
3261
1.86k
  }
3262
108k
  else {
3263
108k
    std::string type("");
3264
543k
    for (int i=0; i<4; ++i) type+=char(input->readULong(1));
3265
108k
    auto id=int(input->readULong(2));
3266
108k
    f << type << ",id=" << id << ",";
3267
108k
    if (type=="SCHU" || type=="SDUD") {
3268
106k
      if (type=="SCHU")
3269
100k
        res=readSCHUObject(zone, id);
3270
6.04k
      else if (type=="SDUD")
3271
6.04k
        res=readSDUDObject(zone, id);
3272
106k
      if (!res) {
3273
1.19k
        f << "##";
3274
1.19k
        if (!inRecord) {
3275
123
          STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDRUserData: can not determine end size\n"));
3276
123
          ascFile.addPos(pos);
3277
123
          ascFile.addNote(f.str().c_str());
3278
123
          return res;
3279
123
        }
3280
1.19k
      }
3281
105k
      else if (!inRecord)
3282
80
        lastPos=input->tell();
3283
106k
    }
3284
1.76k
    else {
3285
1.76k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDRUserData: find unknown type=%s\n", type.c_str()));
3286
1.76k
      f << "###";
3287
1.76k
      static bool first=true;
3288
1.76k
      if (first) {
3289
4
        first=false;
3290
4
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDRUserData: reading data is not implemented\n"));
3291
4
      }
3292
1.76k
      if (!inRecord) {
3293
273
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDRUserData: can not determine end size\n"));
3294
273
        f << "##";
3295
273
        ascFile.addPos(pos);
3296
273
        ascFile.addNote(f.str().c_str());
3297
273
        return res;
3298
273
      }
3299
1.49k
      res=std::make_shared<StarObjectSmallGraphicInternal::SDRUserData>();
3300
1.49k
    }
3301
108k
  }
3302
110k
  if (input->tell()!=lastPos) {
3303
4.72k
    ascFile.addDelimiter(input->tell(),'|');
3304
4.72k
    input->seek(lastPos, librevenge::RVNG_SEEK_SET);
3305
4.72k
  }
3306
110k
  ascFile.addPos(pos);
3307
110k
  ascFile.addNote(f.str().c_str());
3308
110k
  if (inRecord)
3309
108k
    zone.closeRecord("SdrUserData");
3310
110k
  return res;
3311
110k
}
3312
3313
bool StarObjectSmallGraphic::readSDRUserDataList(StarZone &zone, bool inRecord,
3314
    std::vector<std::shared_ptr<StarObjectSmallGraphicInternal::SDRUserData> > &dataList)
3315
81.8k
{
3316
81.8k
  STOFFInputStreamPtr input=zone.input();
3317
81.8k
  long pos=input->tell();
3318
81.8k
  if (inRecord && !zone.openRecord()) {
3319
3.62k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
3320
3.62k
    return false;
3321
3.62k
  }
3322
78.1k
  long lastPos=zone.getRecordLastPosition();
3323
78.1k
  libstoff::DebugFile &ascFile=zone.ascii();
3324
78.1k
  libstoff::DebugStream f;
3325
78.1k
  f << "Entries(SdrUserData)[list]:";
3326
  // svx_svdglue_drawdoc.xx: operator>>(SdrUserDataList)
3327
78.1k
  auto n=int(input->readULong(2));
3328
78.1k
  f << "n=" << n << ",";
3329
78.1k
  ascFile.addPos(pos);
3330
78.1k
  ascFile.addNote(f.str().c_str());
3331
185k
  for (int i=0; i<n; ++i) {
3332
112k
    pos=input->tell();
3333
112k
    auto data=readSDRUserData(zone, inRecord);
3334
112k
    if (!data || input->tell()>lastPos) {
3335
5.66k
      input->seek(pos, librevenge::RVNG_SEEK_SET);
3336
5.66k
      STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDRUserDataList: can not find a glue point\n"));
3337
5.66k
      break;
3338
5.66k
    }
3339
107k
    dataList.push_back(data);
3340
107k
  }
3341
78.1k
  if (inRecord) zone.closeRecord("SdrUserData");
3342
78.1k
  return true;
3343
81.8k
}
3344
3345
////////////////////////////////////////////////////////////
3346
// FM01 object
3347
////////////////////////////////////////////////////////////
3348
std::shared_ptr<StarObjectSmallGraphicInternal::Graphic> StarObjectSmallGraphic::readFmFormObject(StarZone &zone, int identifier)
3349
421
{
3350
421
  STOFFInputStreamPtr input=zone.input();
3351
421
  long pos=input->tell();
3352
421
  libstoff::DebugFile &ascFile=zone.ascii();
3353
421
  libstoff::DebugStream f;
3354
421
  f << "Entries(FM01):";
3355
3356
421
  if (identifier!=33) {
3357
130
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readFmFormObject: find unknown identifier\n"));
3358
130
    f << "###id=" << identifier << ",";
3359
130
    ascFile.addPos(pos);
3360
130
    ascFile.addNote(f.str().c_str());
3361
3362
130
    return std::shared_ptr<StarObjectSmallGraphicInternal::Graphic>();
3363
130
  }
3364
  // svx_fmobj.cxx FmFormObj::ReadData
3365
  // fixme: same code as SdrUnoObj::ReadData
3366
291
  std::shared_ptr<StarObjectSmallGraphicInternal::SdrGraphicUno> graphic(new StarObjectSmallGraphicInternal::SdrGraphicUno());
3367
291
  if (!readSVDRObjectRect(zone, *graphic)) {
3368
123
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readFmFormObject: can not read rect data\n"));
3369
123
    f << "###id=" << identifier << ",";
3370
123
    ascFile.addPos(pos);
3371
123
    ascFile.addNote(f.str().c_str());
3372
3373
123
    return std::shared_ptr<StarObjectSmallGraphicInternal::Graphic>();
3374
123
  }
3375
168
  pos=input->tell();
3376
168
  if (!zone.openRecord()) {
3377
16
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readFmFormObject: can not open uno record\n"));
3378
16
    input->seek(pos, librevenge::RVNG_SEEK_SET);
3379
16
    f << "###id=" << identifier << ",";
3380
16
    ascFile.addPos(pos);
3381
16
    ascFile.addNote(f.str().c_str());
3382
3383
16
    return std::shared_ptr<StarObjectSmallGraphicInternal::Graphic>();
3384
16
  }
3385
152
  f << "FM01[uno]:";
3386
  // + SdrUnoObj::ReadData (checkme)
3387
152
  std::vector<uint32_t> string;
3388
152
  bool ok=true;
3389
152
  if (input->tell()!=zone.getRecordLastPosition() && (!zone.readString(string) || input->tell()>zone.getRecordLastPosition())) {
3390
0
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readFmFormObject: can not read uno string\n"));
3391
0
    f << "###uno";
3392
0
    ok=false;
3393
0
  }
3394
152
  else
3395
152
    graphic->m_unoName=libstoff::getString(string);
3396
152
  f << *graphic;
3397
152
  ascFile.addPos(pos);
3398
152
  ascFile.addNote(f.str().c_str());
3399
152
  if (!ok)
3400
0
    input->seek(zone.getRecordLastPosition(), librevenge::RVNG_SEEK_SET);
3401
152
  zone.closeRecord("FM01");
3402
152
  return graphic;
3403
168
}
3404
3405
////////////////////////////////////////////////////////////
3406
// SCHU object
3407
////////////////////////////////////////////////////////////
3408
std::shared_ptr<StarObjectSmallGraphicInternal::SDRUserData> StarObjectSmallGraphic::readSCHUObject(StarZone &zone, int identifier)
3409
115k
{
3410
115k
  std::shared_ptr<StarObjectSmallGraphicInternal::SCHUGraphic> graphic;
3411
115k
  if (identifier==1) {
3412
14.3k
    auto group=std::make_shared<StarObjectSmallGraphicInternal::SdrGraphicGroup>(1);
3413
14.3k
    if (readSVDRObjectGroup(zone, *group)) {
3414
13.6k
      graphic = std::make_shared<StarObjectSmallGraphicInternal::SCHUGraphic>(identifier);
3415
13.6k
      graphic->m_group=group;
3416
13.6k
    }
3417
14.3k
    return graphic;
3418
14.3k
  }
3419
101k
  STOFFInputStreamPtr input=zone.input();
3420
101k
  long pos=input->tell();
3421
3422
101k
  libstoff::DebugFile &ascFile=zone.ascii();
3423
101k
  libstoff::DebugStream f;
3424
101k
  f << "Entries(SCHU):";
3425
101k
  if (identifier<=0 || identifier>7) {
3426
732
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSCHUObject: find unknown identifier\n"));
3427
732
    f << "###id=" << identifier << ",";
3428
732
    ascFile.addPos(pos);
3429
732
    ascFile.addNote(f.str().c_str());
3430
3431
732
    return graphic;
3432
732
  }
3433
100k
  graphic = std::make_shared<StarObjectSmallGraphicInternal::SCHUGraphic>(identifier);
3434
  // sch_objfac.cxx : SchObjFactory::MakeUserData
3435
100k
  auto vers=int(input->readULong(2));
3436
100k
  switch (identifier) {
3437
67.3k
  case 2:
3438
67.4k
  case 7:
3439
67.4k
    graphic->m_id=int(input->readULong(2));
3440
67.4k
    break;
3441
10.9k
  case 3:
3442
10.9k
    graphic->m_adjust=int(input->readULong(2));
3443
10.9k
    if (vers>=1)
3444
10.8k
      graphic->m_orientation=int(input->readULong(2));
3445
10.9k
    break;
3446
6.85k
  case 4:
3447
6.85k
    graphic->m_row=int(input->readLong(2));
3448
6.85k
    break;
3449
15.4k
  case 5:
3450
15.4k
    graphic->m_column=int(input->readLong(2));
3451
15.4k
    graphic->m_row=int(input->readLong(2));
3452
15.4k
    break;
3453
152
  case 6:
3454
152
    *input >> graphic->m_factor;
3455
152
    break;
3456
0
  default:
3457
0
    f << "##";
3458
0
    break;
3459
100k
  }
3460
100k
  f << *graphic;
3461
100k
  ascFile.addPos(pos);
3462
100k
  ascFile.addNote(f.str().c_str());
3463
100k
  return graphic;
3464
100k
}
3465
3466
////////////////////////////////////////////////////////////
3467
// SDUD object
3468
////////////////////////////////////////////////////////////
3469
std::shared_ptr<StarObjectSmallGraphicInternal::SDRUserData> StarObjectSmallGraphic::readSDUDObject(StarZone &zone, int identifier)
3470
6.04k
{
3471
6.04k
  std::shared_ptr<StarObjectSmallGraphicInternal::SDUDGraphic> res;
3472
6.04k
  STOFFInputStreamPtr input=zone.input();
3473
6.04k
  long pos=input->tell();
3474
3475
6.04k
  libstoff::DebugFile &ascFile=zone.ascii();
3476
6.04k
  libstoff::DebugStream f;
3477
6.04k
  if (identifier<=0 || identifier>2) {
3478
233
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: find unknown identifier\n"));
3479
233
    f << "Entries(SDUD):###id=" << identifier << ",";
3480
233
    ascFile.addPos(pos);
3481
233
    ascFile.addNote(f.str().c_str());
3482
3483
233
    return res;
3484
233
  }
3485
  // sd_sdobjfac.cxx : SchObjFactory::MakeUserData
3486
5.81k
  auto vers=int(input->readULong(2));
3487
5.81k
  f << "vers=" << vers << ",";
3488
5.81k
  if (!zone.openSCHHeader()) {
3489
500
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: can not open main record\n"));
3490
500
    ascFile.addPos(pos);
3491
500
    ascFile.addNote(f.str().c_str());
3492
3493
500
    return res;
3494
500
  }
3495
5.31k
  vers=zone.getHeaderVersion();
3496
5.31k
  long endPos=zone.getRecordLastPosition();
3497
5.31k
  if (identifier==1) {
3498
    // sd_anminfo.cxx SdAnimationInfo::ReadData
3499
5.27k
    auto graphic=std::make_shared<StarObjectSmallGraphicInternal::SDUDGraphicAnimation>();
3500
5.27k
    res=graphic;
3501
5.27k
    bool ok=true;
3502
5.27k
    if (input->readULong(2)) {
3503
530
      uint16_t n;
3504
530
      *input >> n;
3505
530
      if (input->tell()+8*n>endPos) {
3506
205
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: the number of point seems bad\n"));
3507
205
        f << "###n=" << n << ",";
3508
205
        ok=false;
3509
205
      }
3510
325
      else {
3511
1.00k
        for (int pt=0; pt<int(n); ++pt) {
3512
684
          int dim[2];
3513
1.36k
          for (int &i : dim) i=int(input->readLong(4));
3514
684
          graphic->m_polygon.push_back(STOFFVec2i(dim[0],dim[1]));
3515
684
        }
3516
325
      }
3517
530
    }
3518
5.27k
    if (ok) {
3519
10.1k
      for (auto &limit : graphic->m_limits) {
3520
10.1k
        int dim[2];
3521
20.2k
        for (int &i : dim) i=int(input->readLong(4));
3522
10.1k
        limit=STOFFVec2i(dim[0],dim[1]);
3523
10.1k
      }
3524
15.2k
      for (int i=0; i<2; ++i)
3525
10.1k
        graphic->m_values[i]=int(input->readULong(2));
3526
15.2k
      for (bool &flag : graphic->m_flags) flag=input->readULong(2)!=0;
3527
5.06k
      if (input->tell()>endPos) {
3528
105
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: the zone is too short\n"));
3529
105
        f << "###short";
3530
105
        ok=false;
3531
105
      }
3532
5.06k
    }
3533
5.27k
    if (ok) {
3534
9.81k
      for (auto &c : graphic->m_colors) {
3535
9.81k
        STOFFColor color;
3536
9.81k
        if (!input->readColor(color) || input->tell()>endPos) {
3537
265
          STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: can not find a color\n"));
3538
265
          f << "###aColor,";
3539
265
          ok=false;
3540
265
          break;
3541
265
        }
3542
9.54k
        else
3543
9.54k
          c=color;
3544
9.81k
      }
3545
4.96k
    }
3546
5.27k
    int encoding=0;
3547
5.27k
    if (ok && vers>0) {
3548
4.61k
      encoding=int(input->readULong(2));
3549
4.61k
      std::vector<uint32_t> string;
3550
4.61k
      if (ok && (!zone.readString(string, encoding) || input->tell()>endPos)) {
3551
277
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: can not find string\n"));
3552
277
        f << "###string,";
3553
277
        ok=false;
3554
277
      }
3555
4.33k
      else
3556
4.33k
        graphic->m_names[0]=libstoff::getString(string);
3557
4.61k
    }
3558
5.27k
    if (ok && vers>1)
3559
4.32k
      *input >> graphic->m_booleans[0];
3560
5.27k
    if (ok && vers>2)
3561
4.32k
      *input >> graphic->m_booleans[1];
3562
5.27k
    if (ok && vers>3) {
3563
4.32k
      auto nFlag=int(input->readULong(2));
3564
4.32k
      if (nFlag==1) {
3565
        // TODO store surrogate
3566
200
        ascFile.addPos(pos);
3567
200
        ascFile.addNote(f.str().c_str());
3568
200
        pos=input->tell();
3569
200
        f.str("");
3570
200
        f << "SDUD-B:";
3571
200
        if (!readSDRObjectSurrogate(zone) || input->tell()>endPos) {
3572
52
          STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: can not read object surrogate\n"));
3573
52
          f << "###surrogate";
3574
52
          ok=false;
3575
52
        }
3576
148
        else
3577
148
          pos=input->tell();
3578
200
      }
3579
4.32k
    }
3580
5.27k
    if (ok && vers>4) {
3581
17.1k
      for (int i=2; i<5; ++i)
3582
12.8k
        graphic->m_values[i]=int(input->readULong(2));
3583
12.1k
      for (int i=1; i<3; ++i) {
3584
8.24k
        std::vector<uint32_t> string;
3585
8.24k
        if (ok && (!zone.readString(string, encoding) || input->tell()>endPos)) {
3586
393
          STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: can not find string\n"));
3587
393
          f << "###string,";
3588
393
          ok=false;
3589
393
          break;
3590
393
        }
3591
7.85k
        graphic->m_names[i]=libstoff::getString(string);
3592
7.85k
      }
3593
4.27k
      if (ok) {
3594
11.6k
        for (int i=5; i<7; ++i)
3595
7.76k
          graphic->m_values[i]=int(input->readULong(2));
3596
3.88k
      }
3597
4.27k
    }
3598
5.27k
    if (ok && vers>5)
3599
3.88k
      *input >> graphic->m_booleans[2] >> graphic->m_booleans[3];
3600
5.27k
    if (ok && vers>6)
3601
3.88k
      *input >> graphic->m_booleans[4];
3602
5.27k
    if (ok && vers>7)
3603
3.88k
      graphic->m_values[7]=int(input->readULong(2));
3604
5.27k
    if (ok && vers>8)
3605
3.87k
      graphic->m_order=int(input->readULong(4));
3606
5.27k
    if (input->tell()!=endPos) {
3607
1.60k
      ascFile.addDelimiter(input->tell(),'|');
3608
1.60k
      if (ok) {
3609
303
        STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: find extra data\n"));
3610
303
        f << "###";
3611
303
      }
3612
1.60k
      input->seek(endPos, librevenge::RVNG_SEEK_SET);
3613
1.60k
    }
3614
5.27k
    std::string extra=f.str();
3615
5.27k
    f.str("");
3616
5.27k
    f << "Entries(SDUD):" << *graphic << extra;
3617
5.27k
  }
3618
36
  else {
3619
36
    res=std::make_shared<StarObjectSmallGraphicInternal::SDUDGraphic>(identifier);
3620
36
    f.str("");
3621
36
    f << "Entries(SDUD):imageMap,###";
3622
    // imap2.cxx ImageMap::Read ; never seen, complex, so...
3623
36
    STOFF_DEBUG_MSG(("StarObjectSmallGraphic::readSDUDObject: reading imageMap is not implemented\n"));
3624
36
    f << "###";
3625
36
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
3626
36
  }
3627
5.31k
  ascFile.addPos(pos);
3628
5.31k
  ascFile.addNote(f.str().c_str());
3629
5.31k
  zone.closeSCHHeader("SDUD");
3630
5.31k
  return res;
3631
5.81k
}
3632
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: