office-gobmx/hwpfilter/source/hbox.cxx
2011-06-13 23:20:18 +01:00

715 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.

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org 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 version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#include "precompile.h"
#include <ctype.h>
#include "hwpfile.h"
#include "hbox.h"
#include "hpara.h"
#include "hutil.h"
#include "htags.h"
#include "drawdef.h"
#include "hcode.h"
int HBox::boxCount = 0;
HBox::HBox(hchar hch)
{
hh = hch;
boxCount++;
}
HBox::~HBox()
{
boxCount--;
}
int HBox::WSize(void)
{
static int wsize[32] =
{
1, 4, 4, 4, 4, 4, 4, 42, /* dateform */
48, 4, 4, 4, 4, 1, 4, 4, /* hidden */
4, 4, 4, 4, 4, 4, 12, 5, /* chcompose */
3, 3, 123, 4, 32, 4, 2, 2
};
if (hh < 32)
return wsize[hh];
else
return 1;
}
int HBox::GetString(hchar * hstr, int )
{
*hstr++ = hh;
*hstr = 0;
return 1;
}
hunit HBox::Height(CharShape *csty)
{
return( csty->size );
}
// skip block
SkipData::SkipData(hchar hch):HBox(hch)
{
data_block = 0;
}
SkipData::~SkipData(void)
{
delete[]data_block;
}
// FieldCode [5]
FieldCode::FieldCode(void) : HBox(CH_FIELD)
{
str1 = 0;
str2 = 0;
str3 = 0;
bin = 0;
reserved1 = new char[4];
reserved2 = new char[22];
m_pDate = 0L;
}
FieldCode::~FieldCode(void)
{
delete[] str1;
delete[] str2;
delete[] str3;
delete[] bin;
delete[] reserved1;
delete[] reserved2;
if( m_pDate )
delete m_pDate;
}
// book mark(6)
Bookmark::Bookmark(void):HBox(CH_BOOKMARK)
{
}
Bookmark::~Bookmark(void)
{
}
// date format(7)
DateFormat::DateFormat(void):HBox(CH_DATE_FORM)
{
}
// date code(8)
DateCode::DateCode(void):HBox(CH_DATE_CODE)
{
}
#define _DATECODE_WEEK_DEFINES_
#include "datecode.h"
int DateCode::GetString(hchar * hstr, int slen)
{
hchar *fmt, *d;
int i, num;
const char *form;
char cbuf[256];
bool is_pm, add_zero;
add_zero = false;
format[DATE_SIZE - 1] = 0;
fmt = format[0] ? format : defaultform;
d = hstr;
for (; *fmt && ((int) (d - hstr) < DATE_SIZE) && slen > 1; fmt++)
{
form = (add_zero) ? "%02d" : "%d";
add_zero = false;
is_pm = (date[HOUR] >= 12);
*cbuf = 0;
num = -1;
switch (*fmt)
{
case '0':
add_zero = true;
break;
case '1':
num = date[YEAR];
form = "%04d";
break;
case '!':
num = date[YEAR] % 100;
break;
case '2':
num = date[MONTH];
break;
case '@':
memcpy(cbuf, eng_mon + (date[MONTH] - 1) * 3, 3);
cbuf[3] = '.';
cbuf[4] = 0;
break;
case '*':
strcpy(cbuf, en_mon[date[MONTH] - 1]);
break;
case '3': /* 'D' is day of korean */
num = date[DAY];
break;
case '#':
num = date[DAY];
switch (date[DAY] % 10)
{
case 1:
form = "%dst";
break;
case 2:
form = "%dnd";
break;
case 3:
form = "%drd";
break;
default:
form = "%dth";
break;
}
break;
case '4':
num = date[HOUR] - ((date[HOUR] > 12) ? 12 : 0);
break;
case '$':
num = date[HOUR];
break;
case '5':
case '%':
num = date[MIN];
break;
case '6':
*d++ = kor_week[date[WEEK]];
slen--;
break;
case '^':
memcpy(cbuf, eng_week + date[WEEK] * 3, 3);
cbuf[3] = '.';
cbuf[4] = 0;
break;
case '_':
strcpy(cbuf, en_week[date[WEEK]]);
break;
case '7':
if (slen > 3)
{
*d++ = 0xB5A1;
*d++ = (is_pm) ? 0xD281 : 0xB8E5;
}
break;
case '&':
strcpy(cbuf, (is_pm) ? "p.m." : "a.m.");
break;
case '+':
strcpy(cbuf, (is_pm) ? "P.M." : "A.M.");
break;
case '8': // 2.5 feature
case '9':
#if 0
// LATER
mkcurfilename(cbuf, *fmt);
for (i = 0; cbuf[i] != 0 && slen > 1; i++)
{ //for hangle filename
if (cbuf[i] & 0x80 && cbuf[i + 1] != 0)
{
*d++ = (cbuf[i] << 8) | cbuf[i + 1];
i++;
}
else
*d++ = cbuf[i];
slen--;
}
#endif
cbuf[0] = 0;
break;
case '~': // 3.0b feature
if (fmt[1] == 0)
break;
fmt++;
if (*fmt == '6')
{
*d++ = china_week[date[WEEK]];
slen--;
break;
}
break;
default:
if (*fmt == '\\' && *++fmt == 0)
goto done;
*d++ = *fmt;
slen--;
}
if (num != -1)
sprintf(cbuf, form, num);
for (i = 0; 0 != cbuf[i] && slen > 1; i++)
{
*d++ = *(cbuf + i);
slen--;
}
}
done:
*d = 0;
return hstrlen(hstr);
}
// tab(9)
Tab::Tab(void):HBox(CH_TAB)
{
}
// floating box
FBox::FBox(hchar hch):HBox(hch)
{
prev = next = 0;
zorder = 0;
}
FBox::~FBox()
{
}
// tbox(10) TABLE BOX MATH BUTTON HYPERTEXT
TxtBox::TxtBox(void):FBox(CH_TEXT_BOX), cell(0), plists(0)
{
}
TxtBox::~TxtBox(void)
{
delete[]cell;
for (int ii = 0; ii < nCell; ++ii)
{
LinkedListIterator < HWPPara > it(&plists[ii]);
for (; it.current(); it++)
delete it.current();
}
LinkedListIterator < HWPPara > it(&caption);
for (; it.current(); it++)
delete it.current();
delete[]plists;
}
hunit TxtBox::Height(CharShape * csty)
{
return (style.anchor_type == CHAR_ANCHOR) ? box_ys : csty->size;
}
// picture(11)
Picture::Picture(void):FBox(CH_PICTURE)
{
follow = 0;
ishyper = false;
}
Picture::~Picture(void)
{
delete[]follow;
if( pictype == PICTYPE_DRAW && picinfo.picdraw.hdo )
delete (HWPDrawingObject *) picinfo.picdraw.hdo;
LinkedListIterator < HWPPara > it(&caption);
for (; it.current(); it++)
delete it.current();
}
int Picture::Type()
{
return pictype;
}
hunit Picture::Height(CharShape * sty)
{
return (style.anchor_type == CHAR_ANCHOR) ? box_ys : sty->size;
}
// line(14)
// hidden(15)
Hidden::~Hidden(void)
{
LinkedListIterator < HWPPara > it(&plist);
for (; it.current(); it++)
delete it.current();
}
// header/footer(16)
HeaderFooter::~HeaderFooter(void)
{
LinkedListIterator < HWPPara > it(&plist);
for (; it.current(); it++)
delete it.current();
}
// footnote(17)
Footnote::~Footnote(void)
{
LinkedListIterator < HWPPara > it(&plist);
for (; it.current(); it++)
delete it.current();
}
// auto number(18)
// new number(19)
// show page number (20)
// Ȧ<><C8A6><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>/<2F><><EFBFBD>߱<EFBFBD> (21)
// mail merge(22)
int MailMerge::GetString(hchar * hstr, int )
{
*hstr = 0;
return 0;
}
// character compositon(23)
// hyphen(24)
// toc mark(25)
// index mark(26)
// outline(28)
#define OL_HANGL_JASO 0
#define OL_HANGL_KANATA 1
static hchar olHanglJaso(int num, int type)
{
static unsigned char han_init[] =
{ "\x88\x90\x94\x9c\xa0\xa4\xac\xb4\xb8\xc0\xc4\xc8\xcc\xd0" };
static unsigned char jung[] = { 3, 5, 7, 11, 13, 19, 20, 26, 27, 29, 30 };
static unsigned char jung2[] = { 3, 7, 13, 20, 27, 29, 30 };
hchar hh = 0;
if (type == OL_HANGL_JASO)
{
num = num % (14 + (sizeof(jung) / sizeof(char)));
if (num < 14)
hh = (han_init[num] << 8) | 'A';
else
hh = (jung[num - 14] << 5) | 0x8401;
}
else
{
if (num < 14)
hh = (han_init[num] << 8) | 'a';
else
{
int j = (num / 14) % (sizeof(jung2) / sizeof(char));
num = num % 14;
hh = (han_init[num] << 8) | (jung2[j] << 5) | 1;
}
}
return hh;
}
static hchar *GetOutlineStyleChars(int style)
{
static hchar out_bul_style_entry[5][8] = // extern
{
{ // 0 OLSTY_BULLET1
0x2f18, 0x2f12, 0x2f08, 0x2f02, 0x2f06, 0x2f00, 0x2043, 0x0000
},
{ // 1
0x2f18, 0x2f12, 0x2f06, 0x2f00, 0x2f36, 0x2f30, 0x2043, 0x0000
},
{ // 2
0x2f26, 0x2f20, 0x2f06, 0x2f00, 0x2f16, 0x2f10, 0x2043, 0x0000
},
{ // 3
0x2f18, 0x2f16, 0x2f12, 0x2f10, 0x2f06, 0x2f00, 0x2043, 0x0000
},
{ //
0xAC61, 0xB677, 0xB861, 0xB8F7, 0xB781, 0x0000
},
};
if (style >= OLSTY_BULLET1 && style <= OLSTY_BULLET5)
return out_bul_style_entry[style - OLSTY_BULLET1];
return NULL;
}
static void getOutlineNumStr(int style, int level, int num, hchar * hstr)
{
enum
{
U_ROM = 0x01, L_ROM = 0x02, U_ENG = 0x04, L_ENG = 0x08,
HAN = 0x10, NUM = 0x20, L_BR = 0x40, R_BR = 0x80
};
static unsigned char type_tbl[][MAX_OUTLINE_LEVEL] =
{
{
U_ROM, HAN, NUM, HAN | R_BR, L_BR | NUM | R_BR,
L_BR | HAN | R_BR, L_ROM | R_BR
},
{
U_ROM, U_ENG, NUM, L_ENG | R_BR, L_BR | NUM | R_BR,
L_BR | L_ENG | R_BR, L_ROM | R_BR
},
{
NUM, HAN, L_BR | NUM | R_BR, L_BR | HAN | R_BR, NUM |
R_BR, HAN | R_BR, L_ENG
}
};
char fmt = type_tbl[style - OLSTY_NUMSIG1][level];
char buf[80], *ptr;
if (num < 1)
num = 1;
if (fmt & L_BR)
*hstr++ = '(';
if (fmt & NUM)
{
sprintf(buf, "%d", num);
str2hstr(buf, hstr);
hstr += strlen(buf);
}
else if (fmt & (U_ROM | L_ROM))
{
num2roman(num, buf);
if (fmt & U_ROM)
{
ptr = buf;
while (*ptr)
{
*ptr = sal::static_int_cast<char>(toupper(*ptr));
ptr++;
}
}
str2hstr(buf, hstr);
hstr += strlen(buf);
}
else
{
num = (num - 1) % 26;
if (fmt & U_ENG)
*hstr++ = sal::static_int_cast<hchar>('A' + num);
else if (fmt & L_ENG)
*hstr++ = sal::static_int_cast<hchar>('a' + num);
else if (fmt & HAN)
*hstr++ = olHanglJaso(num, OL_HANGL_KANATA);
}
*hstr++ = (fmt & R_BR) ? ')' : '.';
*hstr = 0;
}
enum
{ OUTLINE_ON, OUTLINE_NUM };
/* level <20><> 0<><30><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><> 1.1.1. <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<>̴<EFBFBD>.
number<65><72> <20><><EFBFBD><EFBFBD> <20>״<EFBFBD><D7B4><EFBFBD> <20><><EFBFBD><20>ִ<EFBFBD>. <20><>, 1.2.1<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1,2,1<><31> <20><><EFBFBD><20>ִ<EFBFBD>.
style <20><> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><20>ִ<EFBFBD>. hbox.h<><68> <20><><EFBFBD>ǵ<EFBFBD> <20><><EFBFBD><EFBFBD>..
*/
hchar *Outline::GetUnicode(hchar * hstr, int)
{
hchar *p;
hchar buffer[255];
buffer[0] = 0;
if (kind == OUTLINE_NUM)
{
int levelnum;
switch (shape)
{
case OLSTY_NUMS1:
case OLSTY_NUMS2:
{
char cur_num_str[10], buf[80];
int i;
buf[0] = 0;
for (i = 0; i <= level; i++)
{
levelnum = ((number[i] < 1) ? 1 : number[i]);
if (shape == OLSTY_NUMS2 && i && i == level)
sprintf(cur_num_str, "%d%c", levelnum, 0);
else
sprintf(cur_num_str, "%d%c", levelnum, '.');
strcat(buf, cur_num_str);
}
str2hstr(buf, buffer);
return hstr2ucsstr(buffer, hstr);
}
case OLSTY_NUMSIG1:
case OLSTY_NUMSIG2:
case OLSTY_NUMSIG3:
{
getOutlineNumStr(shape, level, number[level], buffer);
return hstr2ucsstr(buffer, hstr);
}
case OLSTY_BULLET1:
case OLSTY_BULLET2:
case OLSTY_BULLET3:
case OLSTY_BULLET4:
case OLSTY_BULLET5:
{
p = GetOutlineStyleChars(shape);
buffer[0] = p[level];
buffer[1] = 0;
return hstr2ucsstr(buffer, hstr);
}
case OLSTY_USER:
case OLSTY_BULUSER:
{
char dest[80];
int l = 0;
int i = level;
if( deco[i][0] ){
buffer[l++] = deco[i][0];
}
/* level <20><> 0<><30><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><> 1.1.1. <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<>̴<EFBFBD>.
number<65><72> <20><><EFBFBD><EFBFBD> <20>״<EFBFBD><D7B4><EFBFBD> <20><><EFBFBD><20>ִ<EFBFBD>. <20><>, 1.2.1<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1,2,1<><31> <20><><EFBFBD><20>ִ<EFBFBD>.
style <20><> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><20>ִ<EFBFBD>. hbox.h<><68> <20><><EFBFBD>ǵ<EFBFBD> <20><><EFBFBD><EFBFBD>..
*/
switch( user_shape[i] )
{
case 0:
buffer[l++] = '1' + number[i] - 1;
break;
case 1: /* <20><EFBFBD>ڷθ<DAB7> */
case 2: /* <20>ҹ<EFBFBD><D2B9>ڷθ<DAB7> */
num2roman(number[i], dest);
if( user_shape[i] == 1 ){
char *ptr = dest;
while( *ptr )
{
*ptr = sal::static_int_cast<char>(toupper(*ptr));
ptr++;
}
}
str2hstr(dest, buffer + l);
l += strlen(dest);
break;
case 3:
buffer[l++] = 'A' + number[i] -1;
break;
case 4:
buffer[l++] = 'a' + number[i] -1;
break;
case 5:
buffer[l++] = olHanglJaso(number[i] -1, OL_HANGL_KANATA);
break;
case 6:
buffer[l++] = olHanglJaso(number[i] -1, OL_HANGL_JASO);
break;
case 7: /* <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : <20>Ϲ<EFBFBD> <20><><EFBFBD>ڷ<EFBFBD> ǥ<><C7A5> */
buffer[l++] = '1' + number[i] -1;
break;
case 8: /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
buffer[l++] = 0x2e00 + number[i];
break;
case 9: /* <20><> <20><><EFBFBD>ĺ<EFBFBD> <20>ҹ<EFBFBD><D2B9><EFBFBD> */
buffer[l++] = 0x2c20 + number[i];
break;
case 10: /* <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
buffer[l++] = 0x2c50 + number[i] -1;
break;
case 11: /* <20><> <20><> <20><> */
buffer[l++] = 0x2c40 + number[i] -1;
break;
case 12: /* <20>̾<EFBFBD><CCBE><EFBFBD> <20><><EFBFBD><EFBFBD>. */
{
char cur_num_str[10],buf[80];
int j;
buf[0] = 0;
for (j = 0; j <= level; j++)
{
levelnum = ((number[j] < 1) ? 1 : number[j]);
if ((j && j == level) || (j == level && deco[i][1]))
sprintf(cur_num_str, "%d%c", levelnum, 0);
else
sprintf(cur_num_str, "%d%c", levelnum, '.');
strcat(buf, cur_num_str);
}
str2hstr(buf, buffer + l);
l += strlen(buf);
break;
}
default:
buffer[l++] = user_shape[i];
break;
}
if( deco[i][1] ){
buffer[l++] = deco[i][1];
}
buffer[l] = 0;
return hstr2ucsstr(buffer, hstr);
}
}
}
return hstr2ucsstr(buffer, hstr);
}
/* <20><><EFBFBD><EFBFBD> <20><>ĭ(30) */
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ĭ(31) */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */