/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
/* libmwaw
* Version: MPL 2.0 / LGPLv2+
*
* The contents of this file are subject to the Mozilla Public License Version
* 2.0 (the "License"); you may not use this file except in compliance with
* the License or as specified alternatively below. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Major Contributor(s):
* Copyright (C) 2002 William Lachance (wrlach@gmail.com)
* Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
* Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
* Copyright (C) 2006, 2007 Andrew Ziem
* Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
*
*
* All Rights Reserved.
*
* For minor contributions see the git repository.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
* in which case the provisions of the LGPLv2+ are applicable
* instead of those above.
*/
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <sstream>
#include <librevenge/librevenge.h>
#include "MWAWTextListener.hxx"
#include "MWAWPictData.hxx"
#include "MWAWPosition.hxx"
#include "MWAWSubDocument.hxx"
#include "FullWrtParser.hxx"
#include "FullWrtStruct.hxx"
#include "FullWrtGraph.hxx"
/** Internal: the structures of a FullWrtGraph */
namespace FullWrtGraphInternal
{
////////////////////////////////////////
//! Internal: the sidebar of a FullWrtGraph
struct SideBar final : public FullWrtStruct::ZoneHeader {
//! constructor
explicit SideBar(FullWrtStruct::ZoneHeader const &header): FullWrtStruct::ZoneHeader(header), m_box(), m_page(0), m_borderId(0), m_parsed(false)
{
}
//! destructor
~SideBar() final;
//! the position (in point)
MWAWBox2f m_box;
//! the page
int m_page;
//! the border id
int m_borderId;
//! a flag to know if the sidebar is send to the listener
mutable bool m_parsed;
};
SideBar::~SideBar()
{
}
////////////////////////////////////////
//! Internal: the state of a FullWrtGraph
struct State {
//! constructor
State()
: m_version(-1)
, m_sidebarList()
, m_graphicMap()
, m_borderList()
, m_numPages(-1) { }
//! the file version
mutable int m_version;
//! the sidebar list
std::vector<std::shared_ptr<SideBar> > m_sidebarList;
//! zoneId -> graphic entry
std::multimap<int, FullWrtStruct::EntryPtr > m_graphicMap;
//! a list of border
std::vector<FullWrtStruct::Border> m_borderList;
int m_numPages /* the number of pages */;
};
////////////////////////////////////////
//! Internal: the subdocument of a FullWrtGraph
class SubDocument final : public MWAWSubDocument
{
public:
//! constructor
SubDocument(FullWrtGraph &pars, int id, MWAWColor fontColor)
: MWAWSubDocument(pars.m_mainParser, MWAWInputStreamPtr(), MWAWEntry())
, m_graphParser(&pars)
, m_id(id)
, m_fontColor(fontColor) {}
//! destructor
~SubDocument() final {}
//! operator!=
bool operator!=(MWAWSubDocument const &doc) const final;
//! the parser function
void parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType type) final;
protected:
/** the graph parser */
FullWrtGraph *m_graphParser;
//! the zone file id
int m_id;
//! the default font color
MWAWColor m_fontColor;
private:
SubDocument(SubDocument const &orig) = delete;
SubDocument &operator=(SubDocument const &orig) = delete;
};
void SubDocument::parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType /*type*/)
{
if (!listener.get()) {
MWAW_DEBUG_MSG(("FullWrtGraphInternal::SubDocument::parse: no listener\n"));
return;
}
if (!m_graphParser) {
MWAW_DEBUG_MSG(("FullWrtGraphInternal::SubDocument::parse: no graph parser\n"));
return;
}
m_graphParser->send(m_id, m_fontColor);
}
bool SubDocument::operator!=(MWAWSubDocument const &doc) const
{
if (MWAWSubDocument::operator!=(doc)) return true;
auto const *sDoc = dynamic_cast<SubDocument const *>(&doc);
if (!sDoc) return true;
if (m_graphParser != sDoc->m_graphParser) return true;
if (m_id != sDoc->m_id) return true;
if (m_fontColor != sDoc->m_fontColor) return true;
return false;
}
}
////////////////////////////////////////////////////////////
// constructor/destructor, ...
////////////////////////////////////////////////////////////
FullWrtGraph::FullWrtGraph(FullWrtParser &parser)
: m_parserState(parser.getParserState())
, m_state(new FullWrtGraphInternal::State)
, m_mainParser(&parser)
{
}
FullWrtGraph::~FullWrtGraph()
{
}
int FullWrtGraph::version() const
{
if (m_state->m_version < 0)
m_state->m_version = m_parserState->m_version;
return m_state->m_version;
}
int FullWrtGraph::numPages() const
{
if (m_state->m_numPages > 0)
return m_state->m_numPages;
int nPage=0;
for (auto sidebar : m_state->m_sidebarList) {
if (!sidebar)
continue;
if (sidebar->m_page>nPage)
nPage=sidebar->m_page;
}
return (m_state->m_numPages=nPage);
}
bool FullWrtGraph::getBorder(int bId, FullWrtStruct::Border &border) const
{
if (bId < 0 || bId>= int(m_state->m_borderList.size())) {
MWAW_DEBUG_MSG(("FullWrtGraph::getBorder: can not find border %d\n", bId));
border=FullWrtStruct::Border();
return false;
}
border=m_state->m_borderList[size_t(bId)];
return true;
}
bool FullWrtGraph::send(int fileId, MWAWColor const &fontColor)
{
return m_mainParser->send(fileId, fontColor);
}
////////////////////////////////////////////////////////////
//
// Intermediate level
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// low level
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// border
bool FullWrtGraph::readBorderDocInfo(FullWrtStruct::EntryPtr zone)
{
MWAWInputStreamPtr input = zone->m_input;
libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
libmwaw::DebugStream f;
long pos = input->tell();
if (input->readULong(4)!=0x626f7264 || input->readULong(1)) {
input->seek(pos, librevenge::RVNG_SEEK_SET);
return false;
}
long blckSz = input->readLong(4);
long endData = pos+9+blckSz;
auto num = static_cast<int>(input->readULong(2));
int const fSz = 26;
f << "Entries(Border):N=" << num << ",";
if (blckSz < 2 || blckSz != 2 + num*fSz || endData > zone->end()) {
MWAW_DEBUG_MSG(("FullWrtGraph::readBorderDocInfo: problem reading the data block or the number of data\n"));
f << "###";
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
if (endData <= zone->end()) {
input->seek(endData, librevenge::RVNG_SEEK_SET);
return true;
}
input->seek(pos, librevenge::RVNG_SEEK_SET);
return false;
}
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
m_state->m_borderList.push_back(FullWrtStruct::Border());
for (int i = 0; i < num; i++) {
pos = input->tell();
FullWrtStruct::Border mod;
f.str("");
f << "Border-B" << i << ":";
if (!mod.read(zone, fSz))
f << "###";
else
f << mod;
m_state->m_borderList.push_back(mod);
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
input->seek(pos+fSz, librevenge::RVNG_SEEK_SET);
}
return true;
}
////////////////////////////////////////////////////////////
// side bar
std::shared_ptr<FullWrtStruct::ZoneHeader> FullWrtGraph::readSideBar(FullWrtStruct::EntryPtr zone, FullWrtStruct::ZoneHeader const &doc)
{
std::shared_ptr<FullWrtGraphInternal::SideBar> sidebar;
if (doc.m_type != 0x13 && doc.m_type != 0x14) {
MWAW_DEBUG_MSG(("FullWrtGraph::readSideBar: find unexpected type\n"));
return sidebar;
}
MWAWInputStreamPtr input = zone->m_input;
long pos = input->tell();
sidebar.reset(new FullWrtGraphInternal::SideBar(doc));
if (!sidebar->read(zone)) {
input->seek(pos, librevenge::RVNG_SEEK_SET);
sidebar.reset();
return sidebar;
}
int val;
if (input->tell()+12 > zone->end()) {
input->seek(pos, librevenge::RVNG_SEEK_SET);
sidebar.reset();
return sidebar;
}
libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
libmwaw::DebugStream f;
f << "Entries(SideBar):" << *sidebar;
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
for (int i=0; i<3; ++i) {
pos = input->tell();
bool ok=false;
switch (i) {
case 0:
ok=readSideBarPosition(zone, *sidebar);
break;
case 1:
ok=readSideBarFormat(zone, *sidebar);
break;
case 2:
ok=readSideBarUnknown(zone, *sidebar);
break;
default:
break;
}
if (ok) continue;
MWAW_DEBUG_MSG(("FullWrtGraph::readSideBar: pb reading the zone %d\n", i));
f.str("");
static char const *wh[]= {"position","format","unknown"};
f << "SideBar[" << wh[i] << ":###";
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
input->seek(pos, librevenge::RVNG_SEEK_SET);
return sidebar;
}
// checkme: can this exist for a sidebar ?
val = int(input->readLong(1));
if (val==1) {
pos = input->tell();
auto sz = long(input->readULong(4));
if (sz && input->tell()+sz <= zone->end()) {
f.str("");
f << "SideBar[end]:";
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
input->seek(sz, librevenge::RVNG_SEEK_CUR);
}
else {
MWAW_DEBUG_MSG(("FullWrtGraph::readSideBar: find bad end data\n"));
input->seek(pos, librevenge::RVNG_SEEK_SET);
}
}
else if (val) {
MWAW_DEBUG_MSG(("FullWrtGraph::readSideBar: find bad end data(II)\n"));
}
m_state->m_sidebarList.push_back(sidebar);
return sidebar;
}
bool FullWrtGraph::readSideBarPosition(FullWrtStruct::EntryPtr zone, FullWrtGraphInternal::SideBar &frame)
{
MWAWInputStreamPtr input = zone->m_input;
long pos = input->tell();
libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
libmwaw::DebugStream f;
auto sz = long(input->readULong(4));
if (sz < 0 || pos+sz+4 > zone->end())
return false;
f << "SideBar[pos]:";
if (sz < 28) {
MWAW_DEBUG_MSG(("FullWrtGraph::readSideBarPosition: the size seems bad\n"));
f << "###";
input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
return true;
}
int dim[4];
for (auto &d : dim) d=int(input->readLong(2));
frame.m_box=MWAWBox2f(MWAWVec2f(float(dim[1]),float(dim[0])),MWAWVec2f(float(dim[3]),float(dim[2])));
f << "pos=" << frame.m_box << ",";
auto val=int(input->readLong(2));
if (val) f << "w[wrap]=" << val << "pt,";
f << "ptr?=[" << std::hex;
for (int i = 0; i < 2; i++) // two big number
f << input->readULong(4) << ",";
f << std::dec << "],";
val = int(input->readLong(2)); // seems related to floating point position
if (val) f << "unkn=" << std::hex << val << std::dec << ",";// 0|441|442|f91|16ac
val = int(input->readLong(2)); // always 0?
if (val) f << "f0=" << val << ",";
frame.m_page = int(input->readLong(2));
if (frame.m_page) f << "page=" << frame.m_page << ",";
val = int(input->readLong(2)); // number of point in the left part
if (val) f << "N[left]?=" << val << ",";
auto N=static_cast<int>(input->readLong(2));
if (N*4+28 > sz) {
f << "#N=" << N << ",";
N=0;
}
else
f << "N=" << N << ",";
/* probably first the left margin: (x_i,n): meaning to add n times
a point at x, then the same thing for the right margins
-16000/16000=no point (left/right)
*/
f << "mask=[";
for (int i = 0; i < N; i++) {
auto x = int(input->readLong(2));
auto n = int(input->readLong(2));
f << x << ":" << n << ",";
}
f << "],";
if (input->tell() != pos+4+sz) {
asciiFile.addDelimiter(input->tell(),'|');
input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
}
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
return true;
}
bool FullWrtGraph::readSideBarFormat(FullWrtStruct::EntryPtr zone, FullWrtGraphInternal::SideBar &frame)
{
int const vers=version();
MWAWInputStreamPtr input = zone->m_input;
long pos = input->tell();
libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
libmwaw::DebugStream f;
auto sz = long(input->readULong(4));
if (sz < 0 || pos+sz+4 > zone->end())
return false;
f << "SideBar[format]:";
if ((vers==1&&sz!=0x3a)||(vers==2&&sz!=0x38)) {
MWAW_DEBUG_MSG(("FullWrtGraph::readSideBarFormat: the size seems bad\n"));
f << "###";
input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
return true;
}
f << "PTR=" << std::hex << input->readLong(4) << std::dec << ",";
auto N=static_cast<int>(input->readLong(1));
int val;
if (N) {
f << "N=" << N << ",";
val=static_cast<int>(input->readLong(1));
if (val) f << "#f0=" << val << ",";
/* now probably N*[unknData],
find for N=1 005f000000b201d2001600f40f94020004100001009700000000000000000000
*/
}
input->seek(pos+42, librevenge::RVNG_SEEK_SET);
float dim[2];
for (auto &d : dim) d=float(input->readLong(4))/65536.f;
f << "dim?=" << dim[1] << "x" << dim[0] << ",";
val=static_cast<int>(input->readULong(2)); // another dim with a flag?
if (val&0x8000) f << "f1[high],";
if (val&0x7FFF) f << "f1=" << (val&0x7FFF) << ",";
float w=float(input->readLong(4))/65536.f;
f << "w[wrap]=" << w << "pt,";
frame.m_borderId=static_cast<int>(input->readLong(2));
if (frame.m_borderId)
f << "B" << frame.m_borderId-1 << ",";
if (vers==1) {
val=static_cast<int>(input->readLong(2)); // 0|1|4|b|20|..f0
if (val) f << "f2=" << val << ",";
}
val=static_cast<int>(input->readLong(2)); // always 0
if (val)
f << "f3=" << val << ",";
if (input->tell() != pos+4+sz) {
asciiFile.addDelimiter(input->tell(),'|');
input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
}
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
return true;
}
bool FullWrtGraph::readSideBarUnknown(FullWrtStruct::EntryPtr zone, FullWrtGraphInternal::SideBar &/*frame*/)
{
MWAWInputStreamPtr input = zone->m_input;
long pos = input->tell();
libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
libmwaw::DebugStream f;
auto sz = long(input->readULong(4));
if (sz < 0 || pos+sz+4 > zone->end())
return false;
f << "SideBar[unknown]:";
if (sz!=0x30) {
MWAW_DEBUG_MSG(("FullWrtGraph::readSideBarUnknown: the size seems bad\n"));
f << "###";
input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
return true;
}
auto val = static_cast<int>(input->readLong(2));
if (val!=-1)
f << "f0=" << val << ",";
val = static_cast<int>(input->readLong(2));
if (val!=1)
f << "f1=" << val << ",";
val = static_cast<int>(input->readULong(2)); // maybe a color?
if (val)
f << "f2=" << std::hex << val << std::dec << ",";
for (int i=0; i<2; ++i) { // f3=1|2, f4=small numer 0..ff
val = static_cast<int>(input->readULong(2));
if (val)
f << "f" << i+3 << "=" << val << ",";
}
for (int i=0; i<19; ++i) { // g0,g1,g17,g18: in form xyxy, other 0
val = static_cast<int>(input->readULong(2));
if (val)
f << "g" << i << "=" << std::hex << val << std::dec << ",";
}
if (input->tell() != pos+4+sz) {
asciiFile.addDelimiter(input->tell(),'|');
input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
}
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
return true;
}
bool FullWrtGraph::sendSideBar(FullWrtGraphInternal::SideBar const &frame)
{
MWAWTextListenerPtr listener=m_parserState->m_textListener;
if (!listener) {
MWAW_DEBUG_MSG(("FullWrtGraph::sendSideBar can not find the listener\n"));
return true;
}
frame.m_parsed=true;
MWAWPosition pos(frame.m_box[0]+72.f*m_mainParser->getPageLeftTop(),
frame.m_box.size(),librevenge::RVNG_POINT);
pos.setPage(frame.m_page>0 ? frame.m_page : 1);
pos.setRelativePosition(MWAWPosition::Page);
pos.m_wrapping=(frame.m_wrapping==3) ?
MWAWPosition::WBackground : MWAWPosition::WDynamic;
FullWrtStruct::Border border;
MWAWGraphicStyle style;
if (frame.m_borderId && getBorder(frame.m_borderId, border))
border.addTo(style);
MWAWSubDocumentPtr doc(new FullWrtGraphInternal::SubDocument(*this,frame.m_fileId,border.m_frontColor));
listener->insertTextBox(pos, doc, style);
return true;
}
////////////////////////////////////////////////////////////
// graphic: data +
std::shared_ptr<FullWrtStruct::ZoneHeader> FullWrtGraph::readGraphicData(FullWrtStruct::EntryPtr zone, FullWrtStruct::ZoneHeader &doc)
{
std::shared_ptr<FullWrtStruct::ZoneHeader> graphData;
if (doc.m_type != 0x15) {
MWAW_DEBUG_MSG(("FullWrtGraph::readGraphicData: find unexpected type\n"));
return graphData;
}
MWAWInputStreamPtr input = zone->m_input;
long pos = input->tell();
if (!doc.read(zone)) {
input->seek(pos, librevenge::RVNG_SEEK_SET);
return graphData;
}
int const vers = version();
libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
libmwaw::DebugStream f;
if (input->tell()+(vers==2?14:2) > zone->end()) {
input->seek(pos, librevenge::RVNG_SEEK_SET);
return graphData;
}
graphData.reset(new FullWrtStruct::ZoneHeader(doc));
f.str("");
f << "Entries(GraphData):" << doc;
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
if (vers == 2) {
pos = input->tell();
f.str("");
f << "GraphData[1]:";
int dim[4];
for (auto &d : dim) d=int(input->readLong(2));
f << "box=" << dim[1] << "x" << dim[0] << "<->" << dim[3] << "x" << dim[2] << ",";
for (int i = 0; i < 2; i++) { // always 0 ?
auto val = int(input->readLong(2));
if (val)
f << "f" << i << "=" << val << "c";
}
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
}
f.str("");
auto nextData = int(input->readULong(1));
pos = input->tell();
if (nextData==1) {
f << "GraphData[2]:";
auto sz = long(input->readULong(4));
if (sz < 0 || pos+4+sz > zone->end()) {
f << "#sz=" << sz << ",";
input->seek(pos, librevenge::RVNG_SEEK_SET);
}
else if (sz) { // a serie of doc id ( normally 1e )
f << "docId[type1e?]=[";
for (int i = 0; i < sz/2; i++) {
auto id = int(input->readLong(2));
std::string type=m_mainParser->getDocumentTypeName(id);
if (type.empty())
f << "#" << id << ",";
else
f << id << "[" << type << "],";
}
f << "],";
input->seek(pos+4+sz, librevenge::RVNG_SEEK_SET);
}
}
else if (nextData) f << "GraphData[2]:#" << nextData;
input->seek(1, librevenge::RVNG_SEEK_CUR);
if (f.str().length()) {
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
}
return graphData;
}
bool FullWrtGraph::readGraphic(FullWrtStruct::EntryPtr zone)
{
int vers = version();
MWAWInputStreamPtr input = zone->m_input;
libmwaw::DebugFile &asciiFile = zone->getAsciiFile();
libmwaw::DebugStream f;
long pos = zone->begin();
input->seek(pos, librevenge::RVNG_SEEK_SET);
auto sz = long(input->readULong(4));
int expectedSz = vers==1 ? 0x5c : 0x54;
if (sz != expectedSz || pos+sz > zone->end()) return false;
input->seek(sz, librevenge::RVNG_SEEK_CUR);
f << "Entries(Graphic)";
f << "|" << *zone << ":";
if (zone->m_type >= 0)
f << "type=" << std::hex << zone->m_type << std::dec << ",";
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
pos = input->tell();
sz = long(input->readULong(4));
if (!sz || pos+4+sz > zone->end()) {
MWAW_DEBUG_MSG(("FullWrtGraph::readGraphic: can not read graphic size\n"));
return false;
}
f.str("");
f << "Graphic:sz=" << std::hex << sz << std::dec << ",";
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
asciiFile.skipZone(pos+4, pos+4+sz-1);
input->seek(sz, librevenge::RVNG_SEEK_CUR);
m_state->m_graphicMap.insert
(std::multimap<int, FullWrtStruct::EntryPtr >::value_type(zone->id(), zone));
pos = input->tell();
if (pos == zone->end())
return true;
sz = long(input->readULong(4));
if (sz)
input->seek(sz, librevenge::RVNG_SEEK_CUR);
if (pos+4+sz!=zone->end()) {
MWAW_DEBUG_MSG(("FullWrtGraph::readGraphic: end graphic seems odds\n"));
}
asciiFile.addPos(pos);
asciiFile.addNote("Graphic-A");
asciiFile.addPos(input->tell());
asciiFile.addNote("_");
return true;
}
////////////////////////////////////////////////////////////
// send data
////////////////////////////////////////////////////////////
bool FullWrtGraph::sendGraphic(int fId)
{
auto it = m_state->m_graphicMap.find(fId);
if (it == m_state->m_graphicMap.end() || !it->second) {
MWAW_DEBUG_MSG(("FullWrtGraph::sendGraphic: can not find graphic %d\n", fId));
return false;
}
auto zone = it->second;
MWAWInputStreamPtr input = zone->m_input;
long pos = input->tell();
bool ok=sendGraphic(zone);
input->seek(pos, librevenge::RVNG_SEEK_SET);
return ok;
}
bool FullWrtGraph::sendGraphic(FullWrtStruct::EntryPtr zone)
{
MWAWTextListenerPtr listener=m_parserState->m_textListener;
if (!listener) {
MWAW_DEBUG_MSG(("FullWrtGraph::sendGraphic can not find the listener\n"));
return true;
}
zone->setParsed(true);
MWAWInputStreamPtr input = zone->m_input;
long pos = zone->begin();
input->seek(pos, librevenge::RVNG_SEEK_SET);
auto sz = static_cast<int>(input->readULong(4));
input->seek(sz, librevenge::RVNG_SEEK_CUR);
// header
pos = input->tell();
sz = static_cast<int>(input->readULong(4));
#ifdef DEBUG_WITH_FILES
if (1) {
librevenge::RVNGBinaryData file;
input->seek(pos+4, librevenge::RVNG_SEEK_SET);
input->readDataBlock(sz, file);
static int volatile pictName = 0;
libmwaw::DebugStream f;
f << "DATA-" << ++pictName;
libmwaw::Debug::dumpFile(file, f.str().c_str());
}
#endif
input->seek(pos+4, librevenge::RVNG_SEEK_SET);
MWAWBox2f box;
auto res = MWAWPictData::check(input, sz, box);
if (res == MWAWPict::MWAW_R_BAD) {
MWAW_DEBUG_MSG(("FullWrtGraph::sendGraphic: can not find the picture\n"));
return false;
}
MWAWVec2f actualSize, naturalSize;
if (box.size().x() > 0 && box.size().y() > 0) {
actualSize = naturalSize = box.size();
}
else if (actualSize.x() <= 0 || actualSize.y() <= 0) {
MWAW_DEBUG_MSG(("FullWrtGraph::sendGraphic: can not find the picture size\n"));
actualSize = naturalSize = MWAWVec2f(100,100);
}
MWAWPosition pictPos=MWAWPosition(MWAWVec2f(0,0),actualSize, librevenge::RVNG_POINT);
pictPos.setRelativePosition(MWAWPosition::Char);
pictPos.setNaturalSize(naturalSize);
input->seek(pos+4, librevenge::RVNG_SEEK_SET);
std::shared_ptr<MWAWPict> pict(MWAWPictData::get(input, sz));
if (pict) {
MWAWEmbeddedObject picture;
if (pict->getBinary(picture)) {
listener->insertPicture(pictPos, picture);
return true;
}
}
return true;
}
bool FullWrtGraph::sendPageGraphics()
{
for (auto const &frame : m_state->m_sidebarList) {
if (!frame)
continue;
if (!frame->m_parsed)
sendSideBar(*frame);
}
return true;
}
void FullWrtGraph::flushExtra()
{
for (auto it : m_state->m_graphicMap) {
FullWrtStruct::EntryPtr &zone = it.second;
if (!zone || zone->isParsed())
continue;
sendGraphic(zone);
}
}
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: