Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / hwpfilter / source / hwpfile.cxx
blob8cc1f485a07f69a7c4449541ac5992ead412a211
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "precompile.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include "hwplib.h"
27 #include "hwpfile.h"
28 #include "hiodev.h"
29 #include "hfont.h"
30 #include "hstyle.h"
31 #include "hbox.h"
32 #include "hpara.h"
33 #include "htags.h"
34 #include "hcode.h"
35 #include "hstream.h"
37 #include <osl/diagnose.h>
39 #define HWPHeadLen 128
40 #define HWPSummaryLen 1008
42 #define FILESTG_SIGNATURE 0xF8995567
43 #define FILESTG_SIGNATURE_NORMAL 0xF8995568
45 HWPFile *HWPFile::cur_doc = 0;
46 static int ccount = 0;
47 static int pcount = 0;
48 static int datecodecount = 0;
50 HWPFile::HWPFile()
51 : version(HWP_V30)
52 , compressed(false)
53 , encrypted(false)
54 , linenumber(0)
55 , info_block_len(0)
56 , error_code(HWP_NoError)
57 , oledata(0)
58 , m_nCurrentPage(1)
59 , m_nMaxSettedPage(0)
60 , hiodev(0)
61 , currenthyper(0)
63 SetCurrentDoc(this);
66 HWPFile::~HWPFile()
68 delete oledata;
69 delete hiodev;
71 std::list < ColumnInfo* >::iterator it_column = columnlist.begin();
72 for (; it_column != columnlist.end(); ++it_column)
73 delete *it_column;
75 std::list < HWPPara* >::iterator it = plist.begin();
76 for (; it != plist.end(); ++it)
77 delete *it;
79 std::list < Table* >::iterator tbl = tables.begin();
80 for (; tbl != tables.end(); ++tbl)
81 delete *tbl;
83 std::list < HyperText* >::iterator hyp = hyperlist.begin();
84 for (; hyp != hyperlist.end(); ++hyp)
86 delete *hyp;
90 int HWPFile::ReadHwpFile(HStream & stream)
92 if (Open(stream) != HWP_NoError)
93 return State();
94 InfoRead();
95 FontRead();
96 StyleRead();
97 AddColumnInfo();
98 ParaListRead();
99 TagsRead();
101 return State();
104 int detect_hwp_version(const char *str)
106 if (memcmp(V20SIGNATURE, str, HWPIDLen) == 0)
107 return HWP_V20;
108 else if (memcmp(V21SIGNATURE, str, HWPIDLen) == 0)
109 return HWP_V21;
110 else if (memcmp(V30SIGNATURE, str, HWPIDLen) == 0)
111 return HWP_V30;
112 return 0;
115 // HIODev wrapper
117 int HWPFile::Open(HStream & stream)
119 HStreamIODev *hstreamio = new HStreamIODev(stream);
121 if (!hstreamio->open())
123 delete hstreamio;
125 return SetState(HWP_EMPTY_FILE);
128 HIODev *pPrev = SetIODevice(hstreamio);
129 delete pPrev;
131 char idstr[HWPIDLen];
133 if (ReadBlock(idstr, HWPIDLen) <= 0
134 || HWP_V30 != (version = detect_hwp_version(idstr)))
136 return SetState(HWP_UNSUPPORTED_VERSION);
138 return HWP_NoError;
142 int HWPFile::State(void) const
144 return error_code;
148 int HWPFile::SetState(int errcode)
150 error_code = errcode;
151 return error_code;
155 int HWPFile::Read1b(void)
157 return hiodev ? hiodev->read1b() : -1;
161 int HWPFile::Read2b(void)
163 return hiodev ? hiodev->read2b() : -1;
167 long HWPFile::Read4b(void)
169 return hiodev ? hiodev->read4b() : -1;
173 int HWPFile::Read1b(void *ptr, size_t nmemb)
175 return hiodev ? hiodev->read1b(ptr, nmemb) : 0;
179 int HWPFile::Read2b(void *ptr, size_t nmemb)
181 return hiodev ? hiodev->read2b(ptr, nmemb) : 0;
185 int HWPFile::Read4b(void *ptr, size_t nmemb)
187 return hiodev ? hiodev->read4b(ptr, nmemb) : 0;
191 size_t HWPFile::ReadBlock(void *ptr, size_t size)
193 return hiodev ? hiodev->readBlock(ptr, size) : 0;
197 size_t HWPFile::SkipBlock(size_t size)
199 return hiodev ? hiodev->skipBlock(size) : 0;
203 bool HWPFile::SetCompressed(bool flag)
205 return hiodev ? hiodev->setCompressed(flag) : false;
209 HIODev *HWPFile::SetIODevice(HIODev * new_hiodev)
211 HIODev *old_hiodev = hiodev;
213 hiodev = new_hiodev;
215 return old_hiodev;
219 // end of HIODev wrapper
221 bool HWPFile::InfoRead(void)
223 return _hwpInfo.Read(*this);
227 bool HWPFile::FontRead(void)
229 return _hwpFont.Read(*this);
233 bool HWPFile::StyleRead(void)
235 return _hwpStyle.Read(*this);
239 bool HWPFile::ParaListRead(void)
241 return ReadParaList(plist);
244 bool HWPFile::ReadParaList(std::list < HWPPara* > &aplist, unsigned char flag)
246 HWPPara *spNode = new HWPPara;
247 unsigned char tmp_etcflag;
248 unsigned char prev_etcflag = 0;
249 while (spNode->Read(*this, flag))
251 if( !(spNode->etcflag & 0x04) ){
252 tmp_etcflag = spNode->etcflag;
253 spNode->etcflag = prev_etcflag;
254 prev_etcflag = tmp_etcflag;
256 if (spNode->nch && spNode->reuse_shape)
258 if (!aplist.empty()){
259 spNode->pshape = aplist.back()->pshape;
261 else{
262 spNode->nch = 0;
263 spNode->reuse_shape = 0;
266 spNode->pshape.pagebreak = spNode->etcflag;
267 if( spNode->nch )
268 AddParaShape( &spNode->pshape );
270 if (!aplist.empty())
271 aplist.back()->SetNext(spNode);
272 aplist.push_back(spNode);
273 spNode = new HWPPara;
275 delete spNode;
277 return true;
281 bool HWPFile::TagsRead(void)
283 ulong tag;
284 long size;
286 while (1)
288 tag = Read4b();
289 size = Read4b();
290 if (size <= 0 && tag > 0){
291 continue;
294 if (tag == FILETAG_END_OF_COMPRESSED ||
295 tag == FILETAG_END_OF_UNCOMPRESSED)
296 return true;
297 switch (tag)
299 case FILETAG_EMBEDDED_PICTURE:
301 EmPicture *emb = new EmPicture(size);
303 if (true == emb->Read(*this))
304 emblist.push_back(emb);
305 else
306 delete emb;
308 break;
309 case FILETAG_OLE_OBJECT:
310 if (oledata)
311 delete oledata;
312 oledata = new OlePicture(size);
313 oledata->Read(*this);
314 break;
315 case FILETAG_HYPERTEXT:
317 if( (size % 617) != 0 )
318 SkipBlock( size );
319 else
320 for( int i = 0 ; i < size/617 ; i++)
322 HyperText *hypert = new HyperText;
323 hypert->Read(*this);
324 hyperlist.push_back(hypert);
326 break;
328 case 6:
330 ReadBlock(_hwpInfo.back_info.reserved1, 8);
331 _hwpInfo.back_info.luminance = Read4b();
332 _hwpInfo.back_info.contrast = Read4b();
333 _hwpInfo.back_info.effect = sal::static_int_cast<char>(Read1b());
334 ReadBlock(_hwpInfo.back_info.reserved2, 7);
335 ReadBlock(_hwpInfo.back_info.filename, 260);
336 ReadBlock(_hwpInfo.back_info.color, 3);
337 unsigned short nFlag = sal::static_int_cast<unsigned short>(Read2b());
338 _hwpInfo.back_info.flag = nFlag >> 8 ;
339 int nRange = Read4b();
340 _hwpInfo.back_info.range = nRange >> 24;
341 ReadBlock(_hwpInfo.back_info.reserved3, 27);
342 _hwpInfo.back_info.size = Read4b();
344 _hwpInfo.back_info.data = new char[(unsigned int)_hwpInfo.back_info.size];
345 ReadBlock(_hwpInfo.back_info.data, _hwpInfo.back_info.size);
347 if( _hwpInfo.back_info.size > 0 )
348 _hwpInfo.back_info.type = 2;
349 else if( _hwpInfo.back_info.filename[0] )
350 _hwpInfo.back_info.type = 1;
351 else
352 _hwpInfo.back_info.type = 0;
355 _hwpInfo.back_info.isset = true;
357 break;
359 case FILETAG_PRESENTATION:
360 case FILETAG_PREVIEW_IMAGE:
361 case FILETAG_PREVIEW_TEXT:
362 default:
363 SkipBlock(size);
369 ColumnDef *HWPFile::GetColumnDef(int num)
371 std::list<ColumnInfo*>::iterator it = columnlist.begin();
373 for(int i = 0; it != columnlist.end() ; ++it, i++){
374 if( i == num )
375 break;
378 if( it != columnlist.end() )
379 return (*it)->coldef;
380 else
381 return 0;
383 /* @return À妽º´Â 1ºÎÅÍ ½ÃÀÛÇÑ´Ù. */
384 int HWPFile::GetPageMasterNum(int page)
386 std::list<ColumnInfo*>::iterator it = columnlist.begin();
387 ColumnInfo *now = 0;
388 int i;
390 for( i = 1 ; it != columnlist.end() ; ++it, i++){
391 now = *it;
392 if( page < now->start_page )
393 return i-1;
395 return i-1;
398 HyperText *HWPFile::GetHyperText()
400 std::list<HyperText*>::iterator it = hyperlist.begin();
402 for( int i = 0; it != hyperlist.end(); ++it, i++ ){
403 if( i == currenthyper )
404 break;
407 currenthyper++;
408 return *it;
411 EmPicture *HWPFile::GetEmPicture(Picture * pic)
413 char *name = pic->picinfo.picembed.embname;
415 name[0] = 'H';
416 name[1] = 'W';
417 name[2] = 'P';
419 std::list < EmPicture* >::iterator it = emblist.begin();
420 for (; it != emblist.end(); ++it)
421 if (strcmp(name, (*it)->name) == 0)
422 return *it;
423 return 0;
426 EmPicture *HWPFile::GetEmPictureByName(char * name)
428 name[0] = 'H';
429 name[1] = 'W';
430 name[2] = 'P';
432 std::list < EmPicture* >::iterator it = emblist.begin();
433 for (; it != emblist.end(); ++it)
434 if (strcmp(name, (*it)->name) == 0)
435 return *it;
436 return 0;
440 void HWPFile::AddBox(FBox * box)
442 // LATER if we don't use box->next(),
443 // AddBox() and GetBoxHead() are useless;
444 if (!blist.empty())
446 box->prev = blist.back();
447 box->prev->next = box;
449 else
450 box->prev = 0;
451 blist.push_back(box);
455 ParaShape *HWPFile::getParaShape(int index)
457 std::list<ParaShape*>::iterator it = pslist.begin();
459 for( int i = 0; it != pslist.end(); ++it, i++ ){
460 if( i == index )
461 break;
464 return *it;
468 CharShape *HWPFile::getCharShape(int index)
470 std::list<CharShape*>::iterator it = cslist.begin();
472 for( int i = 0; it != cslist.end(); ++it, i++ ){
473 if( i == index )
474 break;
477 return *it;
481 FBoxStyle *HWPFile::getFBoxStyle(int index)
483 std::list<FBoxStyle*>::iterator it = fbslist.begin();
485 for( int i = 0; it != fbslist.end(); ++it, i++ ){
486 if( i == index )
487 break;
490 return *it;
493 DateCode *HWPFile::getDateCode(int index)
495 std::list<DateCode*>::iterator it = datecodes.begin();
497 for( int i = 0; it != datecodes.end(); ++it, i++ ){
498 if( i == index )
499 break;
502 return *it;
505 HeaderFooter *HWPFile::getHeaderFooter(int index)
507 std::list<HeaderFooter*>::iterator it = headerfooters.begin();
509 for( int i = 0; it != headerfooters.end(); ++it, i++ ){
510 if( i == index )
511 break;
514 return *it;
517 ShowPageNum *HWPFile::getPageNumber(int index)
519 std::list<ShowPageNum*>::iterator it = pagenumbers.begin();
521 for( int i = 0; it != pagenumbers.end(); ++it, i++ ){
522 if( i == index )
523 break;
526 return *it;
530 Table *HWPFile::getTable(int index)
532 std::list<Table*>::iterator it = tables.begin();
534 for( int i = 0; it != tables.end(); ++it, i++ ){
535 if( i == index )
536 break;
539 return *it;
542 void HWPFile::AddParaShape(ParaShape * pshape)
544 int nscount = 0;
545 for(int j = 0 ; j < MAXTABS-1 ; j++)
547 if( j > 0 && pshape->tabs[j].position == 0 )
548 break;
549 if( pshape->tabs[0].position == 0 ){
550 if( pshape->tabs[j].type || pshape->tabs[j].dot_continue ||
551 (pshape->tabs[j].position != 1000 *j) )
552 nscount = j;
554 else{
555 if( pshape->tabs[j].type || pshape->tabs[j].dot_continue ||
556 (pshape->tabs[j].position != 1000 * (j + 1)) )
557 nscount = j;
560 if( nscount )
561 pshape->tabs[MAXTABS-1].type = sal::static_int_cast<char>(nscount);
562 int value = compareParaShape(pshape);
563 if( value == 0 || nscount )
565 pshape->index = ++pcount;
566 pslist.push_back(pshape);
568 else
569 pshape->index = value;
573 void HWPFile::AddCharShape(CharShape * cshape)
575 int value = compareCharShape(cshape);
576 if( value == 0 )
578 cshape->index = ++ccount;
579 cslist.push_back(cshape);
581 else
582 cshape->index = value;
585 void HWPFile::AddColumnInfo()
587 ColumnInfo *cinfo = new ColumnInfo(m_nCurrentPage);
588 columnlist.push_back(cinfo);
589 setMaxSettedPage();
592 void HWPFile::SetColumnDef(ColumnDef *coldef)
594 ColumnInfo *cinfo = columnlist.back();
595 if( cinfo->bIsSet )
596 return;
597 cinfo->coldef = coldef;
598 cinfo->bIsSet = true;
601 void HWPFile::AddDateFormat(DateCode * hbox)
603 hbox->key = sal::static_int_cast<char>(++datecodecount);
604 datecodes.push_back(hbox);
607 void HWPFile::AddPageNumber(ShowPageNum * hbox)
609 pagenumbers.push_back(hbox);
612 void HWPFile::AddHeaderFooter(HeaderFooter * hbox)
614 headerfooters.push_back(hbox);
617 void HWPFile::AddTable(Table * hbox)
619 tables.push_back(hbox);
622 void HWPFile::AddFBoxStyle(FBoxStyle * fbstyle)
624 fbslist.push_back(fbstyle);
627 int HWPFile::compareCharShape(CharShape *shape)
629 int count = cslist.size();
630 if( count > 0 )
632 CharShape *cshape=0;
633 for(int i = 0; i< count; i++)
635 cshape = getCharShape(i);
637 if( shape->size == cshape->size &&
638 shape->font[0] == cshape->font[0] &&
639 shape->ratio[0] == cshape->ratio[0] &&
640 shape->space[0] == cshape->space[0] &&
641 shape->color[1] == cshape->color[1] &&
642 shape->color[0] == cshape->color[0] &&
643 shape->shade == cshape->shade &&
644 shape->attr == cshape->attr )
646 return cshape->index;
650 return 0;
654 int HWPFile::compareParaShape(ParaShape *shape)
656 int count = pslist.size();
657 if( count > 0 )
659 ParaShape *pshape=0;
660 for(int i = 0; i< count; i++)
662 pshape = getParaShape(i);
663 if( shape->left_margin == pshape->left_margin &&
664 shape->right_margin == pshape->right_margin &&
665 shape->pspacing_prev == pshape->pspacing_prev &&
666 shape->pspacing_next == pshape->pspacing_next &&
667 shape->indent == pshape->indent &&
668 shape->lspacing == pshape->lspacing &&
669 shape->arrange_type == pshape->arrange_type &&
670 shape->outline == pshape->outline &&
671 shape->pagebreak == pshape->pagebreak)
673 if( shape->cshape->size == pshape->cshape->size &&
674 shape->cshape->font[0] == pshape->cshape->font[0] &&
675 shape->cshape->ratio[0] == pshape->cshape->ratio[0] &&
676 shape->cshape->space[0] == pshape->cshape->space[0] &&
677 shape->cshape->color[1] == pshape->cshape->color[1] &&
678 shape->cshape->color[0] == pshape->cshape->color[0] &&
679 shape->cshape->shade == pshape->cshape->shade &&
680 shape->cshape->attr == pshape->cshape->attr )
682 return pshape->index;
687 return 0;
691 HWPFile *GetCurrentDoc(void)
693 return HWPFile::cur_doc;
697 HWPFile *SetCurrentDoc(HWPFile * hwpfp)
699 HWPFile *org = HWPFile::cur_doc;
701 HWPFile::cur_doc = hwpfp;
702 return org;
705 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */