/src/libmwaw/src/lib/MouseWrtParser.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 | | /* 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 <iomanip> |
35 | | #include <iostream> |
36 | | #include <limits> |
37 | | #include <map> |
38 | | #include <sstream> |
39 | | |
40 | | #include <librevenge/librevenge.h> |
41 | | |
42 | | #include "MWAWTextListener.hxx" |
43 | | #include "MWAWFont.hxx" |
44 | | #include "MWAWFontConverter.hxx" |
45 | | #include "MWAWHeader.hxx" |
46 | | #include "MWAWParagraph.hxx" |
47 | | #include "MWAWPictMac.hxx" |
48 | | #include "MWAWPosition.hxx" |
49 | | #include "MWAWPrinter.hxx" |
50 | | #include "MWAWRSRCParser.hxx" |
51 | | #include "MWAWSubDocument.hxx" |
52 | | |
53 | | #include "MouseWrtParser.hxx" |
54 | | |
55 | | /** Internal: the structures of a MouseWrtParser */ |
56 | | namespace MouseWrtParserInternal |
57 | | { |
58 | | //////////////////////////////////////// |
59 | | //! Internal: class to store zone information of a MouseWrtParser |
60 | | struct Zone { |
61 | | //! constructor |
62 | | Zone() |
63 | 84.3k | : m_font() |
64 | 84.3k | , m_writingHebrew(false) |
65 | 84.3k | , m_text() |
66 | 84.3k | { |
67 | 84.3k | } |
68 | | //! the font |
69 | | MWAWFont m_font; |
70 | | //! flag to know if the writing is reverted |
71 | | bool m_writingHebrew; |
72 | | //! the text entry |
73 | | MWAWEntry m_text; |
74 | | }; |
75 | | |
76 | | //////////////////////////////////////// |
77 | | //! Internal: class to store paragraph information of a MouseWrtParser |
78 | | struct Paragraph { |
79 | | //! constructor |
80 | | explicit Paragraph(int id=0) |
81 | 3.14M | : m_id(id) |
82 | 3.14M | , m_paragraph() |
83 | 3.14M | , m_picture(false) |
84 | 3.14M | { |
85 | 3.14M | } |
86 | | //! the paragraph id |
87 | | int m_id; |
88 | | //! the paragraph |
89 | | MWAWParagraph m_paragraph; |
90 | | //! flag to know if this is a picture |
91 | | bool m_picture; |
92 | | }; |
93 | | //////////////////////////////////////// |
94 | | //! Internal: the state of a MouseWrtParser |
95 | | struct State { |
96 | | //! constructor |
97 | | State() |
98 | 42.1k | : m_actPage(0) |
99 | 42.1k | , m_numPages(0) |
100 | 42.1k | , m_charPLCMap() |
101 | 42.1k | , m_paraPLCMap() |
102 | 42.1k | , m_text() |
103 | 42.1k | { |
104 | 210k | for (auto &size : m_blockSizes) size=0; |
105 | 42.1k | } |
106 | | |
107 | | int m_actPage /** the actual page */, m_numPages /** the number of page of the final document */; |
108 | | /** the first zone's size */ |
109 | | long m_blockSizes[5]; |
110 | | /** the map position to charPLC */ |
111 | | std::map<int, MWAWFont> m_charPLCMap; |
112 | | /** the map position to paraPLC */ |
113 | | std::map<int, Paragraph> m_paraPLCMap; |
114 | | /** the main text entry */ |
115 | | MWAWEntry m_text; |
116 | | /** the header and the footer zone */ |
117 | | Zone m_zones[2]; |
118 | | }; |
119 | | |
120 | | //////////////////////////////////////// |
121 | | //! Internal: the subdocument of a MouseWrtParser |
122 | | class SubDocument final : public MWAWSubDocument |
123 | | { |
124 | | public: |
125 | | SubDocument(MouseWrtParser &pars, MWAWInputStreamPtr const &input, int zoneId) |
126 | 5.01k | : MWAWSubDocument(&pars, input, MWAWEntry()) |
127 | 5.01k | , m_id(zoneId) |
128 | 5.01k | { |
129 | 5.01k | } |
130 | | |
131 | | //! destructor |
132 | 0 | ~SubDocument() final {} |
133 | | |
134 | | //! operator!= |
135 | | bool operator!=(MWAWSubDocument const &doc) const final; |
136 | | |
137 | | //! the parser function |
138 | | void parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType type) final; |
139 | | |
140 | | protected: |
141 | | //! the subdocument id |
142 | | int m_id; |
143 | | }; |
144 | | |
145 | | void SubDocument::parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType /*type*/) |
146 | 5.01k | { |
147 | 5.01k | if (!listener.get()) { |
148 | 0 | MWAW_DEBUG_MSG(("MouseWrtParserInternal::SubDocument::parse: no listener\n")); |
149 | 0 | return; |
150 | 0 | } |
151 | 5.01k | auto *parser=dynamic_cast<MouseWrtParser *>(m_parser); |
152 | 5.01k | if (!parser) { |
153 | 0 | MWAW_DEBUG_MSG(("MouseWrtParserInternal::SubDocument::parse: no parser\n")); |
154 | 0 | return; |
155 | 0 | } |
156 | | |
157 | 5.01k | long pos = m_input->tell(); |
158 | 5.01k | parser->sendZone(m_id); |
159 | 5.01k | m_input->seek(pos, librevenge::RVNG_SEEK_SET); |
160 | 5.01k | } |
161 | | |
162 | | bool SubDocument::operator!=(MWAWSubDocument const &doc) const |
163 | 0 | { |
164 | 0 | if (MWAWSubDocument::operator!=(doc)) return true; |
165 | 0 | auto const *sDoc = dynamic_cast<SubDocument const *>(&doc); |
166 | 0 | if (!sDoc) return true; |
167 | 0 | if (m_id != sDoc->m_id) return true; |
168 | 0 | return false; |
169 | 0 | } |
170 | | } |
171 | | |
172 | | //////////////////////////////////////////////////////////// |
173 | | // constructor/destructor, ... |
174 | | //////////////////////////////////////////////////////////// |
175 | | MouseWrtParser::MouseWrtParser(MWAWInputStreamPtr const &input, MWAWRSRCParserPtr const &rsrcParser, MWAWHeader *header) |
176 | 17.9k | : MWAWTextParser(input, rsrcParser, header) |
177 | 17.9k | , m_state(new MouseWrtParserInternal::State) |
178 | 17.9k | { |
179 | 17.9k | setAsciiName("main-1"); |
180 | 17.9k | } |
181 | | |
182 | | MouseWrtParser::~MouseWrtParser() |
183 | 17.9k | { |
184 | 17.9k | } |
185 | | |
186 | | //////////////////////////////////////////////////////////// |
187 | | // new page |
188 | | //////////////////////////////////////////////////////////// |
189 | | void MouseWrtParser::newPage(int number) |
190 | 22.1k | { |
191 | 22.1k | if (number <= m_state->m_actPage || number > m_state->m_numPages) |
192 | 9.35k | return; |
193 | | |
194 | 25.6k | while (m_state->m_actPage < number) { |
195 | 12.8k | m_state->m_actPage++; |
196 | 12.8k | if (!getTextListener() || m_state->m_actPage == 1) |
197 | 5.60k | continue; |
198 | 7.20k | getTextListener()->insertBreak(MWAWTextListener::PageBreak); |
199 | 7.20k | } |
200 | 12.8k | } |
201 | | |
202 | | //////////////////////////////////////////////////////////// |
203 | | // the parser |
204 | | //////////////////////////////////////////////////////////// |
205 | | void MouseWrtParser::parse(librevenge::RVNGTextInterface *docInterface) |
206 | 6.20k | { |
207 | 6.20k | if (!getInput().get() || !checkHeader(nullptr)) throw(libmwaw::ParseException()); |
208 | 6.20k | bool ok = true; |
209 | 6.20k | try { |
210 | | // create the asciiFile |
211 | 6.20k | ascii().setStream(getInput()); |
212 | 6.20k | ascii().open(asciiName()); |
213 | 6.20k | checkHeader(nullptr); |
214 | 6.20k | ok=createZones(); |
215 | 6.20k | if (ok) { |
216 | 6.20k | createDocument(docInterface); |
217 | 6.20k | sendMainZone(); |
218 | 6.20k | } |
219 | | |
220 | 6.20k | ascii().reset(); |
221 | 6.20k | } |
222 | 6.20k | catch (...) { |
223 | 0 | MWAW_DEBUG_MSG(("MouseWrtParser::parse: exception catched when parsing\n")); |
224 | 0 | ok = false; |
225 | 0 | } |
226 | | |
227 | 6.20k | resetTextListener(); |
228 | 6.20k | if (!ok) throw(libmwaw::ParseException()); |
229 | 6.20k | } |
230 | | |
231 | | //////////////////////////////////////////////////////////// |
232 | | // create the document |
233 | | //////////////////////////////////////////////////////////// |
234 | | void MouseWrtParser::createDocument(librevenge::RVNGTextInterface *documentInterface) |
235 | 6.20k | { |
236 | 6.20k | if (!documentInterface) return; |
237 | 6.20k | if (getTextListener()) { |
238 | 0 | MWAW_DEBUG_MSG(("MouseWrtParser::createDocument: listener already exist\n")); |
239 | 0 | return; |
240 | 0 | } |
241 | | |
242 | | // update the page |
243 | 6.20k | m_state->m_actPage = 0; |
244 | | |
245 | | // create the page list |
246 | 6.20k | MWAWPageSpan ps(getPageSpan()); |
247 | 6.20k | m_state->m_numPages=computeNumPages(); |
248 | 6.20k | ps.setPageSpan(m_state->m_numPages); |
249 | 18.6k | for (int i=0; i<2; ++i) { |
250 | 12.4k | if (!m_state->m_zones[i].m_text.valid()) continue; |
251 | 5.01k | MWAWHeaderFooter hF(i==0 ? MWAWHeaderFooter::HEADER : MWAWHeaderFooter::FOOTER, MWAWHeaderFooter::ALL); |
252 | 5.01k | hF.m_subDocument.reset(new MouseWrtParserInternal::SubDocument(*this, getInput(), i)); |
253 | 5.01k | ps.setHeaderFooter(hF); |
254 | 5.01k | } |
255 | 6.20k | std::vector<MWAWPageSpan> pageList; |
256 | 6.20k | pageList.push_back(ps); |
257 | | // |
258 | 6.20k | MWAWTextListenerPtr listen(new MWAWTextListener(*getParserState(), pageList, documentInterface)); |
259 | 6.20k | setTextListener(listen); |
260 | 6.20k | listen->startDocument(); |
261 | 6.20k | } |
262 | | |
263 | | |
264 | | //////////////////////////////////////////////////////////// |
265 | | // |
266 | | // Intermediate level |
267 | | // |
268 | | //////////////////////////////////////////////////////////// |
269 | | bool MouseWrtParser::createZones() |
270 | 6.20k | { |
271 | 6.20k | MWAWInputStreamPtr input = getInput(); |
272 | 6.20k | libmwaw::DebugStream f; |
273 | 37.2k | for (int i=0; i<5; ++i) { |
274 | 31.0k | if (!m_state->m_blockSizes[i]) continue; |
275 | 18.9k | long pos = input->tell(); |
276 | 18.9k | if (m_state->m_blockSizes[i]<0 || !input->checkPosition(pos+m_state->m_blockSizes[i])) { |
277 | 0 | MWAW_DEBUG_MSG(("MouseWrtParser::createZones: the block sizes are wrong\n")); |
278 | 0 | return false; |
279 | 0 | } |
280 | 18.9k | if (i==1) continue; |
281 | 13.3k | bool done=false; |
282 | 13.3k | switch (i) { |
283 | 4.84k | case 0: |
284 | 4.84k | done=readCharPLCs(m_state->m_blockSizes[i]); |
285 | 4.84k | break; |
286 | 4.35k | case 2: |
287 | 4.35k | done=readParagraphPLCs(m_state->m_blockSizes[i]); |
288 | 4.35k | break; |
289 | 1.10k | case 3: |
290 | 1.10k | done=m_state->m_blockSizes[i]>=120 && readPrintInfo(); |
291 | 1.10k | break; |
292 | 3.01k | case 4: |
293 | 3.01k | done=readDocumentInfo(m_state->m_blockSizes[i]); |
294 | 3.01k | break; |
295 | 0 | default: |
296 | 0 | break; |
297 | 13.3k | } |
298 | 13.3k | if (done) { |
299 | 11.5k | if (input->tell()!=pos+m_state->m_blockSizes[i]) |
300 | 2.68k | ascii().addDelimiter(input->tell(),'|'); |
301 | 11.5k | } |
302 | 1.79k | else { |
303 | 1.79k | f.str(""); |
304 | 1.79k | f << "Entries(Zone" << i << "):"; |
305 | 1.79k | ascii().addPos(pos); |
306 | 1.79k | ascii().addNote(f.str().c_str()); |
307 | 1.79k | } |
308 | 13.3k | input->seek(pos+m_state->m_blockSizes[i], librevenge::RVNG_SEEK_SET); |
309 | 13.3k | } |
310 | 6.20k | m_state->m_text.setBegin(input->tell()); |
311 | 6.20k | m_state->m_text.setLength(m_state->m_blockSizes[1]); |
312 | 6.20k | if (m_state->m_blockSizes[1]<0 || !input->checkPosition(m_state->m_text.end())) { |
313 | 0 | MWAW_DEBUG_MSG(("MouseWrtParser::createZones: can not find the text zone\n")); |
314 | 0 | return false; |
315 | 0 | } |
316 | 6.20k | if (!input->isEnd()) { |
317 | 6.11k | ascii().addPos(input->tell()); |
318 | 6.11k | ascii().addNote("Entries(Unknown):"); |
319 | 6.11k | } |
320 | 6.20k | return true; |
321 | 6.20k | } |
322 | | |
323 | | //////////////////////////////////////////////////////////// |
324 | | // |
325 | | // Low level |
326 | | // |
327 | | //////////////////////////////////////////////////////////// |
328 | | |
329 | | //////////////////////////////////////////////////////////// |
330 | | // read the header |
331 | | //////////////////////////////////////////////////////////// |
332 | | bool MouseWrtParser::checkHeader(MWAWHeader *header, bool strict) |
333 | 24.2k | { |
334 | 24.2k | *m_state = MouseWrtParserInternal::State(); |
335 | | |
336 | 24.2k | MWAWInputStreamPtr input = getInput(); |
337 | 24.2k | if (!input || !input->hasDataFork()) |
338 | 8 | return false; |
339 | | |
340 | 24.1k | libmwaw::DebugStream f; |
341 | 24.1k | f << "FileHeader:"; |
342 | 24.1k | int headerSize=30; |
343 | 24.1k | if (!input->checkPosition(headerSize)) { |
344 | 172 | MWAW_DEBUG_MSG(("MouseWrtParser::checkHeader: file is too short\n")); |
345 | 172 | return false; |
346 | 172 | } |
347 | 24.0k | input->seek(0,librevenge::RVNG_SEEK_SET); |
348 | 24.0k | if (input->readULong(4)!=0x4474d30 || input->readULong(2)!=0x3400) |
349 | 222 | return false; |
350 | 23.7k | long totalSize=m_state->m_blockSizes[0]; |
351 | 138k | for (int i=0; i<5; ++i) { |
352 | 115k | m_state->m_blockSizes[i]=long(input->readLong(4)); |
353 | 115k | if (m_state->m_blockSizes[i]<0) return false; |
354 | 114k | char const *wh[]= {"charPlc","text","paraPLC","printer","zone4"}; |
355 | 114k | f << wh[i] << "[sz]=" << m_state->m_blockSizes[i] << ","; |
356 | 114k | totalSize+=m_state->m_blockSizes[i]; |
357 | 114k | } |
358 | 22.0k | if (totalSize<0 || !input->checkPosition(30+totalSize)) return false; |
359 | 20.8k | if (strict && ((m_state->m_blockSizes[0]%8)!=0 || (m_state->m_blockSizes[2]%38)!=0 || |
360 | 6.47k | (m_state->m_blockSizes[3] && m_state->m_blockSizes[3]<120) || |
361 | 5.94k | (m_state->m_blockSizes[4] && m_state->m_blockSizes[4]<76))) |
362 | 1.30k | return false; |
363 | | // probably a size, maybe pict size |
364 | 19.5k | auto dSz=long(input->readLong(4)); |
365 | 19.5k | if (dSz) { |
366 | 13.2k | MWAW_DEBUG_MSG(("MouseWrtParser::checkHeader: find some extra size?\n")); |
367 | 13.2k | f << "##f0=" << dSz << ","; |
368 | 13.2k | } |
369 | | // ok, we can finish initialization |
370 | 19.5k | if (header) |
371 | 7.13k | header->reset(MWAWDocument::MWAW_T_MOUSEWRITE, 1); |
372 | 19.5k | input->seek(headerSize,librevenge::RVNG_SEEK_SET); |
373 | | |
374 | 19.5k | ascii().addPos(0); |
375 | 19.5k | ascii().addNote(f.str().c_str()); |
376 | 19.5k | ascii().addPos(headerSize); |
377 | 19.5k | return true; |
378 | 20.8k | } |
379 | | |
380 | | //////////////////////////////////////////////////////////// |
381 | | // read the basic structure |
382 | | //////////////////////////////////////////////////////////// |
383 | | bool MouseWrtParser::readCharPLCs(long sz) |
384 | 4.84k | { |
385 | 4.84k | MWAWInputStreamPtr input = getInput(); |
386 | 4.84k | long pos = input->tell(); |
387 | 4.84k | if (sz<0 || (sz%8)!=0 || !input->checkPosition(pos+sz)) { |
388 | 300 | MWAW_DEBUG_MSG(("MouseWrtParser::readCharPLCs: find unexpected size length\n")); |
389 | 300 | return false; |
390 | 300 | } |
391 | 4.54k | long N=sz/8; |
392 | 4.54k | libmwaw::DebugStream f; |
393 | 4.54k | f << "Entries(CharPLC):"; |
394 | 4.54k | ascii().addPos(pos); |
395 | 4.54k | ascii().addNote(f.str().c_str()); |
396 | 2.92M | for (long i=0; i<N; ++i) { |
397 | 2.92M | pos=input->tell(); |
398 | 2.92M | f.str(""); |
399 | 2.92M | f << "CharPLC-C" << i << ":"; |
400 | 2.92M | int cPos; |
401 | 2.92M | MWAWFont font; |
402 | 2.92M | if (i+1!=N && readFont(font, cPos)) { |
403 | 2.92M | f << "cPos=" << cPos << "," << font.getDebugString(getParserState()->m_fontConverter); |
404 | 2.92M | m_state->m_charPLCMap[cPos]=font; |
405 | 2.92M | } |
406 | 2.92M | input->seek(pos+8, librevenge::RVNG_SEEK_SET); |
407 | 2.92M | ascii().addPos(pos); |
408 | 2.92M | ascii().addNote(f.str().c_str()); |
409 | 2.92M | } |
410 | 4.54k | return true; |
411 | 4.84k | } |
412 | | |
413 | | bool MouseWrtParser::readFont(MWAWFont &font, int &cPos) |
414 | 2.92M | { |
415 | 2.92M | MWAWInputStreamPtr input = getInput(); |
416 | 2.92M | long pos = input->tell(); |
417 | 2.92M | if (!input->checkPosition(pos+8)) return false; |
418 | 2.92M | cPos=static_cast<int>(input->readULong(2)); |
419 | 2.92M | libmwaw::DebugStream f; |
420 | 2.92M | font=MWAWFont(); |
421 | 2.92M | auto val=int(input->readULong(1)); |
422 | 2.92M | if (val) f << "f0=" << val << ","; |
423 | 2.92M | font.setSize(float(input->readULong(1))); |
424 | 2.92M | auto flag=static_cast<int>(input->readULong(1)); |
425 | 2.92M | uint32_t flags=0; |
426 | 2.92M | if (flag&0x1) flags |= MWAWFont::boldBit; |
427 | 2.92M | if (flag&0x2) flags |= MWAWFont::italicBit; |
428 | 2.92M | if (flag&0x4) font.setUnderlineStyle(MWAWFont::Line::Simple); |
429 | 2.92M | if (flag&0x8) flags |= MWAWFont::embossBit; |
430 | 2.92M | if (flag&0x10) flags |= MWAWFont::shadowBit; |
431 | 2.92M | if (flag&0x60) f << "#flag[hi]=" << std::hex << (flag&0x60) << std::dec << ","; |
432 | 2.92M | font.setFlags(flags); |
433 | 2.92M | val=static_cast<int>(input->readULong(1)); // 0|7d |
434 | 2.92M | if (val) f << "f1=" << val << ","; |
435 | 2.92M | font.setId(static_cast<int>(input->readULong(2))); |
436 | 2.92M | font.m_extra=f.str().c_str(); |
437 | 2.92M | return true; |
438 | 2.92M | } |
439 | | |
440 | | bool MouseWrtParser::readParagraphPLCs(long sz) |
441 | 4.35k | { |
442 | 4.35k | MWAWInputStreamPtr input = getInput(); |
443 | 4.35k | long pos = input->tell(); |
444 | 4.35k | if (sz<0 || (sz%38)!=0 || !input->checkPosition(pos+sz)) { |
445 | 376 | MWAW_DEBUG_MSG(("MouseWrtParser::readParagraphPLCs: find unexpected size length\n")); |
446 | 376 | return false; |
447 | 376 | } |
448 | 3.97k | auto N=int(sz/38); |
449 | 3.97k | libmwaw::DebugStream f; |
450 | 3.97k | f << "Entries(ParaPLC):"; |
451 | 3.97k | ascii().addPos(pos); |
452 | 3.97k | ascii().addNote(f.str().c_str()); |
453 | 2.36M | for (int i=0; i<N; ++i) { |
454 | 2.36M | pos=input->tell(); |
455 | 2.36M | f.str(""); |
456 | 2.36M | f << "ParaPLC-P" << i << ":"; |
457 | 2.36M | if (i+1==N) { // last is sometimes random |
458 | 3.97k | input->seek(pos+36, librevenge::RVNG_SEEK_SET); |
459 | 3.97k | auto cPos=static_cast<int>(input->readULong(2)); |
460 | 3.97k | f << "cPos=" << cPos << ","; |
461 | 3.97k | input->seek(pos+38, librevenge::RVNG_SEEK_SET); |
462 | 3.97k | ascii().addPos(pos); |
463 | 3.97k | ascii().addNote(f.str().c_str()); |
464 | 3.97k | break; |
465 | 3.97k | } |
466 | 2.36M | MouseWrtParserInternal::Paragraph para(i); |
467 | 2.36M | para.m_paragraph.m_marginsUnit=librevenge::RVNG_POINT; |
468 | | // note: right margins is defined from left, so must be corrected when we know the page length |
469 | 2.36M | para.m_paragraph.m_margins[1] = double(input->readLong(2)); |
470 | 2.36M | para.m_paragraph.m_margins[2] = double(input->readLong(2)); |
471 | 2.36M | auto val=static_cast<int>(input->readULong(1)); |
472 | 2.36M | switch (val) { |
473 | 8.51k | case 0xf: // left |
474 | 8.51k | break; |
475 | 29.8k | case 0x10: |
476 | 29.8k | para.m_paragraph.m_justify = MWAWParagraph::JustificationFull; |
477 | 29.8k | break; |
478 | 31.1k | case 0x11: |
479 | 31.1k | para.m_paragraph.m_justify = MWAWParagraph::JustificationRight; |
480 | 31.1k | break; |
481 | 52.9k | case 0x12: |
482 | 52.9k | para.m_paragraph.m_justify = MWAWParagraph::JustificationCenter; |
483 | 52.9k | break; |
484 | 5.66k | case 0x13: |
485 | 5.66k | f << "justify=rowCol,"; |
486 | 5.66k | break; |
487 | 7.84k | case 0x14: |
488 | 7.84k | f << "justify=col,"; |
489 | 7.84k | break; |
490 | 2.22M | default: |
491 | 2.22M | if (!val) break; |
492 | 1.17M | MWAW_DEBUG_MSG(("MouseWrtParser::readParagraphPLCs: unknown justify\n")); |
493 | 1.17M | f << "#justify=" << std::hex << val << std::dec << ","; |
494 | 2.36M | } |
495 | 7.08M | for (int j=0; j<2; ++j) { // fl0=1|7, maybe related to tabs definition |
496 | 4.72M | val=static_cast<int>(input->readULong(1)); // 1|7 |
497 | 4.72M | if (val) f << "fl" << j << "=" << std::hex << val << std::dec << ","; |
498 | 4.72M | } |
499 | 2.36M | val=static_cast<int>(input->readULong(1)); |
500 | 2.36M | switch (val) { |
501 | 9.57k | case 0xb: |
502 | 9.57k | break; |
503 | 18.7k | case 0xc: |
504 | 18.7k | para.m_paragraph.setInterline(1.1, librevenge::RVNG_PERCENT); |
505 | 18.7k | break; |
506 | 24.0k | case 0xd: |
507 | 24.0k | para.m_paragraph.setInterline(1.5, librevenge::RVNG_PERCENT); |
508 | 24.0k | break; |
509 | 15.8k | case 0xe: |
510 | 15.8k | para.m_paragraph.setInterline(2, librevenge::RVNG_PERCENT); |
511 | 15.8k | break; |
512 | 2.29M | default: |
513 | 2.29M | MWAW_DEBUG_MSG(("MouseWrtParser::readParagraphPLCs: unknown interline\n")); |
514 | 2.29M | f << "#interline=" << val << ","; |
515 | 2.29M | break; |
516 | 2.36M | } |
517 | 2.36M | val=static_cast<int>(input->readULong(1)); // always 0 |
518 | 2.36M | if (val) f << "fl2=" << val << ","; |
519 | 2.36M | val=static_cast<int>(input->readULong(1)); |
520 | 2.36M | switch (val) { |
521 | 1.04M | case 0: |
522 | 1.04M | break; |
523 | 100k | case 1: |
524 | 100k | para.m_picture=true; |
525 | 100k | f << "picture,"; |
526 | 100k | break; |
527 | 1.22M | default: |
528 | 1.22M | MWAW_DEBUG_MSG(("MouseWrtParser::readParagraphPLCs: unknown picture def\n")); |
529 | 1.22M | f << "#picture=" << val << ","; |
530 | 1.22M | break; |
531 | 2.36M | } |
532 | 2.36M | int lastTabPos=0; // check that the tabulation are in increasing order |
533 | 4.11M | for (int j=0; j<10; ++j) { |
534 | 4.11M | val=static_cast<int>(input->readLong(2)); |
535 | 4.11M | if (!val || val<=lastTabPos) break; |
536 | 1.75M | MWAWTabStop tab; |
537 | 1.75M | tab.m_alignment=MWAWTabStop::CENTER; |
538 | 1.75M | tab.m_position=double(val)/72.; |
539 | 1.75M | para.m_paragraph.m_tabs->push_back(tab); |
540 | 1.75M | lastTabPos=val; |
541 | 1.75M | } |
542 | 2.36M | input->seek(pos+30, librevenge::RVNG_SEEK_SET); |
543 | 2.36M | val=static_cast<int>(input->readLong(2)); |
544 | 2.36M | if (val) f << "act[tab]=" << val << ","; |
545 | 2.36M | val=static_cast<int>(input->readULong(1)); |
546 | 2.36M | switch (val) { |
547 | 1.04M | case 0: |
548 | 1.04M | para.m_paragraph.m_writingMode=libmwaw::WritingRightTop; |
549 | 1.04M | break; |
550 | 96.6k | case 1: // normal writing |
551 | 96.6k | break; |
552 | 1.21M | default: |
553 | 1.21M | MWAW_DEBUG_MSG(("MouseWrtParser::readParagraphPLCs: unknown writing mode\n")); |
554 | 1.21M | f << "#writing[mode]=" << val << ","; |
555 | 1.21M | break; |
556 | 2.36M | } |
557 | 9.45M | for (int j=0; j<3; ++j) { // always 0? |
558 | 7.08M | val=static_cast<int>(input->readULong(1)); |
559 | 7.08M | if (val) f << "flA" << j << "=" << val << ","; |
560 | 7.08M | } |
561 | 2.36M | f << para.m_paragraph; |
562 | 2.36M | auto cPos=static_cast<int>(input->readULong(2)); |
563 | 2.36M | f << "cPos=" << cPos << ","; |
564 | 2.36M | m_state->m_paraPLCMap[cPos]=para; |
565 | 2.36M | input->seek(pos+38, librevenge::RVNG_SEEK_SET); |
566 | 2.36M | ascii().addPos(pos); |
567 | 2.36M | ascii().addNote(f.str().c_str()); |
568 | 2.36M | } |
569 | 3.97k | return true; |
570 | 3.97k | } |
571 | | |
572 | | bool MouseWrtParser::readDocumentInfo(long sz) |
573 | 3.01k | { |
574 | 3.01k | MWAWInputStreamPtr input = getInput(); |
575 | 3.01k | long pos = input->tell(); |
576 | 3.01k | if (sz<76 || !input->checkPosition(pos+sz)) { |
577 | 151 | MWAW_DEBUG_MSG(("MouseWrtParser::readDocumentInfo: find unexpected size length\n")); |
578 | 151 | return false; |
579 | 151 | } |
580 | 2.86k | libmwaw::DebugStream f; |
581 | 2.86k | f << "Entries(DocumentInfo):"; |
582 | 2.86k | int val; |
583 | 2.86k | f << "unkns=["; |
584 | 8.58k | for (int i=0; i<2; ++i) { // footer,header |
585 | | // find 0|18|25, does not seems related to heigth... |
586 | 5.72k | val=static_cast<int>(input->readULong(2)); |
587 | 5.72k | if (val) |
588 | 4.08k | f << val << ","; |
589 | 1.64k | else |
590 | 1.64k | f << "_,"; |
591 | 5.72k | } |
592 | 2.86k | f << "],"; |
593 | 5.72k | for (auto &zone : m_state->m_zones) { // header,footer |
594 | 5.72k | val=static_cast<int>(input->readULong(1)); |
595 | 5.72k | switch (val) { |
596 | 2.27k | case 0: |
597 | 2.27k | zone.m_writingHebrew=true; |
598 | 2.27k | f << "writing[mode]=rt-lb,"; |
599 | 2.27k | break; |
600 | 322 | case 1: // normal writing |
601 | 322 | break; |
602 | 3.12k | default: |
603 | 3.12k | MWAW_DEBUG_MSG(("MouseWrtParser::readDocumentInfo: unknown writing mode\n")); |
604 | 3.12k | f << "#writing[mode]=" << val << ","; |
605 | 3.12k | break; |
606 | 5.72k | } |
607 | 5.72k | } |
608 | 2.86k | f << "ids=["; |
609 | 8.58k | for (int i=0; i<2; ++i) { // header,footer |
610 | 5.72k | val=static_cast<int>(input->readULong(4)); |
611 | 5.72k | if (val) |
612 | 4.93k | f << std::hex << val << std::dec << ","; |
613 | 794 | else |
614 | 794 | f << "_,"; |
615 | 5.72k | } |
616 | 2.86k | f << "],"; |
617 | 2.86k | long zoneSize[2]; |
618 | 8.58k | for (int i=0; i<2; ++i) { // header,footer |
619 | 5.72k | zoneSize[i]=long(input->readULong(4)); |
620 | 5.72k | if (zoneSize[i]) f << "block" << i << "[sz]=" << zoneSize[i] << ","; |
621 | 5.72k | } |
622 | 8.58k | for (int i=0; i<2; ++i) { // header,footer, always 0|-1? |
623 | 5.72k | val=static_cast<int>(input->readLong(4)); |
624 | 5.72k | if (val) f << "f" << i+2 << "=" << val << ","; |
625 | 5.72k | } |
626 | 8.58k | for (int i=0; i<2; ++i) { // header,footer |
627 | 5.72k | long actPos=input->tell(); |
628 | 5.72k | int cPos; |
629 | 5.72k | if (zoneSize[i]==0 || !readFont(m_state->m_zones[i].m_font, cPos)) |
630 | 698 | input->seek(actPos+8, librevenge::RVNG_SEEK_SET); |
631 | 5.02k | else |
632 | 5.02k | f << "font" << i << "=[" << m_state->m_zones[i].m_font.getDebugString(getParserState()->m_fontConverter) << "],"; |
633 | 5.72k | } |
634 | 2.86k | ascii().addDelimiter(input->tell(),'|'); |
635 | 2.86k | if (sz > 76+zoneSize[0]+zoneSize[1] || zoneSize[0]<0 || zoneSize[1]<0) { |
636 | 193 | MWAW_DEBUG_MSG(("MouseWrtParser::readDocumentInfo: problem with the zoneSize\n")); |
637 | 193 | f << "##zoneSize,"; |
638 | 193 | input->seek(pos+sz, librevenge::RVNG_SEEK_SET); |
639 | 193 | } |
640 | 2.67k | else { |
641 | 2.67k | input->seek(pos+76, librevenge::RVNG_SEEK_SET); |
642 | 8.01k | for (int i=0; i<2; ++i) { |
643 | 5.34k | if (zoneSize[i]<=0) continue; |
644 | 5.01k | m_state->m_zones[i].m_text.setBegin(input->tell()); |
645 | 5.01k | m_state->m_zones[i].m_text.setLength(zoneSize[i]); |
646 | 5.01k | input->seek(zoneSize[i], librevenge::RVNG_SEEK_CUR); |
647 | 5.01k | } |
648 | 2.67k | } |
649 | | |
650 | 2.86k | ascii().addPos(pos); |
651 | 2.86k | ascii().addNote(f.str().c_str()); |
652 | 2.86k | return true; |
653 | 2.86k | } |
654 | | |
655 | | int MouseWrtParser::computeNumPages() |
656 | 6.20k | { |
657 | 6.20k | if (!m_state->m_text.valid()) return 1; |
658 | 5.60k | MWAWInputStreamPtr input = getInput(); |
659 | 5.60k | int numPages=1; |
660 | 5.60k | auto pIt=m_state->m_paraPLCMap.begin(); |
661 | 5.60k | long const beginPos=m_state->m_text.begin(); |
662 | 194k | while (pIt!=m_state->m_paraPLCMap.end()) { |
663 | 192k | if (pIt->second.m_picture) { |
664 | 15.9k | ++pIt; |
665 | 15.9k | continue; |
666 | 15.9k | } |
667 | 176k | long actPos=beginPos+(pIt++)->first; |
668 | 176k | long lastPos=(pIt!=m_state->m_paraPLCMap.end()) ? beginPos+pIt->first : m_state->m_text.end(); |
669 | 176k | if (lastPos>m_state->m_text.end()) { |
670 | 3.41k | MWAW_DEBUG_MSG(("MouseWrtParser::computeNumPages: oops, problem with some plc pos\n")); |
671 | 3.41k | break; |
672 | 3.41k | } |
673 | 173k | input->seek(actPos, librevenge::RVNG_SEEK_SET); |
674 | 4.63M | for (long cPos=actPos; cPos<lastPos; ++cPos) { |
675 | 4.46M | if (input->readULong(1)==0xd7) |
676 | 7.41k | ++numPages; |
677 | 4.46M | } |
678 | 173k | } |
679 | 5.60k | return numPages; |
680 | 6.20k | } |
681 | | |
682 | | //////////////////////////////////////////////////////////// |
683 | | // read the print info |
684 | | //////////////////////////////////////////////////////////// |
685 | | bool MouseWrtParser::readPrintInfo() |
686 | 491 | { |
687 | 491 | MWAWInputStreamPtr input = getInput(); |
688 | 491 | long pos = input->tell(); |
689 | 491 | libmwaw::DebugStream f; |
690 | | // print info |
691 | 491 | libmwaw::PrinterInfo info; |
692 | 491 | if (!info.read(input)) return false; |
693 | 274 | f << "Entries(PrintInfo):"<< info; |
694 | | |
695 | 274 | MWAWVec2i paperSize = info.paper().size(); |
696 | 274 | MWAWVec2i pageSize = info.page().size(); |
697 | 274 | if (pageSize.x() <= 0 || pageSize.y() <= 0 || |
698 | 165 | paperSize.x() <= 0 || paperSize.y() <= 0) return false; |
699 | | |
700 | | // define margin from print info |
701 | 136 | MWAWVec2i lTopMargin= -1 * info.paper().pos(0); |
702 | 136 | MWAWVec2i rBotMargin=info.paper().pos(1) - info.page().pos(1); |
703 | | |
704 | | // move margin left | top |
705 | 136 | int decalX = lTopMargin.x() > 14 ? lTopMargin.x()-14 : 0; |
706 | 136 | int decalY = lTopMargin.y() > 14 ? lTopMargin.y()-14 : 0; |
707 | 136 | lTopMargin -= MWAWVec2i(decalX, decalY); |
708 | 136 | rBotMargin += MWAWVec2i(decalX, decalY); |
709 | | |
710 | | // decrease right | bottom |
711 | 136 | int rightMarg = rBotMargin.x() -10; |
712 | 136 | if (rightMarg < 0) rightMarg=0; |
713 | 136 | int botMarg = rBotMargin.y() -50; |
714 | 136 | if (botMarg < 0) botMarg=0; |
715 | | |
716 | 136 | getPageSpan().setMarginTop(lTopMargin.y()/72.0); |
717 | 136 | getPageSpan().setMarginBottom(botMarg/72.0); |
718 | 136 | getPageSpan().setMarginLeft(lTopMargin.x()/72.0); |
719 | 136 | getPageSpan().setMarginRight(rightMarg/72.0); |
720 | 136 | getPageSpan().setFormLength(paperSize.y()/72.); |
721 | 136 | getPageSpan().setFormWidth(paperSize.x()/72.); |
722 | | |
723 | 136 | ascii().addPos(pos); |
724 | 136 | ascii().addNote(f.str().c_str()); |
725 | 136 | input->seek(pos+0x78, librevenge::RVNG_SEEK_SET); |
726 | 136 | if (long(input->tell()) != pos+0x78) { |
727 | 0 | MWAW_DEBUG_MSG(("MouseWrtParser::readPrintInfo: file is too short\n")); |
728 | 0 | return false; |
729 | 0 | } |
730 | 136 | ascii().addPos(input->tell()); |
731 | | |
732 | 136 | return true; |
733 | 136 | } |
734 | | |
735 | | //////////////////////////////////////////////////////////// |
736 | | // send the data |
737 | | //////////////////////////////////////////////////////////// |
738 | | bool MouseWrtParser::sendMainZone() |
739 | 6.20k | { |
740 | 6.20k | MWAWListenerPtr listener=getMainListener(); |
741 | 6.20k | if (!listener) { |
742 | 0 | MWAW_DEBUG_MSG(("MouseWrtParser::sendMainZone: can not find the listener\n")); |
743 | 0 | return false; |
744 | 0 | } |
745 | 6.20k | MWAWInputStreamPtr input = getInput(); |
746 | 6.20k | if (!m_state->m_text.valid() || !input->checkPosition(m_state->m_text.end())) { |
747 | 608 | listener->insertChar(' '); |
748 | 608 | return true; |
749 | 608 | } |
750 | 5.60k | long begPos = m_state->m_text.begin(), pos=begPos; |
751 | 5.60k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
752 | 5.60k | auto N=static_cast<int>(m_state->m_text.length()); |
753 | 5.60k | libmwaw::DebugStream f; |
754 | 5.60k | f << "Entries(Text):"; |
755 | 5.60k | double const pageWidth=72. * getPageSpan().getPageWidth(); |
756 | 5.60k | int actPage=1; |
757 | 5.60k | newPage(actPage); |
758 | 4.58M | for (int i=0; i<N; ++i) { |
759 | 4.58M | auto pIt=m_state->m_paraPLCMap.find(i); |
760 | 4.58M | if (pIt!=m_state->m_paraPLCMap.end()) { |
761 | 178k | if (i!=0) { |
762 | 174k | ascii().addPos(pos); |
763 | 174k | ascii().addNote(f.str().c_str()); |
764 | 174k | pos=input->tell(); |
765 | 174k | f.str(""); |
766 | 174k | f << "Text:"; |
767 | 174k | } |
768 | 178k | auto const ¶=pIt->second; |
769 | 178k | f << "[P" << para.m_id << "]"; |
770 | | // time to send the paragraph, so first update the right margins |
771 | 178k | MWAWParagraph paragraph=para.m_paragraph; |
772 | 178k | if (*(paragraph.m_margins[2])>pageWidth) { |
773 | 80.4k | f << "#"; |
774 | 80.4k | paragraph.m_margins[2]=0; |
775 | 80.4k | } |
776 | 97.8k | else |
777 | 97.8k | paragraph.m_margins[2]=pageWidth-*paragraph.m_margins[2]; |
778 | 178k | if (para.m_picture) paragraph.m_justify = MWAWParagraph::JustificationRight; |
779 | 178k | listener->setParagraph(paragraph); |
780 | 178k | if (para.m_picture) { |
781 | 15.0k | f << "[picture],"; |
782 | 15.0k | ++pIt; |
783 | 15.0k | long endPos=pIt==m_state->m_paraPLCMap.end() ? m_state->m_text.end() : begPos+pIt->first; |
784 | 15.0k | if (endPos<=input->tell()) { // check that we do not go backward |
785 | 180 | f << "###"; |
786 | 180 | MWAW_DEBUG_MSG(("MouseWrtParser::sendZone: can not compute the end of picture pos, stop!!!\n")); |
787 | 180 | break; |
788 | 180 | } |
789 | 14.9k | long actPos=input->tell(); |
790 | 14.9k | bool ok=endPos-actPos>9; |
791 | 14.9k | if (ok) { |
792 | | // look for pict |
793 | 5.17k | auto dSz=static_cast<int>(input->readULong(2)); |
794 | 5.17k | if (dSz+9>endPos-actPos || dSz+12<endPos-actPos) { |
795 | 4.72k | f << "#pict?"; |
796 | 4.72k | MWAW_DEBUG_MSG(("MouseWrtParser::sendZone: no sure that this is a picture\n")); |
797 | 4.72k | input->seek(endPos-9, librevenge::RVNG_SEEK_SET); |
798 | 4.72k | } |
799 | 446 | else |
800 | 446 | input->seek(actPos+dSz, librevenge::RVNG_SEEK_SET); |
801 | 5.17k | long pictSz=input->tell()-actPos; |
802 | 5.17k | int dim[4]; |
803 | 20.6k | for (auto &d : dim) d=static_cast<int>(input->readLong(2)); |
804 | 5.17k | MWAWBox2i box(MWAWVec2i(dim[1],dim[0]),MWAWVec2i(dim[3],dim[2])); |
805 | 5.17k | f << "box=" << box << ","; |
806 | 5.17k | if (box.size()[0]<0 || box.size()[1]<0 || box.size()[0]>2000 || box.size()[1]>2000) { |
807 | 2.71k | MWAW_DEBUG_MSG(("MouseWrtParser::sendZone: the bdbox is bad\n")); |
808 | 2.71k | f << "###"; |
809 | 2.71k | ok=false; |
810 | 2.71k | } |
811 | 2.46k | else { |
812 | 2.46k | librevenge::RVNGBinaryData data; |
813 | 2.46k | input->seek(actPos, librevenge::RVNG_SEEK_SET); |
814 | 2.46k | input->readDataBlock(pictSz, data); |
815 | 2.46k | MWAWEmbeddedObject object(data); |
816 | 2.46k | MWAWPosition position(MWAWVec2f(0,0), MWAWVec2f(box.size()), librevenge::RVNG_POINT); |
817 | 2.46k | position.m_anchorTo=MWAWPosition::Char; |
818 | 2.46k | listener->insertPicture(position, object); |
819 | | #ifdef DEBUG_WITH_FILES |
820 | | static int volatile pictName = 0; |
821 | | libmwaw::DebugStream f2; |
822 | | f2 << "Pict-" << ++pictName << ".pct"; |
823 | | libmwaw::Debug::dumpFile(data, f2.str().c_str()); |
824 | | #endif |
825 | 2.46k | ascii().skipZone(actPos, actPos+pictSz-1); |
826 | 2.46k | } |
827 | 5.17k | } |
828 | | |
829 | 14.9k | if (ok || endPos-actPos>20) { |
830 | 4.55k | listener->insertEOL(); |
831 | 4.55k | ascii().addPos(pos); |
832 | 4.55k | ascii().addNote(f.str().c_str()); |
833 | 4.55k | pos=input->tell(); |
834 | 4.55k | f.str(""); |
835 | 4.55k | f << "Text:"; |
836 | 4.55k | input->seek(endPos, librevenge::RVNG_SEEK_SET); |
837 | 4.55k | i=int(endPos-begPos-1); // will be endPos-begPos after |
838 | 4.55k | continue; |
839 | 4.55k | } |
840 | 14.9k | } |
841 | 178k | } |
842 | 4.57M | auto fIt=m_state->m_charPLCMap.find(i); |
843 | 4.57M | if (fIt!=m_state->m_charPLCMap.end()) { |
844 | 112k | listener->setFont(fIt->second); |
845 | 112k | f << "[" << fIt->second.getDebugString(getParserState()->m_fontConverter) << "]"; |
846 | 112k | } |
847 | 4.57M | auto c=static_cast<unsigned char>(input->readULong(1)); |
848 | 4.57M | f << c; |
849 | 4.57M | switch (c) { |
850 | 46.7k | case 0x9: |
851 | 46.7k | listener->insertTab(); |
852 | 46.7k | break; |
853 | 53.3k | case 0xd: |
854 | 53.3k | listener->insertEOL(); |
855 | 53.3k | ascii().addPos(pos); |
856 | 53.3k | ascii().addNote(f.str().c_str()); |
857 | 53.3k | pos=input->tell(); |
858 | 53.3k | f.str(""); |
859 | 53.3k | f << "Text:"; |
860 | 53.3k | break; |
861 | 16.5k | case 0xd7: { |
862 | 16.5k | newPage(++actPage); |
863 | 16.5k | long actPos=input->tell(); |
864 | 16.5k | if (i+1!=N && input->readULong(1)==0xd) { |
865 | 145 | ascii().addPos(pos); |
866 | 145 | ascii().addNote(f.str().c_str()); |
867 | 145 | pos=input->tell(); |
868 | 145 | f.str(""); |
869 | 145 | f << "Text:"; |
870 | 145 | ++i; |
871 | 145 | } |
872 | 16.4k | else |
873 | 16.4k | input->seek(actPos, librevenge::RVNG_SEEK_SET); |
874 | 16.5k | break; |
875 | 0 | } |
876 | 4.45M | default: |
877 | 4.45M | listener->insertCharacter(c); |
878 | 4.45M | break; |
879 | 4.57M | } |
880 | 4.57M | } |
881 | 5.60k | if (input->tell()!=pos) { |
882 | 4.74k | ascii().addPos(pos); |
883 | 4.74k | ascii().addNote(f.str().c_str()); |
884 | 4.74k | } |
885 | 5.60k | return true; |
886 | 5.60k | } |
887 | | |
888 | | bool MouseWrtParser::sendZone(int zoneId) |
889 | 5.01k | { |
890 | 5.01k | if (zoneId < 0 || zoneId >= 2) { |
891 | 0 | MWAW_DEBUG_MSG(("MouseWrtParser::sendZone: invalid zone %d\n", zoneId)); |
892 | 0 | return false; |
893 | 0 | } |
894 | 5.01k | MWAWListenerPtr listener=getMainListener(); |
895 | 5.01k | if (!listener) { |
896 | 0 | MWAW_DEBUG_MSG(("MouseWrtParser::sendZone: can not find the listener\n")); |
897 | 0 | return false; |
898 | 0 | } |
899 | 5.01k | auto const &zone=m_state->m_zones[zoneId]; |
900 | 5.01k | if (!zone.m_text.valid()) return true; |
901 | 5.01k | if (zone.m_writingHebrew) { |
902 | 1.76k | MWAWParagraph para; |
903 | 1.76k | para.m_writingMode=libmwaw::WritingRightTop; |
904 | 1.76k | listener->setParagraph(para); |
905 | 1.76k | } |
906 | 5.01k | listener->setFont(zone.m_font); |
907 | 5.01k | MWAWInputStreamPtr input = getInput(); |
908 | 5.01k | libmwaw::DebugStream f; |
909 | 5.01k | f << "Entries(Text):" << (zoneId==0 ? "header" : "footer") << ","; |
910 | 5.01k | input->seek(zone.m_text.begin(), librevenge::RVNG_SEEK_SET); |
911 | 5.01k | auto N=static_cast<int>(zone.m_text.length()); |
912 | 21.0M | for (long i=0; i<N ; ++i) { |
913 | 21.0M | if (input->isEnd()) { |
914 | 3.19k | MWAW_DEBUG_MSG(("MouseWrtParser::sendZone: oops the text length seems too big\n")); |
915 | 3.19k | f << "###"; |
916 | 3.19k | break; |
917 | 3.19k | } |
918 | 21.0M | auto c=static_cast<unsigned char>(input->readULong(1)); |
919 | 21.0M | f << c; |
920 | 21.0M | switch (c) { |
921 | 122k | case 0x9: |
922 | 122k | MWAW_DEBUG_MSG(("MouseWrtParser::sendZone: oops unexpected tab\n")); |
923 | 122k | listener->insertChar(' '); |
924 | 122k | break; |
925 | 149k | case 0xd: |
926 | 149k | if (i+1==N) |
927 | 59 | break; |
928 | 149k | listener->insertEOL(); |
929 | 149k | break; |
930 | 20.7M | default: |
931 | 20.7M | listener->insertCharacter(c); |
932 | 20.7M | break; |
933 | 21.0M | } |
934 | 21.0M | } |
935 | 5.01k | ascii().addPos(zone.m_text.begin()); |
936 | 5.01k | ascii().addNote(f.str().c_str()); |
937 | 5.01k | return true; |
938 | 5.01k | } |
939 | | |
940 | | // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: |