1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
32 #include <o3tl/sprintf.hxx>
33 #include <rtl/character.hxx>
34 #include <rtl/strbuf.hxx>
35 #include <rtl/string.hxx>
37 int HBox::boxCount
= 0;
54 static const int wsize
[32] =
56 1, 4, 4, 4, 4, 4, 4, 42, /* dateform */
57 48, 4, 4, 4, 4, 1, 4, 4, /* hidden */
58 4, 4, 4, 4, 4, 4, 12, 5, /* chcompose */
59 3, 3, 123, 4, 32, 4, 2, 2
70 SkipData::SkipData(hchar hch
)
81 FieldCode::FieldCode()
87 FieldCode::~FieldCode()
104 DateFormat::DateFormat()
120 const hchar kor_week
[] =
122 0xB7A9, 0xB6A9, 0xD1C1, 0xAE81, 0xA1A2, 0x8B71, 0xC9A1
124 const hchar china_week
[] =
126 0x4CC8, 0x4BE4, 0x525A, 0x48D8, 0x45AB, 0x4270, 0x50B4
128 const char eng_week
[] = { "SunMonTueWedThuFriSat" };
129 const char eng_mon
[] = { "JanFebMarAprMayJunJulAugSepOctNovDec" };
130 const char * const en_mon
[] =
132 "January", "February", "March", "April", "May", "June", "July",
133 "August", "September", "October", "November", "December"
135 const char * const en_week
[] =
137 "Sunday", "Monday", "Tuesday", "Wednesday",
138 "Thursday", "Friday", "Saturday"
141 hchar_string
DateCode::GetString()
148 bool is_pm
, add_zero
;
151 format
[DATE_SIZE
- 1] = 0;
152 fmt
= format
[0] ? format
: defaultform
;
154 for (; *fmt
&& (ret
.size() < DATE_SIZE
); fmt
++)
156 form
= add_zero
? "%02d" : "%d";
159 is_pm
= (date
[HOUR
] >= 12);
173 num
= date
[YEAR
] % 100;
180 static_assert((std::size(eng_mon
) - 1) / 3 == 12);
181 size_t nIndex
= o3tl::make_unsigned(date
[MONTH
] - 1) % 12;
182 memcpy(cbuf
, eng_mon
+ nIndex
* 3, 3);
189 size_t nIndex
= o3tl::make_unsigned(date
[MONTH
] - 1) % std::size(en_mon
);
190 strncat(cbuf
, en_mon
[nIndex
], sizeof(cbuf
) - strlen(cbuf
) - 1);
193 case '3': /* 'D' is day of korean */
198 switch (date
[DAY
] % 10)
215 num
= date
[HOUR
] - ((date
[HOUR
] > 12) ? 12 : 0);
226 size_t nIndex
= o3tl::make_unsigned(date
[WEEK
]) % std::size(kor_week
);
227 ret
.push_back(kor_week
[nIndex
]);
232 static_assert((std::size(eng_week
) - 1) / 3 == 7);
233 size_t nIndex
= o3tl::make_unsigned(date
[WEEK
]) % 7;
234 memcpy(cbuf
, eng_week
+ nIndex
* 3, 3);
241 size_t nIndex
= o3tl::make_unsigned(date
[WEEK
]) % std::size(en_week
);
242 strncat(cbuf
, en_week
[nIndex
], sizeof(cbuf
) - strlen(cbuf
) - 1);
246 ret
.push_back(0xB5A1);
247 ret
.push_back(is_pm
? 0xD281 : 0xB8E5);
250 strncat(cbuf
, is_pm
? "p.m." : "a.m.", sizeof(cbuf
) - strlen(cbuf
) - 1);
253 strncat(cbuf
, is_pm
? "P.M." : "A.M.", sizeof(cbuf
) - strlen(cbuf
) - 1);
255 case '8': // 2.5 feature
259 mkcurfilename(cbuf
, *fmt
);
260 for (i
= 0; cbuf
[i
] != 0 && slen
> 1; i
++)
261 { //for hangle filename
262 if (cbuf
[i
] & 0x80 && cbuf
[i
+ 1] != 0)
264 *d
++ = (cbuf
[i
] << 8) | cbuf
[i
+ 1];
274 case '~': // 3.0b feature
280 size_t nIndex
= o3tl::make_unsigned(date
[WEEK
]) % std::size(china_week
);
281 ret
.push_back(china_week
[nIndex
]);
286 if (*fmt
== '\\' && *++fmt
== 0)
291 o3tl::sprintf(cbuf
, form
, num
);
292 for (i
= 0; 0 != cbuf
[i
]; i
++)
294 ret
.push_back(*(cbuf
+ i
));
311 FBox::FBox(hchar hch
)
341 // tbox(10) TABLE BOX MATH BUTTON HYPERTEXT
359 reserved
[0] = reserved
[1] = 0;
372 , follow_block_size(0)
389 if (pictype
== PICTYPE_DRAW
)
390 delete picinfo
.picdraw
.hdo
;
402 HeaderFooter::~HeaderFooter()
408 Footnote::~Footnote()
415 // show page number (20)
416 // Start/Hide odd-numbered side (21)
419 hchar_string
MailMerge::GetString()
421 return hchar_string();
425 // character composition(23)
431 #define OL_HANGL_JASO 0
432 #define OL_HANGL_KANATA 1
434 static hchar
olHanglJaso(unsigned int num
, int type
)
436 static const unsigned char han_init
[] =
437 { 0x88, 0x90, 0x94, 0x9c, 0xa0, 0xa4, 0xac, 0xb4, 0xb8, 0xc0, 0xc4, 0xc8, 0xcc, 0xd0 };
438 static const unsigned char jung
[] = { 3, 5, 7, 11, 13, 19, 20, 26, 27, 29, 30 };
439 static const unsigned char jung2
[] = { 3, 7, 13, 20, 27, 29, 30 };
443 if (type
== OL_HANGL_JASO
)
445 num
= num
% (14 + SAL_N_ELEMENTS(jung
));
448 hh
= (han_init
[num
] << 8) | 'A';
450 hh
= (jung
[num
- 14] << 5) | 0x8401;
455 hh
= (han_init
[num
] << 8) | 'a';
458 int j
= (num
/ 14) % SAL_N_ELEMENTS(jung2
);
461 hh
= (han_init
[num
] << 8) | (jung2
[j
] << 5) | 1;
468 static const hchar
*GetOutlineStyleChars(int style
)
470 static const hchar out_bul_style_entry
[5][MAX_OUTLINE_LEVEL
+1] = // extern
473 0x2f18, 0x2f12, 0x2f08, 0x2f02, 0x2f06, 0x2f00, 0x2043, 0x0000
476 0x2f18, 0x2f12, 0x2f06, 0x2f00, 0x2f36, 0x2f30, 0x2043, 0x0000
479 0x2f26, 0x2f20, 0x2f06, 0x2f00, 0x2f16, 0x2f10, 0x2043, 0x0000
482 0x2f18, 0x2f16, 0x2f12, 0x2f10, 0x2f06, 0x2f00, 0x2043, 0x0000
485 0xAC61, 0xB677, 0xB861, 0xB8F7, 0xB781, 0x0000, 0x0000, 0x0000
488 if (style
>= OLSTY_BULLET1
&& style
<= OLSTY_BULLET5
)
489 return out_bul_style_entry
[style
- OLSTY_BULLET1
];
494 static void getOutlineNumStr(int style
, int level
, int num
, hchar
* hstr
)
498 U_ROM
= 0x01, L_ROM
= 0x02, U_ENG
= 0x04, L_ENG
= 0x08,
499 HAN
= 0x10, NUM
= 0x20, L_BR
= 0x40, R_BR
= 0x80
501 static const unsigned char type_tbl
[][MAX_OUTLINE_LEVEL
] =
504 U_ROM
, HAN
, NUM
, HAN
| R_BR
, L_BR
| NUM
| R_BR
,
505 L_BR
| HAN
| R_BR
, L_ROM
| R_BR
508 U_ROM
, U_ENG
, NUM
, L_ENG
| R_BR
, L_BR
| NUM
| R_BR
,
509 L_BR
| L_ENG
| R_BR
, L_ROM
| R_BR
512 NUM
, HAN
, L_BR
| NUM
| R_BR
, L_BR
| HAN
| R_BR
, NUM
|
513 R_BR
, HAN
| R_BR
, L_ENG
516 char fmt
= type_tbl
[style
- OLSTY_NUMSIG1
][level
];
525 auto const numbuf
= OString::number(num
);
526 str2hstr(numbuf
.buf
, hstr
);
527 hstr
+= numbuf
.length
;
529 else if (fmt
& (U_ROM
| L_ROM
))
537 *ptr
= sal::static_int_cast
<char>(
538 rtl::toAsciiUpperCase(static_cast<unsigned char>(*ptr
)));
547 num
= (num
- 1) % 26;
549 *hstr
++ = sal::static_int_cast
<hchar
>('A' + num
);
550 else if (fmt
& L_ENG
)
551 *hstr
++ = sal::static_int_cast
<hchar
>('a' + num
);
553 *hstr
++ = olHanglJaso(num
, OL_HANGL_KANATA
);
555 *hstr
++ = (fmt
& R_BR
) ? ')' : '.';
561 { OUTLINE_ON
, OUTLINE_NUM
};
563 /* level starts from zero. ex) '1.1.1.' is the level 2.
564 number has the value. ex) '1.2.1' has '1,2,1'
565 style has the value which starts from 1 according to the definition in hbox.h
567 OUString
Outline::GetUnicode() const
573 if (kind
== OUTLINE_NUM
)
582 for (unsigned int i
= 0; i
<= level
; ++i
)
584 if (i
>= std::size(number
))
587 levelnum
= ((number
[i
] < 1) ? 1 : number
[i
]);
588 buf
.append(OString::number(levelnum
));
589 if (!(shape
== OLSTY_NUMS2
&& i
&& i
== level
))
592 str2hstr(buf
.getStr(), buffer
);
593 return hstr2OUString(buffer
);
599 if (level
< std::size(number
))
600 getOutlineNumStr(shape
, level
, number
[level
], buffer
);
601 return hstr2OUString(buffer
);
609 if (level
< MAX_OUTLINE_LEVEL
)
611 p
= GetOutlineStyleChars(shape
);
612 buffer
[0] = p
[level
];
615 return hstr2OUString(buffer
);
623 if (i
< std::size(deco
) && deco
[i
][0]) {
624 buffer
[l
++] = deco
[i
][0];
626 if (i
< std::size(user_shape
))
628 /* level starts from zero. ex) '1.1.1.' is the level 2.
629 number has the value. ex) '1.2.1' has '1,2,1'
630 style has the value which starts from 1 according to the definition in hbox.h */
631 switch( user_shape
[i
] )
634 buffer
[l
++] = '1' + number
[i
] - 1;
636 case 1: /* Uppercase Roman */
637 case 2: /* Lowercase Roman */
638 num2roman(number
[i
], dest
);
639 if( user_shape
[i
] == 1 ){
643 *ptr
= sal::static_int_cast
<char>(rtl::toAsciiUpperCase(static_cast<unsigned char>(*ptr
)));
647 str2hstr(dest
, buffer
+ l
);
651 buffer
[l
++] = 'A' + number
[i
] -1;
654 buffer
[l
++] = 'a' + number
[i
] -1;
657 buffer
[l
++] = olHanglJaso(number
[i
] -1, OL_HANGL_KANATA
);
660 buffer
[l
++] = olHanglJaso(number
[i
] -1, OL_HANGL_JASO
);
662 case 7: /* Chinese numbers: the number represented by the general */
663 buffer
[l
++] = '1' + number
[i
] -1;
665 case 8: /* Circled numbers */
666 buffer
[l
++] = 0x2e00 + number
[i
];
668 case 9: /* Circled lowercase alphabet */
669 buffer
[l
++] = 0x2c20 + number
[i
];
671 case 10: /* Circled Korean Alphabet */
672 buffer
[l
++] = 0x2c50 + number
[i
] -1;
674 case 11: /* Circled Korean Characters */
675 buffer
[l
++] = 0x2c40 + number
[i
] -1;
677 case 12: /* Sequenced numbers. */
681 for (j
= 0; j
<= level
; j
++)
683 levelnum
= ((number
[j
] < 1) ? 1 : number
[j
]);
684 buf
.append(OString::number(levelnum
));
685 if (!((j
&& j
== level
) || (j
== level
&& deco
[i
][1])))
688 str2hstr(buf
.getStr(), buffer
+ l
);
689 l
+= buf
.getLength();
693 buffer
[l
++] = user_shape
[i
];
697 if (i
< std::size(deco
) && deco
[i
][1]) {
698 buffer
[l
++] = deco
[i
][1];
701 return hstr2OUString(buffer
);
705 return hstr2OUString(buffer
);
709 /* Bundle of spaces (30) */
710 /* Fixed-width spaces (31) */
712 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */