[goffice] fix chinese number rendering
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] fix chinese number rendering
- Date: Thu, 29 Dec 2011 07:28:31 +0000 (UTC)
commit d1250fa08f385892dc84ead0aed93dd44184130c
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date: Thu Dec 29 00:28:00 2011 -0700
fix chinese number rendering
2011-12-238 Andreas J. Guelzow <aguelzow pyrshep ca>
* goffice/utils/go-format.c (go_format_parse_number_new_1): handle locales
before starting the numbers
(numeral_shapes): adjust
(chinese_marker_shapes): new
(convert_numerals): handle chinese position markers
(handle_chinese): new
(go_format_execute): call handle_chinese
(HANDLE_NUMERAL_SHAPE): call handle_chinese
ChangeLog | 11 ++
goffice/utils/go-format.c | 388 ++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 379 insertions(+), 20 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5080ba7..4b89f43 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2011-12-238 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * goffice/utils/go-format.c (go_format_parse_number_new_1): handle locales
+ before starting the numbers
+ (numeral_shapes): adjust
+ (chinese_marker_shapes): new
+ (convert_numerals): handle chinese position markers
+ (handle_chinese): new
+ (go_format_execute): call handle_chinese
+ (HANDLE_NUMERAL_SHAPE): call handle_chinese
+
2011-12-27 Jean Brefort <jean brefort normalesup org>
* configure.in: inhibit eps support for now because it makes gnumeric
diff --git a/goffice/utils/go-format.c b/goffice/utils/go-format.c
index f6de760..74bd61e 100644
--- a/goffice/utils/go-format.c
+++ b/goffice/utils/go-format.c
@@ -1641,6 +1641,13 @@ go_format_parse_number_new_1 (GString *prg, GOFormatParseState *pstate,
for (i = tno_start; i < tno_end; i++) {
const GOFormatParseItem *ti = &GET_TOKEN(i);
+ if (ti->tt & TT_STARTS_NUMBER)
+ break;
+ handle_common_token (ti->tstr, ti->token, prg);
+ }
+
+ for (i = tno_start; i < tno_end; i++) {
+ const GOFormatParseItem *ti = &GET_TOKEN(i);
if (tno_numstart == -1 && (ti->tt & TT_STARTS_NUMBER))
tno_numstart = i;
@@ -1719,11 +1726,6 @@ go_format_parse_number_new_1 (GString *prg, GOFormatParseState *pstate,
ADD_OP (OP_NUM_ENABLE_THOUSANDS);
}
- for (i = tno_start; i < tno_numstart; i++) {
- const GOFormatParseItem *ti = &GET_TOKEN(i);
- handle_common_token (ti->tstr, ti->token, prg);
- }
- /* OP_NUM_SIGN requires that we already know the shape and shape-flags */
ADD_OP (OP_NUM_SIGN);
if (E_part == 1) {
@@ -2963,33 +2965,314 @@ static char const *numeral_shapes[][10]
{"0","1","2","3","4","5","6","7","8","9"}, /* 19 Unused */
{"0","1","2","3","4","5","6","7","8","9"}, /* 1A Unused */
{"\343\200\207","\344\270\200","\344\272\214","\344\270\211","\345\233\233",
- "\344\272\224","\345\205\255","\344\270\203","\345\205\253","\344\271\235"}, /* 1B Japanese 1 */
+ "\344\272\224","\345\205\255","\344\270\203","\345\205\253","\344\271\235"}, /* 1B Japanese 1 (same as Traditional Chinese 1) */
{"\343\200\207","\345\243\261","\345\274\220","\345\217\202","\345\233\233",
"\344\274\215","\345\205\255","\344\270\203","\345\205\253","\344\271\235"}, /* 1C Japanese 2 */
{"\357\274\220","\357\274\221","\357\274\222","\357\274\223","\357\274\224",
- "\357\274\225","\357\274\226","\357\274\227","\357\274\230","\357\274\231"}, /* 1D Japanese 3 */
- {"\343\200\207","\344\270\200","\344\272\214","\344\270\211","\345\233\233",
+ "\357\274\225","\357\274\226","\357\274\227","\357\274\230","\357\274\231"}, /* 1D Japanese 3 (same as Traditional Chinese 3) */
+ /* see http://www.w3.org/TR/css3-lists/ */
+ {"\351\233\266","\344\270\200","\344\272\214","\344\270\211","\345\233\233",
"\344\272\224","\345\205\255","\344\270\203","\345\205\253","\344\271\235"}, /* 1E Simplified Chinese 1 */
- {"\351\233\266","\345\243\271","\350\264\260","\345\217\204","\350\202\206",
+ {"\351\233\266","\345\243\271","\350\264\260","\345\217\201","\350\202\206",
"\344\274\215","\351\231\206","\346\237\222","\346\215\214","\347\216\226"}, /* 1F Simplified Chinese 2 */
{"\357\274\220","\357\274\221","\357\274\222","\357\274\223","\357\274\224",
"\357\274\225","\357\274\226","\357\274\227","\357\274\230","\357\274\231"}, /* 20 Simplified Chinese 3 */
- {"\343\200\207","\344\270\200","\344\272\214","\344\270\211","\345\233\233",
+ {"\351\233\266","\344\270\200","\344\272\214","\344\270\211","\345\233\233",
"\344\272\224","\345\205\255","\344\270\203","\345\205\253","\344\271\235"}, /* 21 Traditional Chinese 1 */
{"\351\233\266","\345\243\271","\350\262\263","\345\217\203","\350\202\206",
"\344\274\215","\351\231\270","\346\237\222","\346\215\214","\347\216\226"}, /* 22 Traditional Chinese 2 */
{"\357\274\220","\357\274\221","\357\274\222","\357\274\223","\357\274\224",
"\357\274\225","\357\274\226","\357\274\227","\357\274\230","\357\274\231"}, /* 23 Traditional Chinese 3 */
{"\343\200\207","\344\270\200","\344\272\214","\344\270\211","\345\233\233",
- "\344\272\224","\345\205\255","\344\270\203","\345\205\253","\344\271\235"}, /* 24 Korean 1 */
+ "\344\272\224","\345\205\255","\344\270\203","\345\205\253","\344\271\235"}, /* 24 Korean 1 (same as Traditional Chinese 1) */
{"\351\233\266","\345\243\271","\350\262\263","\345\217\203","\345\233\233",
"\344\274\215","\345\205\255","\344\270\203","\345\205\253","\344\271\235"}, /* 25 Korean 2 */
{"\357\274\220","\357\274\221","\357\274\222","\357\274\223","\357\274\224",
- "\357\274\225","\357\274\226","\357\274\227","\357\274\230","\357\274\231"}, /* 26 Korean 3 */
+ "\357\274\225","\357\274\226","\357\274\227","\357\274\230","\357\274\231"}, /* 26 Korean 3 (same as Traditional Chinese 3) */
{"\354\230\201","\354\235\274","\354\235\264","\354\202\274","\354\202\254",
"\354\230\244","\354\234\241","\354\271\240","\355\214\224","\352\265\254"} /* 27 Korean 4 */
};
+/* We still need to separate these in traditional and simplified */
+static char const *chinese_marker_shapes[][20] =
+ {
+ {"\345\215\201", /* 10 U+5341 */
+ "\347\231\276", /* 100 U+767E */
+ "\345\215\203", /* 1000 U+5343 */
+ "\344\270\207", /* 10^4 U+4E07 */
+ "\345\204\204", /* 10^8 U+5104 */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\344\270\244", /* 10^16 U+4E24 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 1B Japanese 1 */
+ {"\346\213\276", /* 10 U+62FE */
+ "\347\231\276", /* 100 U+767E */
+ "\351\230\241", /* 1000 U+9621 */
+ "\350\220\254", /* 10^4 U+842C */
+ "\345\204\204", /* 10^8 U+5104 */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\344\270\244", /* 10^16 U+4E24 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 1C Japanese 2 */
+ {"\345\215\201", /* 10 U+5341 */
+ "\347\231\276", /* 100 U+767E */
+ "\345\215\203", /* 1000 U+5343 */
+ "\344\270\207", /* 10^4 U+4E07 */
+ "\345\204\204", /* 10^8 U+5104 */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\344\270\244", /* 10^16 U+4E24 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 1D Japanese 3 */
+ {"\345\215\201", /* 10 U+5341 */
+ "\347\231\276", /* 100 U+767E */
+ "\345\215\203", /* 1000 U+5343 */
+ "\344\270\207", /* 10^4 U+4E07 */
+ "\344\272\277", /* 10^8 U+4EBF */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\345\205\251", /* 10^16 U+5169 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 1E Simplified Chinese 1 */
+ {"\346\213\276", /* 10 U+62FE */
+ "\344\275\260", /* 100 U+4F70 */
+ "\344\273\237", /* 1000 U+4EDF */
+ "\344\270\207", /* 10^4 U+4E07 */
+ "\344\272\277", /* 10^8 U+4EBF */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\345\205\251", /* 10^16 U+5169 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 1F Simplified Chinese 2 */
+ {"\345\215\201", /* 10 U+5341 */
+ "\347\231\276", /* 100 U+767E */
+ "\345\215\203", /* 1000 U+5343 */
+ "\344\270\207", /* 10^4 U+4E07 */
+ "\344\272\277", /* 10^8 U+4EBF */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\345\205\251", /* 10^16 U+5169 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 20 Simplified Chinese 3 */
+ {"\345\215\201", /* 10 U+5341 */
+ "\347\231\276", /* 100 U+767E */
+ "\345\215\203", /* 1000 U+5343 */
+ "\350\220\254", /* 10^4 U+842C */
+ "\345\204\204", /* 10^8 U+5104 */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\344\270\244", /* 10^16 U+4E24 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 21 Traditional Chinese 1 */
+ {"\346\213\276", /* 10 U+62FE */
+ "\344\275\260", /* 100 U+4F70 */
+ "\344\273\237", /* 1000 U+4EDF */
+ "\350\220\254", /* 10^4 U+842C */
+ "\345\204\204", /* 10^8 U+5104 */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\344\270\244", /* 10^16 U+4E24 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 22 Traditional Chinese 2 */
+ {"\345\215\201", /* 10 U+5341 */
+ "\347\231\276", /* 100 U+767E */
+ "\345\215\203", /* 1000 U+5343 */
+ "\350\220\254", /* 10^4 U+842C */
+ "\345\204\204", /* 10^8 U+5104 */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\344\270\244", /* 10^16 U+4E24 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 23 Traditional Chinese 3 */
+ {"\345\215\201", /* 10 U+5341 */
+ "\347\231\276", /* 100 U+767E */
+ "\345\215\203", /* 1000 U+5343 */
+ "\344\270\207", /* 10^4 U+4E07 */
+ "\345\204\204", /* 10^8 U+5104 */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\344\270\244", /* 10^16 U+4E24 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 24 Korean 1 */
+ {"\346\213\276", /* 10 U+62FE */
+ "\347\231\276", /* 100 U+767E */
+ "\344\273\237", /* 1000 U+4EDF */
+ "\350\220\254", /* 10^4 U+842C */
+ "\345\204\204", /* 10^8 U+5104 */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\344\270\244", /* 10^16 U+4E24 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 25 Korean 2 */
+ {"\345\215\201", /* 10 U+5341 */
+ "\347\231\276", /* 100 U+767E */
+ "\345\215\203", /* 1000 U+5343 */
+ "\350\220\254", /* 10^4 U+842C */
+ "\345\204\204", /* 10^8 U+5104 */
+ "\345\205\206", /* 10^12 U+5146 */
+ "\344\270\244", /* 10^16 U+4E24 */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ }, /* 26 Korean 3 */
+ {"\354\213\255", /* 10 U+ */
+ "\353\260\261", /* 100 U+ */
+ "\354\262\234", /* 1000 U+ */
+ "\353\247\214", /* 10^4 U+B9CC */
+ "\354\226\265", /* 10^8 U+C5B5 */
+ "\354\241\260", /* 10^12 U+C870 */
+ "\352\262\275", /* 10^16 U+ACBD */
+ "", /* 10^20 U+ */
+ "", /* 10^24 U+ */
+ "", /* 10^28 U+ */
+ "", /* 10^32 U+ */
+ "", /* 10^36 U+ */
+ "", /* 10^40 U+ */
+ "", /* 10^44 U+ */
+ "", /* 10^48 U+ */
+ "", /* 10^52 U+ */
+ "", /* 10^56 U+ */
+ "", /* 10^60 U+ */
+ "", /* 10^64 U+ */
+ "" /* 10^68 U+ */
+ } /* 27 Korean 4 */
+ };
+
+
+
G_STATIC_ASSERT (G_N_ELEMENTS (minus_shapes) == G_N_ELEMENTS (numeral_shapes));
G_STATIC_ASSERT (G_N_ELEMENTS (plus_shapes) == G_N_ELEMENTS (numeral_shapes));
@@ -3002,15 +3285,24 @@ convert_numerals (GString *str, gsize from, gsize to, guint shape)
if (shape >= G_N_ELEMENTS (numeral_shapes))
return FALSE;
for (i = to; i >= (int)from; i--) {
- if (str->str[i] >= 0x30 /* numeral 0 */&&
- str->str[i] <= 0x39 /* numeral 9 */) {
- gint num = str->str[i] - 0x30;
+ if (str->str[i] >= '0' &&
+ str->str[i] <= '9') {
+ gint num = str->str[i] - '0';
char const *num_str = numeral_shapes[shape][num];
if (*num_str != 0) {
go_string_replace (str, i, 1, num_str, -1);
val = TRUE;
}
- }
+ } else if (shape >= 0x1b && shape <= 0x27 &&
+ str->str[i] >= 'a' &&
+ str->str[i] <= 't') {
+ gint num = str->str[i] - 'a';
+ char const *num_str = chinese_marker_shapes[shape - 0x1B][num];
+ if (*num_str != 0) {
+ go_string_replace (str, i, 1, num_str, -1);
+ val = TRUE;
+ }
+ }
}
return val;
}
@@ -3046,6 +3338,59 @@ convert_sign (GString *str, size_t i, guint shape, guint shape_flags)
go_string_replace (str, i, 1, shaped_sign, -1);
return TRUE;
}
+
+static void
+handle_chinese (GString *numtxt, const char **dot, guint numeral_shape)
+{
+ GString *ntxt;
+ char const *last;
+ gint i, wan;
+ gboolean wan_written = TRUE;
+ gboolean digit_written = FALSE;
+ gboolean suppress_ten;
+ if (numeral_shape < 0x1B || numeral_shape > 0x27)
+ return;
+ last = ((dot && *dot) ? *dot - 1 : numtxt->str + (numtxt->len - 1));
+ if (last <= numtxt->str + 1)
+ return;
+
+ ntxt = g_string_sized_new (100);
+ suppress_ten = (numeral_shape == 0x1b || numeral_shape == 0x1d || numeral_shape == 0x26);
+ i = 0;
+ wan = 0;
+ while (last >= numtxt->str) {
+ if (*last >= '0' && *last <= '9') {
+ if (*last > '0' || digit_written) {
+ if (!wan_written) {
+ g_string_prepend_c (ntxt, 'c' + wan);
+ wan_written = TRUE;
+ }
+ if (i > 0)
+ g_string_prepend_c (ntxt, 'a' + i - 1);
+ if (!suppress_ten || *last != '1')
+ g_string_prepend_c (ntxt, *last);
+ digit_written = TRUE;
+ }
+ } else g_string_prepend_c (ntxt, *last);
+ if (++i > 3) {
+ i = i % 4;
+ wan++;
+ if (wan > 't' - 'c')
+ wan--;
+ wan_written = FALSE;
+ digit_written = FALSE;
+ }
+ last --;
+ }
+
+ if (dot && *dot) {
+ gint len = ntxt->len;
+ g_string_append (ntxt, *dot);
+ *dot = ntxt->str + len;
+ }
+ g_string_assign (numtxt, ntxt->str);
+ g_string_free (ntxt, TRUE);
+}
#endif
#define INSERT_MINUS(pos) do { \
@@ -3530,6 +3875,7 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
numtxt = g_string_sized_new (100);
g_string_printf (numtxt, "%.*" FORMAT_f, n, val);
dot = strstr (numtxt->str, decimal->str);
+ handle_chinese (numtxt, &dot, numeral_shape);
if (dot) {
size_t i = numtxt->len;
dotpos = dot - numtxt->str;
@@ -4103,11 +4449,13 @@ go_format_measure_strlen (const GString *str,
#define HANDLE_NUMERAL_SHAPE \
do { \
- if (num_shape > 1) \
- /* 0: not set; 1: Western */ \
- convert_numerals (str, 0, str->len - 1, num_shape); \
+ if (num_shape > 1) { \
+ /* 0: not set; 1: Western */ \
+ handle_chinese (str, NULL, num_shape); \
+ convert_numerals (str, 0, str->len - 1, num_shape); \
+ } \
} while (0)
-
+
/*
* go_format_general:
* @layout: Optional PangoLayout, probably preseeded with font attribute.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]