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 
21 #include <transliterationImpl.hxx>
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>
31 #include <nativenumbersupplier.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 "\xDB\xB1"
67 #define S_HI_TWO "\xDB\xB2"
68 #define S_HI_THREE "\xDB\xB3"
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 
81 using namespace com::sun::star;
82 using namespace com::sun::star::uno;
83 using namespace ::com::sun::star::i18n;
84 using namespace com::sun::star::lang;
85 
86 namespace 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 
204  0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x03DB, 0x0396, 0x0397, 0x0398,
205  0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03DF,
206  0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03E0
207 };
208 
210  0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03DB, 0x03B6, 0x03B7, 0x03B8,
211  0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03DF,
212  0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03E1
213 };
214 
216  0x0622, 0x0628, 0x067E, 0x062A, 0x062B, 0x062C, 0x0686, 0x062D,
217  0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0698, 0x0633, 0x0634,
218  0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x0640, 0x0641, 0x0642,
219  0x06A9, 0x06AF, 0x0644, 0x0645, 0x0646, 0x0648, 0x0647, 0x06CC
220 };
221 
223  0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
224  0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
225  0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A
226 };
227 
229  0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
230  0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
231  0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
232 };
233 
235  0x002a, 0x2020, 0x2021, 0x00a7
236 };
237 
238 // Tables used for numbering in persian words
240  {0}, // 0
241  {0x06cc, 0x06a9, 0}, // 1
242  {0x062f, 0x0648, 0}, // 2
243  {0x0633, 0x0647, 0}, // 3
244  {0x0686, 0x0647, 0x0627, 0x0631, 0}, // 4
245  {0x067e, 0x0646, 0x062c, 0}, // 5
246  {0x0634, 0x0634, 0}, // 6
247  {0x0647, 0x0641, 0x062a, 0}, // 7
248  {0x0647, 0x0634, 0x062a, 0}, // 8
249  {0x0646, 0x0647, 0}, // 9
250  {0x062f, 0x0647, 0}, // 10
251  {0x06cc, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 11
252  {0x062f, 0x0648, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 12
253  {0x0633, 0x06cc, 0x0632, 0x062f, 0x0647, 0}, // 13
254  {0x0686, 0x0647, 0x0627, 0x0631, 0x062f, 0x0647, 0}, // 14
255  {0x067e, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 15
256  {0x0634, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 16
257  {0x0647, 0x0641, 0x062f, 0x0647, 0}, // 17
258  {0x0647, 0x062c, 0x062f, 0x0647, 0}, // 18
259  {0x0646, 0x0648, 0x0632, 0x062f, 0x0647, 0} // 19
260 };
261 
263  {0x0628, 0x06cc, 0x0633, 0x062a, 0}, // 20
264  {0x0633, 0x06cc, 0}, // 30
265  {0x0686, 0x0647, 0x0644, 0}, // 40
266  {0x067e, 0x0646, 0x062c, 0x0627, 0x0647, 0}, // 50
267  {0x0634, 0x0635, 0x062a, 0}, // 60
268  {0x0647, 0x0641, 0x062a, 0x0627, 0x062f, 0}, // 70
269  {0x0647, 0x0634, 0x062a, 0x0627, 0x062f, 0}, // 80
270  {0x0646, 0x0648, 0x062f, 0} // 90
271 };
272 
274  {0x0635, 0x062f, 0}, // 100
275  {0x062f, 0x0648, 0x06cc, 0x0633, 0x062a, 0}, // 200
276  {0x0633, 0x06cc, 0x0635, 0x062f, 0}, // 300
277  {0x0686, 0x0647, 0x0627, 0x0631, 0x0635, 0x062f, 0}, // 400
278  {0x067e, 0x0627, 0x0646, 0x0635, 0x062f, 0}, // 500
279  {0x0634, 0x0635, 0x062f, 0}, // 600
280  {0x0647, 0x0641, 0x062a, 0x0635, 0x062f, 0}, // 700
281  {0x0647, 0x0634, 0x062a, 0x0635, 0x062f, 0}, // 800
282  {0x0646, 0x0647, 0x0635, 0x062f, 0} // 900
283 };
284 
286  {0x0647, 0x0632, 0x0627, 0x0631, 0}, // 1000
287  {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0648, 0x0646, 0}, // 1000000
288  {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0627, 0x0631, 0x062f, 0} // 1000000000
289 };
290 
292  {0xd558, 0xb098, 0}, // 1
293  {0xb458, 0}, // 2
294  {0xc14b, 0}, // 3
295  {0xb137, 0}, // 4
296  {0xb2e4, 0xc12f, 0}, // 5
297  {0xc5ec, 0xc12f, 0}, // 6
298  {0xc77c, 0xacf1, 0}, // 7
299  {0xc5ec, 0xb35f, 0}, // 8
300  {0xc544, 0xd649, 0} // 9
301 };
302 
304  {0xc5f4, 0}, // 10
305  {0xc2a4, 0xbb3c, 0}, // 20
306  {0xc11c, 0xb978, 0}, // 30
307  {0xb9c8, 0xd754, 0}, // 40
308  {0xc270, 0}, // 50
309  {0xc608, 0xc21c, 0}, // 60
310  {0xc77c, 0xd754, 0}, // 70
311  {0xc5ec, 0xb4e0, 0}, // 80
312  {0xc544, 0xd754, 0} // 90
313 };
314 
315 DefaultNumberingProvider::DefaultNumberingProvider( const Reference < XComponentContext >& rxContext ) : m_xContext(rxContext)
316 {
317 
318 }
319 
321 {
322 }
323 
326 {
327  return LocaleDataImpl::get()->getOutlineNumberingLevels( rLocale );
328 }
329 
332 {
333  return LocaleDataImpl::get()->getContinuousNumberingLevels( rLocale );
334 }
335 
336 static OUString toRoman( sal_Int32 n )
337 {
338 
339 // i, ii, iii, iv, v, vi, vii, vii, viii, ix
340 // (Dummy),1000,500,100,50,10,5,1
341  static const char coRomanArr[] = "MDCLXVI--"; // +2 Dummy entries !!
342  const char* cRomanStr = coRomanArr;
343  sal_uInt16 nMask = 1000;
344  sal_uInt32 nOver1000 = n / nMask;
345  n -= ( nOver1000 * nMask );
346 
347  OUStringBuffer sTmp;
348  while(nOver1000--)
349  sTmp.append(*coRomanArr);
350 
351  while( nMask )
352  {
353  sal_uInt8 nNumber = sal_uInt8( n / nMask );
354  sal_uInt8 nDiff = 1;
355  n %= nMask;
356 
357  if( 5 < nNumber )
358  {
359  if( nNumber < 9 )
360  sTmp.append(*(cRomanStr-1));
361  ++nDiff;
362  nNumber -= 5;
363  }
364  switch( nNumber )
365  {
366  case 3: sTmp.append(*cRomanStr); [[fallthrough]];
367  case 2: sTmp.append(*cRomanStr); [[fallthrough]];
368  case 1: sTmp.append(*cRomanStr); break;
369  case 4: sTmp.append(*cRomanStr).append(*(cRomanStr-nDiff)); break;
370  case 5: sTmp.append(*(cRomanStr-nDiff)); break;
371  }
372 
373  nMask /= 10; // to the next decade
374  cRomanStr += 2;
375  }
376  return sTmp.makeStringAndClear();
377 }
378 
379 // not used:
380 
381 static
382 void lcl_formatChars( const sal_Unicode table[], int tableSize, int n, OUString& s )
383 {
384  // string representation of n is appended to s.
385  // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>AB, ...
386  // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>ab, ...
387 
388  if( n>=tableSize ) lcl_formatChars( table, tableSize, (n-tableSize)/tableSize, s );
389 
390  s += OUStringChar( table[ n % tableSize ] );
391 }
392 
393 static
394 void lcl_formatChars1( const sal_Unicode table[], int tableSize, int n, OUString& s )
395 {
396  // string representation of n is appended to s.
397  // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>BB, ...
398  // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>bb, ...
399 
400  int repeat_count = n / tableSize + 1;
401 
402  for( int i=0; i<repeat_count; i++ )
403  s += OUStringChar( table[ n%tableSize ] );
404 }
405 
406 static
407 void lcl_formatChars2( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
408 {
409  // string representation of n is appended to s.
410  // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Ab, ...
411 
412  if( n>=tableSize )
413  {
414  lcl_formatChars2( table_capital, table_small, tableSize, (n-tableSize)/tableSize, s );
415  s += OUStringChar( table_small[ n % tableSize ] );
416  } else
417  s += OUStringChar( table_capital[ n % tableSize ] );
418 }
419 
420 static
421 void lcl_formatChars3( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
422 {
423  // string representation of n is appended to s.
424  // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Bb, ...
425 
426  int repeat_count = n / tableSize + 1;
427  s += OUStringChar( table_capital[ n%tableSize ] );
428 
429  for( int i=1; i<repeat_count; i++ )
430  s += OUStringChar( table_small[ n%tableSize ] );
431 }
432 
433 
441 static
442 void lcl_formatPersianWord( sal_Int32 nNumber, OUString& rsResult )
443 {
444  OUStringBuffer aTemp(64);
445  static constexpr OUStringLiteral asPersianWord_conjunction_data = u" \u0648 ";
446  OUString asPersianWord_conjunction( asPersianWord_conjunction_data );
447  unsigned char nSection = 0;
448 
449  while (int nPart = nNumber % 1000)
450  {
451  if (nSection)
452  {
453  if (nSection > SAL_N_ELEMENTS( table_PersianWord_decadeX))
454  throw IllegalArgumentException(); // does not happen with sal_Int32
455  aTemp.insert( 0, asPersianWord_conjunction).insert( 0, table_PersianWord_decadeX[nSection-1]);
456  }
457 
458  unsigned int nDigit;
459  if ((nDigit = nPart % 100) < 20)
460  {
461  if (!aTemp.isEmpty())
462  aTemp.insert( 0, u' ');
463  aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
464  }
465  else
466  {
467  if ((nDigit = nPart % 10) != 0)
468  {
469  if (!aTemp.isEmpty())
470  aTemp.insert( 0, asPersianWord_conjunction);
471  aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
472  }
473  if ((nDigit = (nPart / 10) % 10) != 0)
474  {
475  if (!aTemp.isEmpty())
476  aTemp.insert( 0, asPersianWord_conjunction);
477  aTemp.insert( 0, table_PersianWord_decade2[nDigit-2]);
478  }
479  }
480 
481  if ((nDigit = nPart / 100) != 0)
482  {
483  if (!aTemp.isEmpty())
484  aTemp.insert( 0, asPersianWord_conjunction);
485  aTemp.insert( 0, table_PersianWord_decade3[nDigit-1]);
486  }
487 
488  nNumber /= 1000;
489  nSection++;
490  }
491  rsResult += aTemp;
492 }
493 
494 static void lcl_formatKoreanLegalWord(sal_Int32 nNumber, OUString& rsResult) {
495  OUStringBuffer aTemp(64);
496  int digit1 = nNumber % 10;
497  int digit2 = nNumber / 10;
498  if (digit1 > 0)
499  aTemp.insert(0, (table_KoreanLegalWord_decade1[digit1 - 1]));
500  if (digit2 > 0)
501  aTemp.insert(0, (table_KoreanLegalWord_decade2[digit2 - 1]));
502  rsResult += aTemp.makeStringAndClear();
503 }
504 
505 // Greek Letter Numbering
506 
507 // KERAIA separates numerals from other text
508 #define STIGMA u'\x03DB'
509 #define LEFT_KERAIA u'\x0375'
510 #define MYRIAD_SYM u'\x039C'
511 #define DOT_SYM u'.'
512 #define SIGMA_OFFSET 19
513 #define TAU_OFFSET 20
514 #define MYRIAD 10000
515 
516 /*
517 * Return the 1-999999 number's representation in the Greek numbering system.
518 * Adding a "left keraia" to represent numbers in the range 10000 ... 999999 is
519 * not orthodox, so it's better to use the myriad notation and call this method
520 * only for numbers up to 9999.
521 */
522 static
523 OUString gr_smallNum(const sal_Unicode table[], int n)
524 {
525  if (n > 9999)
526  throw IllegalArgumentException();
527 
528  int i = 0;
529  OUStringBuffer sb;
530  for (int v = n; v > 0; v /= 10, i++) {
531  int digit = v % 10;
532  if (digit == 0)
533  continue;
534 
535  sal_Unicode sign = table[(digit - 1) + 9 * (i % 3)];
536  if (sign == STIGMA) {
537  sb.insert(0, table[TAU_OFFSET]);
538  sb.insert(0, table[SIGMA_OFFSET]);
539  } else {
540  sb.insert(0, sign);
541  }
542 
543  if (i > 2)
544  sb.insert(0, LEFT_KERAIA);
545  }
546 
547  return sb.makeStringAndClear();
548 }
549 
550 static
551 void lcl_formatCharsGR(const sal_Unicode table[], int n, OUString& s )
552 {
553  OUStringBuffer sb;
554  int myriadPower = 2;
555 
556  for (int divisor = MYRIAD * MYRIAD; divisor > 1; divisor /= MYRIAD, myriadPower--) {
557  if (n > divisor - 1) {
558  /*
559  * Follow the Diophantus representation of:
560  * A myriad sign, M(10000) as many times as the power
561  * followed by the multiplier for the myriad
562  * followed by a dot
563  * followed by the rest
564  * This is enough for 32-bit integers
565  */
566  for (int i = 0; i < myriadPower; i++)
567  sb.append(MYRIAD_SYM);
568 
569  sb.append(gr_smallNum(table, n/divisor));
570  n %= divisor;
571 
572  if (n > 0)
573  sb.append(DOT_SYM);
574  }
575  }
576  sb.append(gr_smallNum(table,n));
577 
578  s += sb;
579 }
580 
581 static
582 bool should_ignore( std::u16string_view s )
583 {
584  // return true if blank or null
585  return s == u" " || (!s.empty() && s[0]==0);
586 }
587 
592 static OUString lcl_formatArabicZero(sal_Int32 nNumber, sal_Int32 nLimit)
593 {
594  OUString aRet = OUString::number(nNumber);
595  sal_Int32 nDiff = nLimit - aRet.getLength();
596 
597  if (nDiff <= 0)
598  {
599  return aRet;
600  }
601 
602  OUStringBuffer aBuffer;
603  aBuffer.setLength(nDiff);
604  for (sal_Int32 i = 0; i < nDiff; ++i)
605  {
606  aBuffer[i] = '0';
607  }
608  aBuffer.append(aRet);
609  return aBuffer.makeStringAndClear();
610 }
611 
612 static
614  const char* name )
615 {
616  auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
617  [&name](const beans::PropertyValue& rProp) { return rProp.Name.equalsAscii(name); });
618  if (pProp != aProperties.end())
619  return pProp->Value;
620  throw IllegalArgumentException();
621 }
622 
623 //XNumberingFormatter
624 OUString
626  const Locale& aLocale )
627 {
628  // the Sequence of PropertyValues is expected to have at least 4 elements:
629  // elt Name Type purpose
630 
631 
632  // 0. "Prefix" OUString
633  // 1. "NumberingType" sal_Int16 type of formatting from style::NumberingType (roman, arabic, etc)
634  // 2. "Suffix" OUString
635  // ... ... ...
636  // n. "Value" sal_Int32 the number to be formatted
637  // example:
638  // given the Sequence { '(', NumberingType::ROMAN_UPPER, ')', ..., 7 }
639  // makeNumberingString() returns the string "(VII)".
640 
641  // Q: why is the type of numType sal_Int16 instead of style::NumberingType?
642  // A: an Any can't hold a style::NumberingType for some reason.
643  // add.: style::NumberingType holds constants of type sal_Int16, it's not an enum type
644 
645  sal_Int16 natNum = 0;
646  sal_Int16 tableSize = 0;
647  const sal_Unicode *table = nullptr; // initialize to avoid compiler warning
648  bool bRecycleSymbol = false;
649  OUString sNatNumParams;
650  Locale locale;
651 
652  OUString prefix;
653  sal_Int16 numType = -1; // type of formatting from style::NumberingType (roman, arabic, etc)
654  OUString suffix;
655  sal_Int32 number = -1; // the number that needs to be formatted.
656 
657 // int nProperties = aProperties.getLength();
658 // int last = nProperties-1;
659 
660  for (auto const & prop : aProperties)
661  {
662  if (prop.Name == "Prefix")
663  prop.Value >>= prefix;
664  else if (prop.Name == "Suffix")
665  prop.Value >>= suffix;
666  else if (prop.Name == "NumberingType")
667  prop.Value >>= numType;
668  else if (prop.Name == "Value")
669  prop.Value >>= number;
670  }
671 
672  if( number <= 0 )
673  throw IllegalArgumentException();
674 
675  // start empty
676  OUString result;
677 
678  // append prefix
679  if( !should_ignore(prefix) ) result += prefix;
680 
681  // append formatted number
682  using namespace style::NumberingType;
683  switch( numType )
684  {
685  case CHARS_UPPER_LETTER:
686  lcl_formatChars( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>AB, ...
687  break;
688  case CHARS_LOWER_LETTER:
689  lcl_formatChars( lowerLetter, 26, number-1, result );
690  break;
691  case TEXT_NUMBER: // ordinal indicators (1st, 2nd, 3rd, ...)
692  natNum = NativeNumberMode::NATNUM12;
693  sNatNumParams = "capitalize ordinal-number";
694  locale = aLocale;
695  break;
696  case TEXT_CARDINAL: // cardinal number names (One, Two, Three, ...)
697  natNum = NativeNumberMode::NATNUM12;
698  sNatNumParams = "capitalize";
699  locale = aLocale;
700  break;
701  case TEXT_ORDINAL: // ordinal number names (First, Second, Third, ...)
702  natNum = NativeNumberMode::NATNUM12;
703  sNatNumParams = "capitalize ordinal";
704  locale = aLocale;
705  break;
706  case ROMAN_UPPER:
707  result += toRoman( number );
708  break;
709  case ROMAN_LOWER:
710  result += toRoman( number ).toAsciiLowerCase();
711  break;
712  case ARABIC:
713  result += OUString::number( number );
714  break;
715  case NUMBER_NONE:
716  return OUString(); // ignore prefix and suffix
717  case CHAR_SPECIAL:
718  // apparently, we're supposed to return an empty string in this case...
719  return OUString(); // ignore prefix and suffix
720  case PAGE_DESCRIPTOR:
721  case BITMAP:
722  OSL_ASSERT(false);
723  throw IllegalArgumentException();
724  case CHARS_UPPER_LETTER_N:
725  lcl_formatChars1( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
726  break;
727  case CHARS_LOWER_LETTER_N:
728  lcl_formatChars1( lowerLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
729  break;
730  case TRANSLITERATION:
731  try {
732  const OUString &tmp = OUString::number( number );
733  OUString transliteration;
734  getPropertyByName(aProperties, "Transliteration") >>= transliteration;
735  if ( !translit )
737  translit->loadModuleByImplName(transliteration, aLocale);
738  result += translit->transliterateString2String(tmp, 0, tmp.getLength());
739  } catch (Exception& ) {
740  // When transliteration property is missing, return default number (bug #101141#)
741  result += OUString::number( number );
742  // OSL_ASSERT(0);
743  // throw IllegalArgumentException();
744  }
745  break;
746  case NATIVE_NUMBERING:
747  natNum = NativeNumberMode::NATNUM1;
748  locale = aLocale;
749  break;
750  case FULLWIDTH_ARABIC:
751  natNum = NativeNumberMode::NATNUM3;
752  locale = aLocale;
753  break;
754  case NUMBER_LOWER_ZH:
755  natNum = NativeNumberMode::NATNUM7;
756  locale.Language = "zh";
757  break;
758  case NUMBER_UPPER_ZH:
759  natNum = NativeNumberMode::NATNUM8;
760  locale.Language = "zh";
761  break;
762  case NUMBER_UPPER_ZH_TW:
763  natNum = NativeNumberMode::NATNUM8;
764  locale.Language = "zh";
765  locale.Country = "TW";
766  break;
767  case NUMBER_TRADITIONAL_JA:
768  natNum = NativeNumberMode::NATNUM8;
769  locale.Language = "ja";
770  break;
771  case NUMBER_UPPER_KO:
772  natNum = NativeNumberMode::NATNUM8;
773  locale.Language = "ko";
774  break;
775  case NUMBER_HANGUL_KO:
776  natNum = NativeNumberMode::NATNUM11;
777  locale.Language = "ko";
778  break;
779  case NUMBER_DIGITAL_KO:
780  natNum = NativeNumberMode::NATNUM9;
781  locale.Language = "ko";
782  break;
783  case NUMBER_DIGITAL2_KO:
784  natNum = NativeNumberMode::NATNUM1;
785  locale.Language = "ko";
786  break;
787  case NUMBER_LEGAL_KO:
788  if (number < 1 || number >= 100)
789  {
790  natNum = NativeNumberMode::NATNUM11;
791  locale.Language = "ko";
792  }
793  else
794  {
795  lcl_formatKoreanLegalWord(number, result);
796  }
797  break;
798 
799  case CIRCLE_NUMBER:
800  table = table_CircledNumber;
801  tableSize = SAL_N_ELEMENTS(table_CircledNumber);
802  break;
803  case TIAN_GAN_ZH:
804  table = table_TianGan_zh;
805  tableSize = SAL_N_ELEMENTS(table_TianGan_zh);
806  break;
807  case DI_ZI_ZH:
808  table = table_DiZi_zh;
809  tableSize = SAL_N_ELEMENTS(table_DiZi_zh);
810  break;
811  case AIU_FULLWIDTH_JA:
812  table = table_AIUFullWidth_ja_JP;
814  bRecycleSymbol = true;
815  break;
816  case AIU_HALFWIDTH_JA:
817  table = table_AIUHalfWidth_ja_JP;
819  bRecycleSymbol = true;
820  break;
821  case IROHA_FULLWIDTH_JA:
824  bRecycleSymbol = true;
825  break;
826  case IROHA_HALFWIDTH_JA:
829  bRecycleSymbol = true;
830  break;
831  case HANGUL_JAMO_KO:
832  table = table_HangulJamo_ko;
833  tableSize = SAL_N_ELEMENTS(table_HangulJamo_ko);
834  bRecycleSymbol = true;
835  break;
836  case HANGUL_SYLLABLE_KO:
837  table = table_HangulSyllable_ko;
839  bRecycleSymbol = true;
840  break;
841  case HANGUL_CIRCLED_JAMO_KO:
844  bRecycleSymbol = true;
845  break;
846  case HANGUL_CIRCLED_SYLLABLE_KO:
849  bRecycleSymbol = true;
850  break;
851  case CHARS_ARABIC:
852  lcl_formatChars(table_Alphabet_ar, SAL_N_ELEMENTS(table_Alphabet_ar), number - 1, result);
853  break;
854  case CHARS_ARABIC_ABJAD:
855  lcl_formatChars(table_Alphabet_ar_abjad, SAL_N_ELEMENTS(table_Alphabet_ar_abjad), number - 1, result);
856  break;
857  case NUMBER_ARABIC_INDIC:
858  natNum = NativeNumberMode::NATNUM1;
859  locale.Language = "ar";
860  break;
861  case NUMBER_EAST_ARABIC_INDIC:
862  natNum = NativeNumberMode::NATNUM1;
863  locale.Language = "fa";
864  break;
865  case NUMBER_INDIC_DEVANAGARI:
866  natNum = NativeNumberMode::NATNUM1;
867  locale.Language = "hi";
868  break;
869  case CHARS_THAI:
870  lcl_formatChars(table_Alphabet_th, SAL_N_ELEMENTS(table_Alphabet_th), number - 1, result);
871  break;
872  case CHARS_HEBREW:
873  lcl_formatChars(table_Alphabet_he, SAL_N_ELEMENTS(table_Alphabet_he), number - 1, result);
874  break;
875  case NUMBER_HEBREW:
876  natNum = NativeNumberMode::NATNUM1;
877  locale.Language = "he";
878  break;
879  case CHARS_NEPALI:
880  lcl_formatChars(table_Alphabet_ne, SAL_N_ELEMENTS(table_Alphabet_ne), number - 1, result);
881  break;
882  case CHARS_KHMER:
883  lcl_formatChars(table_Alphabet_km, SAL_N_ELEMENTS(table_Alphabet_km), number - 1, result);
884  break;
885  case CHARS_LAO:
886  lcl_formatChars(table_Alphabet_lo, SAL_N_ELEMENTS(table_Alphabet_lo), number - 1, result);
887  break;
888  case CHARS_MYANMAR:
889  lcl_formatChars(table_Alphabet_my, SAL_N_ELEMENTS(table_Alphabet_my), number - 1, result);
890  break;
891  case CHARS_TIBETAN:
892  lcl_formatChars(table_Alphabet_dz, SAL_N_ELEMENTS(table_Alphabet_dz), number - 1, result);
893  break;
894  case CHARS_CYRILLIC_UPPER_LETTER_BG:
895  lcl_formatChars2( table_CyrillicUpperLetter_bg,
896  table_CyrillicLowerLetter_bg,
897  SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
898  result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Ab, ...
899  break;
900  case CHARS_CYRILLIC_LOWER_LETTER_BG:
901  lcl_formatChars( table_CyrillicLowerLetter_bg,
902  SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
903  result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>ab, ...
904  break;
905  case CHARS_CYRILLIC_UPPER_LETTER_N_BG:
906  lcl_formatChars3( table_CyrillicUpperLetter_bg,
907  table_CyrillicLowerLetter_bg,
908  SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
909  result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Bb, ...
910  break;
911  case CHARS_CYRILLIC_LOWER_LETTER_N_BG:
912  lcl_formatChars1( table_CyrillicLowerLetter_bg,
913  SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
914  result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>bb, ...
915  break;
916  case CHARS_CYRILLIC_UPPER_LETTER_RU:
917  lcl_formatChars2( table_CyrillicUpperLetter_ru,
918  table_CyrillicLowerLetter_ru,
919  SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
920  result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
921  break;
922  case CHARS_CYRILLIC_LOWER_LETTER_RU:
923  lcl_formatChars( table_CyrillicLowerLetter_ru,
924  SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
925  result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
926  break;
927  case CHARS_CYRILLIC_UPPER_LETTER_N_RU:
928  lcl_formatChars3( table_CyrillicUpperLetter_ru,
929  table_CyrillicLowerLetter_ru,
930  SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
931  result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
932  break;
933  case CHARS_CYRILLIC_LOWER_LETTER_N_RU:
934  lcl_formatChars1( table_CyrillicLowerLetter_ru,
935  SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
936  result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
937  break;
938  case CHARS_CYRILLIC_UPPER_LETTER_SR:
939  lcl_formatChars2( table_CyrillicUpperLetter_sr,
940  table_CyrillicLowerLetter_sr,
941  SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
942  result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
943  break;
944  case CHARS_CYRILLIC_LOWER_LETTER_SR:
945  lcl_formatChars( table_CyrillicLowerLetter_sr,
946  SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
947  result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
948  break;
949  case CHARS_CYRILLIC_UPPER_LETTER_N_SR:
950  lcl_formatChars3( table_CyrillicUpperLetter_sr,
951  table_CyrillicLowerLetter_sr,
952  SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
953  result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
954  break;
955  case CHARS_CYRILLIC_LOWER_LETTER_N_SR:
956  lcl_formatChars1( table_CyrillicLowerLetter_sr,
957  SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
958  result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
959  break;
960 
961  case CHARS_GREEK_LOWER_LETTER:
962  lcl_formatCharsGR( table_GreekLowerLetter, number, result);
963  break;
964 
965  case CHARS_GREEK_UPPER_LETTER:
966  lcl_formatCharsGR( table_GreekUpperLetter, number, result);
967  break;
968 
969  case CHARS_PERSIAN:
970  lcl_formatChars(table_Alphabet_fa, SAL_N_ELEMENTS(table_Alphabet_fa), number - 1, result);
971  break;
972 
973  case CHARS_PERSIAN_WORD:
974  lcl_formatPersianWord(number, result);
975  break;
976 
977  case SYMBOL_CHICAGO:
978  lcl_formatChars1( table_Chicago, 4, number-1, result ); // *, +, |, S, **, ++, ...
979  break;
980 
981  case ARABIC_ZERO:
982  result += lcl_formatArabicZero(number, 2);
983  break;
984 
985  case ARABIC_ZERO3:
986  result += lcl_formatArabicZero(number, 3);
987  break;
988 
989  case ARABIC_ZERO4:
990  result += lcl_formatArabicZero(number, 4);
991  break;
992 
993  case ARABIC_ZERO5:
994  result += lcl_formatArabicZero(number, 5);
995  break;
996 
997  case SZEKELY_ROVAS: // Old Hungarian
998  natNum = NativeNumberMode::NATNUM12;
999  locale.Language = "hu-Hung";
1000  break;
1001 
1002  default:
1003  OSL_ASSERT(false);
1004  throw IllegalArgumentException();
1005  }
1006 
1007  if (natNum) {
1008  if (!mxNatNum)
1010  result += mxNatNum->getNativeNumberStringParams(OUString::number(number), locale,
1011  natNum, sNatNumParams);
1012  } else if (tableSize) {
1013  if ( number > tableSize && !bRecycleSymbol)
1014  result += OUString::number( number);
1015  else
1016  result += OUStringChar(table[--number % tableSize]);
1017  }
1018 
1019  // append suffix
1020  if( !should_ignore(suffix) ) result += suffix;
1021 
1022  return result;
1023 }
1024 
1025 #define LANG_ALL (1 << 0)
1026 #define LANG_CJK (1 << 1)
1027 #define LANG_CTL (1 << 2)
1028 
1030 {
1031  const char* cSymbol;
1032  sal_Int16 nType;
1033  sal_Int16 langOption;
1034  Supported_NumberingType(sal_Int16 nType_, const char* pSymbol, sal_Int16 opt)
1035  : cSymbol(pSymbol), nType(nType_), langOption(opt) {}
1036 };
1038 {
1039  {style::NumberingType::CHARS_UPPER_LETTER, "A", LANG_ALL},
1040  {style::NumberingType::CHARS_LOWER_LETTER, "a", LANG_ALL},
1041  {style::NumberingType::ROMAN_UPPER, "I", LANG_ALL},
1042  {style::NumberingType::ROMAN_LOWER, "i", LANG_ALL},
1043  {style::NumberingType::ARABIC, "1", LANG_ALL},
1044  {style::NumberingType::NUMBER_NONE, "''", LANG_ALL},
1045  {style::NumberingType::CHAR_SPECIAL, "Bullet", LANG_ALL},
1046  {style::NumberingType::PAGE_DESCRIPTOR, "Page", LANG_ALL},
1047  {style::NumberingType::BITMAP, "Bitmap", LANG_ALL},
1048  {style::NumberingType::SYMBOL_CHICAGO, "*, " S_DAGGER ", " S_DBL_DAGGER ", " S_SECTION ", **, " S_DAGGER S_DAGGER ", ...", LANG_ALL},
1049  {style::NumberingType::TEXT_NUMBER, "1st", LANG_ALL},
1050  {style::NumberingType::TEXT_CARDINAL, "One", LANG_ALL},
1051  {style::NumberingType::TEXT_ORDINAL, "First", LANG_ALL},
1052  {style::NumberingType::CHARS_UPPER_LETTER_N, "AAA", LANG_ALL},
1053  {style::NumberingType::CHARS_LOWER_LETTER_N, "aaa", LANG_ALL},
1054  {style::NumberingType::NATIVE_NUMBERING, "Native Numbering", LANG_CJK|LANG_CTL},
1055  {style::NumberingType::FULLWIDTH_ARABIC, nullptr, LANG_CJK},
1056  {style::NumberingType::CIRCLE_NUMBER, nullptr, LANG_CJK},
1057  {style::NumberingType::NUMBER_LOWER_ZH, nullptr, LANG_CJK},
1058  {style::NumberingType::NUMBER_UPPER_ZH, nullptr, LANG_CJK},
1059  {style::NumberingType::NUMBER_UPPER_ZH_TW, nullptr, LANG_CJK},
1060  {style::NumberingType::TIAN_GAN_ZH, nullptr, LANG_CJK},
1061  {style::NumberingType::DI_ZI_ZH, nullptr, LANG_CJK},
1062  {style::NumberingType::NUMBER_TRADITIONAL_JA, nullptr, LANG_CJK},
1063  {style::NumberingType::AIU_FULLWIDTH_JA, nullptr, LANG_CJK},
1064  {style::NumberingType::AIU_HALFWIDTH_JA, nullptr, LANG_CJK},
1065  {style::NumberingType::IROHA_FULLWIDTH_JA, nullptr, LANG_CJK},
1066  {style::NumberingType::IROHA_HALFWIDTH_JA, nullptr, LANG_CJK},
1067  {style::NumberingType::NUMBER_UPPER_KO, nullptr, LANG_CJK},
1068  {style::NumberingType::NUMBER_HANGUL_KO, nullptr, LANG_CJK},
1069  {style::NumberingType::HANGUL_JAMO_KO, nullptr, LANG_CJK},
1070  {style::NumberingType::HANGUL_SYLLABLE_KO, nullptr, LANG_CJK},
1071  {style::NumberingType::HANGUL_CIRCLED_JAMO_KO, nullptr, LANG_CJK},
1072  {style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO, nullptr, LANG_CJK},
1073  {style::NumberingType::NUMBER_LEGAL_KO, nullptr, LANG_CJK},
1074  {style::NumberingType::NUMBER_DIGITAL_KO, nullptr, LANG_CJK},
1075  {style::NumberingType::NUMBER_DIGITAL2_KO, nullptr, LANG_CJK},
1076  {style::NumberingType::CHARS_ARABIC, nullptr, LANG_CTL},
1077  {style::NumberingType::CHARS_ARABIC_ABJAD, nullptr, LANG_CTL},
1078  {style::NumberingType::NUMBER_ARABIC_INDIC, S_AR_ONE ", " S_AR_TWO ", " S_AR_THREE ", ...", LANG_CTL},
1079  {style::NumberingType::NUMBER_EAST_ARABIC_INDIC, S_FA_ONE ", " S_FA_TWO ", " S_FA_THREE ", ...", LANG_CTL},
1080  {style::NumberingType::NUMBER_INDIC_DEVANAGARI, S_HI_ONE ", " S_HI_TWO ", " S_HI_THREE ", ...", LANG_CTL},
1081  {style::NumberingType::CHARS_THAI, nullptr, LANG_CTL},
1082  {style::NumberingType::CHARS_HEBREW, nullptr, LANG_CTL},
1083  {style::NumberingType::NUMBER_HEBREW, S_HE_ALEPH ", " S_HE_YOD ", " S_HE_QOF ", ...", LANG_CTL},
1084  {style::NumberingType::CHARS_NEPALI, nullptr, LANG_CTL},
1085  {style::NumberingType::CHARS_KHMER, nullptr, LANG_CTL},
1086  {style::NumberingType::CHARS_LAO, nullptr, LANG_CTL},
1087  {style::NumberingType::CHARS_MYANMAR, nullptr, LANG_CTL},
1088  {style::NumberingType::CHARS_TIBETAN, nullptr, LANG_CTL},
1089  {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},
1090  {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},
1091  {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},
1092  {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},
1093  {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},
1094  {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},
1095  {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},
1096  {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},
1097  {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},
1098  {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},
1099  {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},
1100  {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},
1101  {style::NumberingType::CHARS_PERSIAN, nullptr, LANG_CTL},
1102  {style::NumberingType::CHARS_PERSIAN_WORD, nullptr, LANG_CTL},
1103  {style::NumberingType::SZEKELY_ROVAS, nullptr, LANG_CTL},
1104  {style::NumberingType::CHARS_GREEK_UPPER_LETTER, C_GR_A ", " C_GR_B ", ... (gr)", LANG_ALL},
1105  {style::NumberingType::CHARS_GREEK_LOWER_LETTER, S_GR_A ", " S_GR_B ", ... (gr)", LANG_ALL},
1106  {style::NumberingType::ARABIC_ZERO, "01, 02, 03, ...", LANG_ALL},
1107  {style::NumberingType::ARABIC_ZERO3, "001, 002, 003, ...", LANG_ALL},
1108  {style::NumberingType::ARABIC_ZERO4, "0001, 0002, 0003, ...", LANG_ALL},
1109  {style::NumberingType::ARABIC_ZERO5, "00001, 00002, 00003, ...", LANG_ALL},
1110 };
1111 const sal_Int32 nSupported_NumberingTypes = SAL_N_ELEMENTS(aSupportedTypes);
1112 
1114 {
1115  if (index < 0 || index >= nSupported_NumberingTypes)
1116  throw RuntimeException();
1117 
1118  if (aSupportedTypes[index].cSymbol)
1119  return OUString(aSupportedTypes[index].cSymbol, strlen(aSupportedTypes[index].cSymbol), RTL_TEXTENCODING_UTF8);
1120  else {
1121  OUStringBuffer result;
1122  Locale aLocale("en", OUString(), OUString());
1124  auto aPropertiesRange = asNonConstRange(aProperties);
1125  aPropertiesRange[0].Name = "NumberingType";
1126  aPropertiesRange[0].Value <<= aSupportedTypes[index].nType;
1127  aPropertiesRange[1].Name = "Value";
1128  for (sal_Int32 j = 1; j <= 3; j++) {
1129  aPropertiesRange[1].Value <<= j;
1130  result.append( makeNumberingString( aProperties, aLocale ) );
1131  result.append(", ");
1132  }
1133  result.append("...");
1134  // Make known duplicate generated identifiers unique.
1135  // Note this alone works only for newly added numberings, if duplicates
1136  // are in the wild further handling is needed when loading documents
1137  // and asking for numberings.
1138  switch (aSupportedTypes[index].nType)
1139  {
1140  case css::style::NumberingType::NUMBER_DIGITAL_KO:
1141  // Duplicate of NUMBER_HANGUL_KO.
1142  result.append(" (ko-x-digital)");
1143  break;
1144  case css::style::NumberingType::NUMBER_DIGITAL2_KO:
1145  // Duplicate of NUMBER_LOWER_ZH.
1146  result.append(" (ko)");
1147  break;
1148  default:
1149  ; // nothing
1150  }
1151  return result.makeStringAndClear();
1152  }
1153 }
1154 
1155 bool
1157 {
1158  if (! xHierarchicalNameAccess.is()) {
1159  Reference< XMultiServiceFactory > xConfigProvider =
1160  configuration::theDefaultProvider::get(m_xContext);
1161 
1162  if (! xConfigProvider.is())
1163  throw RuntimeException();
1164 
1165  uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1166  {
1167  {"nodepath", uno::Any(OUString("/org.openoffice.Office.Common/I18N"))}
1168  }));
1169 
1170  Reference<XInterface> xInterface = xConfigProvider->createInstanceWithArguments(
1171  "com.sun.star.configuration.ConfigurationAccess", aArgs);
1172 
1173  xHierarchicalNameAccess.set(xInterface, UNO_QUERY_THROW);
1174  }
1175 
1176  Any aEnabled = xHierarchicalNameAccess->getByHierarchicalName(aName);
1177 
1178  bool enabled = false;
1179 
1180  aEnabled >>= enabled;
1181 
1182  return enabled;
1183 }
1184 
1186 {
1187  Sequence< sal_Int16 > aRet(nSupported_NumberingTypes );
1188  sal_Int16* pArray = aRet.getArray();
1189 
1190  bool cjkEnabled = isScriptFlagEnabled("CJK/CJKFont");
1191  bool ctlEnabled = isScriptFlagEnabled("CTL/CTLFont");
1192 
1193  for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++) {
1194  if ( (aSupportedTypes[i].langOption & LANG_ALL) ||
1195  ((aSupportedTypes[i].langOption & LANG_CJK) && cjkEnabled) ||
1196  ((aSupportedTypes[i].langOption & LANG_CTL) && ctlEnabled) )
1197  pArray[i] = aSupportedTypes[i].nType;
1198  }
1199  return aRet;
1200 }
1201 
1202 sal_Int16 DefaultNumberingProvider::getNumberingType( const OUString& rNumberingIdentifier )
1203 {
1204  auto it = maSupportedTypesCache.find(rNumberingIdentifier);
1205  if (it != maSupportedTypesCache.end())
1206  return it->second->nType;
1207  for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1208  if(rNumberingIdentifier == makeNumberingIdentifier(i))
1209  {
1210  maSupportedTypesCache.emplace(rNumberingIdentifier, &aSupportedTypes[i]);
1211  return aSupportedTypes[i].nType;
1212  }
1213  throw RuntimeException();
1214 }
1215 
1216 sal_Bool DefaultNumberingProvider::hasNumberingType( const OUString& rNumberingIdentifier )
1217 {
1218  auto it = maSupportedTypesCache.find(rNumberingIdentifier);
1219  if (it != maSupportedTypesCache.end())
1220  return true;
1221  for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1222  if(rNumberingIdentifier == makeNumberingIdentifier(i))
1223  {
1224  maSupportedTypesCache.emplace(rNumberingIdentifier, &aSupportedTypes[i]);
1225  return true;
1226  }
1227  return false;
1228 }
1229 
1230 OUString DefaultNumberingProvider::getNumberingIdentifier( sal_Int16 nNumberingType )
1231 {
1232  for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1233  if(nNumberingType == aSupportedTypes[i].nType)
1234  return makeNumberingIdentifier(i);
1235  return OUString();
1236 }
1237 
1239 {
1240  return "com.sun.star.text.DefaultNumberingProvider";
1241 }
1242 
1244 {
1245  return cppu::supportsService(this, rServiceName);
1246 }
1247 
1249 {
1250  Sequence< OUString > aRet { "com.sun.star.text.DefaultNumberingProvider" };
1251  return aRet;
1252 }
1253 
1254 }
1255 
1256 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1258  css::uno::XComponentContext *context,
1259  css::uno::Sequence<css::uno::Any> const &)
1260 {
1261  return cppu::acquire(new i18npool::DefaultNumberingProvider(context));
1262 }
1263 
1264 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const sal_Unicode table_CyrillicLowerLetter_bg[]
const sal_Unicode table_Chicago[]
#define S_DBL_DAGGER
static bool should_ignore(std::u16string_view s)
#define S_HI_THREE
#define C_CYR_A
const sal_Unicode table_CircledNumber[]
Definition: bullet.h:222
static void lcl_formatChars3(const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString &s)
#define MYRIAD
ARABIC
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...
const sal_Unicode table_Alphabet_ne[]
#define S_AR_TWO
const sal_Unicode table_Alphabet_ar[]
const sal_Unicode table_AIUFullWidth_ja_JP[]
Definition: bullet.h:22
const sal_Unicode table_AIUHalfWidth_ja_JP[]
Definition: bullet.h:71
const sal_Unicode table_IROHAHalfWidth_ja_JP[]
Definition: bullet.h:171
virtual sal_Bool SAL_CALL hasNumberingType(const OUString &NumberingIdentifier) override
#define LANG_ALL
#define S_SECTION
#define C_CYR_B
exports com.sun.star. table
const sal_Unicode table_GreekLowerLetter[]
virtual OUString SAL_CALL makeNumberingString(const css::uno::Sequence< css::beans::PropertyValue > &aProperties, const css::lang::Locale &aLocale) override
const sal_Unicode table_KoreanLegalWord_decade2[][3]
const sal_Unicode table_HangulJamo_ko[]
Definition: bullet.h:245
sal_uInt16 sal_Unicode
css::uno::Reference< css::uno::XComponentContext > m_xContext
static Any getPropertyByName(const Sequence< beans::PropertyValue > &aProperties, const char *name)
PropertiesInfo aProperties
const sal_Unicode table_CyrillicLowerLetter_sr[]
#define SIGMA_OFFSET
#define LEFT_KERAIA
const sal_Unicode table_IROHAFullWidth_ja_JP[]
Definition: bullet.h:120
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
#define LANG_CJK
#define S_GR_B
const sal_Unicode table_Alphabet_he[]
virtual css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > SAL_CALL getDefaultContinuousNumberingLevels(const css::lang::Locale &aLocale) override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
rtl::Reference< TransliterationImpl > translit
const sal_Unicode table_PersianWord_decade1[][7]
static void lcl_formatPersianWord(sal_Int32 nNumber, OUString &rsResult)
Returns number's representation in persian words up to 999999999999 respectively limited by sal_Int32...
#define SAL_N_ELEMENTS(arr)
static void lcl_formatKoreanLegalWord(sal_Int32 nNumber, OUString &rsResult)
#define MYRIAD_SYM
static rtl::Reference< LocaleDataImpl > get()
Definition: localedata.hxx:78
const sal_Unicode table_Alphabet_lo[]
static void lcl_formatChars1(const sal_Unicode table[], int tableSize, int n, OUString &s)
#define S_FA_TWO
int i
bool isScriptFlagEnabled(const OUString &aName)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
const Supported_NumberingType aSupportedTypes[]
const sal_Unicode table_HangulCircledJamo_ko[]
Definition: bullet.h:280
const sal_Unicode table_HangulSyllable_ko[]
Definition: bullet.h:262
const sal_Unicode table_TianGan_zh[]
Definition: bullet.h:315
float u
unsigned char sal_Bool
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_text_DefaultNumberingProvider_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
const sal_Unicode table_PersianWord_decade2[][6]
static void lcl_formatChars2(const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString &s)
virtual sal_Int16 SAL_CALL getNumberingType(const OUString &NumberingIdentifier) override
#define S_FA_ONE
Constant values shared between i18npool and, for example, the number formatter.
#define S_HI_TWO
#define S_GR_A
const sal_Unicode table_CyrillicLowerLetter_ru[]
const sal_Unicode table_PersianWord_decade3[][7]
#define STIGMA
const sal_Unicode table_CyrillicUpperLetter_sr[]
const sal_Unicode table_Alphabet_my[]
const sal_Unicode table_HangulCircledSyllable_ko[]
Definition: bullet.h:298
#define S_CYR_B
#define DOT_SYM
float v
std::unique_ptr< char[]> aBuffer
virtual css::uno::Sequence< css::uno::Reference< css::container::XIndexAccess > > SAL_CALL getDefaultOutlineNumberings(const css::lang::Locale &aLocale) override
const sal_Unicode table_Alphabet_fa[]
#define S_CYR_A
const sal_Unicode table_Alphabet_km[]
css::uno::Reference< css::container::XHierarchicalNameAccess > xHierarchicalNameAccess
unsigned char sal_uInt8
#define LANG_CTL
#define S_HE_YOD
const sal_Unicode table_PersianWord_decadeX[][8]
QPRO_FUNC_TYPE nType
virtual OUString SAL_CALL getNumberingIdentifier(sal_Int16 NumberingType) override
#define S_HE_ALEPH
#define S_AR_ONE
#define S_DAGGER
const sal_Unicode table_Alphabet_th[]
const sal_Unicode upperLetter[]
rtl::Reference< NativeNumberSupplierService > mxNatNum
#define TAU_OFFSET
#define C_GR_A
virtual OUString SAL_CALL getImplementationName() override
const sal_Unicode table_Alphabet_ar_abjad[]
const sal_Int32 nSupported_NumberingTypes
Any result
#define S_HI_ONE
const sal_Unicode table_DiZi_zh[]
Definition: bullet.h:319
static OUString toRoman(sal_Int32 n)
Reference< XComponentContext > m_xContext
#define C_GR_B
#define S_FA_THREE
const sal_Unicode table_KoreanLegalWord_decade1[][3]
std::map< OUString, const Supported_NumberingType * > maSupportedTypesCache
#define S_HE_QOF
const sal_Unicode table_Alphabet_dz[]
static OUString gr_smallNum(const sal_Unicode table[], int n)
const sal_Unicode lowerLetter[]
const sal_Unicode table_CyrillicUpperLetter_bg[]
const sal_Unicode table_GreekUpperLetter[]
const sal_Unicode table_CyrillicUpperLetter_ru[]
Supported_NumberingType(sal_Int16 nType_, const char *pSymbol, sal_Int16 opt)
static void lcl_formatChars(const sal_Unicode table[], int tableSize, int n, OUString &s)
#define S_AR_THREE
static void lcl_formatCharsGR(const sal_Unicode table[], int n, OUString &s)
virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedNumberingTypes() override