LibreOffice Module i18npool (master) 1
defaultnumberingprovider.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
22#include <com/sun/star/i18n/NativeNumberMode.hpp>
23#include <com/sun/star/lang/IllegalArgumentException.hpp>
24#include <com/sun/star/style/NumberingType.hpp>
25#include <com/sun/star/beans/PropertyValue.hpp>
26#include <com/sun/star/configuration/theDefaultProvider.hpp>
27#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
28#include <osl/diagnose.h>
29#include <rtl/ref.hxx>
30#include <localedata.hxx>
32#include <string.h>
35
36// Cyrillic upper case
37#define C_CYR_A "\xD0\x90"
38#define C_CYR_B "\xD0\x91"
39// Cyrillic lower case
40#define S_CYR_A "\xD0\xB0"
41#define S_CYR_B "\xD0\xB1"
42
43//Greek upper case
44#define C_GR_A "\xCE\x91"
45#define C_GR_B "\xCE\x92"
46//Greek lower case
47#define S_GR_A "\xCE\xB1"
48#define S_GR_B "\xCE\xB2"
49
50//Hebrew
51#define S_HE_ALEPH "\xD7\x90"
52#define S_HE_YOD "\xD7\x99"
53#define S_HE_QOF "\xD7\xA7"
54
55//Arabic-Indic
56#define S_AR_ONE "\xd9\xa1"
57#define S_AR_TWO "\xd9\xa2"
58#define S_AR_THREE "\xd9\xa3"
59
60// East Arabic-Indic
61#define S_FA_ONE "\xDB\xB1"
62#define S_FA_TWO "\xDB\xB2"
63#define S_FA_THREE "\xDB\xB3"
64
65// Indic Devanagari
66#define S_HI_ONE "\xE0\xA5\xA7"
67#define S_HI_TWO "\xE0\xA5\xA8"
68#define S_HI_THREE "\xE0\xA5\xA9"
69
70// Chicago footnote symbols
71#define S_DAGGER "\xE2\x80\xA0"
72#define S_DBL_DAGGER "\xE2\x80\xA1"
73#define S_SECTION "\xC2\xA7"
74
75#include <sal/macros.h>
76#include <rtl/ustring.hxx>
77#include <rtl/ustrbuf.hxx>
78
79#include <bullet.h>
80
81using namespace com::sun::star;
82using namespace com::sun::star::uno;
83using namespace ::com::sun::star::i18n;
84using namespace com::sun::star::lang;
85
86namespace i18npool {
87
89 0x0623, 0x0628, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E,
90 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635,
91 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x0642,
92 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649
93};
94
96 0x0627, 0x0628, 0x062c, 0x062f, 0x0647, 0x0648, 0x0632, 0x062d,
97 0x0637, 0x064a, 0x0643, 0x0644, 0x0645, 0x0646, 0x0633, 0x0639,
98 0x0641, 0x0635, 0x0642, 0x0631, 0x0634, 0x062a, 0x062b, 0x062e,
99 0x0630, 0x0636, 0x0638, 0x063a
100};
101
103 0x0E01, 0x0E02, 0x0E04, 0x0E07,
104 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
105 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
106 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
107 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
108 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E
109};
110
112 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
113 0x05D8, 0x05D9, 0x05DB, 0x05DC, 0x05DE, 0x05E0, 0x05E1, 0x05E2,
114 0x05E4, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA
115};
116
118 0x0915, 0x0916, 0x0917, 0x0918, 0x0919, 0x091A, 0x091B, 0x091C,
119 0x091D, 0x091E, 0x091F, 0x0920, 0x0921, 0x0922, 0x0923, 0x0924,
120 0x0925, 0x0926, 0x0927, 0x0928, 0x092A, 0x092B, 0x092C, 0x092D,
121 0x092E, 0x092F, 0x0930, 0x0932, 0x0935, 0x0936, 0x0937, 0x0938,
122 0x0939
123};
124
126 0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787,
127 0x1788, 0x1789, 0x178A, 0x178B, 0x178C, 0x178D, 0x178E, 0x178F,
128 0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797,
129 0x1798, 0x1799, 0x179A, 0x179B, 0x179C, 0x179F,
130 0x17A0, 0x17A1, 0x17A2
131};
132
134 0x0E81, 0x0E82, 0x0E84, 0x0E87, 0x0E88, 0x0E8A, 0x0E8D, 0x0E94,
135 0x0E95, 0x0E96, 0x0E97, 0x0E99, 0x0E9A, 0x0E9B, 0x0E9C,
136 0x0E9D, 0x0E9E, 0x0E9F, 0x0EA1, 0x0EA2, 0x0EA3, 0x0EA5, 0x0EA7,
137 0x0EAA, 0x0EAB, 0x0EAD, 0x0EAE, 0x0EAF, 0x0EAE, 0x0EDC, 0x0EDD
138};
139
141 0x0F40, 0x0F41, 0x0F42, 0x0F44, 0x0F45, 0x0F46, 0x0F47, 0x0F49,
142 0x0F4F, 0x0F50, 0x0F51, 0x0F53, 0x0F54, 0x0F55, 0x0F56, 0x0F58,
143 0x0F59, 0x0F5A, 0x0F5B, 0x0F5D, 0x0F5E, 0x0F5F, 0x0F60, 0x0F61,
144 0x0F62, 0x0F63, 0x0F64, 0x0F66, 0x0F67, 0x0F68
145};
146
148 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
149 0x1008,/*0x1009,*/0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
150 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
151 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
152 0x1020, 0x1021
153};
154
155// Bulgarian Cyrillic upper case letters
157 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418,
158 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422,
159 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042E,
160 0x042F
161};
162
163// Bulgarian cyrillic lower case letters
165 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438,
166 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442,
167 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044E,
168 0x044F
169};
170
171// Russian Cyrillic upper letters
173 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
174 0x0418, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
175 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
176 0x0429, 0x042B, 0x042D, 0x042E, 0x042F
177};
178
179// Russian cyrillic lower letters
181 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
182 0x0438, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440,
183 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448,
184 0x0449, 0x044B, 0x044D, 0x044E, 0x044F
185};
186
187// Serbian Cyrillic upper letters
189 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0402, 0x0415, 0x0416,
190 0x0417, 0x0418, 0x0408, 0x041A, 0x041B, 0x0409, 0x041C, 0x041D,
191 0x040A, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x040B, 0x0423,
192 0x0424, 0x0425, 0x0426, 0x0427, 0x040F, 0x0428
193};
194
195// Serbian cyrillic lower letters
197 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0452, 0x0435, 0x0436,
198 0x0437, 0x0438, 0x0458, 0x043A, 0x043B, 0x0459, 0x043C, 0x043D,
199 0x045A, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x045B, 0x0443,
200 0x0444, 0x0445, 0x0446, 0x0447, 0x045F, 0x0448
201};
202
203// Ukrainian Cyrillic upper letters
205 0x0410, 0x0411, 0x0412, 0x0413, 0x0490, 0x0414, 0x0415, 0x0404,
206 0x0416, 0x0417, 0x0418, 0x0406, 0x0407, 0x0419, 0x041A, 0x041B,
207 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423,
208 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042C, 0x042E,
209 0x042F
210};
211
212// Ukrainian cyrillic lower letters
214 0x0430, 0x0431, 0x0432, 0x0433, 0x0491, 0x0434, 0x0435, 0x0454,
215 0x0436, 0x0437, 0x0438, 0x0456, 0x0457, 0x0439, 0x043A, 0x043B,
216 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443,
217 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044C, 0x044E,
218 0x044F
219};
220
222 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x03DB, 0x0396, 0x0397, 0x0398,
223 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03DF,
224 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03E0
225};
226
228 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03DB, 0x03B6, 0x03B7, 0x03B8,
229 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03DF,
230 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03E1
231};
232
234 0x0622, 0x0628, 0x067E, 0x062A, 0x062B, 0x062C, 0x0686, 0x062D,
235 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0698, 0x0633, 0x0634,
236 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x0640, 0x0641, 0x0642,
237 0x06A9, 0x06AF, 0x0644, 0x0645, 0x0646, 0x0648, 0x0647, 0x06CC
238};
239
241 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
242 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
243 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A
244};
245
247 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
248 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
249 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
250};
251
253 0x002a, 0x2020, 0x2021, 0x00a7
254};
255
256// Tables used for numbering in persian words
258 {0}, // 0
259 {0x06cc, 0x06a9, 0}, // 1
260 {0x062f, 0x0648, 0}, // 2
261 {0x0633, 0x0647, 0}, // 3
262 {0x0686, 0x0647, 0x0627, 0x0631, 0}, // 4
263 {0x067e, 0x0646, 0x062c, 0}, // 5
264 {0x0634, 0x0634, 0}, // 6
265 {0x0647, 0x0641, 0x062a, 0}, // 7
266 {0x0647, 0x0634, 0x062a, 0}, // 8
267 {0x0646, 0x0647, 0}, // 9
268 {0x062f, 0x0647, 0}, // 10
269 {0x06cc, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 11
270 {0x062f, 0x0648, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 12
271 {0x0633, 0x06cc, 0x0632, 0x062f, 0x0647, 0}, // 13
272 {0x0686, 0x0647, 0x0627, 0x0631, 0x062f, 0x0647, 0}, // 14
273 {0x067e, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 15
274 {0x0634, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 16
275 {0x0647, 0x0641, 0x062f, 0x0647, 0}, // 17
276 {0x0647, 0x062c, 0x062f, 0x0647, 0}, // 18
277 {0x0646, 0x0648, 0x0632, 0x062f, 0x0647, 0} // 19
278};
279
281 {0x0628, 0x06cc, 0x0633, 0x062a, 0}, // 20
282 {0x0633, 0x06cc, 0}, // 30
283 {0x0686, 0x0647, 0x0644, 0}, // 40
284 {0x067e, 0x0646, 0x062c, 0x0627, 0x0647, 0}, // 50
285 {0x0634, 0x0635, 0x062a, 0}, // 60
286 {0x0647, 0x0641, 0x062a, 0x0627, 0x062f, 0}, // 70
287 {0x0647, 0x0634, 0x062a, 0x0627, 0x062f, 0}, // 80
288 {0x0646, 0x0648, 0x062f, 0} // 90
289};
290
292 {0x0635, 0x062f, 0}, // 100
293 {0x062f, 0x0648, 0x06cc, 0x0633, 0x062a, 0}, // 200
294 {0x0633, 0x06cc, 0x0635, 0x062f, 0}, // 300
295 {0x0686, 0x0647, 0x0627, 0x0631, 0x0635, 0x062f, 0}, // 400
296 {0x067e, 0x0627, 0x0646, 0x0635, 0x062f, 0}, // 500
297 {0x0634, 0x0635, 0x062f, 0}, // 600
298 {0x0647, 0x0641, 0x062a, 0x0635, 0x062f, 0}, // 700
299 {0x0647, 0x0634, 0x062a, 0x0635, 0x062f, 0}, // 800
300 {0x0646, 0x0647, 0x0635, 0x062f, 0} // 900
301};
302
304 {0x0647, 0x0632, 0x0627, 0x0631, 0}, // 1000
305 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0648, 0x0646, 0}, // 1000000
306 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0627, 0x0631, 0x062f, 0} // 1000000000
307};
308
310 {0xd558, 0xb098, 0}, // 1
311 {0xb458, 0}, // 2
312 {0xc14b, 0}, // 3
313 {0xb137, 0}, // 4
314 {0xb2e4, 0xc12f, 0}, // 5
315 {0xc5ec, 0xc12f, 0}, // 6
316 {0xc77c, 0xacf1, 0}, // 7
317 {0xc5ec, 0xb35f, 0}, // 8
318 {0xc544, 0xd649, 0} // 9
319};
320
322 {0xc5f4, 0}, // 10
323 {0xc2a4, 0xbb3c, 0}, // 20
324 {0xc11c, 0xb978, 0}, // 30
325 {0xb9c8, 0xd754, 0}, // 40
326 {0xc270, 0}, // 50
327 {0xc608, 0xc21c, 0}, // 60
328 {0xc77c, 0xd754, 0}, // 70
329 {0xc5ec, 0xb4e0, 0}, // 80
330 {0xc544, 0xd754, 0} // 90
331};
332
334{
335
336}
337
339{
340}
341
344{
345 return LocaleDataImpl::get()->getOutlineNumberingLevels( rLocale );
346}
347
350{
351 return LocaleDataImpl::get()->getContinuousNumberingLevels( rLocale );
352}
353
354static OUString toRoman( sal_Int32 n )
355{
356
357// i, ii, iii, iv, v, vi, vii, vii, viii, ix
358// (Dummy),1000,500,100,50,10,5,1
359 static const char coRomanArr[] = "MDCLXVI--"; // +2 Dummy entries !!
360 const char* cRomanStr = coRomanArr;
361 sal_uInt16 nMask = 1000;
362 sal_uInt32 nOver1000 = n / nMask;
363 n -= ( nOver1000 * nMask );
364
365 OUStringBuffer sTmp;
366 while(nOver1000--)
367 sTmp.append(*coRomanArr);
368
369 while( nMask )
370 {
371 sal_uInt8 nNumber = sal_uInt8( n / nMask );
372 sal_uInt8 nDiff = 1;
373 n %= nMask;
374
375 if( 5 < nNumber )
376 {
377 if( nNumber < 9 )
378 sTmp.append(*(cRomanStr-1));
379 ++nDiff;
380 nNumber -= 5;
381 }
382 switch( nNumber )
383 {
384 case 3: sTmp.append(*cRomanStr); [[fallthrough]];
385 case 2: sTmp.append(*cRomanStr); [[fallthrough]];
386 case 1: sTmp.append(*cRomanStr); break;
387 case 4: sTmp.append(OUStringChar(*cRomanStr) + OUStringChar(*(cRomanStr-nDiff))); break;
388 case 5: sTmp.append(*(cRomanStr-nDiff)); break;
389 }
390
391 nMask /= 10; // to the next decade
392 cRomanStr += 2;
393 }
394 return sTmp.makeStringAndClear();
395}
396
397// not used:
398
399static
400void lcl_formatChars( const sal_Unicode table[], int tableSize, int n, OUString& s )
401{
402 // string representation of n is appended to s.
403 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>AB, ...
404 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>ab, ...
405
406 if( n>=tableSize ) lcl_formatChars( table, tableSize, (n-tableSize)/tableSize, s );
407
408 s += OUStringChar( table[ n % tableSize ] );
409}
410
411static
412void lcl_formatChars1( const sal_Unicode table[], int tableSize, int n, OUString& s )
413{
414 // string representation of n is appended to s.
415 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>BB, ...
416 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>bb, ...
417
418 int repeat_count = n / tableSize + 1;
419
420 for( int i=0; i<repeat_count; i++ )
421 s += OUStringChar( table[ n%tableSize ] );
422}
423
424static
425void lcl_formatChars2( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
426{
427 // string representation of n is appended to s.
428 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Ab, ...
429
430 if( n>=tableSize )
431 {
432 lcl_formatChars2( table_capital, table_small, tableSize, (n-tableSize)/tableSize, s );
433 s += OUStringChar( table_small[ n % tableSize ] );
434 } else
435 s += OUStringChar( table_capital[ n % tableSize ] );
436}
437
438static
439void lcl_formatChars3( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
440{
441 // string representation of n is appended to s.
442 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Bb, ...
443
444 int repeat_count = n / tableSize + 1;
445 s += OUStringChar( table_capital[ n%tableSize ] );
446
447 for( int i=1; i<repeat_count; i++ )
448 s += OUStringChar( table_small[ n%tableSize ] );
449}
450
451
459static
460void lcl_formatPersianWord( sal_Int32 nNumber, OUString& rsResult )
461{
462 OUStringBuffer aTemp(64);
463 static constexpr OUStringLiteral asPersianWord_conjunction_data = u" \u0648 ";
464 OUString asPersianWord_conjunction( asPersianWord_conjunction_data );
465 unsigned char nSection = 0;
466
467 while (int nPart = nNumber % 1000)
468 {
469 if (nSection)
470 {
472 throw IllegalArgumentException(); // does not happen with sal_Int32
473 aTemp.insert( 0, table_PersianWord_decadeX[nSection-1] + asPersianWord_conjunction );
474 }
475
476 unsigned int nDigit;
477 if ((nDigit = nPart % 100) < 20)
478 {
479 if (!aTemp.isEmpty())
480 aTemp.insert( 0, u' ');
481 aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
482 }
483 else
484 {
485 if ((nDigit = nPart % 10) != 0)
486 {
487 if (!aTemp.isEmpty())
488 aTemp.insert( 0, asPersianWord_conjunction);
489 aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
490 }
491 if ((nDigit = (nPart / 10) % 10) != 0)
492 {
493 if (!aTemp.isEmpty())
494 aTemp.insert( 0, asPersianWord_conjunction);
495 aTemp.insert( 0, table_PersianWord_decade2[nDigit-2]);
496 }
497 }
498
499 if ((nDigit = nPart / 100) != 0)
500 {
501 if (!aTemp.isEmpty())
502 aTemp.insert( 0, asPersianWord_conjunction);
503 aTemp.insert( 0, table_PersianWord_decade3[nDigit-1]);
504 }
505
506 nNumber /= 1000;
507 nSection++;
508 }
509 rsResult += aTemp;
510}
511
512static void lcl_formatKoreanLegalWord(sal_Int32 nNumber, OUString& rsResult) {
513 OUStringBuffer aTemp(64);
514 int digit1 = nNumber % 10;
515 int digit2 = nNumber / 10;
516 if (digit1 > 0)
517 aTemp.insert(0, (table_KoreanLegalWord_decade1[digit1 - 1]));
518 if (digit2 > 0)
519 aTemp.insert(0, (table_KoreanLegalWord_decade2[digit2 - 1]));
520 rsResult += aTemp;
521}
522
523// Greek Letter Numbering
524
525// KERAIA separates numerals from other text
526#define STIGMA u'\x03DB'
527#define LEFT_KERAIA u'\x0375'
528#define MYRIAD_SYM u'\x039C'
529#define DOT_SYM u'.'
530#define SIGMA_OFFSET 19
531#define TAU_OFFSET 20
532#define MYRIAD 10000
533
534/*
535* Return the 1-999999 number's representation in the Greek numbering system.
536* Adding a "left keraia" to represent numbers in the range 10000 ... 999999 is
537* not orthodox, so it's better to use the myriad notation and call this method
538* only for numbers up to 9999.
539*/
540static
541OUString gr_smallNum(const sal_Unicode table[], int n)
542{
543 if (n > 9999)
544 throw IllegalArgumentException();
545
546 int i = 0;
547 OUStringBuffer sb;
548 for (int v = n; v > 0; v /= 10, i++) {
549 int digit = v % 10;
550 if (digit == 0)
551 continue;
552
553 sal_Unicode sign = table[(digit - 1) + 9 * (i % 3)];
554 if (sign == STIGMA) {
555 sb.insert(0, table[TAU_OFFSET]);
556 sb.insert(0, table[SIGMA_OFFSET]);
557 } else {
558 sb.insert(0, sign);
559 }
560
561 if (i > 2)
562 sb.insert(0, LEFT_KERAIA);
563 }
564
565 return sb.makeStringAndClear();
566}
567
568static
569void lcl_formatCharsGR(const sal_Unicode table[], int n, OUString& s )
570{
571 OUStringBuffer sb;
572 int myriadPower = 2;
573
574 for (int divisor = MYRIAD * MYRIAD; divisor > 1; divisor /= MYRIAD, myriadPower--) {
575 if (n > divisor - 1) {
576 /*
577 * Follow the Diophantus representation of:
578 * A myriad sign, M(10000) as many times as the power
579 * followed by the multiplier for the myriad
580 * followed by a dot
581 * followed by the rest
582 * This is enough for 32-bit integers
583 */
584 for (int i = 0; i < myriadPower; i++)
585 sb.append(MYRIAD_SYM);
586
587 sb.append(gr_smallNum(table, n/divisor));
588 n %= divisor;
589
590 if (n > 0)
591 sb.append(DOT_SYM);
592 }
593 }
594 sb.append(gr_smallNum(table,n));
595
596 s += sb;
597}
598
599static
600bool should_ignore( std::u16string_view s )
601{
602 // return true if blank or null
603 return s == u" " || (!s.empty() && s[0]==0);
604}
605
610static OUString lcl_formatArabicZero(sal_Int32 nNumber, sal_Int32 nLimit)
611{
612 OUString aRet = OUString::number(nNumber);
613 sal_Int32 nDiff = nLimit - aRet.getLength();
614
615 if (nDiff <= 0)
616 {
617 return aRet;
618 }
619
620 OUStringBuffer aBuffer;
621 aBuffer.setLength(nDiff);
622 for (sal_Int32 i = 0; i < nDiff; ++i)
623 {
624 aBuffer[i] = '0';
625 }
626 aBuffer.append(aRet);
627 return aBuffer.makeStringAndClear();
628}
629
630static
632 const char* name )
633{
634 auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
635 [&name](const beans::PropertyValue& rProp) { return rProp.Name.equalsAscii(name); });
636 if (pProp != aProperties.end())
637 return pProp->Value;
638 throw IllegalArgumentException();
639}
640
641//XNumberingFormatter
642OUString
644 const Locale& aLocale )
645{
646 // the Sequence of PropertyValues is expected to have at least 4 elements:
647 // elt Name Type purpose
648
649
650 // 0. "Prefix" OUString
651 // 1. "NumberingType" sal_Int16 type of formatting from style::NumberingType (roman, arabic, etc)
652 // 2. "Suffix" OUString
653 // ... ... ...
654 // n. "Value" sal_Int32 the number to be formatted
655 // example:
656 // given the Sequence { '(', NumberingType::ROMAN_UPPER, ')', ..., 7 }
657 // makeNumberingString() returns the string "(VII)".
658
659 // Q: why is the type of numType sal_Int16 instead of style::NumberingType?
660 // A: an Any can't hold a style::NumberingType for some reason.
661 // add.: style::NumberingType holds constants of type sal_Int16, it's not an enum type
662
663 sal_Int16 natNum = 0;
664 sal_Int16 tableSize = 0;
665 const sal_Unicode *table = nullptr; // initialize to avoid compiler warning
666 bool bRecycleSymbol = false;
667 OUString sNatNumParams;
668 Locale locale;
669
670 OUString prefix;
671 sal_Int16 numType = -1; // type of formatting from style::NumberingType (roman, arabic, etc)
672 OUString suffix;
673 sal_Int32 number = -1; // the number that needs to be formatted.
674
675// int nProperties = aProperties.getLength();
676// int last = nProperties-1;
677
678 for (auto const & prop : aProperties)
679 {
680 if (prop.Name == "Prefix")
681 prop.Value >>= prefix;
682 else if (prop.Name == "Suffix")
683 prop.Value >>= suffix;
684 else if (prop.Name == "NumberingType")
685 prop.Value >>= numType;
686 else if (prop.Name == "Value")
687 prop.Value >>= number;
688 }
689
690 if( number <= 0 )
691 throw IllegalArgumentException();
692
693 // start empty
694 OUString result;
695
696 // append prefix
698
699 // append formatted number
700 using namespace style::NumberingType;
701 switch( numType )
702 {
703 case CHARS_UPPER_LETTER:
704 lcl_formatChars( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>AB, ...
705 break;
706 case CHARS_LOWER_LETTER:
707 lcl_formatChars( lowerLetter, 26, number-1, result );
708 break;
709 case TEXT_NUMBER: // ordinal indicators (1st, 2nd, 3rd, ...)
710 natNum = NativeNumberMode::NATNUM12;
711 sNatNumParams = "capitalize ordinal-number";
712 locale = aLocale;
713 break;
714 case TEXT_CARDINAL: // cardinal number names (One, Two, Three, ...)
715 natNum = NativeNumberMode::NATNUM12;
716 sNatNumParams = "capitalize";
717 locale = aLocale;
718 break;
719 case TEXT_ORDINAL: // ordinal number names (First, Second, Third, ...)
720 natNum = NativeNumberMode::NATNUM12;
721 sNatNumParams = "capitalize ordinal";
722 locale = aLocale;
723 break;
724 case ROMAN_UPPER:
725 result += toRoman( number );
726 break;
727 case ROMAN_LOWER:
728 result += toRoman( number ).toAsciiLowerCase();
729 break;
730 case ARABIC:
731 result += OUString::number( number );
732 break;
733 case NUMBER_NONE:
734 return OUString(); // ignore prefix and suffix
735 case CHAR_SPECIAL:
736 // apparently, we're supposed to return an empty string in this case...
737 return OUString(); // ignore prefix and suffix
738 case PAGE_DESCRIPTOR:
739 case BITMAP:
740 OSL_ASSERT(false);
741 throw IllegalArgumentException();
742 case CHARS_UPPER_LETTER_N:
743 lcl_formatChars1( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
744 break;
745 case CHARS_LOWER_LETTER_N:
746 lcl_formatChars1( lowerLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
747 break;
748 case TRANSLITERATION:
749 try {
750 const OUString &tmp = OUString::number( number );
751 OUString transliteration;
752 getPropertyByName(aProperties, "Transliteration") >>= transliteration;
753 if ( !translit )
755 translit->loadModuleByImplName(transliteration, aLocale);
756 result += translit->transliterateString2String(tmp, 0, tmp.getLength());
757 } catch (Exception& ) {
758 // When transliteration property is missing, return default number (bug #101141#)
759 result += OUString::number( number );
760 // OSL_ASSERT(0);
761 // throw IllegalArgumentException();
762 }
763 break;
764 case NATIVE_NUMBERING:
765 natNum = NativeNumberMode::NATNUM1;
766 locale = aLocale;
767 break;
768 case FULLWIDTH_ARABIC:
769 natNum = NativeNumberMode::NATNUM3;
770 locale = aLocale;
771 break;
772 case NUMBER_LOWER_ZH:
773 natNum = NativeNumberMode::NATNUM12;
774 locale.Language = "zh";
775 break;
776 case NUMBER_UPPER_ZH:
777 natNum = NativeNumberMode::NATNUM5;
778 locale.Language = "zh";
779 break;
780 case NUMBER_UPPER_ZH_TW:
781 natNum = NativeNumberMode::NATNUM5;
782 locale.Language = "zh";
783 locale.Country = "TW";
784 break;
785 case NUMBER_TRADITIONAL_JA:
786 natNum = NativeNumberMode::NATNUM8;
787 locale.Language = "ja";
788 break;
789 case NUMBER_UPPER_KO:
790 natNum = NativeNumberMode::NATNUM8;
791 locale.Language = "ko";
792 break;
793 case NUMBER_HANGUL_KO:
794 natNum = NativeNumberMode::NATNUM11;
795 locale.Language = "ko";
796 break;
797 case NUMBER_DIGITAL_KO:
798 natNum = NativeNumberMode::NATNUM9;
799 locale.Language = "ko";
800 break;
801 case NUMBER_DIGITAL2_KO:
802 natNum = NativeNumberMode::NATNUM1;
803 locale.Language = "ko";
804 break;
805 case NUMBER_LEGAL_KO:
806 if (number < 1 || number >= 100)
807 {
808 natNum = NativeNumberMode::NATNUM11;
809 locale.Language = "ko";
810 }
811 else
812 {
814 }
815 break;
816
817 case CIRCLE_NUMBER:
820 break;
821 case TIAN_GAN_ZH:
823 tableSize = SAL_N_ELEMENTS(table_TianGan_zh);
824 break;
825 case DI_ZI_ZH:
827 tableSize = SAL_N_ELEMENTS(table_DiZi_zh);
828 break;
829 case AIU_FULLWIDTH_JA:
832 bRecycleSymbol = true;
833 break;
834 case AIU_HALFWIDTH_JA:
837 bRecycleSymbol = true;
838 break;
839 case IROHA_FULLWIDTH_JA:
842 bRecycleSymbol = true;
843 break;
844 case IROHA_HALFWIDTH_JA:
847 bRecycleSymbol = true;
848 break;
849 case HANGUL_JAMO_KO:
852 bRecycleSymbol = true;
853 break;
854 case HANGUL_SYLLABLE_KO:
857 bRecycleSymbol = true;
858 break;
859 case HANGUL_CIRCLED_JAMO_KO:
862 bRecycleSymbol = true;
863 break;
864 case HANGUL_CIRCLED_SYLLABLE_KO:
867 bRecycleSymbol = true;
868 break;
869 case CHARS_ARABIC:
871 break;
872 case CHARS_ARABIC_ABJAD:
874 break;
875 case NUMBER_ARABIC_INDIC:
876 natNum = NativeNumberMode::NATNUM1;
877 locale.Language = "ar";
878 break;
879 case NUMBER_EAST_ARABIC_INDIC:
880 natNum = NativeNumberMode::NATNUM1;
881 locale.Language = "fa";
882 break;
883 case NUMBER_INDIC_DEVANAGARI:
884 natNum = NativeNumberMode::NATNUM1;
885 locale.Language = "hi";
886 break;
887 case CHARS_THAI:
889 break;
890 case CHARS_HEBREW:
892 break;
893 case NUMBER_HEBREW:
894 natNum = NativeNumberMode::NATNUM1;
895 locale.Language = "he";
896 break;
897 case CHARS_NEPALI:
899 break;
900 case CHARS_KHMER:
902 break;
903 case CHARS_LAO:
905 break;
906 case CHARS_MYANMAR:
908 break;
909 case CHARS_TIBETAN:
911 break;
912 case CHARS_CYRILLIC_UPPER_LETTER_BG:
916 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Ab, ...
917 break;
918 case CHARS_CYRILLIC_LOWER_LETTER_BG:
921 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>ab, ...
922 break;
923 case CHARS_CYRILLIC_UPPER_LETTER_N_BG:
927 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Bb, ...
928 break;
929 case CHARS_CYRILLIC_LOWER_LETTER_N_BG:
932 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>bb, ...
933 break;
934 case CHARS_CYRILLIC_UPPER_LETTER_RU:
938 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
939 break;
940 case CHARS_CYRILLIC_LOWER_LETTER_RU:
943 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
944 break;
945 case CHARS_CYRILLIC_UPPER_LETTER_N_RU:
949 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
950 break;
951 case CHARS_CYRILLIC_LOWER_LETTER_N_RU:
954 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
955 break;
956 case CHARS_CYRILLIC_UPPER_LETTER_SR:
960 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
961 break;
962 case CHARS_CYRILLIC_LOWER_LETTER_SR:
965 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
966 break;
967 case CHARS_CYRILLIC_UPPER_LETTER_N_SR:
971 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
972 break;
973 case CHARS_CYRILLIC_LOWER_LETTER_N_SR:
976 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
977 break;
978
979 case CHARS_CYRILLIC_UPPER_LETTER_UK:
983 result);
984 break;
985 case CHARS_CYRILLIC_LOWER_LETTER_UK:
988 result);
989 break;
990 case CHARS_CYRILLIC_UPPER_LETTER_N_UK:
994 result);
995 break;
996 case CHARS_CYRILLIC_LOWER_LETTER_N_UK:
999 result);
1000 break;
1001
1002 case CHARS_GREEK_LOWER_LETTER:
1004 break;
1005
1006 case CHARS_GREEK_UPPER_LETTER:
1008 break;
1009
1010 case CHARS_PERSIAN:
1012 break;
1013
1014 case CHARS_PERSIAN_WORD:
1016 break;
1017
1018 case SYMBOL_CHICAGO:
1019 lcl_formatChars1( table_Chicago, 4, number-1, result ); // *, +, |, S, **, ++, ...
1020 break;
1021
1022 case ARABIC_ZERO:
1023 result += lcl_formatArabicZero(number, 2);
1024 break;
1025
1026 case ARABIC_ZERO3:
1027 result += lcl_formatArabicZero(number, 3);
1028 break;
1029
1030 case ARABIC_ZERO4:
1031 result += lcl_formatArabicZero(number, 4);
1032 break;
1033
1034 case ARABIC_ZERO5:
1035 result += lcl_formatArabicZero(number, 5);
1036 break;
1037
1038 case SZEKELY_ROVAS: // Old Hungarian
1039 natNum = NativeNumberMode::NATNUM12;
1040 locale.Language = "hu-Hung";
1041 break;
1042
1043 default:
1044 OSL_ASSERT(false);
1045 throw IllegalArgumentException();
1046 }
1047
1048 if (natNum) {
1049 if (!mxNatNum)
1051 result += mxNatNum->getNativeNumberStringParams(OUString::number(number), locale,
1052 natNum, sNatNumParams);
1053 } else if (tableSize) {
1054 if ( number > tableSize && !bRecycleSymbol)
1055 result += OUString::number( number);
1056 else
1057 result += OUStringChar(table[--number % tableSize]);
1058 }
1059
1060 // append suffix
1061 if( !should_ignore(suffix) ) result += suffix;
1062
1063 return result;
1064}
1065
1066#define LANG_ALL (1 << 0)
1067#define LANG_CJK (1 << 1)
1068#define LANG_CTL (1 << 2)
1069
1071{
1072 const char* cSymbol;
1073 sal_Int16 nType;
1074 sal_Int16 langOption;
1075 Supported_NumberingType(sal_Int16 nType_, const char* pSymbol, sal_Int16 opt)
1076 : cSymbol(pSymbol), nType(nType_), langOption(opt) {}
1077};
1079{
1080 {style::NumberingType::CHARS_UPPER_LETTER, "A", LANG_ALL},
1081 {style::NumberingType::CHARS_LOWER_LETTER, "a", LANG_ALL},
1082 {style::NumberingType::ROMAN_UPPER, "I", LANG_ALL},
1083 {style::NumberingType::ROMAN_LOWER, "i", LANG_ALL},
1084 {style::NumberingType::ARABIC, "1", LANG_ALL},
1085 {style::NumberingType::NUMBER_NONE, "''", LANG_ALL},
1086 {style::NumberingType::CHAR_SPECIAL, "Bullet", LANG_ALL},
1087 {style::NumberingType::PAGE_DESCRIPTOR, "Page", LANG_ALL},
1088 {style::NumberingType::BITMAP, "Bitmap", LANG_ALL},
1089 {style::NumberingType::SYMBOL_CHICAGO, "*, " S_DAGGER ", " S_DBL_DAGGER ", " S_SECTION ", **, " S_DAGGER S_DAGGER ", ...", LANG_ALL},
1090 {style::NumberingType::TEXT_NUMBER, "1st", LANG_ALL},
1091 {style::NumberingType::TEXT_CARDINAL, "One", LANG_ALL},
1092 {style::NumberingType::TEXT_ORDINAL, "First", LANG_ALL},
1093 {style::NumberingType::CHARS_UPPER_LETTER_N, "AAA", LANG_ALL},
1094 {style::NumberingType::CHARS_LOWER_LETTER_N, "aaa", LANG_ALL},
1095 {style::NumberingType::NATIVE_NUMBERING, "Native Numbering", LANG_CJK|LANG_CTL},
1096 {style::NumberingType::FULLWIDTH_ARABIC, nullptr, LANG_CJK},
1097 {style::NumberingType::CIRCLE_NUMBER, nullptr, LANG_CJK},
1098 // The cSymbol is defined here for compatibility with files created by old releases.
1099 // Otherwise if nullptr, these 3 digits may change as NATNUM12 depends on 3rd-party lib.
1100 {style::NumberingType::NUMBER_LOWER_ZH, "一, 二, 三, ...", LANG_CJK},
1101 {style::NumberingType::NUMBER_UPPER_ZH, nullptr, LANG_CJK},
1102 {style::NumberingType::NUMBER_UPPER_ZH_TW, nullptr, LANG_CJK},
1103 {style::NumberingType::TIAN_GAN_ZH, nullptr, LANG_CJK},
1104 {style::NumberingType::DI_ZI_ZH, nullptr, LANG_CJK},
1105 {style::NumberingType::NUMBER_TRADITIONAL_JA, nullptr, LANG_CJK},
1106 {style::NumberingType::AIU_FULLWIDTH_JA, nullptr, LANG_CJK},
1107 {style::NumberingType::AIU_HALFWIDTH_JA, nullptr, LANG_CJK},
1108 {style::NumberingType::IROHA_FULLWIDTH_JA, nullptr, LANG_CJK},
1109 {style::NumberingType::IROHA_HALFWIDTH_JA, nullptr, LANG_CJK},
1110 {style::NumberingType::NUMBER_UPPER_KO, nullptr, LANG_CJK},
1111 {style::NumberingType::NUMBER_HANGUL_KO, nullptr, LANG_CJK},
1112 {style::NumberingType::HANGUL_JAMO_KO, nullptr, LANG_CJK},
1113 {style::NumberingType::HANGUL_SYLLABLE_KO, nullptr, LANG_CJK},
1114 {style::NumberingType::HANGUL_CIRCLED_JAMO_KO, nullptr, LANG_CJK},
1115 {style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO, nullptr, LANG_CJK},
1116 {style::NumberingType::NUMBER_LEGAL_KO, nullptr, LANG_CJK},
1117 {style::NumberingType::NUMBER_DIGITAL_KO, nullptr, LANG_CJK},
1118 {style::NumberingType::NUMBER_DIGITAL2_KO, nullptr, LANG_CJK},
1119 {style::NumberingType::CHARS_ARABIC, nullptr, LANG_CTL},
1120 {style::NumberingType::CHARS_ARABIC_ABJAD, nullptr, LANG_CTL},
1121 {style::NumberingType::NUMBER_ARABIC_INDIC, S_AR_ONE ", " S_AR_TWO ", " S_AR_THREE ", ...", LANG_CTL},
1122 {style::NumberingType::NUMBER_EAST_ARABIC_INDIC, S_FA_ONE ", " S_FA_TWO ", " S_FA_THREE ", ...", LANG_CTL},
1123 {style::NumberingType::NUMBER_INDIC_DEVANAGARI, S_HI_ONE ", " S_HI_TWO ", " S_HI_THREE ", ...", LANG_CTL},
1124 {style::NumberingType::CHARS_THAI, nullptr, LANG_CTL},
1125 {style::NumberingType::CHARS_HEBREW, nullptr, LANG_CTL},
1126 {style::NumberingType::NUMBER_HEBREW, S_HE_ALEPH ", " S_HE_YOD ", " S_HE_QOF ", ...", LANG_CTL},
1127 {style::NumberingType::CHARS_NEPALI, nullptr, LANG_CTL},
1128 {style::NumberingType::CHARS_KHMER, nullptr, LANG_CTL},
1129 {style::NumberingType::CHARS_LAO, nullptr, LANG_CTL},
1130 {style::NumberingType::CHARS_MYANMAR, nullptr, LANG_CTL},
1131 {style::NumberingType::CHARS_TIBETAN, nullptr, LANG_CTL},
1132 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_BG, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_A S_CYR_B ", ... (bg)", LANG_ALL},
1133 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_BG, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_A S_CYR_B ", ... (bg)", LANG_ALL},
1134 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_N_BG, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_B S_CYR_B ", ... (bg)", LANG_ALL},
1135 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_N_BG, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_B S_CYR_B ", ... (bg)", LANG_ALL},
1136 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_RU, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_A S_CYR_B ", ... (ru)", LANG_ALL},
1137 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_RU, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_A S_CYR_B ", ... (ru)", LANG_ALL},
1138 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_N_RU, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_B S_CYR_B ", ... (ru)", LANG_ALL},
1139 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_N_RU, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_B S_CYR_B ", ... (ru)", LANG_ALL},
1140 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_SR, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_A S_CYR_B ", ... (sr)", LANG_ALL},
1141 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_SR, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_A S_CYR_B ", ... (sr)", LANG_ALL},
1142 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_N_SR, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_B S_CYR_B ", ... (sr)", LANG_ALL},
1143 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_N_SR, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_B S_CYR_B ", ... (sr)", LANG_ALL},
1144 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_UK, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_A S_CYR_B ", ... (uk)", LANG_ALL},
1145 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_UK, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_A S_CYR_B ", ... (uk)", LANG_ALL},
1146 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_N_UK, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_B S_CYR_B ", ... (uk)", LANG_ALL},
1147 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_N_UK, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_B S_CYR_B ", ... (uk)", LANG_ALL},
1148 {style::NumberingType::CHARS_PERSIAN, nullptr, LANG_CTL},
1149 {style::NumberingType::CHARS_PERSIAN_WORD, nullptr, LANG_CTL},
1150 {style::NumberingType::SZEKELY_ROVAS, nullptr, LANG_CTL},
1151 {style::NumberingType::CHARS_GREEK_UPPER_LETTER, C_GR_A ", " C_GR_B ", ... (gr)", LANG_ALL},
1152 {style::NumberingType::CHARS_GREEK_LOWER_LETTER, S_GR_A ", " S_GR_B ", ... (gr)", LANG_ALL},
1153 {style::NumberingType::ARABIC_ZERO, "01, 02, 03, ...", LANG_ALL},
1154 {style::NumberingType::ARABIC_ZERO3, "001, 002, 003, ...", LANG_ALL},
1155 {style::NumberingType::ARABIC_ZERO4, "0001, 0002, 0003, ...", LANG_ALL},
1156 {style::NumberingType::ARABIC_ZERO5, "00001, 00002, 00003, ...", LANG_ALL},
1157};
1159
1161{
1162 if (index < 0 || index >= nSupported_NumberingTypes)
1163 throw RuntimeException();
1164
1165 if (aSupportedTypes[index].cSymbol)
1166 return OUString(aSupportedTypes[index].cSymbol, strlen(aSupportedTypes[index].cSymbol), RTL_TEXTENCODING_UTF8);
1167 else {
1168 OUStringBuffer result;
1169 Locale aLocale("en", OUString(), OUString());
1171 auto aPropertiesRange = asNonConstRange(aProperties);
1172 aPropertiesRange[0].Name = "NumberingType";
1173 aPropertiesRange[0].Value <<= aSupportedTypes[index].nType;
1174 aPropertiesRange[1].Name = "Value";
1175 for (sal_Int32 j = 1; j <= 3; j++) {
1176 aPropertiesRange[1].Value <<= j;
1177 result.append( makeNumberingString( aProperties, aLocale ) + ", " );
1178 }
1179 result.append("...");
1180 // Make known duplicate generated identifiers unique.
1181 // Note this alone works only for newly added numberings, if duplicates
1182 // are in the wild further handling is needed when loading documents
1183 // and asking for numberings.
1184 switch (aSupportedTypes[index].nType)
1185 {
1186 case css::style::NumberingType::NUMBER_DIGITAL_KO:
1187 // Duplicate of NUMBER_HANGUL_KO.
1188 result.append(" (ko-x-digital)");
1189 break;
1190 case css::style::NumberingType::NUMBER_DIGITAL2_KO:
1191 // Duplicate of NUMBER_LOWER_ZH.
1192 result.append(" (ko)");
1193 break;
1194 default:
1195 ; // nothing
1196 }
1197 return result.makeStringAndClear();
1198 }
1199}
1200
1201bool
1203{
1204 if (! xHierarchicalNameAccess.is()) {
1205 Reference< XMultiServiceFactory > xConfigProvider =
1206 configuration::theDefaultProvider::get(m_xContext);
1207
1208 if (! xConfigProvider.is())
1209 throw RuntimeException();
1210
1211 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1212 {
1213 {"nodepath", uno::Any(OUString("/org.openoffice.Office.Common/I18N"))}
1214 }));
1215
1216 Reference<XInterface> xInterface = xConfigProvider->createInstanceWithArguments(
1217 "com.sun.star.configuration.ConfigurationAccess", aArgs);
1218
1219 xHierarchicalNameAccess.set(xInterface, UNO_QUERY_THROW);
1220 }
1221
1222 Any aEnabled = xHierarchicalNameAccess->getByHierarchicalName(aName);
1223
1224 bool enabled = false;
1225
1226 aEnabled >>= enabled;
1227
1228 return enabled;
1229}
1230
1232{
1234 sal_Int16* pArray = aRet.getArray();
1235
1236 bool cjkEnabled = isScriptFlagEnabled("CJK/CJKFont");
1237 bool ctlEnabled = isScriptFlagEnabled("CTL/CTLFont");
1238
1239 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++) {
1240 if ( (aSupportedTypes[i].langOption & LANG_ALL) ||
1241 ((aSupportedTypes[i].langOption & LANG_CJK) && cjkEnabled) ||
1242 ((aSupportedTypes[i].langOption & LANG_CTL) && ctlEnabled) )
1243 pArray[i] = aSupportedTypes[i].nType;
1244 }
1245 return aRet;
1246}
1247
1248sal_Int16 DefaultNumberingProvider::getNumberingType( const OUString& rNumberingIdentifier )
1249{
1250 auto it = maSupportedTypesCache.find(rNumberingIdentifier);
1251 if (it != maSupportedTypesCache.end())
1252 return it->second->nType;
1253 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1254 if(rNumberingIdentifier == makeNumberingIdentifier(i))
1255 {
1256 maSupportedTypesCache.emplace(rNumberingIdentifier, &aSupportedTypes[i]);
1257 return aSupportedTypes[i].nType;
1258 }
1259 throw RuntimeException();
1260}
1261
1262sal_Bool DefaultNumberingProvider::hasNumberingType( const OUString& rNumberingIdentifier )
1263{
1264 auto it = maSupportedTypesCache.find(rNumberingIdentifier);
1265 if (it != maSupportedTypesCache.end())
1266 return true;
1267 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1268 if(rNumberingIdentifier == makeNumberingIdentifier(i))
1269 {
1270 maSupportedTypesCache.emplace(rNumberingIdentifier, &aSupportedTypes[i]);
1271 return true;
1272 }
1273 return false;
1274}
1275
1276OUString DefaultNumberingProvider::getNumberingIdentifier( sal_Int16 nNumberingType )
1277{
1278 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1279 if(nNumberingType == aSupportedTypes[i].nType)
1280 return makeNumberingIdentifier(i);
1281 return OUString();
1282}
1283
1285{
1286 return "com.sun.star.text.DefaultNumberingProvider";
1287}
1288
1290{
1291 return cppu::supportsService(this, rServiceName);
1292}
1293
1295{
1296 Sequence< OUString > aRet { "com.sun.star.text.DefaultNumberingProvider" };
1297 return aRet;
1298}
1299
1300}
1301
1302extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1304 css::uno::XComponentContext *context,
1305 css::uno::Sequence<css::uno::Any> const &)
1306{
1307 return cppu::acquire(new i18npool::DefaultNumberingProvider(context));
1308}
1309
1310/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xContext
PropertiesInfo aProperties
std::map< OUString, const Supported_NumberingType * > maSupportedTypesCache
virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedNumberingTypes() override
virtual OUString SAL_CALL getNumberingIdentifier(sal_Int16 NumberingType) override
bool isScriptFlagEnabled(const OUString &aName)
virtual sal_Bool SAL_CALL hasNumberingType(const OUString &NumberingIdentifier) override
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
css::uno::Reference< css::uno::XComponentContext > m_xContext
css::uno::Reference< css::container::XHierarchicalNameAccess > xHierarchicalNameAccess
DefaultNumberingProvider(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
virtual sal_Int16 SAL_CALL getNumberingType(const OUString &NumberingIdentifier) override
rtl::Reference< TransliterationImpl > translit
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
rtl::Reference< NativeNumberSupplierService > mxNatNum
virtual css::uno::Sequence< css::uno::Reference< css::container::XIndexAccess > > SAL_CALL getDefaultOutlineNumberings(const css::lang::Locale &aLocale) override
virtual OUString SAL_CALL makeNumberingString(const css::uno::Sequence< css::beans::PropertyValue > &aProperties, const css::lang::Locale &aLocale) override
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > SAL_CALL getDefaultContinuousNumberingLevels(const css::lang::Locale &aLocale) override
static rtl::Reference< LocaleDataImpl > get()
Definition: localedata.hxx:77
#define S_DAGGER
#define S_DBL_DAGGER
#define STIGMA
#define S_HE_YOD
#define DOT_SYM
#define MYRIAD
#define S_CYR_B
#define C_GR_A
#define C_CYR_B
#define S_SECTION
#define S_HE_ALEPH
#define S_GR_B
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_text_DefaultNumberingProvider_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
#define C_CYR_A
#define S_GR_A
#define C_GR_B
#define S_FA_TWO
#define S_HI_THREE
#define S_FA_THREE
#define S_AR_TWO
#define SIGMA_OFFSET
#define LANG_CTL
#define S_HE_QOF
#define S_CYR_A
#define S_FA_ONE
#define S_AR_ONE
#define S_HI_ONE
#define LEFT_KERAIA
#define TAU_OFFSET
#define MYRIAD_SYM
#define S_HI_TWO
#define LANG_CJK
#define S_AR_THREE
#define LANG_ALL
float v
float u
const char * name
OUString aName
sal_Int64 n
#define SAL_N_ELEMENTS(arr)
@ table
@ Exception
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
Constant values shared between i18npool and, for example, the number formatter.
static void lcl_formatChars1(const sal_Unicode table[], int tableSize, int n, OUString &s)
const sal_Unicode lowerLetter[]
const sal_Unicode table_PersianWord_decade2[][6]
const sal_Unicode table_CyrillicUpperLetter_uk[]
const sal_Unicode table_PersianWord_decadeX[][8]
const sal_Unicode table_CyrillicLowerLetter_sr[]
const sal_Unicode table_HangulCircledJamo_ko[]
Definition: bullet.h:314
const sal_Unicode table_CyrillicLowerLetter_ru[]
const Supported_NumberingType aSupportedTypes[]
const sal_Unicode table_Alphabet_my[]
static void lcl_formatChars3(const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString &s)
const sal_Unicode table_HangulCircledSyllable_ko[]
Definition: bullet.h:332
const sal_Unicode table_Alphabet_fa[]
const sal_Unicode table_TianGan_zh[]
Definition: bullet.h:349
const sal_Unicode table_CyrillicUpperLetter_ru[]
const sal_Unicode table_GreekUpperLetter[]
const sal_Unicode table_CyrillicLowerLetter_uk[]
const sal_Unicode table_IROHAFullWidth_ja_JP[]
Definition: bullet.h:124
static bool should_ignore(std::u16string_view s)
const sal_Unicode table_AIUHalfWidth_ja_JP[]
Definition: bullet.h:75
const sal_Unicode table_Alphabet_lo[]
static OUString toRoman(sal_Int32 n)
const sal_Unicode table_HangulJamo_ko[]
Definition: bullet.h:279
const sal_Unicode table_Alphabet_ar[]
const sal_Unicode table_KoreanLegalWord_decade1[][3]
const sal_Unicode table_PersianWord_decade1[][7]
const sal_Unicode table_KoreanLegalWord_decade2[][3]
const sal_Unicode table_AIUFullWidth_ja_JP[]
Definition: bullet.h:26
const sal_Unicode table_PersianWord_decade3[][7]
const sal_Int32 nSupported_NumberingTypes
const sal_Unicode table_Alphabet_he[]
static void lcl_formatChars(const sal_Unicode table[], int tableSize, int n, OUString &s)
const sal_Unicode table_Alphabet_km[]
const sal_Unicode table_Alphabet_ne[]
static void lcl_formatPersianWord(sal_Int32 nNumber, OUString &rsResult)
Returns number's representation in persian words up to 999999999999 respectively limited by sal_Int32...
const sal_Unicode table_HangulSyllable_ko[]
Definition: bullet.h:296
const sal_Unicode table_CyrillicUpperLetter_sr[]
const sal_Unicode table_CyrillicLowerLetter_bg[]
static void lcl_formatCharsGR(const sal_Unicode table[], int n, OUString &s)
static OUString lcl_formatArabicZero(sal_Int32 nNumber, sal_Int32 nLimit)
Turn nNumber into a string and pad the result to nLimit by inserting zero characters at the start.
static void lcl_formatChars2(const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString &s)
static OUString gr_smallNum(const sal_Unicode table[], int n)
const sal_Unicode table_Alphabet_dz[]
const sal_Unicode upperLetter[]
const sal_Unicode table_Alphabet_ar_abjad[]
const sal_Unicode table_IROHAHalfWidth_ja_JP[]
Definition: bullet.h:175
const sal_Unicode table_DiZi_zh[]
Definition: bullet.h:353
const sal_Unicode table_GreekLowerLetter[]
static void lcl_formatKoreanLegalWord(sal_Int32 nNumber, OUString &rsResult)
const sal_Unicode table_Alphabet_th[]
const sal_Unicode table_CircledNumber[]
Definition: bullet.h:226
const sal_Unicode table_Chicago[]
const sal_Unicode table_CyrillicUpperLetter_bg[]
static Any getPropertyByName(const Sequence< beans::PropertyValue > &aProperties, const char *name)
index
ARABIC
QPRO_FUNC_TYPE nType
Supported_NumberingType(sal_Int16 nType_, const char *pSymbol, sal_Int16 opt)
unsigned char sal_uInt8
unsigned char sal_Bool
sal_uInt16 sal_Unicode
Any result
std::unique_ptr< char[]> aBuffer