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 #include <algorithm>
35 #include <iomanip>
36 #include <iostream>
37 #include <limits>
38 #include <map>
39 #include <sstream>
40
41 #include <librevenge/librevenge.h>
42
43 #include "MWAWTextListener.hxx"
44 #include "MWAWFont.hxx"
45 #include "MWAWFontConverter.hxx"
46 #include "MWAWHeader.hxx"
47 #include "MWAWParagraph.hxx"
48 #include "MWAWPictData.hxx"
49 #include "MWAWPosition.hxx"
50 #include "MWAWPrinter.hxx"
51 #include "MWAWRSRCParser.hxx"
52 #include "MWAWSubDocument.hxx"
53
54 #include "libmwaw_internal.hxx"
55
56 #include "MacDocParser.hxx"
57
58 /** Internal: the structures of a MacDocParser */
59 namespace MacDocParserInternal
60 {
61 ////////////////////////////////////////
62 //! Internal: the index data of a MacDocParser
63 struct Index {
64 //! constructor
IndexMacDocParserInternal::Index65 Index()
66 : m_entry()
67 , m_level(0)
68 , m_numChild(0)
69 , m_page(0)
70 , m_box()
71 , m_extra("")
72 {
73 }
74 //! operator<<
operator <<(std::ostream & o,Index const & index)75 friend std::ostream &operator<<(std::ostream &o, Index const &index)
76 {
77 if (index.m_level) o << "level=" << index.m_level << ",";
78 if (index.m_page) o << "page=" << index.m_page << ",";
79 o << "box=" << index.m_box << ",";
80 if (index.m_numChild) o << "numChild=" << index.m_numChild << ",";
81 o << index.m_extra;
82 return o;
83 }
84 //! the text entry
85 MWAWEntry m_entry;
86 //! the entry level
87 int m_level;
88 //! the number of child
89 int m_numChild;
90 //! the page
91 int m_page;
92 //! the bdbox
93 MWAWBox2i m_box;
94 //! extra data
95 std::string m_extra;
96 };
97
98 ////////////////////////////////////////
99 //! Internal: the state of a MacDocParser
100 struct State {
101 //! constructor
StateMacDocParserInternal::State102 State()
103 : m_idPictureMap()
104 , m_indexList()
105 , m_idFontMap()
106 , m_actPage(0)
107 , m_numPages(0)
108 {
109 }
110 //! the picture page map
111 std::map<int,MWAWEntry> m_idPictureMap;
112 //! the index list
113 std::vector<Index> m_indexList;
114 //! a map id to index font
115 std::map<int, MWAWFont> m_idFontMap;
116 int m_actPage /** the actual page */, m_numPages /** the number of page of the final document */;
117 };
118
119 }
120
121 ////////////////////////////////////////////////////////////
122 // constructor/destructor, ...
123 ////////////////////////////////////////////////////////////
MacDocParser(MWAWInputStreamPtr const & input,MWAWRSRCParserPtr const & rsrcParser,MWAWHeader * header)124 MacDocParser::MacDocParser(MWAWInputStreamPtr const &input, MWAWRSRCParserPtr const &rsrcParser, MWAWHeader *header)
125 : MWAWTextParser(input, rsrcParser, header)
126 , m_state()
127 {
128 init();
129 }
130
~MacDocParser()131 MacDocParser::~MacDocParser()
132 {
133 }
134
init()135 void MacDocParser::init()
136 {
137 resetTextListener();
138
139 m_state.reset(new MacDocParserInternal::State);
140
141 // no margins ( ie. the document is a set of picture corresponding to each page )
142 getPageSpan().setMargins(0.01);
143 }
144
rsrcInput()145 MWAWInputStreamPtr MacDocParser::rsrcInput()
146 {
147 return getRSRCParser()->getInput();
148 }
149
rsrcAscii()150 libmwaw::DebugFile &MacDocParser::rsrcAscii()
151 {
152 return getRSRCParser()->ascii();
153 }
154
155 ////////////////////////////////////////////////////////////
156 // new page
157 ////////////////////////////////////////////////////////////
newPage(int number)158 void MacDocParser::newPage(int number)
159 {
160 if (number <= m_state->m_actPage || number > m_state->m_numPages)
161 return;
162
163 while (m_state->m_actPage < number) {
164 m_state->m_actPage++;
165 if (!getTextListener() || m_state->m_actPage == 1)
166 continue;
167 getTextListener()->insertBreak(MWAWTextListener::PageBreak);
168 }
169 }
170
171 ////////////////////////////////////////////////////////////
172 // the parser
173 ////////////////////////////////////////////////////////////
parse(librevenge::RVNGTextInterface * docInterface)174 void MacDocParser::parse(librevenge::RVNGTextInterface *docInterface)
175 {
176 if (!getInput().get() || !getRSRCParser() || !checkHeader(nullptr)) throw(libmwaw::ParseException());
177 bool ok = false;
178 try {
179 checkHeader(nullptr);
180 ok = createZones();
181 if (ok) {
182 createDocument(docInterface);
183 sendContents();
184 }
185 ascii().reset();
186 }
187 catch (...) {
188 MWAW_DEBUG_MSG(("MacDocParser::parse: exception catched when parsing\n"));
189 ok = false;
190 }
191
192 resetTextListener();
193 if (!ok) throw(libmwaw::ParseException());
194 }
195
196 ////////////////////////////////////////////////////////////
197 // create the document
198 ////////////////////////////////////////////////////////////
createDocument(librevenge::RVNGTextInterface * documentInterface)199 void MacDocParser::createDocument(librevenge::RVNGTextInterface *documentInterface)
200 {
201 if (!documentInterface) return;
202 if (getTextListener()) {
203 MWAW_DEBUG_MSG(("MacDocParser::createDocument: listener already exist\n"));
204 return;
205 }
206
207 // update the page
208 m_state->m_actPage = 0;
209
210 // create the page list
211 auto numPages = int(m_state->m_idPictureMap.size());
212 if (!m_state->m_indexList.empty())
213 numPages++;
214 MWAWPageSpan ps(getPageSpan());
215 ps.setPageSpan(numPages+1);
216 std::vector<MWAWPageSpan> pageList(1,ps);
217 //
218 MWAWTextListenerPtr listen(new MWAWTextListener(*getParserState(), pageList, documentInterface));
219 setTextListener(listen);
220 listen->startDocument();
221 }
222
223
224 ////////////////////////////////////////////////////////////
225 //
226 // Intermediate level
227 //
228 ////////////////////////////////////////////////////////////
createZones()229 bool MacDocParser::createZones()
230 {
231 MWAWRSRCParserPtr rsrcParser = getRSRCParser();
232 auto &entryMap = rsrcParser->getEntriesMap();
233
234 // the index font zone: 1001, ...
235 auto it = entryMap.lower_bound("MDLv");
236 while (it != entryMap.end()) {
237 if (it->first != "MDLv")
238 break;
239 MWAWEntry const &entry = it++->second;
240 readFont(entry);
241 }
242 // index zone: 1 MDIx
243 it = entryMap.lower_bound("MDIx");
244 while (it != entryMap.end()) {
245 if (it->first != "MDIx")
246 break;
247 MWAWEntry const &entry = it++->second;
248 readIndex(entry);
249 }
250 // bookmark zone: Mdbk 1, ...
251 it = entryMap.lower_bound("MDbk");
252 while (it != entryMap.end()) {
253 if (it->first != "MDbk")
254 break;
255 MWAWEntry const &entry = it++->second;
256 readBookmark(entry);
257 }
258 // doc preference MDop:128 crypted ?
259
260 // the picture zone: 1, ...
261 bool pageSizeSet=false;
262 it = entryMap.lower_bound("MDpg");
263 while (it != entryMap.end()) {
264 if (it->first != "MDpg")
265 break;
266 MWAWEntry const &entry = it++->second;
267 m_state->m_idPictureMap[entry.id()]=entry;
268 if (!pageSizeSet) {
269 // as we do not read MDop, use picture to find page size
270 librevenge::RVNGBinaryData data;
271 if (!getRSRCParser()->parsePICT(entry, data))
272 continue;
273 MWAWInputStreamPtr pictInput=MWAWInputStream::get(data, false);
274 if (!pictInput)
275 continue;
276 MWAWBox2f box;
277 auto res = MWAWPictData::check(pictInput,static_cast<int>(data.size()), box);
278 if (res != MWAWPict::MWAW_R_BAD && box.size()[0]>0 && box.size()[1]>0) {
279 pageSizeSet=true;
280 getPageSpan().setFormWidth(double(box.size()[0])/72.);
281 getPageSpan().setFormLength(double(box.size()[1])/72.);
282 }
283 }
284 }
285 // windows pos? 128
286 it = entryMap.lower_bound("MDwp");
287 while (it != entryMap.end()) {
288 if (it->first != "MDwp")
289 break;
290 MWAWEntry const &entry = it++->second;
291 readWP(entry);
292 }
293
294 #ifdef DEBUG_WITH_FILES
295 // the file zone: 1, ...
296 it = entryMap.lower_bound("MDfi");
297 while (it != entryMap.end()) {
298 if (it->first != "MDfi")
299 break;
300 MWAWEntry const &entry = it++->second;
301 readFile(entry);
302 }
303
304 // get rid of the default application resource
305 libmwaw::DebugFile &ascFile = rsrcAscii();
306 static char const *appliRsrc[]= {
307 "ALRT","BNDL","CNTL","CURS","CDEF", "CODE","DLOG","DLGX","DITL","FREF",
308 "ICON","ICN#","MENU","MBAR","MDEF", "SIZE","TMPL","WIND",
309 "acur","cicn","crsr","dctb","icl4", "icl8","ics4","ics8","ics#","ictb",
310 "mstr","snd ",
311 "DATA", "MDsr" /* srd: version string */
312 };
313 for (int r=0; r < 18+12+2; ++r) {
314 it = entryMap.lower_bound(appliRsrc[r]);
315 while (it != entryMap.end()) {
316 if (it->first != appliRsrc[r])
317 break;
318 MWAWEntry const &entry = it++->second;
319 if (entry.isParsed()) continue;
320 entry.setParsed(true);
321 ascFile.skipZone(entry.begin()-4,entry.end()-1);
322 }
323 }
324 #endif
325
326 return !m_state->m_idPictureMap.empty();
327 }
328
329
sendContents()330 bool MacDocParser::sendContents()
331 {
332 MWAWTextListenerPtr listener=getTextListener();
333 if (!listener) {
334 MWAW_DEBUG_MSG(("MacDocParser::sendContents: can not find the listener\n"));
335 return false;
336 }
337 int actPage=0;
338 if (sendIndex())
339 newPage(++actPage);
340 listener->setParagraph(MWAWParagraph());
341 for (auto &it : m_state->m_idPictureMap) {
342 sendPicture(it.second);
343 newPage(++actPage);
344 }
345 return true;
346 }
347
348 ////////////////////////////////////////////////////////////
349 //
350 // Low level
351 //
352 ////////////////////////////////////////////////////////////
353
354 // font
readFont(MWAWEntry const & entry)355 bool MacDocParser::readFont(MWAWEntry const &entry)
356 {
357 MWAWInputStreamPtr input = rsrcInput();
358 if (entry.length()<12 || !input || !input->checkPosition(entry.end())) {
359 MWAW_DEBUG_MSG(("MacDocParser::readFont: the entry seems bad\n"));
360 return false;
361 }
362
363 entry.setParsed(true);
364 input->seek(entry.begin(), librevenge::RVNG_SEEK_SET);
365 libmwaw::DebugFile &ascFile = rsrcAscii();
366 libmwaw::DebugStream f;
367 auto fSz=static_cast<int>(input->readULong(1));
368 if (fSz<0 || 1+long(fSz)+1-(fSz%2)+10>entry.length()) {
369 f << "Entries(Font):###fSz=" << fSz;
370 ascFile.addPos(entry.begin()-4);
371 ascFile.addNote(f.str().c_str());
372 return false;
373 }
374 MWAWFont font;
375 std::string name("");
376 for (int i=0; i<fSz; i++)
377 name+=char(input->readLong(1));
378 font.setId(getParserState()->m_fontConverter->getId(name));
379 if ((fSz%2)==0)
380 input->seek(1, librevenge::RVNG_SEEK_CUR);
381 font.setSize(float(input->readULong(2)));
382 auto flag = static_cast<int>(input->readULong(2));
383 uint32_t flags=0;
384 if (flag&0x1) flags |= MWAWFont::boldBit;
385 if (flag&0x2) flags |= MWAWFont::italicBit;
386 if (flag&0x4) font.setUnderlineStyle(MWAWFont::Line::Simple);
387 if (flag&0x8) flags |= MWAWFont::embossBit;
388 if (flag&0x10) flags |= MWAWFont::shadowBit;
389 if (flag&0x20) font.setDeltaLetterSpacing(-1);
390 if (flag&0x40) font.setDeltaLetterSpacing(1);
391 if (flag&0x80) f << "#flag0[0x80],";
392 font.setFlags(flags);
393 unsigned char col[3];
394 for (auto &c : col) c=static_cast<unsigned char>(input->readULong(2)>>8);
395 font.setColor(MWAWColor(col[0],col[1],col[2]));
396 font.m_extra = f.str();
397 f.str("");
398 f << "Entries(Font)[" << entry.id() << "]:"
399 << font.getDebugString(getParserState()->m_fontConverter);
400 m_state->m_idFontMap[entry.id()-999]=font;
401 ascFile.addPos(entry.begin()-4);
402 ascFile.addNote(f.str().c_str());
403 return true;
404 }
405
406 //
407 // index functions
408 //
readIndex(MWAWEntry const & entry)409 bool MacDocParser::readIndex(MWAWEntry const &entry)
410 {
411 if (entry.length()<4) {
412 MWAW_DEBUG_MSG(("MacDocParser::readIndex: the entry seems bad\n"));
413 return false;
414 }
415 if (entry.id()!=1) {
416 MWAW_DEBUG_MSG(("MacDocParser::readIndex: the entry id seems bad\n"));
417 }
418 entry.setParsed(true);
419 MWAWInputStreamPtr input = rsrcInput();
420 input->seek(entry.begin(), librevenge::RVNG_SEEK_SET);
421
422 libmwaw::DebugFile &ascFile = rsrcAscii();
423 ascFile.addPos(entry.begin()-4);
424 ascFile.addNote("Entries(Index)");
425 libmwaw::DebugStream f;
426 long pos;
427 while (!input->isEnd()) {
428 pos=input->tell();
429 if (pos+21>=entry.end())
430 break;
431
432 f.str("");
433 MacDocParserInternal::Index index;
434 auto val=static_cast<int>(input->readLong(2));
435 if (val) f << "#f0=" << val << ",";
436 index.m_page=static_cast<int>(input->readLong(2));
437 if (index.m_page<=0) {
438 input->seek(pos, librevenge::RVNG_SEEK_SET);
439 break;
440 }
441 int dim[4];
442 for (auto &d : dim) d=static_cast<int>(input->readLong(2));
443 index.m_box=MWAWBox2i(MWAWVec2i(dim[1],dim[0]),MWAWVec2i(dim[3],dim[2]));
444 val=static_cast<int>(input->readLong(2));
445 if (val) f << "#f1=" << val << ",";
446 index.m_numChild=static_cast<int>(input->readLong(2));
447 for (int i=0; i<2; ++i) {
448 val=static_cast<int>(input->readLong(2));
449 if (val) f << "#f" << i+2 << "=" << val << ",";
450 }
451 index.m_extra=f.str();
452 f.str("");
453 f << "Index:" << index;
454 index.m_entry.setBegin(input->tell());
455 std::string name("");
456 bool ok=false;
457 while (!input->isEnd()) {
458 if (input->tell()>=entry.end())
459 break;
460 auto c=char(input->readLong(1));
461 if (c==0) {
462 ok = true;
463 break;
464 }
465 name+=c;
466 }
467 if (!ok) {
468 input->seek(pos, librevenge::RVNG_SEEK_SET);
469 break;
470 }
471 index.m_entry.setEnd(input->tell()-1);
472 m_state->m_indexList.push_back(index);
473 f << name;
474 ascFile.addPos(pos);
475 ascFile.addNote(f.str().c_str());
476 }
477 f.str("");
478 f << "Index[end]:";
479 pos=input->tell();
480 if (pos!=entry.end()-4) {
481 MWAW_DEBUG_MSG(("MacDocParser::readIndex: problem reading end\n"));
482 f << "###";
483 }
484 ascFile.addPos(pos);
485 ascFile.addNote(f.str().c_str());
486 return true;
487 }
488
updateIndex(int actIndex,int actLevel)489 int MacDocParser::updateIndex(int actIndex, int actLevel)
490 {
491 auto numIndex=static_cast<int>(m_state->m_indexList.size());
492 if (actIndex < 0 || actIndex >= numIndex) {
493 MWAW_DEBUG_MSG(("MacDocParser::updateIndex: the actual index seems bad\n"));
494 return -1;
495 }
496 auto &index = m_state->m_indexList[size_t(actIndex++)];
497 index.m_level=actLevel;
498 for (int c=0; c < index.m_numChild; ++c) {
499 actIndex=updateIndex(actIndex, actLevel+1);
500 if (actIndex==-1)
501 break;
502 }
503 return actIndex;
504 }
505
sendIndex()506 bool MacDocParser::sendIndex()
507 {
508 MWAWTextListenerPtr listener=getTextListener();
509 if (!listener) {
510 MWAW_DEBUG_MSG(("MacDocParser::sendIndex: can not find the listener\n"));
511 return false;
512 }
513 if (m_state->m_indexList.empty())
514 return false;
515 int id=0;
516 auto numIndex=size_t(m_state->m_indexList.size());
517 do
518 id=updateIndex(id,1);
519 while (id>0 && id < static_cast<int>(numIndex));
520 listener->setFont(MWAWFont(3,12,MWAWFont::boldBit));
521 MWAWParagraph para;
522 para.m_justify = MWAWParagraph::JustificationCenter;
523 listener->setParagraph(para);
524 listener->insertUnicodeString(librevenge::RVNGString("Index"));
525 listener->insertEOL();
526 listener->insertEOL();
527
528 MWAWInputStreamPtr input = rsrcInput();
529 para=MWAWParagraph();
530 double w = getPageWidth();
531 MWAWTabStop tab;
532 tab.m_alignment = MWAWTabStop::RIGHT;
533 tab.m_leaderCharacter='.';
534 tab.m_position = w-0.3;
535 para.m_tabs->push_back(tab);
536 #ifdef DEBUG
537 int n=0;
538 #endif
539 for (auto const &index : m_state->m_indexList) {
540 #ifdef DEBUG
541 ++n;
542 #endif
543 if (!index.m_entry.valid() || index.m_level<=0)
544 continue;
545 para.m_margins[1]=0.5*double(index.m_level);
546 listener->setParagraph(para);
547 if (m_state->m_idFontMap.find(index.m_level)!=m_state->m_idFontMap.end())
548 listener->setFont(m_state->m_idFontMap.find(index.m_level)->second);
549 else {
550 MWAW_DEBUG_MSG(("MacDocParser::sendIndex: can not find font for index %d\n", int(n-1)));
551 listener->setFont(MWAWFont());
552 }
553 input->seek(index.m_entry.begin(), librevenge::RVNG_SEEK_SET);
554 for (long c=0; c < index.m_entry.length(); ++c) {
555 auto ch=static_cast<unsigned char>(input->readULong(1));
556 if (ch==9)
557 listener->insertCharacter(' ');
558 else
559 listener->insertCharacter(ch);
560 }
561 if (index.m_page>0) {
562 std::stringstream s;
563 s << index.m_page;
564 listener->setFont(MWAWFont());
565 listener->insertTab();
566 listener->insertUnicodeString(librevenge::RVNGString(s.str().c_str()));
567 }
568 listener->insertEOL();
569 }
570 return true;
571 }
572
573 // picture
sendPicture(MWAWEntry const & entry)574 bool MacDocParser::sendPicture(MWAWEntry const &entry)
575 {
576 if (!getTextListener()) {
577 MWAW_DEBUG_MSG(("MacDocParser::sendPicture: can not find the listener\n"));
578 return false;
579 }
580 librevenge::RVNGBinaryData data;
581 if (!getRSRCParser()->parsePICT(entry, data))
582 return false;
583
584 entry.setParsed(true);
585 auto dataSz=int(data.size());
586 if (!dataSz)
587 return false;
588 MWAWInputStreamPtr pictInput=MWAWInputStream::get(data, false);
589 if (!pictInput) {
590 MWAW_DEBUG_MSG(("MacDocParser::sendPicture: oops can not find an input\n"));
591 return false;
592 }
593 MWAWBox2f box;
594 auto res = MWAWPictData::check(pictInput, dataSz,box);
595 if (res == MWAWPict::MWAW_R_BAD) {
596 MWAW_DEBUG_MSG(("MacDocParser::sendPicture: can not find the picture\n"));
597 return false;
598 }
599 pictInput->seek(0,librevenge::RVNG_SEEK_SET);
600 std::shared_ptr<MWAWPict> thePict(MWAWPictData::get(pictInput, dataSz));
601 MWAWPosition pictPos=MWAWPosition(MWAWVec2f(0,0),box.size(), librevenge::RVNG_POINT);
602 pictPos.setRelativePosition(MWAWPosition::Char);
603 if (thePict) {
604 MWAWEmbeddedObject picture;
605 if (thePict->getBinary(picture))
606 getTextListener()->insertPicture(pictPos, picture);
607 }
608 return true;
609 }
610
611 // file: unknown format: 0002 0000 0000 00 + FileInfo + DataFrk + RSRCFork ?
readFile(MWAWEntry const & entry)612 bool MacDocParser::readFile(MWAWEntry const &entry)
613 {
614 entry.setParsed(true);
615 #ifdef DEBUG_WITH_FILES
616 MWAWInputStreamPtr input = rsrcInput();
617 input->seek(entry.begin(), librevenge::RVNG_SEEK_SET);
618 librevenge::RVNGBinaryData data;
619 input->readDataBlock(entry.length(), data);
620
621 libmwaw::DebugFile &ascFile = rsrcAscii();
622
623 static int volatile fileName = 0;
624 libmwaw::DebugStream f;
625 f << "FILE" << ++fileName;
626 libmwaw::Debug::dumpFile(data, f.str().c_str());
627
628 ascFile.addPos(entry.begin()-4);
629 ascFile.addNote(f.str().c_str());
630 ascFile.skipZone(entry.begin(),entry.end()-1);
631 #endif
632
633 return true;
634 }
635
636 // bookmark. note the name is stored as resource name
readBookmark(MWAWEntry const & entry)637 bool MacDocParser::readBookmark(MWAWEntry const &entry)
638 {
639 if (entry.length()!=8) {
640 MWAW_DEBUG_MSG(("MacDocParser::readWP: the entry seems bad\n"));
641 return false;
642 }
643
644 entry.setParsed(true);
645 MWAWInputStreamPtr input = rsrcInput();
646 input->seek(entry.begin(), librevenge::RVNG_SEEK_SET);
647 libmwaw::DebugFile &ascFile = rsrcAscii();
648 libmwaw::DebugStream f;
649 f << "Entries(BookMark)[" << entry.id() << "]:";
650 long val=input->readLong(4);
651 if (val) f << "page=" << val << ",";
652 val=input->readLong(4);
653 if (val) f << "yPos?=" << val << ",";
654 ascFile.addPos(entry.begin()-4);
655 ascFile.addNote(f.str().c_str());
656 return true;
657 }
658
659 // unknown related to window position?
readWP(MWAWEntry const & entry)660 bool MacDocParser::readWP(MWAWEntry const &entry)
661 {
662 if (entry.length()!=4) {
663 MWAW_DEBUG_MSG(("MacDocParser::readWP: the entry seems bad\n"));
664 return false;
665 }
666
667 entry.setParsed(true);
668 MWAWInputStreamPtr input = rsrcInput();
669 input->seek(entry.begin(), librevenge::RVNG_SEEK_SET);
670 libmwaw::DebugFile &ascFile = rsrcAscii();
671 libmwaw::DebugStream f;
672 f << "Entries(WP)[" << entry.id() << "]:";
673 for (int i=0; i < 2; ++i) { // f0=0|a6|c6, f1=0|1 show index ?
674 long val=input->readLong(2);
675 if (val)
676 f << "f" << i << "=" << val << ",";
677 }
678 ascFile.addPos(entry.begin()-4);
679 ascFile.addNote(f.str().c_str());
680 return true;
681 }
682
683 ////////////////////////////////////////////////////////////
684 // read the header
685 ////////////////////////////////////////////////////////////
checkHeader(MWAWHeader * header,bool strict)686 bool MacDocParser::checkHeader(MWAWHeader *header, bool strict)
687 {
688 *m_state = MacDocParserInternal::State();
689 /** no data fork, may be ok, but this means
690 that the file contains no text, so... */
691 MWAWInputStreamPtr input = getInput();
692 if (!input || !getRSRCParser())
693 return false;
694 if (input->hasDataFork()) {
695 MWAW_DEBUG_MSG(("MacDocParser::checkHeader: find a datafork, odd!!!\n"));
696 }
697 if (strict) {
698 // check if at least one picture zone exists
699 auto &entryMap = getRSRCParser()->getEntriesMap();
700 if (entryMap.find("MDpg") == entryMap.end())
701 return false;
702 }
703 if (header)
704 header->reset(MWAWDocument::MWAW_T_MACDOC, version());
705
706 return true;
707 }
708
709 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
710