Bump for 3.6-28
[LibreOffice.git] / hwpfilter / source / hbox.cxx
blob30c2d4827ad8a99e7dcefc92a56993d7f1fc58cb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "precompile.h"
31 #include <ctype.h>
33 #include <osl/diagnose.h>
35 #include "hwpfile.h"
36 #include "hbox.h"
37 #include "hpara.h"
38 #include "hutil.h"
39 #include "htags.h"
40 #include "drawdef.h"
41 #include "hcode.h"
43 int HBox::boxCount = 0;
45 HBox::HBox(hchar hch)
47 hh = hch;
48 boxCount++;
52 HBox::~HBox()
54 boxCount--;
58 int HBox::WSize(void)
60 static const int wsize[32] =
62 1, 4, 4, 4, 4, 4, 4, 42, /* dateform */
63 48, 4, 4, 4, 4, 1, 4, 4, /* hidden */
64 4, 4, 4, 4, 4, 4, 12, 5, /* chcompose */
65 3, 3, 123, 4, 32, 4, 2, 2
68 if (hh < 32)
69 return wsize[hh];
70 else
71 return 1;
75 hchar_string HBox::GetString()
77 hchar_string ret;
78 ret.push_back(hh);
79 return ret;
83 hunit HBox::Height(CharShape *csty)
85 return( csty->size );
89 // skip block
90 SkipData::SkipData(hchar hch):HBox(hch)
92 data_block = 0;
96 SkipData::~SkipData(void)
98 delete[]data_block;
102 // FieldCode [5]
103 FieldCode::FieldCode(void) : HBox(CH_FIELD)
105 str1 = 0;
106 str2 = 0;
107 str3 = 0;
108 bin = 0;
109 reserved1 = new char[4];
110 reserved2 = new char[22];
111 m_pDate = 0L;
115 FieldCode::~FieldCode(void)
117 delete[] str1;
118 delete[] str2;
119 delete[] str3;
120 delete[] bin;
121 delete[] reserved1;
122 delete[] reserved2;
123 if( m_pDate )
124 delete m_pDate;
128 // book mark(6)
129 Bookmark::Bookmark(void):HBox(CH_BOOKMARK)
134 Bookmark::~Bookmark(void)
139 // date format(7)
140 DateFormat::DateFormat(void):HBox(CH_DATE_FORM)
145 // date code(8)
147 DateCode::DateCode(void):HBox(CH_DATE_CODE)
152 #define _DATECODE_WEEK_DEFINES_
153 #include "datecode.h"
155 hchar_string DateCode::GetString()
157 hchar_string ret;
158 const hchar *fmt;
159 int i, num;
160 const char *form;
161 char cbuf[256];
162 bool is_pm, add_zero;
164 add_zero = false;
165 format[DATE_SIZE - 1] = 0;
166 fmt = format[0] ? format : defaultform;
168 for (; *fmt && ((int) ret.size() < DATE_SIZE); fmt++)
170 form = (add_zero) ? "%02d" : "%d";
172 add_zero = false;
173 is_pm = (date[HOUR] >= 12);
174 *cbuf = 0;
175 num = -1;
177 switch (*fmt)
179 case '0':
180 add_zero = true;
181 break;
182 case '1':
183 num = date[YEAR];
184 form = "%04d";
185 break;
186 case '!':
187 num = date[YEAR] % 100;
188 break;
189 case '2':
190 num = date[MONTH];
191 break;
192 case '@':
193 memcpy(cbuf, eng_mon + (date[MONTH] - 1) * 3, 3);
194 cbuf[3] = '.';
195 cbuf[4] = 0;
196 break;
197 case '*':
198 strcpy(cbuf, en_mon[date[MONTH] - 1]);
199 break;
200 case '3': /* 'D' is day of korean */
201 num = date[DAY];
202 break;
203 case '#':
204 num = date[DAY];
205 switch (date[DAY] % 10)
207 case 1:
208 form = "%dst";
209 break;
210 case 2:
211 form = "%dnd";
212 break;
213 case 3:
214 form = "%drd";
215 break;
216 default:
217 form = "%dth";
218 break;
220 break;
221 case '4':
222 num = date[HOUR] - ((date[HOUR] > 12) ? 12 : 0);
223 break;
224 case '$':
225 num = date[HOUR];
226 break;
227 case '5':
228 case '%':
229 num = date[MIN];
230 break;
231 case '6':
232 ret.push_back(kor_week[date[WEEK]]);
233 break;
234 case '^':
235 memcpy(cbuf, eng_week + date[WEEK] * 3, 3);
236 cbuf[3] = '.';
237 cbuf[4] = 0;
238 break;
239 case '_':
240 strcpy(cbuf, en_week[date[WEEK]]);
241 break;
242 case '7':
243 ret.push_back(0xB5A1);
244 ret.push_back((is_pm) ? 0xD281 : 0xB8E5);
245 break;
246 case '&':
247 strcpy(cbuf, (is_pm) ? "p.m." : "a.m.");
248 break;
249 case '+':
250 strcpy(cbuf, (is_pm) ? "P.M." : "A.M.");
251 break;
252 case '8': // 2.5 feature
253 case '9':
254 #if 0
255 // LATER
256 mkcurfilename(cbuf, *fmt);
257 for (i = 0; cbuf[i] != 0 && slen > 1; i++)
258 { //for hangle filename
259 if (cbuf[i] & 0x80 && cbuf[i + 1] != 0)
261 *d++ = (cbuf[i] << 8) | cbuf[i + 1];
262 i++;
264 else
265 *d++ = cbuf[i];
266 slen--;
268 #endif
269 cbuf[0] = 0;
270 break;
271 case '~': // 3.0b feature
272 if (fmt[1] == 0)
273 break;
274 fmt++;
275 if (*fmt == '6')
277 ret.push_back(china_week[date[WEEK]]);
278 break;
280 break;
281 default:
282 if (*fmt == '\\' && *++fmt == 0)
283 goto done;
284 ret.push_back(*fmt);
286 if (num != -1)
287 sprintf(cbuf, form, num);
288 for (i = 0; 0 != cbuf[i]; i++)
290 ret.push_back(*(cbuf + i));
293 done:
294 return ret;
298 // tab(9)
300 Tab::Tab(void):HBox(CH_TAB)
305 // floating box
306 FBox::FBox(hchar hch):HBox(hch)
308 prev = next = 0;
309 zorder = 0;
313 FBox::~FBox()
318 // tbox(10) TABLE BOX MATH BUTTON HYPERTEXT
320 TxtBox::TxtBox(void):FBox(CH_TEXT_BOX), cell(0), plists(0)
325 TxtBox::~TxtBox(void)
327 delete[]cell;
329 for (int ii = 0; ii < nCell; ++ii)
331 std::list < HWPPara* >::iterator it = plists[ii].begin();
332 for (; it != plists[ii].end(); ++it)
334 HWPPara* pPara = *it;
335 delete pPara;
339 std::list < HWPPara* >::iterator it = caption.begin();
340 for (; it != caption.end(); ++it)
342 HWPPara* pPara = *it;
343 delete pPara;
346 delete[]plists;
350 hunit TxtBox::Height(CharShape * csty)
352 return (style.anchor_type == CHAR_ANCHOR) ? box_ys : csty->size;
356 // picture(11)
358 Picture::Picture(void):FBox(CH_PICTURE)
360 follow = 0;
361 ishyper = false;
365 Picture::~Picture(void)
367 delete[]follow;
368 if( pictype == PICTYPE_DRAW && picinfo.picdraw.hdo )
369 delete (HWPDrawingObject *) picinfo.picdraw.hdo;
371 std::list < HWPPara* >::iterator it = caption.begin();
372 for (; it != caption.end(); ++it)
374 HWPPara* pPara = *it;
375 delete pPara;
380 int Picture::Type()
382 return pictype;
386 hunit Picture::Height(CharShape * sty)
388 return (style.anchor_type == CHAR_ANCHOR) ? box_ys : sty->size;
392 // line(14)
393 // hidden(15)
394 Hidden::~Hidden(void)
396 std::list < HWPPara* >::iterator it = plist.begin();
397 for (; it != plist.end(); ++it)
399 HWPPara* pPara = *it;
400 delete pPara;
405 // header/footer(16)
406 HeaderFooter::~HeaderFooter(void)
408 std::list < HWPPara* >::iterator it = plist.begin();
409 for (; it != plist.end(); ++it)
411 HWPPara* pPara = *it;
412 delete pPara;
417 // footnote(17)
418 Footnote::~Footnote(void)
420 std::list < HWPPara* >::iterator it = plist.begin();
421 for (; it != plist.end(); ++it)
423 HWPPara* pPara = *it;
424 delete pPara;
429 // auto number(18)
430 // new number(19)
431 // show page number (20)
432 // Ȧ¼öÂʽÃÀÛ/°¨Ãß±â (21)
434 // mail merge(22)
435 hchar_string MailMerge::GetString()
437 return hchar_string();
441 // character compositon(23)
442 // hyphen(24)
443 // toc mark(25)
444 // index mark(26)
445 // outline(28)
447 #define OL_HANGL_JASO 0
448 #define OL_HANGL_KANATA 1
450 static hchar olHanglJaso(int num, int type)
452 static const unsigned char han_init[] =
453 { 0x88, 0x90, 0x94, 0x9c, 0xa0, 0xa4, 0xac, 0xb4, 0xb8, 0xc0, 0xc4, 0xc8, 0xcc, 0xd0 };
454 static const unsigned char jung[] = { 3, 5, 7, 11, 13, 19, 20, 26, 27, 29, 30 };
455 static const unsigned char jung2[] = { 3, 7, 13, 20, 27, 29, 30 };
457 hchar hh = 0;
459 if (type == OL_HANGL_JASO)
461 num = num % (14 + (sizeof(jung) / sizeof(char)));
463 if (num < 14)
464 hh = (han_init[num] << 8) | 'A';
465 else
466 hh = (jung[num - 14] << 5) | 0x8401;
468 else
470 if (num < 14)
471 hh = (han_init[num] << 8) | 'a';
472 else
474 int j = (num / 14) % (sizeof(jung2) / sizeof(char));
476 num = num % 14;
477 hh = (han_init[num] << 8) | (jung2[j] << 5) | 1;
480 return hh;
484 static const hchar *GetOutlineStyleChars(int style)
486 static const hchar out_bul_style_entry[5][8] = // extern
488 { // 0 OLSTY_BULLET1
489 0x2f18, 0x2f12, 0x2f08, 0x2f02, 0x2f06, 0x2f00, 0x2043, 0x0000
491 { // 1
492 0x2f18, 0x2f12, 0x2f06, 0x2f00, 0x2f36, 0x2f30, 0x2043, 0x0000
494 { // 2
495 0x2f26, 0x2f20, 0x2f06, 0x2f00, 0x2f16, 0x2f10, 0x2043, 0x0000
497 { // 3
498 0x2f18, 0x2f16, 0x2f12, 0x2f10, 0x2f06, 0x2f00, 0x2043, 0x0000
500 { //
501 0xAC61, 0xB677, 0xB861, 0xB8F7, 0xB781, 0x0000
504 if (style >= OLSTY_BULLET1 && style <= OLSTY_BULLET5)
505 return out_bul_style_entry[style - OLSTY_BULLET1];
506 return NULL;
510 static void getOutlineNumStr(int style, int level, int num, hchar * hstr)
512 enum
514 U_ROM = 0x01, L_ROM = 0x02, U_ENG = 0x04, L_ENG = 0x08,
515 HAN = 0x10, NUM = 0x20, L_BR = 0x40, R_BR = 0x80
517 static const unsigned char type_tbl[][MAX_OUTLINE_LEVEL] =
520 U_ROM, HAN, NUM, HAN | R_BR, L_BR | NUM | R_BR,
521 L_BR | HAN | R_BR, L_ROM | R_BR
524 U_ROM, U_ENG, NUM, L_ENG | R_BR, L_BR | NUM | R_BR,
525 L_BR | L_ENG | R_BR, L_ROM | R_BR
528 NUM, HAN, L_BR | NUM | R_BR, L_BR | HAN | R_BR, NUM |
529 R_BR, HAN | R_BR, L_ENG
532 char fmt = type_tbl[style - OLSTY_NUMSIG1][level];
533 char buf[80], *ptr;
535 if (num < 1)
536 num = 1;
537 if (fmt & L_BR)
538 *hstr++ = '(';
539 if (fmt & NUM)
541 sprintf(buf, "%d", num);
542 str2hstr(buf, hstr);
543 hstr += strlen(buf);
545 else if (fmt & (U_ROM | L_ROM))
547 num2roman(num, buf);
548 if (fmt & U_ROM)
550 ptr = buf;
551 while (*ptr)
553 *ptr = sal::static_int_cast<char>(toupper(*ptr));
554 ptr++;
557 str2hstr(buf, hstr);
558 hstr += strlen(buf);
560 else
562 num = (num - 1) % 26;
563 if (fmt & U_ENG)
564 *hstr++ = sal::static_int_cast<hchar>('A' + num);
565 else if (fmt & L_ENG)
566 *hstr++ = sal::static_int_cast<hchar>('a' + num);
567 else if (fmt & HAN)
568 *hstr++ = olHanglJaso(num, OL_HANGL_KANATA);
570 *hstr++ = (fmt & R_BR) ? ')' : '.';
571 *hstr = 0;
575 enum
576 { OUTLINE_ON, OUTLINE_NUM };
578 /* level Àº 0ºÎÅÍ ½ÃÀÛ. Áï 1.1.1. ÀÇ ·¹º§Àº 2ÀÌ´Ù.
579 number´Â °ªÀÌ ±×´ë·Î µé¾î°¡ ÀÖ´Ù. Áï, 1.2.1¿¡´Â 1,2,1ÀÌ µé¾î°¡ ÀÖ´Ù.
580 style Àº 1ºÎÅÍ °ªÀÌ µé¾î°¡ ÀÖ´Ù. hbox.h¿¡ Á¤ÀÇµÈ µ¥·Î..
582 hchar_string Outline::GetUnicode() const
584 const hchar *p;
585 hchar buffer[255];
587 buffer[0] = 0;
588 if (kind == OUTLINE_NUM)
590 int levelnum;
591 switch (shape)
593 case OLSTY_NUMS1:
594 case OLSTY_NUMS2:
596 char cur_num_str[10], buf[80];
597 int i;
599 buf[0] = 0;
600 for (i = 0; i <= level; i++)
602 levelnum = ((number[i] < 1) ? 1 : number[i]);
603 if (shape == OLSTY_NUMS2 && i && i == level)
604 sprintf(cur_num_str, "%d%c", levelnum, 0);
605 else
606 sprintf(cur_num_str, "%d%c", levelnum, '.');
607 strcat(buf, cur_num_str);
609 str2hstr(buf, buffer);
610 return hstr2ucsstr(buffer);
612 case OLSTY_NUMSIG1:
613 case OLSTY_NUMSIG2:
614 case OLSTY_NUMSIG3:
616 getOutlineNumStr(shape, level, number[level], buffer);
617 return hstr2ucsstr(buffer);
619 case OLSTY_BULLET1:
620 case OLSTY_BULLET2:
621 case OLSTY_BULLET3:
622 case OLSTY_BULLET4:
623 case OLSTY_BULLET5:
625 p = GetOutlineStyleChars(shape);
626 buffer[0] = p[level];
627 buffer[1] = 0;
628 return hstr2ucsstr(buffer);
630 case OLSTY_USER:
631 case OLSTY_BULUSER:
633 char dest[80];
634 int l = 0;
635 int i = level;
636 if( deco[i][0] ){
637 buffer[l++] = deco[i][0];
639 /* level Àº 0ºÎÅÍ ½ÃÀÛ. Áï 1.1.1. ÀÇ ·¹º§Àº 2ÀÌ´Ù.
640 number´Â °ªÀÌ ±×´ë·Î µé¾î°¡ ÀÖ´Ù. Áï, 1.2.1¿¡´Â 1,2,1ÀÌ µé¾î°¡ ÀÖ´Ù.
641 style Àº 1ºÎÅÍ °ªÀÌ µé¾î°¡ ÀÖ´Ù. hbox.h¿¡ Á¤ÀÇµÈ µ¥·Î..
643 switch( user_shape[i] )
645 case 0:
646 buffer[l++] = '1' + number[i] - 1;
647 break;
648 case 1: /* ´ë¹®Àڷθ¶ */
649 case 2: /* ¼Ò¹®Àڷθ¶ */
650 num2roman(number[i], dest);
651 if( user_shape[i] == 1 ){
652 char *ptr = dest;
653 while( *ptr )
655 *ptr = sal::static_int_cast<char>(toupper(*ptr));
656 ptr++;
659 str2hstr(dest, buffer + l);
660 l += strlen(dest);
661 break;
662 case 3:
663 buffer[l++] = 'A' + number[i] -1;
664 break;
665 case 4:
666 buffer[l++] = 'a' + number[i] -1;
667 break;
668 case 5:
669 buffer[l++] = olHanglJaso(number[i] -1, OL_HANGL_KANATA);
670 break;
671 case 6:
672 buffer[l++] = olHanglJaso(number[i] -1, OL_HANGL_JASO);
673 break;
674 case 7: /* ÇÑÀÚ ¼ýÀÚ : ÀÏ¹Ý ¼ýÀڷΠǥÇö */
675 buffer[l++] = '1' + number[i] -1;
676 break;
677 case 8: /* ¿ø¼ýÀÚ */
678 buffer[l++] = 0x2e00 + number[i];
679 break;
680 case 9: /* ¿ø ¾ËÆĺª ¼Ò¹®ÀÚ */
681 buffer[l++] = 0x2c20 + number[i];
682 break;
683 case 10: /* ¿ø °¡³ª´Ù */
684 buffer[l++] = 0x2c50 + number[i] -1;
685 break;
686 case 11: /* ¿ø ¤¡ ¤¤ */
687 buffer[l++] = 0x2c40 + number[i] -1;
688 break;
689 case 12: /* À̾îÁø ¼ýÀÚ. */
691 char cur_num_str[10],buf[80];
692 int j;
693 buf[0] = 0;
694 for (j = 0; j <= level; j++)
696 levelnum = ((number[j] < 1) ? 1 : number[j]);
697 if ((j && j == level) || (j == level && deco[i][1]))
698 sprintf(cur_num_str, "%d%c", levelnum, 0);
699 else
700 sprintf(cur_num_str, "%d%c", levelnum, '.');
701 strcat(buf, cur_num_str);
703 str2hstr(buf, buffer + l);
704 l += strlen(buf);
705 break;
707 default:
708 buffer[l++] = user_shape[i];
709 break;
711 if( deco[i][1] ){
712 buffer[l++] = deco[i][1];
714 buffer[l] = 0;
715 return hstr2ucsstr(buffer);
719 return hstr2ucsstr(buffer);
723 /* ¹­À½ ºóÄ­(30) */
724 /* °íÁ¤Æø ºóÄ­(31) */
726 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */