merge the formfield patch from ooo-build
[ooovba.git] / hwpfilter / source / hbox.cpp
blobfe2bc9e6a4544fae7cdf73e2644adea4faceca33
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: hbox.cpp,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "precompile.h"
33 #include <ctype.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 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 int HBox::GetString(hchar * hstr, int )
77 *hstr++ = hh;
78 *hstr = 0;
79 return 1;
83 hunit HBox::Height(CharShape *csty)
85 return( csty->size );
89 // skip block
90 SkipBlock::SkipBlock(hchar hch):HBox(hch)
92 data_block = 0;
96 SkipBlock::~SkipBlock(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 int DateCode::GetString(hchar * hstr, int slen)
157 hchar *fmt, *d;
158 int i, num;
159 const char *form;
160 char cbuf[256];
161 bool is_pm, add_zero;
163 add_zero = false;
164 format[DATE_SIZE - 1] = 0;
165 fmt = format[0] ? format : defaultform;
167 d = hstr;
168 for (; *fmt && ((int) (d - hstr) < DATE_SIZE) && slen > 1; 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 *d++ = kor_week[date[WEEK]];
233 slen--;
234 break;
235 case '^':
236 memcpy(cbuf, eng_week + date[WEEK] * 3, 3);
237 cbuf[3] = '.';
238 cbuf[4] = 0;
239 break;
240 case '_':
241 strcpy(cbuf, en_week[date[WEEK]]);
242 break;
243 case '7':
244 if (slen > 3)
246 *d++ = 0xB5A1;
247 *d++ = (is_pm) ? 0xD281 : 0xB8E5;
249 break;
250 case '&':
251 strcpy(cbuf, (is_pm) ? "p.m." : "a.m.");
252 break;
253 case '+':
254 strcpy(cbuf, (is_pm) ? "P.M." : "A.M.");
255 break;
256 case '8': // 2.5 feature
257 case '9':
258 #if 0
259 // LATER
260 mkcurfilename(cbuf, *fmt);
261 for (i = 0; cbuf[i] != 0 && slen > 1; i++)
262 { //for hangle filename
263 if (cbuf[i] & 0x80 && cbuf[i + 1] != 0)
265 *d++ = (cbuf[i] << 8) | cbuf[i + 1];
266 i++;
268 else
269 *d++ = cbuf[i];
270 slen--;
272 #endif
273 cbuf[0] = 0;
274 break;
275 case '~': // 3.0b feature
276 if (fmt[1] == 0)
277 break;
278 fmt++;
279 if (*fmt == '6')
281 *d++ = china_week[date[WEEK]];
282 slen--;
283 break;
285 break;
286 default:
287 if (*fmt == '\\' && *++fmt == 0)
288 goto done;
289 *d++ = *fmt;
290 slen--;
292 if (num != -1)
293 sprintf(cbuf, form, num);
294 for (i = 0; 0 != cbuf[i] && slen > 1; i++)
296 *d++ = *(cbuf + i);
297 slen--;
300 done:
301 *d = 0;
302 return hstrlen(hstr);
306 // tab(9)
308 Tab::Tab(void):HBox(CH_TAB)
313 // floating box
314 FBox::FBox(hchar hch):HBox(hch)
316 prev = next = 0;
317 zorder = 0;
321 FBox::~FBox()
326 // tbox(10) TABLE BOX MATH BUTTON HYPERTEXT
328 TxtBox::TxtBox(void):FBox(CH_TEXT_BOX), cell(0), plists(0)
333 TxtBox::~TxtBox(void)
335 delete[]cell;
337 for (int ii = 0; ii < nCell; ++ii)
339 LinkedListIterator < HWPPara > it(&plists[ii]);
340 for (; it.current(); it++)
341 delete it.current();
344 LinkedListIterator < HWPPara > it(&caption);
345 for (; it.current(); it++)
346 delete it.current();
348 delete[]plists;
352 hunit TxtBox::Height(CharShape * csty)
354 return (style.anchor_type == CHAR_ANCHOR) ? box_ys : csty->size;
358 // picture(11)
360 Picture::Picture(void):FBox(CH_PICTURE)
362 follow = 0;
363 ishyper = false;
367 Picture::~Picture(void)
369 delete[]follow;
370 if( pictype == PICTYPE_DRAW && picinfo.picdraw.hdo )
371 delete (HWPDrawingObject *) picinfo.picdraw.hdo;
373 LinkedListIterator < HWPPara > it(&caption);
374 for (; it.current(); it++)
375 delete it.current();
379 int Picture::Type()
381 return pictype;
385 hunit Picture::Height(CharShape * sty)
387 return (style.anchor_type == CHAR_ANCHOR) ? box_ys : sty->size;
391 // line(14)
392 // hidden(15)
393 Hidden::~Hidden(void)
395 LinkedListIterator < HWPPara > it(&plist);
396 for (; it.current(); it++)
397 delete it.current();
401 // header/footer(16)
402 HeaderFooter::~HeaderFooter(void)
404 LinkedListIterator < HWPPara > it(&plist);
405 for (; it.current(); it++)
406 delete it.current();
410 // footnote(17)
411 Footnote::~Footnote(void)
413 LinkedListIterator < HWPPara > it(&plist);
414 for (; it.current(); it++)
415 delete it.current();
419 // auto number(18)
420 // new number(19)
421 // show page number (20)
422 // Ȧ¼öÂʽÃÀÛ/°¨Ãß±â (21)
424 // mail merge(22)
425 int MailMerge::GetString(hchar * hstr, int )
427 *hstr = 0;
428 return 0;
432 // character compositon(23)
433 // hyphen(24)
434 // toc mark(25)
435 // index mark(26)
436 // outline(28)
438 #define OL_HANGL_JASO 0
439 #define OL_HANGL_KANATA 1
441 static hchar olHanglJaso(int num, int type)
443 static unsigned char han_init[] =
444 { "\x88\x90\x94\x9c\xa0\xa4\xac\xb4\xb8\xc0\xc4\xc8\xcc\xd0" };
445 static unsigned char jung[] = { 3, 5, 7, 11, 13, 19, 20, 26, 27, 29, 30 };
446 static unsigned char jung2[] = { 3, 7, 13, 20, 27, 29, 30 };
448 hchar hh = 0;
449 int j;
451 if (type == OL_HANGL_JASO)
453 num = num % (14 + (sizeof(jung) / sizeof(char)));
455 if (num < 14)
456 hh = (han_init[num] << 8) | 'A';
457 else
458 hh = (jung[num - 14] << 5) | 0x8401;
460 else
462 if (num < 14)
463 hh = (han_init[num] << 8) | 'a';
464 else
466 j = (num / 14) % (sizeof(jung2) / sizeof(char));
468 num = num % 14;
469 hh = (han_init[num] << 8) | (jung2[j] << 5) | 1;
472 return hh;
476 static hchar *GetOutlineStyleChars(int style)
478 static hchar out_bul_style_entry[5][8] = // extern
480 { // 0 OLSTY_BULLET1
481 0x2f18, 0x2f12, 0x2f08, 0x2f02, 0x2f06, 0x2f00, 0x2043, 0x0000
483 { // 1
484 0x2f18, 0x2f12, 0x2f06, 0x2f00, 0x2f36, 0x2f30, 0x2043, 0x0000
486 { // 2
487 0x2f26, 0x2f20, 0x2f06, 0x2f00, 0x2f16, 0x2f10, 0x2043, 0x0000
489 { // 3
490 0x2f18, 0x2f16, 0x2f12, 0x2f10, 0x2f06, 0x2f00, 0x2043, 0x0000
492 { //
493 0xAC61, 0xB677, 0xB861, 0xB8F7, 0xB781, 0x0000
496 if (style >= OLSTY_BULLET1 && style <= OLSTY_BULLET5)
497 return out_bul_style_entry[style - OLSTY_BULLET1];
498 return NULL;
502 static void getOutlineNumStr(int style, int level, int num, hchar * hstr)
504 enum
506 U_ROM = 0x01, L_ROM = 0x02, U_ENG = 0x04, L_ENG = 0x08,
507 HAN = 0x10, NUM = 0x20, L_BR = 0x40, R_BR = 0x80
509 static unsigned char type_tbl[][MAX_OUTLINE_LEVEL] =
512 U_ROM, HAN, NUM, HAN | R_BR, L_BR | NUM | R_BR,
513 L_BR | HAN | R_BR, L_ROM | R_BR
516 U_ROM, U_ENG, NUM, L_ENG | R_BR, L_BR | NUM | R_BR,
517 L_BR | L_ENG | R_BR, L_ROM | R_BR
520 NUM, HAN, L_BR | NUM | R_BR, L_BR | HAN | R_BR, NUM |
521 R_BR, HAN | R_BR, L_ENG
524 char fmt = type_tbl[style - OLSTY_NUMSIG1][level];
525 char buf[80], *ptr;
527 if (num < 1)
528 num = 1;
529 if (fmt & L_BR)
530 *hstr++ = '(';
531 if (fmt & NUM)
533 sprintf(buf, "%d", num);
534 str2hstr(buf, hstr);
535 hstr += strlen(buf);
537 else if (fmt & (U_ROM | L_ROM))
539 num2roman(num, buf);
540 if (fmt & U_ROM)
542 ptr = buf;
543 while (*ptr)
545 *ptr = sal::static_int_cast<char>(toupper(*ptr));
546 ptr++;
549 str2hstr(buf, hstr);
550 hstr += strlen(buf);
552 else
554 num = (num - 1) % 26;
555 if (fmt & U_ENG)
556 *hstr++ = sal::static_int_cast<hchar>('A' + num);
557 else if (fmt & L_ENG)
558 *hstr++ = sal::static_int_cast<hchar>('a' + num);
559 else if (fmt & HAN)
560 *hstr++ = olHanglJaso(num, OL_HANGL_KANATA);
562 *hstr++ = (fmt & R_BR) ? ')' : '.';
563 *hstr = 0;
567 enum
568 { OUTLINE_ON, OUTLINE_NUM };
570 /* level Àº 0ºÎÅÍ ½ÃÀÛ. Áï 1.1.1. ÀÇ ·¹º§Àº 2ÀÌ´Ù.
571 number´Â °ªÀÌ ±×´ë·Î µé¾î°¡ ÀÖ´Ù. Áï, 1.2.1¿¡´Â 1,2,1ÀÌ µé¾î°¡ ÀÖ´Ù.
572 style Àº 1ºÎÅÍ °ªÀÌ µé¾î°¡ ÀÖ´Ù. hbox.h¿¡ Á¤ÀÇµÈ µ¥·Î..
574 hchar *Outline::GetUnicode(hchar * hstr, int)
576 int levelnum;
577 hchar *p;
578 hchar buffer[255];
580 buffer[0] = 0;
581 if (kind == OUTLINE_NUM)
583 switch (shape)
585 case OLSTY_NUMS1:
586 case OLSTY_NUMS2:
588 char cur_num_str[10], buf[80];
589 int i;
591 buf[0] = 0;
592 for (i = 0; i <= level; i++)
594 levelnum = ((number[i] < 1) ? 1 : number[i]);
595 if (shape == OLSTY_NUMS2 && i && i == level)
596 sprintf(cur_num_str, "%d%c", levelnum, 0);
597 else
598 sprintf(cur_num_str, "%d%c", levelnum, '.');
599 strcat(buf, cur_num_str);
601 str2hstr(buf, buffer);
602 return hstr2ucsstr(buffer, hstr);
604 case OLSTY_NUMSIG1:
605 case OLSTY_NUMSIG2:
606 case OLSTY_NUMSIG3:
608 getOutlineNumStr(shape, level, number[level], buffer);
609 return hstr2ucsstr(buffer, hstr);
611 case OLSTY_BULLET1:
612 case OLSTY_BULLET2:
613 case OLSTY_BULLET3:
614 case OLSTY_BULLET4:
615 case OLSTY_BULLET5:
617 p = GetOutlineStyleChars(shape);
618 buffer[0] = p[level];
619 buffer[1] = 0;
620 return hstr2ucsstr(buffer, hstr);
622 case OLSTY_USER:
623 case OLSTY_BULUSER:
625 char dest[80];
626 int l = 0;
627 int i = level;
628 if( deco[i][0] ){
629 buffer[l++] = deco[i][0];
631 /* level Àº 0ºÎÅÍ ½ÃÀÛ. Áï 1.1.1. ÀÇ ·¹º§Àº 2ÀÌ´Ù.
632 number´Â °ªÀÌ ±×´ë·Î µé¾î°¡ ÀÖ´Ù. Áï, 1.2.1¿¡´Â 1,2,1ÀÌ µé¾î°¡ ÀÖ´Ù.
633 style Àº 1ºÎÅÍ °ªÀÌ µé¾î°¡ ÀÖ´Ù. hbox.h¿¡ Á¤ÀÇµÈ µ¥·Î..
635 switch( user_shape[i] )
637 case 0:
638 buffer[l++] = '1' + number[i] - 1;
639 break;
640 case 1: /* ´ë¹®Àڷθ¶ */
641 case 2: /* ¼Ò¹®Àڷθ¶ */
642 num2roman(number[i], dest);
643 if( user_shape[i] == 1 ){
644 char *ptr = dest;
645 while( *ptr )
647 *ptr = sal::static_int_cast<char>(toupper(*ptr));
648 ptr++;
651 str2hstr(dest, buffer + l);
652 l += strlen(dest);
653 break;
654 case 3:
655 buffer[l++] = 'A' + number[i] -1;
656 break;
657 case 4:
658 buffer[l++] = 'a' + number[i] -1;
659 break;
660 case 5:
661 buffer[l++] = olHanglJaso(number[i] -1, OL_HANGL_KANATA);
662 break;
663 case 6:
664 buffer[l++] = olHanglJaso(number[i] -1, OL_HANGL_JASO);
665 break;
666 case 7: /* ÇÑÀÚ ¼ýÀÚ : ÀÏ¹Ý ¼ýÀڷΠǥÇö */
667 buffer[l++] = '1' + number[i] -1;
668 break;
669 case 8: /* ¿ø¼ýÀÚ */
670 buffer[l++] = 0x2e00 + number[i];
671 break;
672 case 9: /* ¿ø ¾ËÆĺª ¼Ò¹®ÀÚ */
673 buffer[l++] = 0x2c20 + number[i];
674 break;
675 case 10: /* ¿ø °¡³ª´Ù */
676 buffer[l++] = 0x2c50 + number[i] -1;
677 break;
678 case 11: /* ¿ø ¤¡ ¤¤ */
679 buffer[l++] = 0x2c40 + number[i] -1;
680 break;
681 case 12: /* À̾îÁø ¼ýÀÚ. */
683 char cur_num_str[10],buf[80];
684 int j;
685 buf[0] = 0;
686 for (j = 0; j <= level; j++)
688 levelnum = ((number[j] < 1) ? 1 : number[j]);
689 if ((j && j == level) || (j == level && deco[i][1]))
690 sprintf(cur_num_str, "%d%c", levelnum, 0);
691 else
692 sprintf(cur_num_str, "%d%c", levelnum, '.');
693 strcat(buf, cur_num_str);
695 str2hstr(buf, buffer + l);
696 l += strlen(buf);
697 break;
699 default:
700 buffer[l++] = user_shape[i];
701 break;
703 if( deco[i][1] ){
704 buffer[l++] = deco[i][1];
706 buffer[l] = 0;
707 return hstr2ucsstr(buffer, hstr);
711 return hstr2ucsstr(buffer, hstr);
715 /* ¹­À½ ºóÄ­(30) */
716 /* °íÁ¤Æø ºóÄ­(31) */