fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / hwpfilter / source / hbox.cxx
blobddcd815d5e786d76f2ba5319c286643bd6e2df67
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "precompile.h"
22 #include <ctype.h>
24 #include <osl/diagnose.h>
26 #include "hwpfile.h"
27 #include "hbox.h"
28 #include "hpara.h"
29 #include "hutil.h"
30 #include "htags.h"
31 #include "drawdef.h"
32 #include "hcode.h"
34 int HBox::boxCount = 0;
36 HBox::HBox(hchar hch)
38 hh = hch;
39 boxCount++;
43 HBox::~HBox()
45 boxCount--;
49 int HBox::WSize()
51 static const int wsize[32] =
53 1, 4, 4, 4, 4, 4, 4, 42, /* dateform */
54 48, 4, 4, 4, 4, 1, 4, 4, /* hidden */
55 4, 4, 4, 4, 4, 4, 12, 5, /* chcompose */
56 3, 3, 123, 4, 32, 4, 2, 2
59 if (hh < 32)
60 return wsize[hh];
61 else
62 return 1;
66 hchar_string HBox::GetString()
68 hchar_string ret;
69 ret.push_back(hh);
70 return ret;
74 hunit HBox::Height(CharShape *csty)
76 return( csty->size );
79 // skip block
80 SkipData::SkipData(hchar hch)
81 : HBox(hch)
82 , data_block_len(0)
83 , dummy(0)
84 , data_block(0)
88 SkipData::~SkipData()
90 delete[]data_block;
94 // FieldCode [5]
95 FieldCode::FieldCode()
96 : HBox(CH_FIELD)
97 , location_info(0)
98 , str1(NULL)
99 , str2(NULL)
100 , str3(NULL)
101 , bin(NULL)
102 , m_pDate(NULL)
104 reserved1 = new char[4];
105 reserved2 = new char[22];
108 FieldCode::~FieldCode()
110 delete[] str1;
111 delete[] str2;
112 delete[] str3;
113 delete[] bin;
114 delete[] reserved1;
115 delete[] reserved2;
116 delete m_pDate;
119 // book mark(6)
120 Bookmark::Bookmark()
121 : HBox(CH_BOOKMARK)
122 , dummy(0)
123 , type(0)
127 Bookmark::~Bookmark()
131 // date format(7)
132 DateFormat::DateFormat()
133 : HBox(CH_DATE_FORM)
134 , dummy(0)
138 // date code(8)
139 DateCode::DateCode()
140 : HBox(CH_DATE_CODE)
141 , dummy(0)
142 , key(0)
146 #define _DATECODE_WEEK_DEFINES_
147 #include "datecode.h"
149 hchar_string DateCode::GetString()
151 hchar_string ret;
152 const hchar *fmt;
153 int i, num;
154 const char *form;
155 char cbuf[256];
156 bool is_pm, add_zero;
158 add_zero = false;
159 format[DATE_SIZE - 1] = 0;
160 fmt = format[0] ? format : defaultform;
162 for (; *fmt && ((int) ret.size() < DATE_SIZE); fmt++)
164 form = (add_zero) ? "%02d" : "%d";
166 add_zero = false;
167 is_pm = (date[HOUR] >= 12);
168 *cbuf = 0;
169 num = -1;
171 switch (*fmt)
173 case '0':
174 add_zero = true;
175 break;
176 case '1':
177 num = date[YEAR];
178 form = "%04d";
179 break;
180 case '!':
181 num = date[YEAR] % 100;
182 break;
183 case '2':
184 num = date[MONTH];
185 break;
186 case '@':
187 memcpy(cbuf, eng_mon + (date[MONTH] - 1) * 3, 3);
188 cbuf[3] = '.';
189 cbuf[4] = 0;
190 break;
191 case '*':
192 strncat(cbuf, en_mon[date[MONTH] - 1], sizeof(cbuf) - strlen(cbuf) - 1);
193 break;
194 case '3': /* 'D' is day of korean */
195 num = date[DAY];
196 break;
197 case '#':
198 num = date[DAY];
199 switch (date[DAY] % 10)
201 case 1:
202 form = "%dst";
203 break;
204 case 2:
205 form = "%dnd";
206 break;
207 case 3:
208 form = "%drd";
209 break;
210 default:
211 form = "%dth";
212 break;
214 break;
215 case '4':
216 num = date[HOUR] - ((date[HOUR] > 12) ? 12 : 0);
217 break;
218 case '$':
219 num = date[HOUR];
220 break;
221 case '5':
222 case '%':
223 num = date[MIN];
224 break;
225 case '6':
226 ret.push_back(kor_week[date[WEEK]]);
227 break;
228 case '^':
229 memcpy(cbuf, eng_week + date[WEEK] * 3, 3);
230 cbuf[3] = '.';
231 cbuf[4] = 0;
232 break;
233 case '_':
234 strncat(cbuf, en_week[date[WEEK]], sizeof(cbuf) - strlen(cbuf) - 1);
235 break;
236 case '7':
237 ret.push_back(0xB5A1);
238 ret.push_back((is_pm) ? 0xD281 : 0xB8E5);
239 break;
240 case '&':
241 strncat(cbuf, (is_pm) ? "p.m." : "a.m.", sizeof(cbuf) - strlen(cbuf) - 1);
242 break;
243 case '+':
244 strncat(cbuf, (is_pm) ? "P.M." : "A.M.", sizeof(cbuf) - strlen(cbuf) - 1);
245 break;
246 case '8': // 2.5 feature
247 case '9':
248 #if 0
249 // LATER
250 mkcurfilename(cbuf, *fmt);
251 for (i = 0; cbuf[i] != 0 && slen > 1; i++)
252 { //for hangle filename
253 if (cbuf[i] & 0x80 && cbuf[i + 1] != 0)
255 *d++ = (cbuf[i] << 8) | cbuf[i + 1];
256 i++;
258 else
259 *d++ = cbuf[i];
260 slen--;
262 #endif
263 cbuf[0] = 0;
264 break;
265 case '~': // 3.0b feature
266 if (fmt[1] == 0)
267 break;
268 fmt++;
269 if (*fmt == '6')
271 ret.push_back(china_week[date[WEEK]]);
272 break;
274 break;
275 default:
276 if (*fmt == '\\' && *++fmt == 0)
277 goto done;
278 ret.push_back(*fmt);
280 if (num != -1)
281 sprintf(cbuf, form, num);
282 for (i = 0; 0 != cbuf[i]; i++)
284 ret.push_back(*(cbuf + i));
287 done:
288 return ret;
291 // tab(9)
292 Tab::Tab()
293 : HBox(CH_TAB)
294 , width(0)
295 , leader(0)
296 , dummy(0)
300 // floating box
301 FBox::FBox(hchar hch)
302 : HBox(hch)
303 , zorder(0)
304 , option(0)
305 , ctrl_ch(0)
306 , box_xs(0)
307 , box_ys(0)
308 , cap_xs(0)
309 , cap_ys(0)
310 , xs(0)
311 , ys(0)
312 , cap_margin(0)
313 , xpos_type(0)
314 , ypos_type(0)
315 , smart_linesp(0)
316 , boundsy(0)
317 , boundey(0)
318 , boundx(0)
319 , draw(0)
320 , pgx(0)
321 , pgy(0)
322 , pgno(0)
323 , showpg(0)
324 , prev(NULL)
325 , next(NULL)
329 FBox::~FBox()
333 // tbox(10) TABLE BOX MATH BUTTON HYPERTEXT
334 TxtBox::TxtBox()
335 : FBox(CH_TEXT_BOX)
336 , dummy(0)
337 , dummy1(0)
338 , cap_len(0)
339 , next(0)
340 , dummy2(0)
341 , reserved1(0)
342 , cap_pos(0)
343 , num(0)
344 , dummy3(0)
345 , baseline(0)
346 , type(0)
347 , nCell(0)
348 , protect(0)
349 , cell(0)
350 , m_pTable(NULL)
351 , plists(NULL)
353 reserved[0] = reserved[1] = 0;
356 TxtBox::~TxtBox()
358 delete[]cell;
360 for (int ii = 0; ii < nCell; ++ii)
362 std::list < HWPPara* >::iterator it = plists[ii].begin();
363 for (; it != plists[ii].end(); ++it)
365 HWPPara* pPara = *it;
366 delete pPara;
370 std::list < HWPPara* >::iterator it = caption.begin();
371 for (; it != caption.end(); ++it)
373 HWPPara* pPara = *it;
374 delete pPara;
377 delete[]plists;
381 hunit TxtBox::Height(CharShape * csty)
383 return (style.anchor_type == CHAR_ANCHOR) ? box_ys : csty->size;
387 // picture(11)
389 Picture::Picture()
390 : FBox(CH_PICTURE)
391 , dummy(0)
392 , follow_block_size(0)
393 , dummy1(0)
394 , dummy2(0)
395 , reserved1(0)
396 , cap_pos(0)
397 , num(0)
398 , pictype(0)
399 , follow(0)
400 , ishyper(false)
404 Picture::~Picture()
406 delete[]follow;
407 if( pictype == PICTYPE_DRAW && picinfo.picdraw.hdo )
408 delete static_cast<HWPDrawingObject *>(picinfo.picdraw.hdo);
410 std::list < HWPPara* >::iterator it = caption.begin();
411 for (; it != caption.end(); ++it)
413 HWPPara* pPara = *it;
414 delete pPara;
419 int Picture::Type()
421 return pictype;
425 hunit Picture::Height(CharShape * sty)
427 return (style.anchor_type == CHAR_ANCHOR) ? box_ys : sty->size;
431 // line(14)
432 // hidden(15)
433 Hidden::~Hidden()
435 std::list < HWPPara* >::iterator it = plist.begin();
436 for (; it != plist.end(); ++it)
438 HWPPara* pPara = *it;
439 delete pPara;
444 // header/footer(16)
445 HeaderFooter::~HeaderFooter()
447 std::list < HWPPara* >::iterator it = plist.begin();
448 for (; it != plist.end(); ++it)
450 HWPPara* pPara = *it;
451 delete pPara;
456 // footnote(17)
457 Footnote::~Footnote()
459 std::list < HWPPara* >::iterator it = plist.begin();
460 for (; it != plist.end(); ++it)
462 HWPPara* pPara = *it;
463 delete pPara;
468 // auto number(18)
469 // new number(19)
470 // show page number (20)
471 // 홀수쪽시작/감추기 (21)
473 // mail merge(22)
474 hchar_string MailMerge::GetString()
476 return hchar_string();
480 // character compositon(23)
481 // hyphen(24)
482 // toc mark(25)
483 // index mark(26)
484 // outline(28)
486 #define OL_HANGL_JASO 0
487 #define OL_HANGL_KANATA 1
489 static hchar olHanglJaso(int num, int type)
491 static const unsigned char han_init[] =
492 { 0x88, 0x90, 0x94, 0x9c, 0xa0, 0xa4, 0xac, 0xb4, 0xb8, 0xc0, 0xc4, 0xc8, 0xcc, 0xd0 };
493 static const unsigned char jung[] = { 3, 5, 7, 11, 13, 19, 20, 26, 27, 29, 30 };
494 static const unsigned char jung2[] = { 3, 7, 13, 20, 27, 29, 30 };
496 hchar hh = 0;
498 if (type == OL_HANGL_JASO)
500 num = num % (14 + (sizeof(jung) / sizeof(char)));
502 if (num < 14)
503 hh = (han_init[num] << 8) | 'A';
504 else
505 hh = (jung[num - 14] << 5) | 0x8401;
507 else
509 if (num < 14)
510 hh = (han_init[num] << 8) | 'a';
511 else
513 int j = (num / 14) % (sizeof(jung2) / sizeof(char));
515 num = num % 14;
516 hh = (han_init[num] << 8) | (jung2[j] << 5) | 1;
519 return hh;
523 static const hchar *GetOutlineStyleChars(int style)
525 static const hchar out_bul_style_entry[5][8] = // extern
527 { // 0 OLSTY_BULLET1
528 0x2f18, 0x2f12, 0x2f08, 0x2f02, 0x2f06, 0x2f00, 0x2043, 0x0000
530 { // 1
531 0x2f18, 0x2f12, 0x2f06, 0x2f00, 0x2f36, 0x2f30, 0x2043, 0x0000
533 { // 2
534 0x2f26, 0x2f20, 0x2f06, 0x2f00, 0x2f16, 0x2f10, 0x2043, 0x0000
536 { // 3
537 0x2f18, 0x2f16, 0x2f12, 0x2f10, 0x2f06, 0x2f00, 0x2043, 0x0000
540 0xAC61, 0xB677, 0xB861, 0xB8F7, 0xB781, 0x0000
543 if (style >= OLSTY_BULLET1 && style <= OLSTY_BULLET5)
544 return out_bul_style_entry[style - OLSTY_BULLET1];
545 return NULL;
549 static void getOutlineNumStr(int style, int level, int num, hchar * hstr)
551 enum
553 U_ROM = 0x01, L_ROM = 0x02, U_ENG = 0x04, L_ENG = 0x08,
554 HAN = 0x10, NUM = 0x20, L_BR = 0x40, R_BR = 0x80
556 static const unsigned char type_tbl[][MAX_OUTLINE_LEVEL] =
559 U_ROM, HAN, NUM, HAN | R_BR, L_BR | NUM | R_BR,
560 L_BR | HAN | R_BR, L_ROM | R_BR
563 U_ROM, U_ENG, NUM, L_ENG | R_BR, L_BR | NUM | R_BR,
564 L_BR | L_ENG | R_BR, L_ROM | R_BR
567 NUM, HAN, L_BR | NUM | R_BR, L_BR | HAN | R_BR, NUM |
568 R_BR, HAN | R_BR, L_ENG
571 char fmt = type_tbl[style - OLSTY_NUMSIG1][level];
572 char buf[80], *ptr;
574 if (num < 1)
575 num = 1;
576 if (fmt & L_BR)
577 *hstr++ = '(';
578 if (fmt & NUM)
580 sprintf(buf, "%d", num);
581 str2hstr(buf, hstr);
582 hstr += strlen(buf);
584 else if (fmt & (U_ROM | L_ROM))
586 num2roman(num, buf);
587 if (fmt & U_ROM)
589 ptr = buf;
590 while (*ptr)
592 *ptr = sal::static_int_cast<char>(toupper(*ptr));
593 ptr++;
596 str2hstr(buf, hstr);
597 hstr += strlen(buf);
599 else
601 num = (num - 1) % 26;
602 if (fmt & U_ENG)
603 *hstr++ = sal::static_int_cast<hchar>('A' + num);
604 else if (fmt & L_ENG)
605 *hstr++ = sal::static_int_cast<hchar>('a' + num);
606 else if (fmt & HAN)
607 *hstr++ = olHanglJaso(num, OL_HANGL_KANATA);
609 *hstr++ = (fmt & R_BR) ? ')' : '.';
610 *hstr = 0;
614 enum
615 { OUTLINE_ON, OUTLINE_NUM };
617 /* level 은 0부터 시작. 즉 1.1.1. 의 레벨은 2이다.
618 number는 값이 그대로 들어가 있다. 즉, 1.2.1에는 1,2,1이 들어가 있다.
619 style 은 1부터 값이 들어가 있다. hbox.h에 정의된 데로..
621 hchar_string Outline::GetUnicode() const
623 const hchar *p;
624 hchar buffer[255];
626 buffer[0] = 0;
627 if (kind == OUTLINE_NUM)
629 int levelnum;
630 switch (shape)
632 case OLSTY_NUMS1:
633 case OLSTY_NUMS2:
635 char cur_num_str[10], buf[80];
636 int i;
638 buf[0] = 0;
639 for (i = 0; i <= level; i++)
641 levelnum = ((number[i] < 1) ? 1 : number[i]);
642 if (shape == OLSTY_NUMS2 && i && i == level)
643 sprintf(cur_num_str, "%d%c", levelnum, 0);
644 else
645 sprintf(cur_num_str, "%d%c", levelnum, '.');
646 strcat(buf, cur_num_str);
648 str2hstr(buf, buffer);
649 return hstr2ucsstr(buffer);
651 case OLSTY_NUMSIG1:
652 case OLSTY_NUMSIG2:
653 case OLSTY_NUMSIG3:
655 getOutlineNumStr(shape, level, number[level], buffer);
656 return hstr2ucsstr(buffer);
658 case OLSTY_BULLET1:
659 case OLSTY_BULLET2:
660 case OLSTY_BULLET3:
661 case OLSTY_BULLET4:
662 case OLSTY_BULLET5:
664 p = GetOutlineStyleChars(shape);
665 buffer[0] = p[level];
666 buffer[1] = 0;
667 return hstr2ucsstr(buffer);
669 case OLSTY_USER:
670 case OLSTY_BULUSER:
672 char dest[80];
673 int l = 0;
674 int i = level;
675 if( deco[i][0] ){
676 buffer[l++] = deco[i][0];
678 /* level 은 0부터 시작. 즉 1.1.1. 의 레벨은 2이다.
679 number는 값이 그대로 들어가 있다. 즉, 1.2.1에는 1,2,1이 들어가 있다.
680 style 은 1부터 값이 들어가 있다. hbox.h에 정의된 데로..
682 switch( user_shape[i] )
684 case 0:
685 buffer[l++] = '1' + number[i] - 1;
686 break;
687 case 1: /* 대문자로마 */
688 case 2: /* 소문자로마 */
689 num2roman(number[i], dest);
690 if( user_shape[i] == 1 ){
691 char *ptr = dest;
692 while( *ptr )
694 *ptr = sal::static_int_cast<char>(toupper(*ptr));
695 ptr++;
698 str2hstr(dest, buffer + l);
699 l += strlen(dest);
700 break;
701 case 3:
702 buffer[l++] = 'A' + number[i] -1;
703 break;
704 case 4:
705 buffer[l++] = 'a' + number[i] -1;
706 break;
707 case 5:
708 buffer[l++] = olHanglJaso(number[i] -1, OL_HANGL_KANATA);
709 break;
710 case 6:
711 buffer[l++] = olHanglJaso(number[i] -1, OL_HANGL_JASO);
712 break;
713 case 7: /* 한자 숫자 : 일반 숫자로 표현 */
714 buffer[l++] = '1' + number[i] -1;
715 break;
716 case 8: /* 원숫자 */
717 buffer[l++] = 0x2e00 + number[i];
718 break;
719 case 9: /* 원 알파벳 소문자 */
720 buffer[l++] = 0x2c20 + number[i];
721 break;
722 case 10: /* 원 가나다 */
723 buffer[l++] = 0x2c50 + number[i] -1;
724 break;
725 case 11: /* 원 ㄱ ㄴ */
726 buffer[l++] = 0x2c40 + number[i] -1;
727 break;
728 case 12: /* 이어진 숫자. */
730 char cur_num_str[10],buf[80];
731 int j;
732 buf[0] = 0;
733 for (j = 0; j <= level; j++)
735 levelnum = ((number[j] < 1) ? 1 : number[j]);
736 if ((j && j == level) || (j == level && deco[i][1]))
737 sprintf(cur_num_str, "%d%c", levelnum, 0);
738 else
739 sprintf(cur_num_str, "%d%c", levelnum, '.');
740 strcat(buf, cur_num_str);
742 str2hstr(buf, buffer + l);
743 l += strlen(buf);
744 break;
746 default:
747 buffer[l++] = user_shape[i];
748 break;
750 if( deco[i][1] ){
751 buffer[l++] = deco[i][1];
753 buffer[l] = 0;
754 return hstr2ucsstr(buffer);
758 return hstr2ucsstr(buffer);
762 /* 묶음 빈칸(30) */
763 /* 고정폭 빈칸(31) */
765 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */