1 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2 
3 /* libmwaw
4 * Version: MPL 2.0 / LGPLv2+
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 2.0 (the "License"); you may not use this file except in compliance with
8 * the License or as specified alternatively below. You may obtain a copy of
9 * the License at http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * Major Contributor(s):
17 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
18 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
19 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
20 * Copyright (C) 2006, 2007 Andrew Ziem
21 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
22 *
23 *
24 * All Rights Reserved.
25 *
26 * For minor contributions see the git repository.
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
30 * in which case the provisions of the LGPLv2+ are applicable
31 * instead of those above.
32 */
33 
34 /*
35  * Structures used by Claris Works parser
36  *
37  */
38 #ifndef CLARIS_WKS_STRUCT
39 #  define CLARIS_WKS_STRUCT
40 
41 #include <iostream>
42 #include <set>
43 #include <vector>
44 
45 #include "libmwaw_internal.hxx"
46 
47 class MWAWParserState;
48 
49 /** namespace to store the main structure which appears in a ClarisDraw/ClarisWorks file */
50 namespace ClarisWksStruct
51 {
52 //! a basic structure
53 struct Struct {
54   //! constructor
StructClarisWksStruct::Struct55   Struct()
56     : m_size(0)
57     , m_numData(0)
58     , m_dataSize(-1)
59     , m_headerSize(-1)
60     , m_type(-1)
61   {
62     for (auto &val : m_values) val=0;
63   }
64   //! try to read the header
65   bool readHeader(MWAWInputStreamPtr input, bool strict=false);
66   //! operator<<
67   friend std::ostream &operator<<(std::ostream &o, Struct const &z);
68   //! the size of the DSET header
69   long m_size;
70   //! the number of header
71   long m_numData;
72   //! the data size
73   long m_dataSize;
74   //! the header size
75   long m_headerSize;
76   //! the type
77   int m_type;
78   //! an unknown value
79   int m_values[2];
80 };
81 /** try to read a int structured zone
82     where \a fSz to the int size: 1(int8), 2(int16), 4(int32) */
83 bool readIntZone(MWAWParserState &parserState, char const *zoneName, bool hasEntete, int fSz, std::vector<int> &res);
84 //! try to read a structured zone with unknown content
85 bool readStructZone(MWAWParserState &parserState, char const *zoneName, bool hasEntete);
86 //! main structure which correspond to a document part
87 struct DSET {
88   struct Child;
89 
90   //! the zone position
91   enum Position { P_Main=0, P_Header, P_Footer, P_Frame, P_Footnote, P_Table,
92                   P_GraphicMaster,
93                   P_Slide, P_SlideNote, P_SlideThumbnail, P_SlideMaster, P_Unknown
94                 };
95   /** the different types of zone child */
96   enum ChildType { C_Zone, C_SubText, C_Graphic, C_Unknown };
97 
98   //! constructor
DSETClarisWksStruct::DSET99   DSET()
100     : m_size(0)
101     , m_numData(0)
102     , m_dataSz(-1)
103     , m_headerSz(-1)
104     , m_position(P_Unknown)
105     , m_fileType(-1)
106     , m_page(-1)
107     , m_box()
108     , m_pageDimension(0,0)
109     , m_id(0)
110     , m_fathersList()
111     , m_beginSelection(0)
112     , m_endSelection(-1)
113     , m_textType(0)
114     , m_childs()
115     , m_otherChilds()
116     , m_parsed(false)
117     , m_internal(0)
118   {
119     for (auto &fl : m_flags) fl=0;
120   }
121   DSET(DSET const &)=default;
122   //! virtual destructor
~DSETClarisWksStruct::DSET123   virtual ~DSET() {}
124 
125   //! test if the zone is an header/footer
isHeaderFooterClarisWksStruct::DSET126   bool isHeaderFooter() const
127   {
128     return m_position==P_Header||m_position==P_Footer;
129   }
130 
131   //! test if the zone is a slide
isSlideClarisWksStruct::DSET132   bool isSlide() const
133   {
134     return m_position==P_Slide || m_position==P_SlideNote || m_position==P_SlideThumbnail || m_position==P_SlideMaster;
135   }
136   //! return the zone bdbox
getBdBoxClarisWksStruct::DSET137   MWAWBox2f getBdBox() const
138   {
139     MWAWVec2f minPt(m_box[0][0], m_box[0][1]);
140     MWAWVec2f maxPt(m_box[1][0], m_box[1][1]);
141     for (int c=0; c<2; ++c) {
142       if (m_box.size()[c]>=0) continue;
143       minPt[c]=m_box[1][c];
144       maxPt[c]=m_box[0][c];
145     }
146     return MWAWBox2f(minPt,maxPt);
147   }
148   /** returns the maximum page */
getMaximumPageClarisWksStruct::DSET149   int getMaximumPage() const
150   {
151     if (m_position==ClarisWksStruct::DSET::P_Slide)
152       return m_page;
153     if (m_position!=ClarisWksStruct::DSET::P_Main)
154       return 0;
155     int nPages=m_page;
156     for (const auto &child : m_childs) {
157       if (child.m_page > nPages)
158         nPages=child.m_page;
159     }
160     return nPages;
161   }
162 
163   //! virtual function to remove a child from a list
164   virtual void removeChild(int cId, bool normalChild);
165   //! virtual function to remove a child from a list
166   virtual void removeChild(int cId);
167   //! try to update the child page and bounding box
168   void updateChildPositions(MWAWVec2f const &pageDim, float formLength, int numHorizontalPages=1);
169   //! find forbidden page break
170   void findForbiddenPagesBreaking(float pageDim, float formDim, int dim, MWAWVariable<int> &lastPage) const;
171   //! returns the child box (ie. the union of the childs box)
172   MWAWBox2i getUnionChildBox() const;
173 
174   //! operator<<
175   friend std::ostream &operator<<(std::ostream &o, DSET const &doc);
176 
177   //! the size of the DSET header
178   long m_size;
179   //! the number of header
180   long m_numData;
181   //! the data size
182   long m_dataSz;
183   //! the header size
184   long m_headerSz;
185 
186   //! the zone type
187   Position m_position;
188   //! the type ( 0: text, -1: graphic, ...)
189   int m_fileType;
190 
191   //! the page (if known)
192   int m_page;
193   //! the bounding box (if known)
194   MWAWBox2f m_box;
195   //! the page dimension (if know)
196   MWAWVec2f m_pageDimension;
197 
198   //! the zone identificator
199   int m_id;
200   //! the list of fathers
201   std::set<int> m_fathersList;
202 
203   //! the begin of selection ( at least in text header)
204   int m_beginSelection;
205   //! the end of selection ( at least in text header)
206   int m_endSelection;
207 
208   //! the text type (header/footer,footnote, ...)
209   int m_textType;
210 
211   //! some unknown flag
212   int m_flags[4];
213 
214   //! the list of child zone
215   std::vector<Child> m_childs;
216   //! the list of other child
217   std::vector<int> m_otherChilds;
218 
219   //! a flag to know if the entry is sent or not to the listener
220   mutable bool m_parsed;
221   //! an internal variable used to do some computation
222   mutable int m_internal;
223 
224   //! structure used to define the child of a DSET structure
225   struct Child {
226     //! constructor
ChildClarisWksStruct::DSET::Child227     Child()
228       : m_type(C_Unknown)
229       , m_id(-1)
230       , m_posC(-1)
231       , m_page(-1)
232       , m_box()
233     {
234     }
235     //! return the zone bdbox
getBdBoxClarisWksStruct::DSET::Child236     MWAWBox2f getBdBox() const
237     {
238       MWAWVec2f minPt(m_box[0][0], m_box[0][1]);
239       MWAWVec2f maxPt(m_box[1][0], m_box[1][1]);
240       for (int c=0; c<2; ++c) {
241         if (m_box.size()[c]>=0) continue;
242         minPt[c]=m_box[1][c];
243         maxPt[c]=m_box[0][c];
244       }
245       return MWAWBox2f(minPt,maxPt);
246     }
247 
248     //! operator<<
operator <<ClarisWksStruct::DSET249     friend std::ostream &operator<<(std::ostream &o, Child const &ch)
250     {
251       switch (ch.m_type) {
252       case C_SubText:
253         o << "text,";
254         break;
255       case C_Zone:
256         o << "zone,";
257         break;
258       case C_Graphic:
259         o << "graphic,";
260         break;
261       case C_Unknown:
262         o << "#type,";
263 #if !defined(__clang__)
264       default:
265 #endif
266         break;
267       }
268       if (ch.m_id != -1) o << "id=" << ch.m_id << ",";
269       if (ch.m_posC != -1) o << "posC=" << ch.m_posC << ",";
270       if (ch.m_page>=0) o << "pg=" << ch.m_page << ",";
271       if (ch.m_box.size().x() > 0 || ch.m_box.size().y() > 0)
272         o << "box=" << ch.m_box << ",";
273       return o;
274     }
275 
276     //! the type
277     ChildType m_type;
278     //! the identificator
279     int m_id;
280     //! a position (used in text zone to store the character )
281     long m_posC;
282     //! the page if known
283     int m_page;
284     //! the bdbox
285     MWAWBox2f m_box;
286   };
287 };
288 }
289 
290 #endif
291 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
292