merged tag ooo/DEV300_m102
[LibreOffice.git] / hwpfilter / source / hwpfile.cpp
blob54f35a206ab037ff34dec5d1b99c2b293663cf3c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #include "precompile.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34 #include "hwplib.h"
35 #include "hwpfile.h"
36 #include "hiodev.h"
37 #include "hfont.h"
38 #include "hstyle.h"
39 #include "hbox.h"
40 #include "hpara.h"
41 #include "htags.h"
42 #include "hcode.h"
43 #include "hstream.h"
45 #define HWPIDLen 30
46 #define HWPHeadLen 128
47 #define HWPSummaryLen 1008
49 #define V20SIGNATURE "HWP Document File V2.00 \032\1\2\3\4\5"
50 #define V21SIGNATURE "HWP Document File V2.10 \032\1\2\3\4\5"
51 #define V30SIGNATURE "HWP Document File V3.00 \032\1\2\3\4\5"
53 #define FILESTG_SIGNATURE 0xF8995567
54 #define FILESTG_SIGNATURE_NORMAL 0xF8995568
56 HWPFile *HWPFile::cur_doc = 0;
57 static int ccount = 0;
58 static int pcount = 0;
59 static int datecodecount = 0;
61 HWPFile::HWPFile(void)
63 Init();
67 /**
68 * TODO : Ãß°¡µÈ ½ºÅ¸Àϸ®½ºÆ®¿¡ ´ëÇÑ ¸Þ¸ð¸® ÇØÁ¦
70 HWPFile::~HWPFile(void)
72 if (oledata)
73 delete oledata;
75 if (hiodev)
76 delete hiodev;
78 LinkedListIterator < ColumnInfo > it_column(&columnlist);
79 for (; it_column.current(); it_column++)
80 delete it_column.current();
82 LinkedListIterator < HWPPara > it(&plist);
83 for (; it.current(); it++)
84 delete it.current();
86 LinkedListIterator < Table > tbl(&tables);
87 for (; tbl.current(); tbl++)
88 delete tbl.current();
90 LinkedListIterator < HyperText > hyp(&hyperlist);
91 for (; hyp.current(); hyp++)
93 delete hyp.current();
98 void HWPFile::Init(void)
100 version = HWP_V30;
101 info_block_len = 0;
102 compressed = false;
103 encrypted = false;
105 error_code = HWP_NoError;
106 hiodev = 0;
107 oledata = 0;
108 SetCurrentDoc(this);
109 currenthyper = 0;
110 m_nCurrentPage = 1;
111 m_nMaxSettedPage = 0;
115 int HWPFile::ReadHwpFile(HStream & stream)
117 if (Open(stream) != HWP_NoError)
118 return State();
119 // printf("HWPFile::ReadHwpFile\n");
120 InfoRead();
121 // printf("HWPFile::InfoRead Done.\n");
122 FontRead();
123 // printf("HWPFile::FontRead Done.\n");
124 StyleRead();
125 // printf("HWPFile::StyleRead Done.\n");
126 AddColumnInfo();
127 ParaListRead();
128 // printf("HWPFile::ParaListRead Done.\n");
129 TagsRead();
130 //printf("HWPFile::TagsRead Done. State: %d\n", State());
132 return State();
136 static int hwp_version(char *str)
138 if (memcmp(V20SIGNATURE, str, HWPIDLen) == 0)
139 return HWP_V20;
140 else if (memcmp(V21SIGNATURE, str, HWPIDLen) == 0)
141 return HWP_V21;
142 else if (memcmp(V30SIGNATURE, str, HWPIDLen) == 0)
143 return HWP_V30;
144 return 0;
148 // HIODev wrapper
150 int HWPFile::Open(HStream & stream)
152 HStreamIODev *hstreamio;
154 if (0 == (hstreamio = new HStreamIODev(stream)))
156 printf(" hstreamio is not instanciate \n");
157 return SetState(errno);
159 if (!hstreamio->open())
161 delete hstreamio;
163 return SetState(HWP_EMPTY_FILE);
165 SetIODevice(hstreamio);
167 char idstr[HWPIDLen];
169 if (ReadBlock(idstr, HWPIDLen) <= 0
170 || HWP_V30 != (version = hwp_version(idstr)))
172 return SetState(HWP_UNSUPPORTED_VERSION);
174 return HWP_NoError;
178 int HWPFile::State(void) const
180 return error_code;
184 int HWPFile::SetState(int errcode)
186 error_code = errcode;
187 return error_code;
191 int HWPFile::Read1b(void)
193 return hiodev ? hiodev->read1b() : -1;
197 int HWPFile::Read2b(void)
199 return hiodev ? hiodev->read2b() : -1;
203 long HWPFile::Read4b(void)
205 return hiodev ? hiodev->read4b() : -1;
209 int HWPFile::Read1b(void *ptr, size_t nmemb)
211 return hiodev ? hiodev->read1b(ptr, nmemb) : 0;
215 int HWPFile::Read2b(void *ptr, size_t nmemb)
217 return hiodev ? hiodev->read2b(ptr, nmemb) : 0;
221 int HWPFile::Read4b(void *ptr, size_t nmemb)
223 return hiodev ? hiodev->read4b(ptr, nmemb) : 0;
227 size_t HWPFile::ReadBlock(void *ptr, size_t size)
229 return hiodev ? hiodev->readBlock(ptr, size) : 0;
233 size_t HWPFile::SkipBlock(size_t size)
235 return hiodev ? hiodev->skipBlock(size) : 0;
239 bool HWPFile::SetCompressed(bool flag)
241 return hiodev ? hiodev->setCompressed(flag) : false;
245 HIODev *HWPFile::SetIODevice(HIODev * new_hiodev)
247 HIODev *old_hiodev = hiodev;
249 hiodev = new_hiodev;
250 return old_hiodev;
254 // end of HIODev wrapper
256 bool HWPFile::InfoRead(void)
258 return _hwpInfo.Read(*this);
262 bool HWPFile::FontRead(void)
264 return _hwpFont.Read(*this);
268 bool HWPFile::StyleRead(void)
270 return _hwpStyle.Read(*this);
274 bool HWPFile::ParaListRead(void)
276 return ReadParaList(plist);
279 bool HWPFile::ReadParaList(LinkedList < HWPPara > &aplist, unsigned char flag)
281 LinkedListIterator < HWPPara > it(&aplist);
283 HWPPara *spNode = new HWPPara;
284 unsigned char tmp_etcflag;
285 unsigned char prev_etcflag = 0;
286 while (spNode->Read(*this, flag))
288 if( !(spNode->etcflag & 0x04) ){
289 tmp_etcflag = spNode->etcflag;
290 spNode->etcflag = prev_etcflag;
291 prev_etcflag = tmp_etcflag;
293 if (spNode->nch && spNode->reuse_shape)
295 if (aplist.count()){
296 spNode->pshape = aplist.last()->pshape;
298 else{
299 spNode->nch = 0;
300 spNode->reuse_shape = 0;
303 spNode->pshape.pagebreak = spNode->etcflag;
304 if( spNode->nch )
305 AddParaShape( &spNode->pshape );
307 if (aplist.count())
308 aplist.last()->SetNext(spNode);
309 aplist.insert(spNode, -1);
310 spNode = new HWPPara;
312 delete spNode;
314 return true;
318 bool HWPFile::TagsRead(void)
320 ulong tag;
321 long size;
323 while (1)
325 tag = Read4b();
326 size = Read4b();
327 if (size <= 0 && tag > 0){
328 //return false;
329 continue;
332 if (tag == FILETAG_END_OF_COMPRESSED ||
333 tag == FILETAG_END_OF_UNCOMPRESSED)
334 return true;
335 switch (tag)
337 case FILETAG_EMBEDDED_PICTURE:
339 EmPicture *emb = new EmPicture(size);
341 if (true == emb->Read(*this))
342 emblist.insert(emb, -1);
343 else
344 delete emb;
346 break;
347 case FILETAG_OLE_OBJECT:
348 if (oledata)
349 delete oledata;
350 oledata = new OlePicture(size);
351 oledata->Read(*this);
352 break;
353 case FILETAG_HYPERTEXT:
355 if( (size % 617) != 0 )
356 SkipBlock( size );
357 else
358 for( int i = 0 ; i < size/617 ; i++)
360 HyperText *hypert = new HyperText;
361 hypert->Read(*this);
362 hyperlist.insert(hypert, -1);
364 break;
366 case 6:
368 ReadBlock(_hwpInfo.back_info.reserved1, 8);
369 _hwpInfo.back_info.luminance = Read4b();
370 _hwpInfo.back_info.contrast = Read4b();
371 _hwpInfo.back_info.effect = sal::static_int_cast<char>(Read1b());
372 ReadBlock(_hwpInfo.back_info.reserved2, 7);
373 ReadBlock(_hwpInfo.back_info.filename, 260);
374 ReadBlock(_hwpInfo.back_info.color, 3);
375 unsigned short nFlag = sal::static_int_cast<unsigned short>(Read2b());
376 _hwpInfo.back_info.flag = nFlag >> 8 ;
377 int nRange = Read4b();
378 _hwpInfo.back_info.range = nRange >> 24;
379 ReadBlock(_hwpInfo.back_info.reserved3, 27);
380 _hwpInfo.back_info.size = Read4b();
382 _hwpInfo.back_info.data = new char[(unsigned int)_hwpInfo.back_info.size];
383 ReadBlock(_hwpInfo.back_info.data, _hwpInfo.back_info.size);
385 if( _hwpInfo.back_info.size > 0 )
386 _hwpInfo.back_info.type = 2;
387 else if( _hwpInfo.back_info.filename[0] )
388 _hwpInfo.back_info.type = 1;
389 else
390 _hwpInfo.back_info.type = 0;
393 _hwpInfo.back_info.isset = true;
395 break;
397 case FILETAG_PRESENTATION:
398 case FILETAG_PREVIEW_IMAGE:
399 case FILETAG_PREVIEW_TEXT:
400 default:
401 SkipBlock(size);
404 // return false;
408 ColumnDef *HWPFile::GetColumnDef(int num)
410 ColumnInfo *cinfo = columnlist.find(num);
411 if( cinfo )
412 return cinfo->coldef;
413 else
414 return 0;
416 /* @return À妽º´Â 1ºÎÅÍ ½ÃÀÛÇÑ´Ù. */
417 int HWPFile::GetPageMasterNum(int page)
419 LinkedListIterator<ColumnInfo> it(&columnlist);
420 //os: unused
421 //ColumnInfo *prev = 0;
422 ColumnInfo *now = 0;
423 int i;
425 for( i = 1 ; it.current() ; it++, i++){
426 now = it.current();
427 if( page < now->start_page )
428 return i-1;
430 return i-1;
433 HyperText *HWPFile::GetHyperText()
435 return hyperlist.find(currenthyper++);
438 EmPicture *HWPFile::GetEmPicture(Picture * pic)
440 char *name = pic->picinfo.picembed.embname;
442 name[0] = 'H';
443 name[1] = 'W';
444 name[2] = 'P';
446 LinkedListIterator < EmPicture > it(&emblist);
447 for (; it.current(); it++)
448 if (strcmp(name, it.current()->name) == 0)
449 return it.current();
450 return 0;
453 EmPicture *HWPFile::GetEmPictureByName(char * name)
455 name[0] = 'H';
456 name[1] = 'W';
457 name[2] = 'P';
459 LinkedListIterator < EmPicture > it(&emblist);
460 for (; it.current(); it++)
461 if (strcmp(name, it.current()->name) == 0)
462 return it.current();
463 return 0;
467 void HWPFile::AddBox(FBox * box)
469 // LATER if we don't use box->next(),
470 // AddBox() and GetBoxHead() are useless;
471 if (blist.count())
473 box->prev = blist.last();
474 box->prev->next = box;
476 else
477 box->prev = 0;
478 blist.insert(box, -1);
482 ParaShape *HWPFile::getParaShape(int index)
484 return pslist.find(index);
488 CharShape *HWPFile::getCharShape(int index)
490 return cslist.find(index);
494 FBoxStyle *HWPFile::getFBoxStyle(int index)
496 return fbslist.find(index);
499 DateCode *HWPFile::getDateCode(int index)
501 return datecodes.find(index);
504 HeaderFooter *HWPFile::getHeaderFooter(int index)
506 return headerfooters.find(index);
509 ShowPageNum *HWPFile::getPageNumber(int index)
511 return pagenumbers.find(index);
514 Table *HWPFile::getTable(int index)
516 return tables.find(index);
519 void HWPFile::AddParaShape(ParaShape * pshape)
521 int nscount = 0;
522 for(int j = 0 ; j < MAXTABS-1 ; j++)
524 if( j > 0 && pshape->tabs[j].position == 0 )
525 break;
526 if( pshape->tabs[0].position == 0 ){
527 if( pshape->tabs[j].type || pshape->tabs[j].dot_continue ||
528 (pshape->tabs[j].position != 1000 *j) )
529 nscount = j;
531 else{
532 if( pshape->tabs[j].type || pshape->tabs[j].dot_continue ||
533 (pshape->tabs[j].position != 1000 * (j + 1)) )
534 nscount = j;
537 if( nscount )
538 pshape->tabs[MAXTABS-1].type = sal::static_int_cast<char>(nscount);
539 int value = compareParaShape(pshape);
540 if( value == 0 || nscount )
542 pshape->index = ++pcount;
543 pslist.insert(pshape, -1);
545 else
546 pshape->index = value;
550 void HWPFile::AddCharShape(CharShape * cshape)
552 int value = compareCharShape(cshape);
553 if( value == 0 )
555 cshape->index = ++ccount;
556 cslist.insert(cshape, -1);
558 else
559 cshape->index = value;
562 void HWPFile::AddColumnInfo()
564 ColumnInfo *cinfo = new ColumnInfo(m_nCurrentPage);
565 columnlist.insert(cinfo, -1);
566 setMaxSettedPage();
569 void HWPFile::SetColumnDef(ColumnDef *coldef)
571 ColumnInfo *cinfo = columnlist.last();
572 if( cinfo->bIsSet )
573 return;
574 cinfo->coldef = coldef;
575 cinfo->bIsSet = true;
578 void HWPFile::AddDateFormat(DateCode * hbox)
580 hbox->key = sal::static_int_cast<char>(++datecodecount);
581 datecodes.insert(hbox, -1);
584 void HWPFile::AddPageNumber(ShowPageNum * hbox)
586 pagenumbers.insert(hbox, -1);
589 void HWPFile::AddHeaderFooter(HeaderFooter * hbox)
591 headerfooters.insert(hbox, -1);
594 void HWPFile::AddTable(Table * hbox)
596 tables.insert(hbox, -1);
599 void HWPFile::AddFBoxStyle(FBoxStyle * fbstyle)
601 fbslist.insert(fbstyle, -1);
604 int HWPFile::compareCharShape(CharShape *shape)
606 int count = cslist.count();
607 if( count > 0 )
609 CharShape *cshape=0;
610 for(int i = 0; i< count; i++)
612 cshape = cslist.find(i);
614 if( shape->size == cshape->size &&
615 shape->font[0] == cshape->font[0] &&
616 shape->ratio[0] == cshape->ratio[0] &&
617 shape->space[0] == cshape->space[0] &&
618 shape->color[1] == cshape->color[1] &&
619 shape->color[0] == cshape->color[0] &&
620 shape->shade == cshape->shade &&
621 shape->attr == cshape->attr )
623 return cshape->index;
627 return 0;
631 int HWPFile::compareParaShape(ParaShape *shape)
633 int count = pslist.count();
634 if( count > 0 )
636 ParaShape *pshape=0;
637 for(int i = 0; i< count; i++)
639 pshape = pslist.find(i);
640 if( shape->left_margin == pshape->left_margin &&
641 shape->right_margin == pshape->right_margin &&
642 shape->pspacing_prev == pshape->pspacing_prev &&
643 shape->pspacing_next == pshape->pspacing_next &&
644 shape->indent == pshape->indent &&
645 shape->lspacing == pshape->lspacing &&
646 shape->arrange_type == pshape->arrange_type &&
647 shape->outline == pshape->outline &&
648 shape->pagebreak == pshape->pagebreak)
650 if( shape->cshape->size == pshape->cshape->size &&
651 shape->cshape->font[0] == pshape->cshape->font[0] &&
652 shape->cshape->ratio[0] == pshape->cshape->ratio[0] &&
653 shape->cshape->space[0] == pshape->cshape->space[0] &&
654 shape->cshape->color[1] == pshape->cshape->color[1] &&
655 shape->cshape->color[0] == pshape->cshape->color[0] &&
656 shape->cshape->shade == pshape->cshape->shade &&
657 shape->cshape->attr == pshape->cshape->attr )
659 return pshape->index;
664 return 0;
668 HWPFile *GetCurrentDoc(void)
670 return HWPFile::cur_doc;
674 HWPFile *SetCurrentDoc(HWPFile * hwpfp)
676 HWPFile *org = HWPFile::cur_doc;
678 HWPFile::cur_doc = hwpfp;
679 return org;