From d026447658aec554d922d284926e20e049024c68 Mon Sep 17 00:00:00 2001 From: Pantelis Koukousoulas Date: Sat, 11 Jul 2009 07:45:21 +0300 Subject: [PATCH] Support for greek numerals References: http://www.spinellis.gr/blog/20090625/ (Greek Numerals in OpenOffice.org) http://user.services.openoffice.org/en/forum/viewtopic.php?f=7&t=7269 ([Issue+Workaround] Custom Numbering in Bullets and Numbering) http://www.opengr.net/forum/viewtopic.php?f=13&t=51 And the references transitively mentioned in the above. This functionality was implemented during Greek Coding Camp 2009. NOTE: the present implementation uses the (modern) two-letter version of '6' (sigma taf) instead of the ancient greek / katharevousa version that uses the 'stigma' character. OTOH, we do use the katharevousa 'qoppa' and 'sampi' because there is no standard modern version that replaces them. If you have that many bullets so that these symbols are needed, then you had it comin' anyway :p Author: Pantelis Koukousoulas License: LGPLv3 / MPL Signed-off-by: Pantelis Koukousoulas --- .../defaultnumberingprovider.cxx | 106 ++++++++++++++++++++ offapi/com/sun/star/style/NumberingType.idl | 14 +++ clone/components/cui/source/tabpages/numpages.src | 3 +- clone/writer/sw/source/ui/misc/numberingtypelistbox.src | 26 +++-- 4 files changed, 136 insertions(+), 13 deletions(-) Index: libo/i18npool/source/defaultnumberingprovider/defaultnumberingprovider.cxx =================================================================== --- libo.orig/i18npool/source/defaultnumberingprovider/defaultnumberingprovider.cxx 2011-03-08 19:42:55.000000000 +0000 +++ libo/i18npool/source/defaultnumberingprovider/defaultnumberingprovider.cxx 2011-03-10 12:24:58.000000000 +0000 @@ -44,6 +44,13 @@ #define S_CYR_A "\xD0\xB0" #define S_CYR_B "\xD0\xB1" +//Greek upper case +#define C_GR_A "\xCE\x91" +#define C_GR_B "\xCE\x92" +//Greek lower case +#define S_GR_A "\xCE\xB1" +#define S_GR_B "\xCE\xB2" + #include #include #include @@ -170,6 +177,18 @@ 0x0444, 0x0445, 0x0446, 0x0447, 0x045F, 0x0448 }; +static sal_Unicode table_GreekUpperLetter[] = { + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x03DB, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03DF, + 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03E0 +}; + +static sal_Unicode table_GreekLowerLetter[] = { + 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03DB, 0x03B6, 0x03B7, 0x03B8, + 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03DF, + 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03E1 +}; + static sal_Unicode table_Alphabet_fa[] = { 0x0622, 0x0628, 0x067E, 0x062A, 0x062B, 0x062C, 0x0686, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0698, 0x0633, 0x0634, @@ -314,6 +333,82 @@ s += OUString::valueOf( table_small[ n%tableSize ] ); } +// Greek Letter Numbering + +// KERAIA separates numerals from other text +#define STIGMA (sal_Unicode) 0x03DB +#define LEFT_KERAIA (sal_Unicode) 0x0375 +#define MYRIAD_SYM (sal_Unicode) 0x039C +#define DOT_SYM (sal_Unicode) 0x002E +#define SIGMA_OFFSET 19 +#define TAU_OFFSET 20 +#define MYRIAD 10000 + +/* +* Return the 1-999999 number's representation in the Greek numbering system. +* Adding a "left keraia" to represent numbers in the range 10000 ... 999999 is +* not orthodox, so it's better to use the myriad notation and call this method +* only for numbers up to 9999. +*/ +static +OUStringBuffer gr_smallNum(sal_Unicode table[], int n) +{ + if (n > 9999) + throw IllegalArgumentException(); + + int i = 0; + OUStringBuffer sb; + for (int v = n; v > 0; v /= 10, i++) { + int digit = v % 10; + if (digit == 0) + continue; + + sal_Unicode sign = table[(digit - 1) + 9 * (i % 3)]; + if (sign == STIGMA) { + sb.insert(0, table[TAU_OFFSET]); + sb.insert(0, table[SIGMA_OFFSET]); + } else { + sb.insert(0, sign); + } + + if (i > 2) + sb.insert(0, LEFT_KERAIA); + } + + return sb; +} + +static +void lcl_formatCharsGR( sal_Unicode table[], int n, OUString& s ) +{ + OUStringBuffer sb; + int myriadPower = 2; + + for (int divisor = MYRIAD * MYRIAD; divisor > 1; divisor /= MYRIAD, myriadPower--) { + if (n > divisor - 1) { + /* + * Follow the Diophantus representation of: + * A myriad sign, M(10000) as many times as the power + * followed by the multiplier for the myriad + * followed by a dot + * followed by the rest + * This is enough for 32-bit integers + */ + for (int i = 0; i < myriadPower; i++) + sb.append(MYRIAD_SYM); + + sb.append(gr_smallNum(table, n/divisor)); + n %= divisor; + + if (n > 0) + sb.append(DOT_SYM); + } + } + sb.append(gr_smallNum(table,n)); + + s += sb.makeStringAndClear(); +} + static int should_ignore( OUString s ) { @@ -622,6 +717,15 @@ SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1, result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ... break; + + case CHARS_GREEK_LOWER_LETTER: + lcl_formatCharsGR( table_GreekLowerLetter, number, result); + break; + + case CHARS_GREEK_UPPER_LETTER: + lcl_formatCharsGR( table_GreekUpperLetter, number, result); + break; + case CHARS_PERSIAN: lcl_formatChars(table_Alphabet_fa, sizeof(table_Alphabet_fa) / sizeof(sal_Unicode), number - 1, result); break; @@ -710,6 +814,8 @@ {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}, {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}, {style::NumberingType::CHARS_PERSIAN, NULL, LANG_CTL}, + {style::NumberingType::CHARS_GREEK_LOWER_LETTER, C_GR_A ", " C_GR_B ", ... (gr)", LANG_ALL}, + {style::NumberingType::CHARS_GREEK_UPPER_LETTER, S_GR_A ", " S_GR_B ", ... (gr)", LANG_ALL}, }; static const sal_Int32 nSupported_NumberingTypes = sizeof(aSupportedTypes) / sizeof(Supported_NumberingType); Index: libo/offapi/com/sun/star/style/NumberingType.idl =================================================================== --- libo.orig/offapi/com/sun/star/style/NumberingType.idl 2011-03-08 19:55:40.000000000 +0000 +++ libo/offapi/com/sun/star/style/NumberingType.idl 2011-03-10 12:24:17.000000000 +0000 @@ -471,6 +471,20 @@ */ const short CHARS_CYRILLIC_LOWER_LETTER_N_SR = 51; + //------------------------------------------------------------------------- + /** Numbering in Greek alphabet upper case letters + + @since OOo 3.2 + */ + const short CHARS_GREEK_UPPER_LETTER = 52; + + //------------------------------------------------------------------------- + /** Numbering in Greek alphabet lower case letters + + @since OOo 3.2 + */ + const short CHARS_GREEK_LOWER_LETTER = 53; + }; //============================================================================= Index: libo/clone/components/cui/source/tabpages/numpages.src =================================================================== --- libo.orig/clone/components/cui/source/tabpages/numpages.src 2011-03-08 18:10:47.000000000 +0000 +++ libo/clone/components/cui/source/tabpages/numpages.src 2011-03-10 12:24:17.000000000 +0000 @@ -213,7 +213,8 @@ < "а, б, .., аа, аб, ... (Serbian)" ; 49 /*CHARS_CYRILLIC_LOWER_LETTER_SR */; > ; < "А, Б, .., Аа, Бб, ... (Serbian)" ; 50 /*CHARS_CYRILLIC_UPPER_LETTER_N_SR */; > ; < "а, б, .., аа, бб, ... (Serbian)" ; 51 /*CHARS_CYRILLIC_LOWER_LETTER_N_SR */; > ; - + < "Α, Β, Γ, ... (Greek Upper Letter)"; 52 /*CHARS_GREEK_UPPER_LETTER */; > ; + < "α, β, γ, ... (Greek Lower Letter)"; 53 /*CHARS_GREEK_LOWER_LETTER */; > ; }; }; FixedText FT_PREFIX Index: libo/clone/writer/sw/source/ui/misc/numberingtypelistbox.src =================================================================== --- libo.orig/clone/writer/sw/source/ui/misc/numberingtypelistbox.src 2011-03-10 12:25:19.000000000 +0000 +++ libo/clone/writer/sw/source/ui/misc/numberingtypelistbox.src 2011-03-10 12:27:18.000000000 +0000 @@ -57,6 +57,8 @@ < "а, б, .., аа, аб, ... (Serbian)" ; 49 /*CHARS_CYRILLIC_LOWER_LETTER_SR */; > ; < "А, Б, .., Аа, Бб, ... (Serbian)" ; 50 /*CHARS_CYRILLIC_UPPER_LETTER_N_SR */; > ; < "а, б, .., аа, бб, ... (Serbian)" ; 51 /*CHARS_CYRILLIC_LOWER_LETTER_N_SR */; > ; + < "Α, Β, Γ, ... (Greek Upper Letter)"; 52 /*CHARS_GREEK_UPPER_LETTER */; > ; + < "α, β, γ, ... (Greek Lower Letter)"; 53 /*CHARS_GREEK_LOWER_LETTER */; > ; }; }; };