/* -*- 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.
*/
/*
* Structures used by Claris Works parser
*
*/
#ifndef CLARIS_WKS_STRUCT
# define CLARIS_WKS_STRUCT
#include <iostream>
#include <set>
#include <vector>
#include "libmwaw_internal.hxx"
class MWAWParserState;
/** namespace to store the main structure which appears in a ClarisDraw/ClarisWorks file */
namespace ClarisWksStruct
{
//! a basic structure
struct Struct {
//! constructor
Struct()
: m_size(0)
, m_numData(0)
, m_dataSize(-1)
, m_headerSize(-1)
, m_type(-1)
{
for (auto &val : m_values) val=0;
}
//! try to read the header
bool readHeader(MWAWInputStreamPtr input, bool strict=false);
//! operator<<
friend std::ostream &operator<<(std::ostream &o, Struct const &z);
//! the size of the DSET header
long m_size;
//! the number of header
long m_numData;
//! the data size
long m_dataSize;
//! the header size
long m_headerSize;
//! the type
int m_type;
//! an unknown value
int m_values[2];
};
/** try to read a int structured zone
where \a fSz to the int size: 1(int8), 2(int16), 4(int32) */
bool readIntZone(MWAWParserState &parserState, char const *zoneName, bool hasEntete, int fSz, std::vector<int> &res);
//! try to read a structured zone with unknown content
bool readStructZone(MWAWParserState &parserState, char const *zoneName, bool hasEntete);
//! main structure which correspond to a document part
struct DSET {
struct Child;
//! the zone position
enum Position { P_Main=0, P_Header, P_Footer, P_Frame, P_Footnote, P_Table,
P_GraphicMaster,
P_Slide, P_SlideNote, P_SlideThumbnail, P_SlideMaster, P_Unknown
};
/** the different types of zone child */
enum ChildType { C_Zone, C_SubText, C_Graphic, C_Unknown };
//! constructor
DSET()
: m_size(0)
, m_numData(0)
, m_dataSz(-1)
, m_headerSz(-1)
, m_position(P_Unknown)
, m_fileType(-1)
, m_page(-1)
, m_box()
, m_pageDimension(0,0)
, m_id(0)
, m_fathersList()
, m_beginSelection(0)
, m_endSelection(-1)
, m_textType(0)
, m_childs()
, m_otherChilds()
, m_parsed(false)
, m_internal(0)
{
for (auto &fl : m_flags) fl=0;
}
//! virtual destructor
virtual ~DSET() {}
//! test if the zone is an header/footer
bool isHeaderFooter() const
{
return m_position==P_Header||m_position==P_Footer;
}
//! test if the zone is a slide
bool isSlide() const
{
return m_position==P_Slide || m_position==P_SlideNote || m_position==P_SlideThumbnail || m_position==P_SlideMaster;
}
//! return the zone bdbox
MWAWBox2f getBdBox() const
{
MWAWVec2f minPt(m_box[0][0], m_box[0][1]);
MWAWVec2f maxPt(m_box[1][0], m_box[1][1]);
for (int c=0; c<2; ++c) {
if (m_box.size()[c]>=0) continue;
minPt[c]=m_box[1][c];
maxPt[c]=m_box[0][c];
}
return MWAWBox2f(minPt,maxPt);
}
/** returns the maximum page */
int getMaximumPage() const
{
if (m_position==ClarisWksStruct::DSET::P_Slide)
return m_page;
if (m_position!=ClarisWksStruct::DSET::P_Main)
return 0;
int nPages=m_page;
for (const auto &child : m_childs) {
if (child.m_page > nPages)
nPages=child.m_page;
}
return nPages;
}
//! virtual function to remove a child from a list
virtual void removeChild(int cId, bool normalChild);
//! virtual function to remove a child from a list
virtual void removeChild(int cId);
//! try to update the child page and bounding box
void updateChildPositions(MWAWVec2f const &pageDim, float formLength, int numHorizontalPages=1);
//! find forbidden page break
void findForbiddenPagesBreaking(float pageDim, float formDim, int dim, MWAWVariable<int> &lastPage) const;
//! returns the child box (ie. the union of the childs box)
MWAWBox2i getUnionChildBox() const;
//! operator<<
friend std::ostream &operator<<(std::ostream &o, DSET const &doc);
//! the size of the DSET header
long m_size;
//! the number of header
long m_numData;
//! the data size
long m_dataSz;
//! the header size
long m_headerSz;
//! the zone type
Position m_position;
//! the type ( 0: text, -1: graphic, ...)
int m_fileType;
//! the page (if known)
int m_page;
//! the bounding box (if known)
MWAWBox2f m_box;
//! the page dimension (if know)
MWAWVec2f m_pageDimension;
//! the zone identificator
int m_id;
//! the list of fathers
std::set<int> m_fathersList;
//! the begin of selection ( at least in text header)
int m_beginSelection;
//! the end of selection ( at least in text header)
int m_endSelection;
//! the text type (header/footer,footnote, ...)
int m_textType;
//! some unknown flag
int m_flags[4];
//! the list of child zone
std::vector<Child> m_childs;
//! the list of other child
std::vector<int> m_otherChilds;
//! a flag to know if the entry is sent or not to the listener
mutable bool m_parsed;
//! an internal variable used to do some computation
mutable int m_internal;
//! structure used to define the child of a DSET structure
struct Child {
//! constructor
Child()
: m_type(C_Unknown)
, m_id(-1)
, m_posC(-1)
, m_page(-1)
, m_box()
{
}
//! return the zone bdbox
MWAWBox2f getBdBox() const
{
MWAWVec2f minPt(m_box[0][0], m_box[0][1]);
MWAWVec2f maxPt(m_box[1][0], m_box[1][1]);
for (int c=0; c<2; ++c) {
if (m_box.size()[c]>=0) continue;
minPt[c]=m_box[1][c];
maxPt[c]=m_box[0][c];
}
return MWAWBox2f(minPt,maxPt);
}
//! operator<<
friend std::ostream &operator<<(std::ostream &o, Child const &ch)
{
switch (ch.m_type) {
case C_SubText:
o << "text,";
break;
case C_Zone:
o << "zone,";
break;
case C_Graphic:
o << "graphic,";
break;
case C_Unknown:
o << "#type,";
#if !defined(__clang__)
default:
#endif
break;
}
if (ch.m_id != -1) o << "id=" << ch.m_id << ",";
if (ch.m_posC != -1) o << "posC=" << ch.m_posC << ",";
if (ch.m_page>=0) o << "pg=" << ch.m_page << ",";
if (ch.m_box.size().x() > 0 || ch.m_box.size().y() > 0)
o << "box=" << ch.m_box << ",";
return o;
}
//! the type
ChildType m_type;
//! the identificator
int m_id;
//! a position (used in text zone to store the character )
long m_posC;
//! the page if known
int m_page;
//! the bdbox
MWAWBox2f m_box;
};
};
}
#endif
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: