office-gobmx/hwpfilter/source/hwpfile.cpp
Vladimir Glazounov 0b77645807 INTEGRATION: CWS dr33 (1.1.26); FILE MERGED
2005/02/14 13:31:36 dr 1.1.26.1: #i42367# remove non-ASCII characters at end of line, even in comments
2005-02-16 17:17:47 +00:00

775 lines
18 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*************************************************************************
*
* $RCSfile: hwpfile.cpp,v $
*
* $Revision: 1.2 $
*
* last change: $Author: vg $ $Date: 2005-02-16 18:17:32 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2001 by Mizi Research Inc.
* Copyright 2003 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Mizi Research Inc.
*
* Copyright: 2001 by Mizi Research Inc.
* Copyright: 2003 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
/* $Id: hwpfile.cpp,v 1.2 2005-02-16 18:17:32 vg Exp $ */
#include "precompile.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "hwplib.h"
#include "hwpfile.h"
#include "hiodev.h"
#include "hfont.h"
#include "hstyle.h"
#include "hbox.h"
#include "hpara.h"
#include "htags.h"
#include "hcode.h"
#include "hstream.h"
#define HWPIDLen 30
#define HWPHeadLen 128
#define HWPSummaryLen 1008
#define V20SIGNATURE "HWP Document File V2.00 \032\1\2\3\4\5"
#define V21SIGNATURE "HWP Document File V2.10 \032\1\2\3\4\5"
#define V30SIGNATURE "HWP Document File V3.00 \032\1\2\3\4\5"
#define FILESTG_SIGNATURE 0xF8995567
#define FILESTG_SIGNATURE_NORMAL 0xF8995568
HWPFile *HWPFile::cur_doc = 0;
static int ccount = 0;
static int pcount = 0;
static int datecodecount = 0;
HWPFile::HWPFile(void)
{
Init();
}
HWPFile::HWPFile(HStream & stream)
{
Init();
Open(stream);
}
/**
* TODO : <20>߰<EFBFBD><DFB0><EFBFBD> <20><>Ÿ<EFBFBD>ϸ<EFBFBD><CFB8><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20>޸<EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD>
*/
HWPFile::~HWPFile(void)
{
if (hiodev)
delete hiodev;
LinkedListIterator < ColumnInfo > it_column(&columnlist);
for (; it_column.current(); it_column++)
delete it_column.current();
LinkedListIterator < HWPPara > it(&plist);
for (; it.current(); it++)
delete it.current();
LinkedListIterator < Table > tbl(&tables);
for (; tbl.current(); tbl++)
delete tbl.current();
LinkedListIterator < HyperText > hyp(&hyperlist);
for (; hyp.current(); hyp++)
{
delete hyp.current();
}
}
void HWPFile::Init(void)
{
version = HWP_V30;
info_block_len = 0;
compressed = false;
encrypted = false;
error_code = HWP_NoError;
hiodev = 0;
oledata = 0;
SetCurrentDoc(this);
currenthyper = 0;
m_nCurrentPage = 1;
m_nMaxSettedPage = 0;
}
int HWPFile::ReadHwpFile(HStream & stream)
{
if (Open(stream) != HWP_NoError)
return State();
// printf("HWPFile::ReadHwpFile\n");
InfoRead();
// printf("HWPFile::InfoRead Done.\n");
FontRead();
// printf("HWPFile::FontRead Done.\n");
StyleRead();
// printf("HWPFile::StyleRead Done.\n");
AddColumnInfo();
ParaListRead();
// printf("HWPFile::ParaListRead Done.\n");
TagsRead();
//printf("HWPFile::TagsRead Done. State: %d\n", State());
return State();
}
static int hwp_version(char *str)
{
if (memcmp(V20SIGNATURE, str, HWPIDLen) == 0)
return HWP_V20;
else if (memcmp(V21SIGNATURE, str, HWPIDLen) == 0)
return HWP_V21;
else if (memcmp(V30SIGNATURE, str, HWPIDLen) == 0)
return HWP_V30;
return 0;
}
// HIODev wrapper
int HWPFile::Open(HStream & stream)
{
HStreamIODev *hstreamio;
if (!(hstreamio = new HStreamIODev(stream)))
{
printf(" hstreamio is not instanciate \n");
return SetState(errno);
}
if (!hstreamio->open())
{
delete hstreamio;
return SetState(HWP_EMPTY_FILE);
}
SetIODevice(hstreamio);
char idstr[HWPIDLen];
if (ReadBlock(idstr, HWPIDLen) <= 0
|| HWP_V30 != (version = hwp_version(idstr)))
{
return SetState(HWP_UNSUPPORTED_VERSION);
}
return HWP_NoError;
}
void HWPFile::Flush(void)
{
if (hiodev)
hiodev->flush();
}
void HWPFile::Close(void)
{
if (hiodev)
hiodev->close();
}
int HWPFile::State(void) const
{
return error_code;
}
int HWPFile::SetState(int errcode)
{
error_code = errcode;
return error_code;
}
int HWPFile::Read1b(void)
{
return hiodev ? hiodev->read1b() : -1;
}
int HWPFile::Read2b(void)
{
return hiodev ? hiodev->read2b() : -1;
}
long HWPFile::Read4b(void)
{
return hiodev ? hiodev->read4b() : -1;
}
int HWPFile::Read1b(void *ptr, size_t nmemb)
{
return hiodev ? hiodev->read1b(ptr, nmemb) : 0;
}
int HWPFile::Read2b(void *ptr, size_t nmemb)
{
return hiodev ? hiodev->read2b(ptr, nmemb) : 0;
}
int HWPFile::Read4b(void *ptr, size_t nmemb)
{
return hiodev ? hiodev->read4b(ptr, nmemb) : 0;
}
size_t HWPFile::ReadBlock(void *ptr, size_t size)
{
return hiodev ? hiodev->readBlock(ptr, size) : 0;
}
size_t HWPFile::SkipBlock(size_t size)
{
return hiodev ? hiodev->skipBlock(size) : 0;
}
bool HWPFile::SetCompressed(bool flag)
{
return hiodev ? hiodev->setCompressed(flag) : false;
}
HIODev *HWPFile::SetIODevice(HIODev * new_hiodev)
{
HIODev *old_hiodev = hiodev;
hiodev = new_hiodev;
return old_hiodev;
}
// end of HIODev wrapper
bool HWPFile::InfoRead(void)
{
return _hwpInfo.Read(*this);
}
bool HWPFile::FontRead(void)
{
return _hwpFont.Read(*this);
}
bool HWPFile::StyleRead(void)
{
return _hwpStyle.Read(*this);
}
bool HWPFile::ParaListRead(void)
{
return ReadParaList(plist);
}
bool HWPFile::ReadParaList(LinkedList < HWPPara > &aplist, unsigned char flag)
{
LinkedListIterator < HWPPara > it(&aplist);
HWPPara *spNode = new HWPPara;
unsigned char tmp_etcflag;
unsigned char prev_etcflag = 0;
while (spNode->Read(*this, flag))
{
if( !(spNode->etcflag & 0x04) ){
tmp_etcflag = spNode->etcflag;
spNode->etcflag = prev_etcflag;
prev_etcflag = tmp_etcflag;
}
if (spNode->nch && spNode->reuse_shape)
{
if (aplist.count()){
spNode->pshape = aplist.last()->pshape;
}
else{
spNode->nch = 0;
spNode->reuse_shape = 0;
}
}
spNode->pshape.pagebreak = spNode->etcflag;
if( spNode->nch )
AddParaShape( &spNode->pshape );
if (aplist.count())
aplist.last()->SetNext(spNode);
aplist.insert(spNode, -1);
spNode = new HWPPara;
}
delete spNode;
return true;
}
bool HWPFile::TagsRead(void)
{
ulong tag;
long size;
while (1)
{
tag = Read4b();
size = Read4b();
if (size <= 0 && tag > 0){
//return false;
continue;
}
if (tag == FILETAG_END_OF_COMPRESSED ||
tag == FILETAG_END_OF_UNCOMPRESSED)
return true;
switch (tag)
{
case FILETAG_EMBEDDED_PICTURE:
{
EmPicture *emb = new EmPicture(size);
if (true == emb->Read(*this))
emblist.insert(emb, -1);
else
delete emb;
}
break;
case FILETAG_OLE_OBJECT:
oledata = new OlePicture(size);
oledata->Read(*this);
break;
case FILETAG_HYPERTEXT:
{
if( (size % 617) != 0 )
SkipBlock( size );
else
for( int i = 0 ; i < size/617 ; i++)
{
HyperText *hypert = new HyperText;
hypert->Read(*this);
hyperlist.insert(hypert, -1);
}
break;
}
case 6:
{
ReadBlock(_hwpInfo.back_info.reserved1, 8);
_hwpInfo.back_info.luminance = Read4b();
_hwpInfo.back_info.contrast = Read4b();
_hwpInfo.back_info.effect = Read1b();
ReadBlock(_hwpInfo.back_info.reserved2, 7);
ReadBlock(_hwpInfo.back_info.filename, 260);
ReadBlock(_hwpInfo.back_info.color, 3);
unsigned short nFlag = Read2b();
_hwpInfo.back_info.flag = nFlag >> 8 ;
int nRange = Read4b();
_hwpInfo.back_info.range = nRange >> 24;
ReadBlock(_hwpInfo.back_info.reserved3, 27);
_hwpInfo.back_info.size = Read4b();
_hwpInfo.back_info.data = new char[(unsigned int)_hwpInfo.back_info.size];
ReadBlock(_hwpInfo.back_info.data, _hwpInfo.back_info.size);
if( _hwpInfo.back_info.size > 0 )
_hwpInfo.back_info.type = 2;
else if( _hwpInfo.back_info.filename[0] )
_hwpInfo.back_info.type = 1;
else
_hwpInfo.back_info.type = 0;
_hwpInfo.back_info.isset = true;
break;
}
case FILETAG_PRESENTATION:
case FILETAG_PREVIEW_IMAGE:
case FILETAG_PREVIEW_TEXT:
default:
SkipBlock(size);
}
}
return false;
}
const char *HWPFile::GetFileName() const
{
return fname;
}
bool HWPFile::IsCompressedFile() const
{
return compressed;
}
enum HWPFile::Paper HWPFile::GetPaperKind() const
{
return (enum Paper) (_hwpInfo.paper.paper_kind);
}
void HWPFile::GetPaperSize(hunit & Width, hunit & Height) const
{
Width = _hwpInfo.paper.paper_width;
Height = _hwpInfo.paper.paper_height;
}
bool HWPFile::GetPaperOrientation() const
{
return (_hwpInfo.paper.paper_direction != 1);
}
ColumnDef *HWPFile::GetColumnDef(int num)
{
ColumnInfo *cinfo = columnlist.find(num);
if( cinfo )
return cinfo->coldef;
else
return 0;
}
/* @return <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. */
int HWPFile::GetPageMasterNum(int page)
{
LinkedListIterator<ColumnInfo> it(&columnlist);
ColumnInfo *prev = 0;
ColumnInfo *now = 0;
int i;
for( i = 1 ; it.current() ; it++, i++){
now = it.current();
if( page < now->start_page )
return i-1;
}
return i-1;
}
int HWPFile::GetFontCount(int lang)
{
return _hwpFont.NFonts(lang);
}
const char *HWPFile::GetFontName(int lang, int id)
{
return _hwpFont.GetFontName(lang, id);
}
HyperText *HWPFile::GetHyperText()
{
return hyperlist.find(currenthyper++);
}
EmPicture *HWPFile::GetEmPicture(Picture * pic)
{
char *name = pic->picinfo.picembed.embname;
name[0] = 'H';
name[1] = 'W';
name[2] = 'P';
LinkedListIterator < EmPicture > it(&emblist);
for (; it.current(); it++)
if (strcmp(name, it.current()->name) == 0)
return it.current();
return 0;
}
EmPicture *HWPFile::GetEmPictureByName(char * name)
{
name[0] = 'H';
name[1] = 'W';
name[2] = 'P';
LinkedListIterator < EmPicture > it(&emblist);
for (; it.current(); it++)
if (strcmp(name, it.current()->name) == 0)
return it.current();
return 0;
}
void HWPFile::AddBox(FBox * box)
{
// LATER if we don't use box->next(),
// AddBox() and GetBoxHead() are useless;
if (blist.count())
{
box->prev = blist.last();
box->prev->next = box;
}
else
box->prev = 0;
blist.insert(box, -1);
}
ParaShape *HWPFile::getParaShape(int index)
{
return pslist.find(index);
}
CharShape *HWPFile::getCharShape(int index)
{
return cslist.find(index);
}
FBoxStyle *HWPFile::getFBoxStyle(int index)
{
return fbslist.find(index);
}
DateCode *HWPFile::getDateCode(int index)
{
return datecodes.find(index);
}
HeaderFooter *HWPFile::getHeaderFooter(int index)
{
return headerfooters.find(index);
}
ShowPageNum *HWPFile::getPageNumber(int index)
{
return pagenumbers.find(index);
}
Table *HWPFile::getTable(int index)
{
return tables.find(index);
}
void HWPFile::AddParaShape(ParaShape * pshape)
{
int nscount = 0;
for(int j = 0 ; j < MAXTABS-1 ; j++)
{
if( j > 0 && pshape->tabs[j].position == 0 )
break;
if( pshape->tabs[0].position == 0 ){
if( pshape->tabs[j].type || pshape->tabs[j].dot_continue ||
(pshape->tabs[j].position != 1000 *j) )
nscount = j;
}
else{
if( pshape->tabs[j].type || pshape->tabs[j].dot_continue ||
(pshape->tabs[j].position != 1000 * (j + 1)) )
nscount = j;
}
}
if( nscount )
pshape->tabs[MAXTABS-1].type = nscount;
int value = compareParaShape(pshape);
if( value == 0 || nscount )
{
pshape->index = ++pcount;
pslist.insert(pshape, -1);
}
else
pshape->index = value;
}
void HWPFile::AddCharShape(CharShape * cshape)
{
int value = compareCharShape(cshape);
if( value == 0 )
{
cshape->index = ++ccount;
cslist.insert(cshape, -1);
}
else
cshape->index = value;
}
void HWPFile::AddColumnInfo()
{
ColumnInfo *cinfo = new ColumnInfo(m_nCurrentPage);
columnlist.insert(cinfo, -1);
setMaxSettedPage();
}
void HWPFile::SetColumnDef(ColumnDef *coldef)
{
ColumnInfo *cinfo = columnlist.last();
if( cinfo->bIsSet )
return;
cinfo->coldef = coldef;
cinfo->bIsSet = true;
}
void HWPFile::AddDateFormat(DateCode * hbox)
{
hbox->key = ++datecodecount;
datecodes.insert(hbox, -1);
}
void HWPFile::AddPageNumber(ShowPageNum * hbox)
{
pagenumbers.insert(hbox, -1);
}
void HWPFile::AddHeaderFooter(HeaderFooter * hbox)
{
headerfooters.insert(hbox, -1);
}
void HWPFile::AddTable(Table * hbox)
{
tables.insert(hbox, -1);
}
void HWPFile::AddFBoxStyle(FBoxStyle * fbstyle)
{
fbslist.insert(fbstyle, -1);
}
int HWPFile::compareCharShape(CharShape *shape)
{
int count = cslist.count();
if( count > 0 )
{
CharShape *cshape=0;
for(int i = 0; i< count; i++)
{
cshape = cslist.find(i);
if( shape->size == cshape->size &&
shape->font[0] == cshape->font[0] &&
shape->ratio[0] == cshape->ratio[0] &&
shape->space[0] == cshape->space[0] &&
shape->color[1] == cshape->color[1] &&
shape->color[0] == cshape->color[0] &&
shape->shade == cshape->shade &&
shape->attr == cshape->attr )
{
return cshape->index;
}
}
}
return 0;
}
int HWPFile::compareParaShape(ParaShape *shape)
{
int count = pslist.count();
if( count > 0 )
{
ParaShape *pshape=0;
for(int i = 0; i< count; i++)
{
pshape = pslist.find(i);
if( shape->left_margin == pshape->left_margin &&
shape->right_margin == pshape->right_margin &&
shape->pspacing_prev == pshape->pspacing_prev &&
shape->pspacing_next == pshape->pspacing_next &&
shape->indent == pshape->indent &&
shape->lspacing == pshape->lspacing &&
shape->arrange_type == pshape->arrange_type &&
shape->outline == pshape->outline &&
shape->pagebreak == pshape->pagebreak)
{
if( shape->cshape->size == pshape->cshape->size &&
shape->cshape->font[0] == pshape->cshape->font[0] &&
shape->cshape->ratio[0] == pshape->cshape->ratio[0] &&
shape->cshape->space[0] == pshape->cshape->space[0] &&
shape->cshape->color[1] == pshape->cshape->color[1] &&
shape->cshape->color[0] == pshape->cshape->color[0] &&
shape->cshape->shade == pshape->cshape->shade &&
shape->cshape->attr == pshape->cshape->attr )
{
return pshape->index;
}
}
}
}
return 0;
}
HWPFile *GetCurrentDoc(void)
{
return HWPFile::cur_doc;
}
HWPFile *SetCurrentDoc(HWPFile * hwpfp)
{
HWPFile *org = HWPFile::cur_doc;
HWPFile::cur_doc = hwpfp;
return org;
}