LCOV - code coverage report
Current view: top level - i18npool/source/defaultnumberingprovider - defaultnumberingprovider.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 174 376 46.3 %
Date: 2015-06-13 12:38:46 Functions: 15 27 55.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      20             : #include <defaultnumberingprovider.hxx>
      21             : #include <com/sun/star/style/NumberingType.hpp>
      22             : #include <com/sun/star/beans/PropertyValue.hpp>
      23             : #include <com/sun/star/configuration/theDefaultProvider.hpp>
      24             : #include <com/sun/star/text/HoriOrientation.hpp>
      25             : #include <osl/diagnose.h>
      26             : #include <localedata.hxx>
      27             : #include <nativenumbersupplier.hxx>
      28             : #include <stdio.h>
      29             : #include <string.h>
      30             : #include <cppuhelper/supportsservice.hxx>
      31             : 
      32             : // Cyrillic upper case
      33             : #define C_CYR_A "\xD0\x90"
      34             : #define C_CYR_B "\xD0\x91"
      35             : // Cyrillic lower case
      36             : #define S_CYR_A "\xD0\xB0"
      37             : #define S_CYR_B "\xD0\xB1"
      38             : 
      39             : //Greek upper case
      40             : #define C_GR_A "\xCE\x91"
      41             : #define C_GR_B "\xCE\x92"
      42             : //Greek lower case
      43             : #define S_GR_A "\xCE\xB1"
      44             : #define S_GR_B "\xCE\xB2"
      45             : 
      46             : #include <math.h>
      47             : #include <sal/macros.h>
      48             : #include <rtl/ustring.hxx>
      49             : #include <rtl/ustrbuf.hxx>
      50             : #include <com/sun/star/i18n/XTransliteration.hpp>
      51             : #include <com/sun/star/i18n/TransliterationType.hpp>
      52             : #include <com/sun/star/i18n/TransliterationModulesNew.hpp>
      53             : #include <com/sun/star/i18n/XLocaleData.hpp>
      54             : 
      55             : #include <bullet.h>
      56             : 
      57             : using namespace com::sun::star;
      58             : using namespace com::sun::star::uno;
      59             : using namespace com::sun::star::lang;
      60             : 
      61             : namespace com { namespace sun { namespace star { namespace i18n {
      62             : 
      63             : static const sal_Unicode table_Alphabet_ar[] = {
      64             :     0x0623, 0x0628, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E,
      65             :     0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635,
      66             :     0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x0642,
      67             :     0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649
      68             : };
      69             : 
      70             : static const sal_Unicode table_Alphabet_ar_abjad[] = {
      71             :     0x0627, 0x0628, 0x062c, 0x062f, 0x0647, 0x0648, 0x0632, 0x062d,
      72             :     0x0637, 0x064a, 0x0643, 0x0644, 0x0645, 0x0646, 0x0633, 0x0639,
      73             :     0x0641, 0x0635, 0x0642, 0x0631, 0x0634, 0x062a, 0x062b, 0x062e,
      74             :     0x0630, 0x0636, 0x0638, 0x063a
      75             : };
      76             : 
      77             : static const sal_Unicode table_Alphabet_th[] = {
      78             :     0x0E01, 0x0E02, 0x0E04, 0x0E07,
      79             :     0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
      80             :     0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
      81             :     0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
      82             :     0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
      83             :     0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E
      84             : };
      85             : 
      86             : static const sal_Unicode table_Alphabet_he[] = {
      87             :     0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
      88             :     0x05D8, 0x05D9, 0x05DB, 0x05DC, 0x05DE, 0x05E0, 0x05E1, 0x05E2,
      89             :     0x05E4, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA
      90             : };
      91             : 
      92             : static const sal_Unicode table_Alphabet_ne[] = {
      93             :     0x0915, 0x0916, 0x0917, 0x0918, 0x0919, 0x091A, 0x091B, 0x091C,
      94             :     0x091D, 0x091E, 0x091F, 0x0920, 0x0921, 0x0922, 0x0923, 0x0924,
      95             :     0x0925, 0x0926, 0x0927, 0x0928, 0x092A, 0x092B, 0x092C, 0x092D,
      96             :     0x092E, 0x092F, 0x0930, 0x0932, 0x0935, 0x0936, 0x0937, 0x0938,
      97             :     0x0939
      98             : };
      99             : 
     100             : static const sal_Unicode table_Alphabet_km[] = {
     101             :     0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787,
     102             :     0x1788, 0x1789, 0x178A, 0x178B, 0x178C, 0x178D, 0x178E, 0x178F,
     103             :     0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797,
     104             :     0x1798, 0x1799, 0x179A, 0x179B, 0x179C, 0x179F,
     105             :     0x17A0, 0x17A1, 0x17A2
     106             : };
     107             : 
     108             : static const sal_Unicode table_Alphabet_lo[] = {
     109             :     0x0E81, 0x0E82, 0x0E84, 0x0E87, 0x0E88, 0x0E8A, 0x0E8D, 0x0E94,
     110             :     0x0E95, 0x0E96, 0x0E97, 0x0E99, 0x0E9A, 0x0E9B, 0x0E9C,
     111             :     0x0E9D, 0x0E9E, 0x0E9F, 0x0EA1, 0x0EA2, 0x0EA3, 0x0EA5, 0x0EA7,
     112             :     0x0EAA, 0x0EAB, 0x0EAD, 0x0EAE, 0x0EAF, 0x0EAE, 0x0EDC, 0x0EDD
     113             : };
     114             : 
     115             : static const sal_Unicode table_Alphabet_dz[] = {
     116             :     0x0F40, 0x0F41, 0x0F42, 0x0F44, 0x0F45, 0x0F46, 0x0F47, 0x0F49,
     117             :     0x0F4F, 0x0F50, 0x0F51, 0x0F53, 0x0F54, 0x0F55, 0x0F56, 0x0F58,
     118             :     0x0F59, 0x0F5A, 0x0F5B, 0x0F5D, 0x0F5E, 0x0F5F, 0x0F60, 0x0F61,
     119             :     0x0F62, 0x0F63, 0x0F64, 0x0F66, 0x0F67, 0x0F68
     120             : };
     121             : 
     122             : static const sal_Unicode table_Alphabet_my[] = {
     123             :     0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
     124             :     0x1008,/*0x1009,*/0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
     125             :     0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
     126             :     0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
     127             :     0x1020, 0x1021
     128             : };
     129             : 
     130             : // Bulgarian Cyrillic upper case letters
     131             : static const sal_Unicode table_CyrillicUpperLetter_bg[] = {
     132             :     0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418,
     133             :     0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422,
     134             :     0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042E,
     135             :     0x042F
     136             : };
     137             : 
     138             : // Bulgarian cyrillic lower case letters
     139             : static const sal_Unicode table_CyrillicLowerLetter_bg[] = {
     140             :     0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438,
     141             :     0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442,
     142             :     0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044E,
     143             :     0x044F
     144             : };
     145             : 
     146             : // Russian Cyrillic upper letters
     147             : static const sal_Unicode table_CyrillicUpperLetter_ru[] = {
     148             :     0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
     149             :     0x0418, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
     150             :     0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
     151             :     0x0429, 0x042B, 0x042D, 0x042E, 0x042F
     152             : };
     153             : 
     154             : // Russian cyrillic lower letters
     155             : static const sal_Unicode table_CyrillicLowerLetter_ru[] = {
     156             :     0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
     157             :     0x0438, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440,
     158             :     0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448,
     159             :     0x0449, 0x044B, 0x044D, 0x044E, 0x044F
     160             : };
     161             : 
     162             : // Serbian Cyrillic upper letters
     163             : static const sal_Unicode table_CyrillicUpperLetter_sr[] = {
     164             :     0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0402, 0x0415, 0x0416,
     165             :     0x0417, 0x0418, 0x0408, 0x041A, 0x041B, 0x0409, 0x041C, 0x041D,
     166             :     0x040A, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x040B, 0x0423,
     167             :     0x0424, 0x0425, 0x0426, 0x0427, 0x040F, 0x0428
     168             : };
     169             : 
     170             : // Serbian cyrillic lower letters
     171             : static const sal_Unicode table_CyrillicLowerLetter_sr[] = {
     172             :     0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0452, 0x0435, 0x0436,
     173             :     0x0437, 0x0438, 0x0458, 0x043A, 0x043B, 0x0459, 0x043C, 0x043D,
     174             :     0x045A, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x045B, 0x0443,
     175             :     0x0444, 0x0445, 0x0446, 0x0447, 0x045F, 0x0448
     176             : };
     177             : 
     178             : static const sal_Unicode table_GreekUpperLetter[] = {
     179             :     0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x03DB, 0x0396, 0x0397, 0x0398,
     180             :     0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03DF,
     181             :     0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03E0
     182             : };
     183             : 
     184             : static const sal_Unicode table_GreekLowerLetter[] = {
     185             :     0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03DB, 0x03B6, 0x03B7, 0x03B8,
     186             :     0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03DF,
     187             :     0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03E1
     188             : };
     189             : 
     190             : static const sal_Unicode table_Alphabet_fa[] = {
     191             :     0x0622, 0x0628, 0x067E, 0x062A, 0x062B, 0x062C, 0x0686, 0x062D,
     192             :     0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0698, 0x0633, 0x0634,
     193             :     0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x0640, 0x0641, 0x0642,
     194             :     0x06A9, 0x06AF, 0x0644, 0x0645, 0x0646, 0x0648, 0x0647, 0x06CC
     195             : };
     196             : 
     197             : static const sal_Unicode upperLetter[] = {
     198             :     0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
     199             :     0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
     200             :     0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A
     201             : };
     202             : 
     203             : static const sal_Unicode lowerLetter[] = {
     204             :     0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
     205             :     0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
     206             :     0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
     207             : };
     208             : 
     209             : // Tables used for numbering in persian words
     210             : static const sal_Unicode table_PersianWord_decade1[][7]={
     211             :     {0},                                                 // 0
     212             :     {0x06cc, 0x06a9, 0},                                 // 1
     213             :     {0x062f, 0x0648, 0},                                 // 2
     214             :     {0x0633, 0x0647, 0},                                 // 3
     215             :     {0x0686, 0x0647, 0x0627, 0x0631, 0},                 // 4
     216             :     {0x067e, 0x0646, 0x062c, 0},                         // 5
     217             :     {0x0634, 0x0634, 0},                                 // 6
     218             :     {0x0647, 0x0641, 0x062a, 0},                         // 7
     219             :     {0x0647, 0x0634, 0x062a, 0},                         // 8
     220             :     {0x0646, 0x0647, 0},                                 // 9
     221             :     {0x062f, 0x0647, 0},                                 // 10
     222             :     {0x06cc, 0x0627, 0x0632, 0x062f, 0x0647, 0},         // 11
     223             :     {0x062f, 0x0648, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 12
     224             :     {0x0633, 0x06cc, 0x0632, 0x062f, 0x0647, 0},         // 13
     225             :     {0x0686, 0x0647, 0x0627, 0x0631, 0x062f, 0x0647, 0}, // 14
     226             :     {0x067e, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 15
     227             :     {0x0634, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 16
     228             :     {0x0647, 0x0641, 0x062f, 0x0647, 0},                 // 17
     229             :     {0x0647, 0x062c, 0x062f, 0x0647, 0},                 // 18
     230             :     {0x0646, 0x0648, 0x0632, 0x062f, 0x0647, 0}          // 19
     231             : };
     232             : 
     233             : static const sal_Unicode table_PersianWord_decade2[][6]={
     234             :     {0x0628, 0x06cc, 0x0633, 0x062a, 0},                 // 20
     235             :     {0x0633, 0x06cc, 0},                                 // 30
     236             :     {0x0686, 0x0647, 0x0644, 0},                         // 40
     237             :     {0x067e, 0x0646, 0x062c, 0x0627, 0x0647, 0},         // 50
     238             :     {0x0634, 0x0635, 0x062a, 0},                         // 60
     239             :     {0x0647, 0x0641, 0x062a, 0x0627, 0x062f, 0},         // 70
     240             :     {0x0647, 0x0634, 0x062a, 0x0627, 0x062f, 0},         // 80
     241             :     {0x0646, 0x0648, 0x062f, 0}                          // 90
     242             : };
     243             : 
     244             : static const sal_Unicode table_PersianWord_decade3[][7]={
     245             :     {0x0635, 0x062f, 0},                                 // 100
     246             :     {0x062f, 0x0648, 0x06cc, 0x0633, 0x062a, 0},         // 200
     247             :     {0x0633, 0x06cc, 0x0635, 0x062f, 0},                 // 300
     248             :     {0x0686, 0x0647, 0x0627, 0x0631, 0x0635, 0x062f, 0}, // 400
     249             :     {0x067e, 0x0627, 0x0646, 0x0635, 0x062f, 0},         // 500
     250             :     {0x0634, 0x0635, 0x062f, 0},                         // 600
     251             :     {0x0647, 0x0641, 0x062a, 0x0635, 0x062f, 0},         // 700
     252             :     {0x0647, 0x0634, 0x062a, 0x0635, 0x062f, 0},         // 800
     253             :     {0x0646, 0x0647, 0x0635, 0x062f, 0}                  // 900
     254             : };
     255             : 
     256             : static const sal_Unicode table_PersianWord_decadeX[][8]={
     257             :     {0x0647, 0x0632, 0x0627, 0x0631, 0},                        // 1000
     258             :     {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0648, 0x0646, 0},        // 1000000
     259             :     {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0627, 0x0631, 0x062f, 0} // 1000000000
     260             : };
     261             : 
     262             : 
     263          59 : DefaultNumberingProvider::DefaultNumberingProvider( const Reference < XComponentContext >& rxContext ) : m_xContext(rxContext),translit(NULL)
     264             : {
     265             : 
     266          59 : }
     267             : 
     268         156 : DefaultNumberingProvider::~DefaultNumberingProvider()
     269             : {
     270          52 :     delete translit;
     271         104 : }
     272             : 
     273           0 : void DefaultNumberingProvider::impl_loadTranslit()
     274             : {
     275           0 :     if ( !translit )
     276           0 :         translit = new TransliterationImpl(m_xContext);
     277           0 : }
     278             : 
     279             : Sequence< Reference<container::XIndexAccess> >
     280           0 : DefaultNumberingProvider::getDefaultOutlineNumberings(const Locale& rLocale ) throw(RuntimeException, std::exception)
     281             : {
     282           0 :      return LocaleDataImpl().getOutlineNumberingLevels( rLocale );
     283             : }
     284             : 
     285             : Sequence< Sequence<beans::PropertyValue> >
     286           0 : DefaultNumberingProvider::getDefaultContinuousNumberingLevels( const Locale& rLocale ) throw(RuntimeException, std::exception)
     287             : {
     288           0 :      return LocaleDataImpl().getContinuousNumberingLevels( rLocale );
     289             : }
     290             : 
     291        1006 : OUString toRoman( sal_Int32 n )
     292             : {
     293             : 
     294             : //              i, ii, iii, iv, v, vi, vii, vii, viii, ix
     295             : //                                                      (Dummy),1000,500,100,50,10,5,1
     296             :     static const sal_Char coRomanArr[] = "MDCLXVI--";       // +2 Dummy entries !!
     297        1006 :     const sal_Char* cRomanStr = coRomanArr;
     298        1006 :     sal_uInt16 nMask = 1000;
     299        1006 :     sal_uInt32 nOver1000 = n / nMask;
     300        1006 :     n -= ( nOver1000 * nMask );
     301             : 
     302        1006 :     OUStringBuffer sTmp;
     303        2012 :     while(nOver1000--)
     304           0 :         sTmp.append(*coRomanArr);
     305             : 
     306        6036 :     while( nMask )
     307             :     {
     308        4024 :         sal_uInt8 nZahl = sal_uInt8( n / nMask );
     309        4024 :         sal_uInt8 nDiff = 1;
     310        4024 :         n %= nMask;
     311             : 
     312        4024 :         if( 5 < nZahl )
     313             :         {
     314          25 :             if( nZahl < 9 )
     315          25 :                 sTmp.append(*(cRomanStr-1));
     316          25 :             ++nDiff;
     317          25 :             nZahl -= 5;
     318             :         }
     319        4024 :         switch( nZahl )
     320             :         {
     321          31 :             case 3: sTmp.append(*cRomanStr);           //no break!
     322         188 :             case 2: sTmp.append(*cRomanStr);           //no break!
     323         957 :             case 1: sTmp.append(*cRomanStr);           break;
     324          22 :             case 4: sTmp.append(*cRomanStr).append(*(cRomanStr-nDiff)); break;
     325          27 :             case 5: sTmp.append(*(cRomanStr-nDiff));   break;
     326             :         }
     327             : 
     328        4024 :         nMask /= 10;                    // to the next decade
     329        4024 :         cRomanStr += 2;
     330             :     }
     331        1006 :     return sTmp.makeStringAndClear();
     332             : }
     333             : 
     334             : // not used:
     335             : 
     336             : static
     337        2462 : void lcl_formatChars( const sal_Unicode table[], int tableSize, int n, OUString& s )
     338             : {
     339             :      // string representation of n is appended to s.
     340             :      // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>AB, ...
     341             :      // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>ab, ...
     342             : 
     343        2462 :      if( n>=tableSize ) lcl_formatChars( table, tableSize, (n-tableSize)/tableSize, s );
     344             : 
     345        2462 :      s += OUString( table[ n % tableSize ] );
     346        2462 : }
     347             : 
     348             : static
     349         126 : void lcl_formatChars1( const sal_Unicode table[], int tableSize, int n, OUString& s )
     350             : {
     351             :      // string representation of n is appended to s.
     352             :      // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>BB, ...
     353             :      // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>bb, ...
     354             : 
     355         126 :      int repeat_count = n / tableSize + 1;
     356             : 
     357         252 :      for( int i=0; i<repeat_count; i++ )
     358         126 :          s += OUString( table[ n%tableSize ] );
     359         126 : }
     360             : 
     361             : static
     362           0 : void lcl_formatChars2( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
     363             : {
     364             :      // string representation of n is appended to s.
     365             :      // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Ab, ...
     366             : 
     367           0 :      if( n>=tableSize )
     368             :      {
     369           0 :           lcl_formatChars2( table_capital, table_small, tableSize, (n-tableSize)/tableSize, s );
     370           0 :           s += OUString( table_small[ n % tableSize ] );
     371             :      } else
     372           0 :           s += OUString( table_capital[ n % tableSize ] );
     373           0 : }
     374             : 
     375             : static
     376           0 : void lcl_formatChars3( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
     377             : {
     378             :      // string representation of n is appended to s.
     379             :      // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Bb, ...
     380             : 
     381           0 :      int repeat_count = n / tableSize + 1;
     382           0 :      s += OUString( table_capital[ n%tableSize ] );
     383             : 
     384           0 :      for( int i=1; i<repeat_count; i++ )
     385           0 :          s += OUString( table_small[ n%tableSize ] );
     386           0 : }
     387             : 
     388             : 
     389             : /** Returns number's representation in persian words up to 999999999999
     390             :     respectively limited by sal_Int32 >=0.
     391             :     The caller assures that nNumber is not negative.
     392             :  */
     393             : static
     394           0 : void lcl_formatPersianWord( sal_Int32 nNumber, OUString& rsResult )
     395             :     throw( IllegalArgumentException, RuntimeException )
     396             : {
     397           0 :     OUStringBuffer aTemp(64);
     398             :     static const sal_Unicode asPersianWord_conjunction_data[] = {0x20,0x0648,0x20,0};
     399           0 :     OUString asPersianWord_conjunction( asPersianWord_conjunction_data );
     400           0 :     unsigned char nSection = 0;
     401             : 
     402           0 :     while (int nPart = nNumber % 1000)
     403             :     {
     404           0 :         if (nSection)
     405             :         {
     406           0 :             if (nSection > SAL_N_ELEMENTS( table_PersianWord_decadeX))
     407           0 :                 throw IllegalArgumentException();   // does not happen with sal_Int32
     408           0 :             aTemp.insert( 0, asPersianWord_conjunction).insert( 0, table_PersianWord_decadeX[nSection-1]);
     409             :         }
     410             : 
     411             :         unsigned int nDigit;
     412           0 :         if ((nDigit = nPart % 100) < 20)
     413             :         {
     414           0 :             if (!aTemp.isEmpty())
     415           0 :                 aTemp.insert( 0, sal_Unicode(0x0020));
     416           0 :             aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
     417             :         }
     418             :         else
     419             :         {
     420           0 :             if ((nDigit = nPart % 10) != 0)
     421             :             {
     422           0 :                 if (!aTemp.isEmpty())
     423           0 :                     aTemp.insert( 0, asPersianWord_conjunction);
     424           0 :                 aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
     425             :             }
     426           0 :             if ((nDigit = (nPart / 10) % 10) != 0)
     427             :             {
     428           0 :                 if (!aTemp.isEmpty())
     429           0 :                     aTemp.insert( 0, asPersianWord_conjunction);
     430           0 :                 aTemp.insert( 0, table_PersianWord_decade2[nDigit-2]);
     431             :             }
     432             :         }
     433             : 
     434           0 :         if ((nDigit = nPart / 100) != 0)
     435             :         {
     436           0 :             if (!aTemp.isEmpty())
     437           0 :                 aTemp.insert( 0, asPersianWord_conjunction);
     438           0 :             aTemp.insert( 0, table_PersianWord_decade3[nDigit-1]);
     439             :         }
     440             : 
     441           0 :         nNumber /= 1000;
     442           0 :         nSection++;
     443             :     }
     444           0 :     rsResult += aTemp.makeStringAndClear();
     445           0 : }
     446             : 
     447             : 
     448             : // Greek Letter Numbering
     449             : 
     450             : // KERAIA separates numerals from other text
     451             : #define STIGMA        (sal_Unicode) 0x03DB
     452             : #define LEFT_KERAIA   (sal_Unicode) 0x0375
     453             : #define MYRIAD_SYM    (sal_Unicode) 0x039C
     454             : #define DOT_SYM       (sal_Unicode) 0x002E
     455             : #define SIGMA_OFFSET  19
     456             : #define TAU_OFFSET    20
     457             : #define MYRIAD        10000
     458             : 
     459             : /*
     460             : * Return the 1-999999 number's representation in the Greek numbering system.
     461             : * Adding a "left keraia" to represent numbers in the range 10000 ... 999999 is
     462             : * not orthodox, so it's better to use the myriad notation and call this method
     463             : * only for numbers up to 9999.
     464             : */
     465             : static
     466           0 : OUString gr_smallNum(const sal_Unicode table[], int n)
     467             : {
     468           0 :     if (n > 9999)
     469           0 :         throw IllegalArgumentException();
     470             : 
     471           0 :     int i = 0;
     472           0 :     OUStringBuffer sb;
     473           0 :     for (int v = n; v > 0; v /= 10, i++) {
     474           0 :         int digit = v % 10;
     475           0 :         if (digit == 0)
     476           0 :             continue;
     477             : 
     478           0 :         sal_Unicode sign = table[(digit - 1) + 9 * (i % 3)];
     479           0 :         if (sign == STIGMA) {
     480           0 :             sb.insert(0, table[TAU_OFFSET]);
     481           0 :             sb.insert(0, table[SIGMA_OFFSET]);
     482             :         } else {
     483           0 :             sb.insert(0, sign);
     484             :         }
     485             : 
     486           0 :         if (i > 2)
     487           0 :             sb.insert(0, LEFT_KERAIA);
     488             :     }
     489             : 
     490           0 :     return sb.makeStringAndClear();
     491             : }
     492             : 
     493             : static
     494           0 : void lcl_formatCharsGR(const sal_Unicode table[], int n, OUString& s )
     495             : {
     496           0 :     OUStringBuffer sb;
     497           0 :     int myriadPower = 2;
     498             : 
     499           0 :     for (int divisor = MYRIAD * MYRIAD; divisor > 1; divisor /= MYRIAD, myriadPower--) {
     500           0 :         if (n > divisor - 1) {
     501             :             /*
     502             :              * Follow the Diophantus representation of:
     503             :              *   A myriad sign, M(10000) as many times as the power
     504             :              *   followed by the multiplier for the myriad
     505             :              *   followed by a dot
     506             :              *   followed by the rest
     507             :              *   This is enough for 32-bit integers
     508             :              */
     509           0 :             for (int i = 0; i < myriadPower; i++)
     510           0 :                 sb.append(MYRIAD_SYM);
     511             : 
     512           0 :             sb.append(gr_smallNum(table, n/divisor));
     513           0 :             n %= divisor;
     514             : 
     515           0 :             if (n > 0)
     516           0 :                 sb.append(DOT_SYM);
     517             :         }
     518             :     }
     519           0 :     sb.append(gr_smallNum(table,n));
     520             : 
     521           0 :     s += sb.makeStringAndClear();
     522           0 : }
     523             : 
     524             : static
     525       28218 : bool should_ignore( const OUString& s )
     526             : {
     527             :         // return true if blank or null
     528       28218 :         return s == " " || (!s.isEmpty() && s[0]==0);
     529             : }
     530             : 
     531             : static
     532       56456 : Any getPropertyByName( const Sequence<beans::PropertyValue>& aProperties,
     533             :                                                 const char* name, bool bRequired )
     534             : {
     535      127026 :         for( int i=0; i<aProperties.getLength(); i++ )
     536       98798 :                 if( aProperties[i].Name.equalsAscii(name) )
     537       28228 :                         return aProperties[i].Value;
     538       28228 :         if(bRequired)
     539           0 :             throw IllegalArgumentException();
     540       28228 :         return Any();
     541             : }
     542             : 
     543             : //XNumberingFormatter
     544             : OUString
     545       14114 : DefaultNumberingProvider::makeNumberingString( const Sequence<beans::PropertyValue>& aProperties,
     546             :                                                const Locale& aLocale )
     547             :      throw( IllegalArgumentException, RuntimeException, std::exception )
     548             : {
     549             :      // the Sequence of PropertyValues is expected to have at least 4 elements:
     550             :      // elt Name              Type             purpose
     551             : 
     552             : 
     553             :      // 0.  "Prefix"          OUString
     554             :      // 1.  "NumberingType"   sal_Int16        type of formatting from style::NumberingType (roman, arabic, etc)
     555             :      // 2.  "Suffix"          OUString
     556             :      // ... ...               ...
     557             :      // n.  "Value"           sal_Int32        the number to be formatted
     558             :      // example:
     559             :      // given the Sequence { '(', NumberingType::ROMAN_UPPER, ')', ..., 7 }
     560             :      // makeNumberingString() returns the string "(VII)".
     561             : 
     562             :      // Q: why is the type of numType sal_Int16 instead of style::NumberingType?
     563             :      // A: an Any can't hold a style::NumberingType for some reason.
     564             :         //      add.: style::NumberingType holds constants of type sal_Int16, it's not an enum type
     565             : 
     566       14114 :      sal_Int16 natNum = 0;
     567       14114 :      sal_Int16 tableSize = 0;
     568       14114 :      const sal_Unicode *table = NULL;     // initialize to avoid compiler warning
     569       14114 :      bool recycleSymbol = false;
     570       14114 :      Locale locale;
     571             : 
     572       28228 :      OUString  prefix;
     573       14114 :      sal_Int16        numType = -1; // type of formatting from style::NumberingType (roman, arabic, etc)
     574       28228 :      OUString  suffix;
     575       14114 :      sal_Int32        number = -12345; // the number that needs to be formatted.
     576             : 
     577             : //     int nProperties = aProperties.getLength();
     578             : //     int last        = nProperties-1;
     579             : 
     580             :      try {
     581       14114 :         getPropertyByName(aProperties, "Prefix", false)      >>=prefix;
     582           0 :      } catch (Exception&) {
     583             :         //prefix _must_ be empty here!
     584             :      }
     585             :      try {
     586       14114 :         getPropertyByName(aProperties, "Suffix", false)      >>=suffix;
     587           0 :      } catch (Exception&) {
     588             :         //suffix _must_ be empty here!
     589             :      }
     590             :      try {
     591       14114 :         getPropertyByName(aProperties, "NumberingType", true)   >>=numType;
     592           0 :      } catch (Exception& ) {
     593           0 :         numType = -1;
     594             :      }
     595             :      try {
     596       14114 :         getPropertyByName(aProperties, "Value", true)       >>=number;
     597           0 :      } catch (Exception& ) {
     598           0 :         number = -1;
     599             :      }
     600             : 
     601       14114 :      if( number <= 0 )
     602           5 :           throw IllegalArgumentException();
     603             : 
     604             :      // start empty
     605       28218 :      OUString result;
     606             : 
     607             :       // append prefix
     608       14109 :       if( !should_ignore(prefix) ) result += prefix;
     609             : 
     610             :       // append formatted number
     611             :       using namespace style::NumberingType;
     612       14109 :       switch( numType )
     613             :       {
     614             :           case CHARS_UPPER_LETTER:
     615        1189 :                lcl_formatChars( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>AB, ...
     616        1189 :                break;
     617             :           case CHARS_LOWER_LETTER:
     618        1255 :                lcl_formatChars( lowerLetter, 26, number-1, result );
     619        1255 :                break;
     620             :           case ROMAN_UPPER:
     621         234 :                result += toRoman( number );
     622         234 :                break;
     623             :           case ROMAN_LOWER:
     624         772 :                result += toRoman( number ).toAsciiLowerCase();
     625         772 :                break;
     626             :           case ARABIC:
     627        7347 :                result += OUString::number( number );
     628        7347 :                break;
     629             :           case NUMBER_NONE:
     630           0 :                return OUString(""); // ignore prefix and suffix
     631             :           case CHAR_SPECIAL:
     632             :                // apparently, we're supposed to return an empty string in this case...
     633           0 :                return OUString(""); // ignore prefix and suffix
     634             :           case PAGE_DESCRIPTOR:
     635             :           case BITMAP:
     636             :                OSL_ASSERT(false);
     637           0 :                throw IllegalArgumentException();
     638             :           case CHARS_UPPER_LETTER_N:
     639          60 :                lcl_formatChars1( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
     640          60 :                break;
     641             :           case CHARS_LOWER_LETTER_N:
     642          66 :                lcl_formatChars1( lowerLetter, 26,  number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
     643          66 :                break;
     644             :           case TRANSLITERATION:
     645             :                try {
     646           0 :                     const OUString &tmp = OUString::number( number );
     647           0 :                     OUString transliteration;
     648           0 :                     getPropertyByName(aProperties, "Transliteration", true) >>= transliteration;
     649           0 :                     impl_loadTranslit();
     650           0 :                     translit->loadModuleByImplName(transliteration, aLocale);
     651           0 :                     result += translit->transliterateString2String(tmp, 0, tmp.getLength());
     652           0 :                } catch (Exception& ) {
     653             :                     // When translteration property is missing, return default number (bug #101141#)
     654           0 :                     result += OUString::number( number );
     655             :                     // OSL_ASSERT(0);
     656             :                     // throw IllegalArgumentException();
     657             :                }
     658           0 :                break;
     659             :           case NATIVE_NUMBERING:
     660           0 :                 natNum = NativeNumberMode::NATNUM1;
     661           0 :                 locale = aLocale;
     662           0 :                 break;
     663             :           case FULLWIDTH_ARABIC:
     664         120 :                 natNum = NativeNumberMode::NATNUM3;
     665         120 :                 locale = aLocale;
     666         120 :                 break;
     667             :           case NUMBER_LOWER_ZH:
     668         476 :                 natNum = NativeNumberMode::NATNUM7;
     669         476 :                 locale.Language = "zh";
     670         476 :                 break;
     671             :           case NUMBER_UPPER_ZH:
     672         140 :                 natNum = NativeNumberMode::NATNUM8;
     673         140 :                 locale.Language = "zh";
     674         140 :                 break;
     675             :           case NUMBER_UPPER_ZH_TW:
     676         400 :                 natNum = NativeNumberMode::NATNUM8;
     677         400 :                 locale.Language = "zh";
     678         400 :                 locale.Country = "TW";
     679         400 :                 break;
     680             :           case NUMBER_TRADITIONAL_JA:
     681         140 :                 natNum = NativeNumberMode::NATNUM8;
     682         140 :                 locale.Language = "ja";
     683         140 :                 break;
     684             :           case NUMBER_UPPER_KO:
     685           0 :                 natNum = NativeNumberMode::NATNUM8;
     686           0 :                 locale.Language = "ko";
     687           0 :                 break;
     688             :           case NUMBER_HANGUL_KO:
     689         120 :                 natNum = NativeNumberMode::NATNUM11;
     690         120 :                 locale.Language = "ko";
     691         120 :                 break;
     692             : 
     693             :           case CIRCLE_NUMBER:
     694         120 :               table = table_CircledNumber;
     695         120 :               tableSize = SAL_N_ELEMENTS(table_CircledNumber);
     696         120 :               break;
     697             :           case TIAN_GAN_ZH:
     698         412 :               table = table_TianGan_zh;
     699         412 :               tableSize = SAL_N_ELEMENTS(table_TianGan_zh);
     700         412 :               break;
     701             :           case DI_ZI_ZH:
     702         400 :               table = table_DiZi_zh;
     703         400 :               tableSize = SAL_N_ELEMENTS(table_DiZi_zh);
     704         400 :               break;
     705             :           case AIU_FULLWIDTH_JA:
     706         140 :               table = table_AIUFullWidth_ja_JP;
     707         140 :               tableSize = SAL_N_ELEMENTS(table_AIUFullWidth_ja_JP);
     708         140 :               recycleSymbol = true;
     709         140 :               break;
     710             :           case AIU_HALFWIDTH_JA:
     711         140 :               table = table_AIUHalfWidth_ja_JP;
     712         140 :               tableSize = SAL_N_ELEMENTS(table_AIUHalfWidth_ja_JP);
     713         140 :               recycleSymbol = true;
     714         140 :               break;
     715             :           case IROHA_FULLWIDTH_JA:
     716         140 :               table = table_IROHAFullWidth_ja_JP;
     717         140 :               tableSize = SAL_N_ELEMENTS(table_IROHAFullWidth_ja_JP);
     718         140 :               recycleSymbol = true;
     719         140 :               break;
     720             :           case IROHA_HALFWIDTH_JA:
     721         140 :               table = table_IROHAHalfWidth_ja_JP;
     722         140 :               tableSize = SAL_N_ELEMENTS(table_IROHAHalfWidth_ja_JP);
     723         140 :               recycleSymbol = true;
     724         140 :               break;
     725             :           case HANGUL_JAMO_KO:
     726         140 :               table = table_HangulJamo_ko;
     727         140 :               tableSize = SAL_N_ELEMENTS(table_HangulJamo_ko);
     728         140 :               recycleSymbol = true;
     729         140 :               break;
     730             :           case HANGUL_SYLLABLE_KO:
     731         140 :               table = table_HangulSyllable_ko;
     732         140 :               tableSize = SAL_N_ELEMENTS(table_HangulSyllable_ko);
     733         140 :               recycleSymbol = true;
     734         140 :               break;
     735             :           case HANGUL_CIRCLED_JAMO_KO:
     736           0 :               table = table_HangulCircledJamo_ko;
     737           0 :               tableSize = SAL_N_ELEMENTS(table_HangulCircledJamo_ko);
     738           0 :               recycleSymbol = true;
     739           0 :               break;
     740             :           case HANGUL_CIRCLED_SYLLABLE_KO:
     741           0 :               table = table_HangulCircledSyllable_ko;
     742           0 :               tableSize = SAL_N_ELEMENTS(table_HangulCircledSyllable_ko);
     743           0 :               recycleSymbol = true;
     744           0 :               break;
     745             :           case CHARS_ARABIC:
     746           0 :               lcl_formatChars(table_Alphabet_ar, SAL_N_ELEMENTS(table_Alphabet_ar), number - 1, result);
     747           0 :               break;
     748             :           case CHARS_ARABIC_ABJAD:
     749           0 :               lcl_formatChars(table_Alphabet_ar_abjad, SAL_N_ELEMENTS(table_Alphabet_ar_abjad), number - 1, result);
     750           0 :               break;
     751             :           case CHARS_THAI:
     752           0 :               lcl_formatChars(table_Alphabet_th, SAL_N_ELEMENTS(table_Alphabet_th), number - 1, result);
     753           0 :               break;
     754             :           case CHARS_HEBREW:
     755          18 :               lcl_formatChars(table_Alphabet_he, SAL_N_ELEMENTS(table_Alphabet_he), number - 1, result);
     756          18 :               break;
     757             :           case CHARS_NEPALI:
     758           0 :               lcl_formatChars(table_Alphabet_ne, SAL_N_ELEMENTS(table_Alphabet_ne), number - 1, result);
     759           0 :               break;
     760             :           case CHARS_KHMER:
     761           0 :               lcl_formatChars(table_Alphabet_km, SAL_N_ELEMENTS(table_Alphabet_km), number - 1, result);
     762           0 :               break;
     763             :           case CHARS_LAO:
     764           0 :               lcl_formatChars(table_Alphabet_lo, SAL_N_ELEMENTS(table_Alphabet_lo), number - 1, result);
     765           0 :               break;
     766             :           case CHARS_MYANMAR:
     767           0 :               lcl_formatChars(table_Alphabet_my, SAL_N_ELEMENTS(table_Alphabet_my), number - 1, result);
     768           0 :               break;
     769             :          case CHARS_TIBETAN:
     770           0 :               lcl_formatChars(table_Alphabet_dz, SAL_N_ELEMENTS(table_Alphabet_dz), number - 1, result);
     771           0 :               break;
     772             :          case CHARS_CYRILLIC_UPPER_LETTER_BG:
     773             :               lcl_formatChars2( table_CyrillicUpperLetter_bg,
     774             :                       table_CyrillicLowerLetter_bg,
     775             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
     776           0 :                       result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Ab, ...
     777           0 :               break;
     778             :          case CHARS_CYRILLIC_LOWER_LETTER_BG:
     779             :               lcl_formatChars( table_CyrillicLowerLetter_bg,
     780             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
     781           0 :                       result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>ab, ...
     782           0 :               break;
     783             :          case CHARS_CYRILLIC_UPPER_LETTER_N_BG:
     784             :               lcl_formatChars3( table_CyrillicUpperLetter_bg,
     785             :                       table_CyrillicLowerLetter_bg,
     786             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
     787           0 :                       result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Bb, ...
     788           0 :               break;
     789             :          case CHARS_CYRILLIC_LOWER_LETTER_N_BG:
     790             :               lcl_formatChars1( table_CyrillicLowerLetter_bg,
     791             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
     792           0 :                       result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>bb, ...
     793           0 :               break;
     794             :          case CHARS_CYRILLIC_UPPER_LETTER_RU:
     795             :               lcl_formatChars2( table_CyrillicUpperLetter_ru,
     796             :                       table_CyrillicLowerLetter_ru,
     797             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
     798           0 :                       result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
     799           0 :               break;
     800             :          case CHARS_CYRILLIC_LOWER_LETTER_RU:
     801             :               lcl_formatChars( table_CyrillicLowerLetter_ru,
     802             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
     803           0 :                       result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
     804           0 :               break;
     805             :          case CHARS_CYRILLIC_UPPER_LETTER_N_RU:
     806             :               lcl_formatChars3( table_CyrillicUpperLetter_ru,
     807             :                       table_CyrillicLowerLetter_ru,
     808             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
     809           0 :                       result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
     810           0 :               break;
     811             :          case CHARS_CYRILLIC_LOWER_LETTER_N_RU:
     812             :               lcl_formatChars1( table_CyrillicLowerLetter_ru,
     813             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
     814           0 :                       result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
     815           0 :               break;
     816             :          case CHARS_CYRILLIC_UPPER_LETTER_SR:
     817             :               lcl_formatChars2( table_CyrillicUpperLetter_sr,
     818             :                       table_CyrillicLowerLetter_sr,
     819             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
     820           0 :                       result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
     821           0 :               break;
     822             :          case CHARS_CYRILLIC_LOWER_LETTER_SR:
     823             :               lcl_formatChars( table_CyrillicLowerLetter_sr,
     824             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
     825           0 :                       result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
     826           0 :               break;
     827             :          case CHARS_CYRILLIC_UPPER_LETTER_N_SR:
     828             :               lcl_formatChars3( table_CyrillicUpperLetter_sr,
     829             :                       table_CyrillicLowerLetter_sr,
     830             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
     831           0 :                       result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
     832           0 :               break;
     833             :          case CHARS_CYRILLIC_LOWER_LETTER_N_SR:
     834             :               lcl_formatChars1( table_CyrillicLowerLetter_sr,
     835             :                       SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
     836           0 :                       result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
     837           0 :               break;
     838             : 
     839             :           case CHARS_GREEK_LOWER_LETTER:
     840           0 :               lcl_formatCharsGR( table_GreekLowerLetter, number, result);
     841           0 :               break;
     842             : 
     843             :           case CHARS_GREEK_UPPER_LETTER:
     844           0 :               lcl_formatCharsGR( table_GreekUpperLetter, number, result);
     845           0 :               break;
     846             : 
     847             :           case CHARS_PERSIAN:
     848           0 :               lcl_formatChars(table_Alphabet_fa, SAL_N_ELEMENTS(table_Alphabet_fa), number - 1, result);
     849           0 :               break;
     850             : 
     851             :           case CHARS_PERSIAN_WORD:
     852           0 :               lcl_formatPersianWord(number, result);
     853           0 :               break;
     854             : 
     855             :           default:
     856             :                OSL_ASSERT(false);
     857           0 :                throw IllegalArgumentException();
     858             :       }
     859             : 
     860       14109 :         if (natNum) {
     861        1396 :             NativeNumberSupplierService sNatNum;
     862        1396 :             result += sNatNum.getNativeNumberString(OUString::number( number ), locale, natNum);
     863       12713 :         } else if (tableSize) {
     864        1772 :             if ( number > tableSize && !recycleSymbol)
     865         360 :                 result += OUString::number( number);
     866             :             else
     867        1412 :                 result += OUString(&table[--number % tableSize], 1);
     868             :         }
     869             : 
     870             :         // append suffix
     871       14109 :         if( !should_ignore(suffix) ) result += suffix;
     872             : 
     873       28223 :         return result;
     874             : }
     875             : 
     876             : #define LANG_ALL        (1 << 0)
     877             : #define LANG_CJK        (1 << 1)
     878             : #define LANG_CTL        (1 << 2)
     879             : 
     880             : struct Supported_NumberingType
     881             : {
     882             :         sal_Int16               nType;
     883             :         const sal_Char* cSymbol;
     884             :         sal_Int16               langOption;
     885             : };
     886             : static const Supported_NumberingType aSupportedTypes[] =
     887             : {
     888             :         {style::NumberingType::CHARS_UPPER_LETTER,      "A", LANG_ALL},
     889             :         {style::NumberingType::CHARS_LOWER_LETTER,      "a", LANG_ALL},
     890             :         {style::NumberingType::ROMAN_UPPER,                     "I", LANG_ALL},
     891             :         {style::NumberingType::ROMAN_LOWER,                     "i", LANG_ALL},
     892             :         {style::NumberingType::ARABIC,                          "1", LANG_ALL},
     893             :         {style::NumberingType::NUMBER_NONE,                     "''", LANG_ALL},
     894             :         {style::NumberingType::CHAR_SPECIAL,                    "Bullet", LANG_ALL},
     895             :         {style::NumberingType::PAGE_DESCRIPTOR,                 "Page", LANG_ALL},
     896             :         {style::NumberingType::BITMAP,                          "Bitmap", LANG_ALL},
     897             :         {style::NumberingType::CHARS_UPPER_LETTER_N,    "AAA", LANG_ALL},
     898             :         {style::NumberingType::CHARS_LOWER_LETTER_N,    "aaa", LANG_ALL},
     899             :         {style::NumberingType::NATIVE_NUMBERING,        "Native Numbering", LANG_CJK|LANG_CTL},
     900             :         {style::NumberingType::FULLWIDTH_ARABIC,        NULL, LANG_CJK},
     901             :         {style::NumberingType::CIRCLE_NUMBER,           NULL, LANG_CJK},
     902             :         {style::NumberingType::NUMBER_LOWER_ZH,         NULL, LANG_CJK},
     903             :         {style::NumberingType::NUMBER_UPPER_ZH,         NULL, LANG_CJK},
     904             :         {style::NumberingType::NUMBER_UPPER_ZH_TW,      NULL, LANG_CJK},
     905             :         {style::NumberingType::TIAN_GAN_ZH,             NULL, LANG_CJK},
     906             :         {style::NumberingType::DI_ZI_ZH,                NULL, LANG_CJK},
     907             :         {style::NumberingType::NUMBER_TRADITIONAL_JA,   NULL, LANG_CJK},
     908             :         {style::NumberingType::AIU_FULLWIDTH_JA,        NULL, LANG_CJK},
     909             :         {style::NumberingType::AIU_HALFWIDTH_JA,        NULL, LANG_CJK},
     910             :         {style::NumberingType::IROHA_FULLWIDTH_JA,      NULL, LANG_CJK},
     911             :         {style::NumberingType::IROHA_HALFWIDTH_JA,      NULL, LANG_CJK},
     912             :         {style::NumberingType::NUMBER_UPPER_KO,         NULL, LANG_CJK},
     913             :         {style::NumberingType::NUMBER_HANGUL_KO,        NULL, LANG_CJK},
     914             :         {style::NumberingType::HANGUL_JAMO_KO,          NULL, LANG_CJK},
     915             :         {style::NumberingType::HANGUL_SYLLABLE_KO,      NULL, LANG_CJK},
     916             :         {style::NumberingType::HANGUL_CIRCLED_JAMO_KO,  NULL, LANG_CJK},
     917             :         {style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO,      NULL, LANG_CJK},
     918             :         {style::NumberingType::CHARS_ARABIC,    NULL, LANG_CTL},
     919             :         {style::NumberingType::CHARS_ARABIC_ABJAD,   NULL, LANG_CTL},
     920             :         {style::NumberingType::CHARS_THAI,      NULL, LANG_CTL},
     921             :         {style::NumberingType::CHARS_HEBREW,    NULL, LANG_CTL},
     922             :         {style::NumberingType::CHARS_NEPALI,    NULL, LANG_CTL},
     923             :         {style::NumberingType::CHARS_KHMER,     NULL, LANG_CTL},
     924             :         {style::NumberingType::CHARS_LAO,       NULL, LANG_CTL},
     925             :         {style::NumberingType::CHARS_MYANMAR,   NULL, LANG_CTL},
     926             :         {style::NumberingType::CHARS_TIBETAN,   NULL, LANG_CTL},
     927             :         {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},
     928             :         {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},
     929             :         {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},
     930             :         {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},
     931             :         {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},
     932             :         {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},
     933             :         {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},
     934             :         {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},
     935             :         {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},
     936             :         {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},
     937             :         {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},
     938             :         {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},
     939             :         {style::NumberingType::CHARS_PERSIAN,   NULL, LANG_CTL},
     940             :         {style::NumberingType::CHARS_PERSIAN_WORD,   NULL, LANG_CTL},
     941             :         {style::NumberingType::CHARS_GREEK_UPPER_LETTER,   C_GR_A ", " C_GR_B ", ... (gr)", LANG_ALL},
     942             :         {style::NumberingType::CHARS_GREEK_LOWER_LETTER,   S_GR_A ", " S_GR_B ", ... (gr)", LANG_ALL},
     943             : };
     944             : static const sal_Int32 nSupported_NumberingTypes = sizeof(aSupportedTypes) / sizeof(Supported_NumberingType);
     945             : 
     946         600 : OUString DefaultNumberingProvider::makeNumberingIdentifier(sal_Int16 index)
     947             :                                 throw(RuntimeException)
     948             : {
     949         600 :     if (aSupportedTypes[index].cSymbol)
     950         480 :         return OUString(aSupportedTypes[index].cSymbol, strlen(aSupportedTypes[index].cSymbol), RTL_TEXTENCODING_UTF8);
     951             :     //            return OUString::createFromAscii(aSupportedTypes[index].cSymbol);
     952             :     else {
     953         120 :         OUString result;
     954         240 :         Locale aLocale(OUString("en"), OUString(), OUString());
     955         240 :         Sequence<beans::PropertyValue> aProperties(2);
     956         120 :         aProperties[0].Name = "NumberingType";
     957         120 :         aProperties[0].Value <<= aSupportedTypes[index].nType;
     958         120 :         aProperties[1].Name = "Value";
     959         480 :         for (sal_Int32 j = 1; j <= 3; j++) {
     960         360 :             aProperties[1].Value <<= j;
     961         360 :             result += makeNumberingString( aProperties, aLocale );
     962         360 :             result += ", ";
     963             :         }
     964         120 :         result += "...";
     965         240 :         return result;
     966             :     }
     967             : }
     968             : 
     969             : bool SAL_CALL
     970           0 : DefaultNumberingProvider::isScriptFlagEnabled(const OUString& aName) throw(RuntimeException)
     971             : {
     972           0 :     if (! xHierarchicalNameAccess.is()) {
     973             :         Reference< XMultiServiceFactory > xConfigProvider =
     974           0 :             configuration::theDefaultProvider::get(m_xContext);
     975             : 
     976           0 :         if (! xConfigProvider.is())
     977           0 :             throw RuntimeException();
     978             : 
     979           0 :         Sequence< Any > aArgs(1);
     980           0 :         beans::PropertyValue aPath;
     981           0 :         aPath.Name = "nodepath";
     982           0 :         aPath.Value <<= OUString("/org.openoffice.Office.Common/I18N"),
     983           0 :         aArgs[0] <<= aPath;
     984             : 
     985           0 :         Reference<XInterface> xInterface = xConfigProvider->createInstanceWithArguments(
     986           0 :             OUString("com.sun.star.configuration.ConfigurationAccess"), aArgs);
     987             : 
     988           0 :         xHierarchicalNameAccess.set(xInterface, UNO_QUERY);
     989             : 
     990           0 :         if (! xHierarchicalNameAccess.is())
     991           0 :             throw RuntimeException();
     992             :     }
     993             : 
     994           0 :     Any aEnabled = xHierarchicalNameAccess->getByHierarchicalName(aName);
     995             : 
     996           0 :     bool enabled = false;
     997             : 
     998           0 :     aEnabled >>= enabled;
     999             : 
    1000           0 :     return enabled;
    1001             : }
    1002             : 
    1003           0 : Sequence< sal_Int16 > DefaultNumberingProvider::getSupportedNumberingTypes(  )
    1004             :                                 throw(RuntimeException, std::exception)
    1005             : {
    1006           0 :     Sequence< sal_Int16 > aRet(nSupported_NumberingTypes );
    1007           0 :     sal_Int16* pArray = aRet.getArray();
    1008             : 
    1009           0 :     bool cjkEnabled = isScriptFlagEnabled(OUString("CJK/CJKFont"));
    1010           0 :     bool ctlEnabled = isScriptFlagEnabled(OUString("CTL/CTLFont"));
    1011             : 
    1012           0 :     for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++) {
    1013           0 :         if ( (aSupportedTypes[i].langOption & LANG_ALL) ||
    1014           0 :                 ((aSupportedTypes[i].langOption & LANG_CJK) && cjkEnabled) ||
    1015           0 :                 ((aSupportedTypes[i].langOption & LANG_CTL) && ctlEnabled) )
    1016           0 :             pArray[i] = aSupportedTypes[i].nType;
    1017             :     }
    1018           0 :     return aRet;
    1019             : }
    1020             : 
    1021          20 : sal_Int16 DefaultNumberingProvider::getNumberingType( const OUString& rNumberingIdentifier )
    1022             :                                 throw(RuntimeException, std::exception)
    1023             : {
    1024         300 :     for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
    1025         300 :         if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
    1026          40 :             return aSupportedTypes[i].nType;
    1027           0 :     throw RuntimeException();
    1028             : }
    1029             : 
    1030          20 : sal_Bool DefaultNumberingProvider::hasNumberingType( const OUString& rNumberingIdentifier )
    1031             :                                 throw(RuntimeException, std::exception)
    1032             : {
    1033         300 :     for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
    1034         300 :         if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
    1035          20 :             return sal_True;
    1036           0 :     return sal_False;
    1037             : }
    1038             : 
    1039           0 : OUString DefaultNumberingProvider::getNumberingIdentifier( sal_Int16 nNumberingType )
    1040             :                                 throw(RuntimeException, std::exception)
    1041             : {
    1042           0 :     for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
    1043           0 :         if(nNumberingType == aSupportedTypes[i].nType)
    1044           0 :             return makeNumberingIdentifier(i);
    1045           0 :     return OUString();
    1046             : }
    1047             : 
    1048           1 : OUString DefaultNumberingProvider::getImplementationName()
    1049             :                 throw( RuntimeException, std::exception )
    1050             : {
    1051           1 :     return OUString("com.sun.star.text.DefaultNumberingProvider");
    1052             : }
    1053             : 
    1054           0 : sal_Bool DefaultNumberingProvider::supportsService(const OUString& rServiceName)
    1055             :                 throw( RuntimeException, std::exception )
    1056             : {
    1057           0 :     return cppu::supportsService(this, rServiceName);
    1058             : }
    1059             : 
    1060           1 : Sequence< OUString > DefaultNumberingProvider::getSupportedServiceNames()
    1061             :                 throw( RuntimeException, std::exception )
    1062             : {
    1063           1 :     Sequence< OUString > aRet(1);
    1064           1 :     aRet[0] = "com.sun.star.text.DefaultNumberingProvider";
    1065           1 :     return aRet;
    1066             : }
    1067             : 
    1068             : } } } }
    1069             : 
    1070             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    1071          59 : com_sun_star_text_DefaultNumberingProvider_get_implementation(
    1072             :     css::uno::XComponentContext *context,
    1073             :     css::uno::Sequence<css::uno::Any> const &)
    1074             : {
    1075          59 :     return cppu::acquire(new css::i18n::DefaultNumberingProvider(context));
    1076             : }
    1077             : 
    1078             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11