From e709cdbae31228c8e5d275b36d3710d959ca2c1a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 29 Dec 2000 03:56:06 +0000 Subject: [PATCH] Added support for composite Unicode characters in MultiByteToWideChar and WideCharToMultiByte. --- memory/codepage.c | 3 - unicode/Makefile.in | 1 + unicode/compose.c | 1089 +++++++++++++++++++++++++++++++++++++++++++ unicode/cpmap.pl | 153 +++++- unicode/mbtowc.c | 110 ++++- unicode/wctomb.c | 279 +++++++++-- 6 files changed, 1578 insertions(+), 57 deletions(-) create mode 100644 unicode/compose.c diff --git a/memory/codepage.c b/memory/codepage.c index 5a7efd93d34..142d693726e 100644 --- a/memory/codepage.c +++ b/memory/codepage.c @@ -254,7 +254,6 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen, if (srclen == -1) srclen = strlen(src) + 1; - if (flags & MB_COMPOSITE) FIXME("MB_COMPOSITE not supported\n"); if (flags & MB_USEGLYPHCHARS) FIXME("MB_USEGLYPHCHARS not supported\n"); switch(page) @@ -330,8 +329,6 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen, if (srclen == -1) srclen = strlenW(src) + 1; -/* if (flags & WC_COMPOSITECHECK) FIXME( "WC_COMPOSITECHECK (%lx) not supported\n", flags );*/ - switch(page) { case CP_UTF7: diff --git a/unicode/Makefile.in b/unicode/Makefile.in index 832d107aea0..e92599eac74 100644 --- a/unicode/Makefile.in +++ b/unicode/Makefile.in @@ -70,6 +70,7 @@ CODEPAGES = \ C_SRCS = \ casemap.c \ + compose.c \ cptable.c \ mbtowc.c \ string.c \ diff --git a/unicode/compose.c b/unicode/compose.c new file mode 100644 index 00000000000..7fc034501ee --- /dev/null +++ b/unicode/compose.c @@ -0,0 +1,1089 @@ +/* Unicode char composition */ +/* Automatically generated; DO NOT EDIT!! */ + +#include "wine/unicode.h" + +const WCHAR unicode_compose_table[0x844] = +{ + /* second chars + offsets */ + 0x0300, 0x0046, 0x0301, 0x009a, 0x0302, 0x0110, 0x0303, 0x0130, + 0x0304, 0x014c, 0x0306, 0x0178, 0x0307, 0x0198, 0x0308, 0x01c6, + 0x0309, 0x01fc, 0x030a, 0x0214, 0x030b, 0x021a, 0x030c, 0x0220, + 0x030f, 0x0245, 0x0311, 0x0253, 0x0313, 0x025f, 0x0314, 0x026d, + 0x031b, 0x027d, 0x0323, 0x0281, 0x0324, 0x02ab, 0x0325, 0x02ad, + 0x0326, 0x02af, 0x0327, 0x02b3, 0x0328, 0x02c9, 0x032d, 0x02d3, + 0x032e, 0x02df, 0x0330, 0x02e1, 0x0331, 0x02e7, 0x0338, 0x02f8, + 0x0342, 0x0324, 0x0345, 0x0341, 0x05b4, 0x0380, 0x05b7, 0x0381, + 0x05b8, 0x0383, 0x05b9, 0x0384, 0x05bc, 0x0385, 0x05bf, 0x039b, + 0x05c1, 0x039e, 0x05c2, 0x03a0, 0x0653, 0x03a2, 0x0654, 0x03a3, + 0x0655, 0x03a9, 0x093c, 0x03aa, 0x09bc, 0x03b5, 0x09be, 0x03b8, + 0x09d7, 0x03b9, 0x0a3c, 0x03ba, 0x0b3c, 0x03c0, 0x0b3e, 0x03c2, + 0x0b56, 0x03c3, 0x0b57, 0x03c4, 0x0bbe, 0x03c5, 0x0bd7, 0x03c7, + 0x0c56, 0x03c9, 0x0cc2, 0x03ca, 0x0cd5, 0x03cb, 0x0cd6, 0x03ce, + 0x0d3e, 0x03cf, 0x0d57, 0x03d1, 0x0dca, 0x03d2, 0x0dcf, 0x03d4, + 0x0ddf, 0x03d5, 0x0f72, 0x03d6, 0x0f74, 0x03d7, 0x0f80, 0x03d8, + 0x0fb5, 0x03db, 0x0fb7, 0x03dd, 0x102e, 0x03e7, 0x3099, 0x03e8, + 0x309a, 0x0418, 0x0000, 0x0422, + /* 0x0300 */ + 0x0041, 0x00c0, 0x0045, 0x00c8, 0x0049, 0x00cc, 0x004e, 0x01f8, + 0x004f, 0x00d2, 0x0055, 0x00d9, 0x0057, 0x1e80, 0x0059, 0x1ef2, + 0x0061, 0x00e0, 0x0065, 0x00e8, 0x0069, 0x00ec, 0x006e, 0x01f9, + 0x006f, 0x00f2, 0x0075, 0x00f9, 0x0077, 0x1e81, 0x0079, 0x1ef3, + 0x00a8, 0x1fed, 0x00c2, 0x1ea6, 0x00ca, 0x1ec0, 0x00d4, 0x1ed2, + 0x00dc, 0x01db, 0x00e2, 0x1ea7, 0x00ea, 0x1ec1, 0x00f4, 0x1ed3, + 0x00fc, 0x01dc, 0x0102, 0x1eb0, 0x0103, 0x1eb1, 0x0112, 0x1e14, + 0x0113, 0x1e15, 0x014c, 0x1e50, 0x014d, 0x1e51, 0x01a0, 0x1edc, + 0x01a1, 0x1edd, 0x01af, 0x1eea, 0x01b0, 0x1eeb, 0x0391, 0x1fba, + 0x0395, 0x1fc8, 0x0397, 0x1fca, 0x0399, 0x1fda, 0x039f, 0x1ff8, + 0x03a5, 0x1fea, 0x03a9, 0x1ffa, 0x03b1, 0x1f70, 0x03b5, 0x1f72, + 0x03b7, 0x1f74, 0x03b9, 0x1f76, 0x03bf, 0x1f78, 0x03c5, 0x1f7a, + 0x03c9, 0x1f7c, 0x03ca, 0x1fd2, 0x03cb, 0x1fe2, 0x0415, 0x0400, + 0x0418, 0x040d, 0x0435, 0x0450, 0x0438, 0x045d, 0x1f00, 0x1f02, + 0x1f01, 0x1f03, 0x1f08, 0x1f0a, 0x1f09, 0x1f0b, 0x1f10, 0x1f12, + 0x1f11, 0x1f13, 0x1f18, 0x1f1a, 0x1f19, 0x1f1b, 0x1f20, 0x1f22, + 0x1f21, 0x1f23, 0x1f28, 0x1f2a, 0x1f29, 0x1f2b, 0x1f30, 0x1f32, + 0x1f31, 0x1f33, 0x1f38, 0x1f3a, 0x1f39, 0x1f3b, 0x1f40, 0x1f42, + 0x1f41, 0x1f43, 0x1f48, 0x1f4a, 0x1f49, 0x1f4b, 0x1f50, 0x1f52, + 0x1f51, 0x1f53, 0x1f59, 0x1f5b, 0x1f60, 0x1f62, 0x1f61, 0x1f63, + 0x1f68, 0x1f6a, 0x1f69, 0x1f6b, 0x1fbf, 0x1fcd, 0x1ffe, 0x1fdd, + /* 0x0301 */ + 0x0041, 0x00c1, 0x0043, 0x0106, 0x0045, 0x00c9, 0x0047, 0x01f4, + 0x0049, 0x00cd, 0x004b, 0x1e30, 0x004c, 0x0139, 0x004d, 0x1e3e, + 0x004e, 0x0143, 0x004f, 0x00d3, 0x0050, 0x1e54, 0x0052, 0x0154, + 0x0053, 0x015a, 0x0055, 0x00da, 0x0057, 0x1e82, 0x0059, 0x00dd, + 0x005a, 0x0179, 0x0061, 0x00e1, 0x0063, 0x0107, 0x0065, 0x00e9, + 0x0067, 0x01f5, 0x0069, 0x00ed, 0x006b, 0x1e31, 0x006c, 0x013a, + 0x006d, 0x1e3f, 0x006e, 0x0144, 0x006f, 0x00f3, 0x0070, 0x1e55, + 0x0072, 0x0155, 0x0073, 0x015b, 0x0075, 0x00fa, 0x0077, 0x1e83, + 0x0079, 0x00fd, 0x007a, 0x017a, 0x00a8, 0x0385, 0x00c2, 0x1ea4, + 0x00c5, 0x01fa, 0x00c6, 0x01fc, 0x00c7, 0x1e08, 0x00ca, 0x1ebe, + 0x00cf, 0x1e2e, 0x00d4, 0x1ed0, 0x00d5, 0x1e4c, 0x00d8, 0x01fe, + 0x00dc, 0x01d7, 0x00e2, 0x1ea5, 0x00e5, 0x01fb, 0x00e6, 0x01fd, + 0x00e7, 0x1e09, 0x00ea, 0x1ebf, 0x00ef, 0x1e2f, 0x00f4, 0x1ed1, + 0x00f5, 0x1e4d, 0x00f8, 0x01ff, 0x00fc, 0x01d8, 0x0102, 0x1eae, + 0x0103, 0x1eaf, 0x0112, 0x1e16, 0x0113, 0x1e17, 0x014c, 0x1e52, + 0x014d, 0x1e53, 0x0168, 0x1e78, 0x0169, 0x1e79, 0x01a0, 0x1eda, + 0x01a1, 0x1edb, 0x01af, 0x1ee8, 0x01b0, 0x1ee9, 0x0308, 0x0344, + 0x0391, 0x0386, 0x0395, 0x0388, 0x0397, 0x0389, 0x0399, 0x038a, + 0x039f, 0x038c, 0x03a5, 0x038e, 0x03a9, 0x038f, 0x03b1, 0x03ac, + 0x03b5, 0x03ad, 0x03b7, 0x03ae, 0x03b9, 0x03af, 0x03bf, 0x03cc, + 0x03c5, 0x03cd, 0x03c9, 0x03ce, 0x03ca, 0x0390, 0x03cb, 0x03b0, + 0x03d2, 0x03d3, 0x0413, 0x0403, 0x041a, 0x040c, 0x0433, 0x0453, + 0x043a, 0x045c, 0x1f00, 0x1f04, 0x1f01, 0x1f05, 0x1f08, 0x1f0c, + 0x1f09, 0x1f0d, 0x1f10, 0x1f14, 0x1f11, 0x1f15, 0x1f18, 0x1f1c, + 0x1f19, 0x1f1d, 0x1f20, 0x1f24, 0x1f21, 0x1f25, 0x1f28, 0x1f2c, + 0x1f29, 0x1f2d, 0x1f30, 0x1f34, 0x1f31, 0x1f35, 0x1f38, 0x1f3c, + 0x1f39, 0x1f3d, 0x1f40, 0x1f44, 0x1f41, 0x1f45, 0x1f48, 0x1f4c, + 0x1f49, 0x1f4d, 0x1f50, 0x1f54, 0x1f51, 0x1f55, 0x1f59, 0x1f5d, + 0x1f60, 0x1f64, 0x1f61, 0x1f65, 0x1f68, 0x1f6c, 0x1f69, 0x1f6d, + 0x1fbf, 0x1fce, 0x1ffe, 0x1fde, + /* 0x0302 */ + 0x0041, 0x00c2, 0x0043, 0x0108, 0x0045, 0x00ca, 0x0047, 0x011c, + 0x0048, 0x0124, 0x0049, 0x00ce, 0x004a, 0x0134, 0x004f, 0x00d4, + 0x0053, 0x015c, 0x0055, 0x00db, 0x0057, 0x0174, 0x0059, 0x0176, + 0x005a, 0x1e90, 0x0061, 0x00e2, 0x0063, 0x0109, 0x0065, 0x00ea, + 0x0067, 0x011d, 0x0068, 0x0125, 0x0069, 0x00ee, 0x006a, 0x0135, + 0x006f, 0x00f4, 0x0073, 0x015d, 0x0075, 0x00fb, 0x0077, 0x0175, + 0x0079, 0x0177, 0x007a, 0x1e91, 0x1ea0, 0x1eac, 0x1ea1, 0x1ead, + 0x1eb8, 0x1ec6, 0x1eb9, 0x1ec7, 0x1ecc, 0x1ed8, 0x1ecd, 0x1ed9, + /* 0x0303 */ + 0x0041, 0x00c3, 0x0045, 0x1ebc, 0x0049, 0x0128, 0x004e, 0x00d1, + 0x004f, 0x00d5, 0x0055, 0x0168, 0x0056, 0x1e7c, 0x0059, 0x1ef8, + 0x0061, 0x00e3, 0x0065, 0x1ebd, 0x0069, 0x0129, 0x006e, 0x00f1, + 0x006f, 0x00f5, 0x0075, 0x0169, 0x0076, 0x1e7d, 0x0079, 0x1ef9, + 0x00c2, 0x1eaa, 0x00ca, 0x1ec4, 0x00d4, 0x1ed6, 0x00e2, 0x1eab, + 0x00ea, 0x1ec5, 0x00f4, 0x1ed7, 0x0102, 0x1eb4, 0x0103, 0x1eb5, + 0x01a0, 0x1ee0, 0x01a1, 0x1ee1, 0x01af, 0x1eee, 0x01b0, 0x1eef, + /* 0x0304 */ + 0x0041, 0x0100, 0x0045, 0x0112, 0x0047, 0x1e20, 0x0049, 0x012a, + 0x004f, 0x014c, 0x0055, 0x016a, 0x0059, 0x0232, 0x0061, 0x0101, + 0x0065, 0x0113, 0x0067, 0x1e21, 0x0069, 0x012b, 0x006f, 0x014d, + 0x0075, 0x016b, 0x0079, 0x0233, 0x00c4, 0x01de, 0x00c6, 0x01e2, + 0x00d5, 0x022c, 0x00d6, 0x022a, 0x00dc, 0x01d5, 0x00e4, 0x01df, + 0x00e6, 0x01e3, 0x00f5, 0x022d, 0x00f6, 0x022b, 0x00fc, 0x01d6, + 0x01ea, 0x01ec, 0x01eb, 0x01ed, 0x0226, 0x01e0, 0x0227, 0x01e1, + 0x022e, 0x0230, 0x022f, 0x0231, 0x0391, 0x1fb9, 0x0399, 0x1fd9, + 0x03a5, 0x1fe9, 0x03b1, 0x1fb1, 0x03b9, 0x1fd1, 0x03c5, 0x1fe1, + 0x0418, 0x04e2, 0x0423, 0x04ee, 0x0438, 0x04e3, 0x0443, 0x04ef, + 0x1e36, 0x1e38, 0x1e37, 0x1e39, 0x1e5a, 0x1e5c, 0x1e5b, 0x1e5d, + /* 0x0306 */ + 0x0041, 0x0102, 0x0045, 0x0114, 0x0047, 0x011e, 0x0049, 0x012c, + 0x004f, 0x014e, 0x0055, 0x016c, 0x0061, 0x0103, 0x0065, 0x0115, + 0x0067, 0x011f, 0x0069, 0x012d, 0x006f, 0x014f, 0x0075, 0x016d, + 0x0228, 0x1e1c, 0x0229, 0x1e1d, 0x0391, 0x1fb8, 0x0399, 0x1fd8, + 0x03a5, 0x1fe8, 0x03b1, 0x1fb0, 0x03b9, 0x1fd0, 0x03c5, 0x1fe0, + 0x0410, 0x04d0, 0x0415, 0x04d6, 0x0416, 0x04c1, 0x0418, 0x0419, + 0x0423, 0x040e, 0x0430, 0x04d1, 0x0435, 0x04d7, 0x0436, 0x04c2, + 0x0438, 0x0439, 0x0443, 0x045e, 0x1ea0, 0x1eb6, 0x1ea1, 0x1eb7, + /* 0x0307 */ + 0x0041, 0x0226, 0x0042, 0x1e02, 0x0043, 0x010a, 0x0044, 0x1e0a, + 0x0045, 0x0116, 0x0046, 0x1e1e, 0x0047, 0x0120, 0x0048, 0x1e22, + 0x0049, 0x0130, 0x004d, 0x1e40, 0x004e, 0x1e44, 0x004f, 0x022e, + 0x0050, 0x1e56, 0x0052, 0x1e58, 0x0053, 0x1e60, 0x0054, 0x1e6a, + 0x0057, 0x1e86, 0x0058, 0x1e8a, 0x0059, 0x1e8e, 0x005a, 0x017b, + 0x0061, 0x0227, 0x0062, 0x1e03, 0x0063, 0x010b, 0x0064, 0x1e0b, + 0x0065, 0x0117, 0x0066, 0x1e1f, 0x0067, 0x0121, 0x0068, 0x1e23, + 0x006d, 0x1e41, 0x006e, 0x1e45, 0x006f, 0x022f, 0x0070, 0x1e57, + 0x0072, 0x1e59, 0x0073, 0x1e61, 0x0074, 0x1e6b, 0x0077, 0x1e87, + 0x0078, 0x1e8b, 0x0079, 0x1e8f, 0x007a, 0x017c, 0x015a, 0x1e64, + 0x015b, 0x1e65, 0x0160, 0x1e66, 0x0161, 0x1e67, 0x017f, 0x1e9b, + 0x1e62, 0x1e68, 0x1e63, 0x1e69, + /* 0x0308 */ + 0x0041, 0x00c4, 0x0045, 0x00cb, 0x0048, 0x1e26, 0x0049, 0x00cf, + 0x004f, 0x00d6, 0x0055, 0x00dc, 0x0057, 0x1e84, 0x0058, 0x1e8c, + 0x0059, 0x0178, 0x0061, 0x00e4, 0x0065, 0x00eb, 0x0068, 0x1e27, + 0x0069, 0x00ef, 0x006f, 0x00f6, 0x0074, 0x1e97, 0x0075, 0x00fc, + 0x0077, 0x1e85, 0x0078, 0x1e8d, 0x0079, 0x00ff, 0x00d5, 0x1e4e, + 0x00f5, 0x1e4f, 0x016a, 0x1e7a, 0x016b, 0x1e7b, 0x0399, 0x03aa, + 0x03a5, 0x03ab, 0x03b9, 0x03ca, 0x03c5, 0x03cb, 0x03d2, 0x03d4, + 0x0406, 0x0407, 0x0410, 0x04d2, 0x0415, 0x0401, 0x0416, 0x04dc, + 0x0417, 0x04de, 0x0418, 0x04e4, 0x041e, 0x04e6, 0x0423, 0x04f0, + 0x0427, 0x04f4, 0x042b, 0x04f8, 0x042d, 0x04ec, 0x0430, 0x04d3, + 0x0435, 0x0451, 0x0436, 0x04dd, 0x0437, 0x04df, 0x0438, 0x04e5, + 0x043e, 0x04e7, 0x0443, 0x04f1, 0x0447, 0x04f5, 0x044b, 0x04f9, + 0x044d, 0x04ed, 0x0456, 0x0457, 0x04d8, 0x04da, 0x04d9, 0x04db, + 0x04e8, 0x04ea, 0x04e9, 0x04eb, + /* 0x0309 */ + 0x0041, 0x1ea2, 0x0045, 0x1eba, 0x0049, 0x1ec8, 0x004f, 0x1ece, + 0x0055, 0x1ee6, 0x0059, 0x1ef6, 0x0061, 0x1ea3, 0x0065, 0x1ebb, + 0x0069, 0x1ec9, 0x006f, 0x1ecf, 0x0075, 0x1ee7, 0x0079, 0x1ef7, + 0x00c2, 0x1ea8, 0x00ca, 0x1ec2, 0x00d4, 0x1ed4, 0x00e2, 0x1ea9, + 0x00ea, 0x1ec3, 0x00f4, 0x1ed5, 0x0102, 0x1eb2, 0x0103, 0x1eb3, + 0x01a0, 0x1ede, 0x01a1, 0x1edf, 0x01af, 0x1eec, 0x01b0, 0x1eed, + /* 0x030a */ + 0x0041, 0x00c5, 0x0055, 0x016e, 0x0061, 0x00e5, 0x0075, 0x016f, + 0x0077, 0x1e98, 0x0079, 0x1e99, + /* 0x030b */ + 0x004f, 0x0150, 0x0055, 0x0170, 0x006f, 0x0151, 0x0075, 0x0171, + 0x0423, 0x04f2, 0x0443, 0x04f3, + /* 0x030c */ + 0x0041, 0x01cd, 0x0043, 0x010c, 0x0044, 0x010e, 0x0045, 0x011a, + 0x0047, 0x01e6, 0x0048, 0x021e, 0x0049, 0x01cf, 0x004b, 0x01e8, + 0x004c, 0x013d, 0x004e, 0x0147, 0x004f, 0x01d1, 0x0052, 0x0158, + 0x0053, 0x0160, 0x0054, 0x0164, 0x0055, 0x01d3, 0x005a, 0x017d, + 0x0061, 0x01ce, 0x0063, 0x010d, 0x0064, 0x010f, 0x0065, 0x011b, + 0x0067, 0x01e7, 0x0068, 0x021f, 0x0069, 0x01d0, 0x006a, 0x01f0, + 0x006b, 0x01e9, 0x006c, 0x013e, 0x006e, 0x0148, 0x006f, 0x01d2, + 0x0072, 0x0159, 0x0073, 0x0161, 0x0074, 0x0165, 0x0075, 0x01d4, + 0x007a, 0x017e, 0x00dc, 0x01d9, 0x00fc, 0x01da, 0x01b7, 0x01ee, + 0x0292, 0x01ef, + /* 0x030f */ + 0x0041, 0x0200, 0x0045, 0x0204, 0x0049, 0x0208, 0x004f, 0x020c, + 0x0052, 0x0210, 0x0055, 0x0214, 0x0061, 0x0201, 0x0065, 0x0205, + 0x0069, 0x0209, 0x006f, 0x020d, 0x0072, 0x0211, 0x0075, 0x0215, + 0x0474, 0x0476, 0x0475, 0x0477, + /* 0x0311 */ + 0x0041, 0x0202, 0x0045, 0x0206, 0x0049, 0x020a, 0x004f, 0x020e, + 0x0052, 0x0212, 0x0055, 0x0216, 0x0061, 0x0203, 0x0065, 0x0207, + 0x0069, 0x020b, 0x006f, 0x020f, 0x0072, 0x0213, 0x0075, 0x0217, + /* 0x0313 */ + 0x0391, 0x1f08, 0x0395, 0x1f18, 0x0397, 0x1f28, 0x0399, 0x1f38, + 0x039f, 0x1f48, 0x03a9, 0x1f68, 0x03b1, 0x1f00, 0x03b5, 0x1f10, + 0x03b7, 0x1f20, 0x03b9, 0x1f30, 0x03bf, 0x1f40, 0x03c1, 0x1fe4, + 0x03c5, 0x1f50, 0x03c9, 0x1f60, + /* 0x0314 */ + 0x0391, 0x1f09, 0x0395, 0x1f19, 0x0397, 0x1f29, 0x0399, 0x1f39, + 0x039f, 0x1f49, 0x03a1, 0x1fec, 0x03a5, 0x1f59, 0x03a9, 0x1f69, + 0x03b1, 0x1f01, 0x03b5, 0x1f11, 0x03b7, 0x1f21, 0x03b9, 0x1f31, + 0x03bf, 0x1f41, 0x03c1, 0x1fe5, 0x03c5, 0x1f51, 0x03c9, 0x1f61, + /* 0x031b */ + 0x004f, 0x01a0, 0x0055, 0x01af, 0x006f, 0x01a1, 0x0075, 0x01b0, + /* 0x0323 */ + 0x0041, 0x1ea0, 0x0042, 0x1e04, 0x0044, 0x1e0c, 0x0045, 0x1eb8, + 0x0048, 0x1e24, 0x0049, 0x1eca, 0x004b, 0x1e32, 0x004c, 0x1e36, + 0x004d, 0x1e42, 0x004e, 0x1e46, 0x004f, 0x1ecc, 0x0052, 0x1e5a, + 0x0053, 0x1e62, 0x0054, 0x1e6c, 0x0055, 0x1ee4, 0x0056, 0x1e7e, + 0x0057, 0x1e88, 0x0059, 0x1ef4, 0x005a, 0x1e92, 0x0061, 0x1ea1, + 0x0062, 0x1e05, 0x0064, 0x1e0d, 0x0065, 0x1eb9, 0x0068, 0x1e25, + 0x0069, 0x1ecb, 0x006b, 0x1e33, 0x006c, 0x1e37, 0x006d, 0x1e43, + 0x006e, 0x1e47, 0x006f, 0x1ecd, 0x0072, 0x1e5b, 0x0073, 0x1e63, + 0x0074, 0x1e6d, 0x0075, 0x1ee5, 0x0076, 0x1e7f, 0x0077, 0x1e89, + 0x0079, 0x1ef5, 0x007a, 0x1e93, 0x01a0, 0x1ee2, 0x01a1, 0x1ee3, + 0x01af, 0x1ef0, 0x01b0, 0x1ef1, + /* 0x0324 */ + 0x0055, 0x1e72, 0x0075, 0x1e73, + /* 0x0325 */ + 0x0041, 0x1e00, 0x0061, 0x1e01, + /* 0x0326 */ + 0x0053, 0x0218, 0x0054, 0x021a, 0x0073, 0x0219, 0x0074, 0x021b, + /* 0x0327 */ + 0x0043, 0x00c7, 0x0044, 0x1e10, 0x0045, 0x0228, 0x0047, 0x0122, + 0x0048, 0x1e28, 0x004b, 0x0136, 0x004c, 0x013b, 0x004e, 0x0145, + 0x0052, 0x0156, 0x0053, 0x015e, 0x0054, 0x0162, 0x0063, 0x00e7, + 0x0064, 0x1e11, 0x0065, 0x0229, 0x0067, 0x0123, 0x0068, 0x1e29, + 0x006b, 0x0137, 0x006c, 0x013c, 0x006e, 0x0146, 0x0072, 0x0157, + 0x0073, 0x015f, 0x0074, 0x0163, + /* 0x0328 */ + 0x0041, 0x0104, 0x0045, 0x0118, 0x0049, 0x012e, 0x004f, 0x01ea, + 0x0055, 0x0172, 0x0061, 0x0105, 0x0065, 0x0119, 0x0069, 0x012f, + 0x006f, 0x01eb, 0x0075, 0x0173, + /* 0x032d */ + 0x0044, 0x1e12, 0x0045, 0x1e18, 0x004c, 0x1e3c, 0x004e, 0x1e4a, + 0x0054, 0x1e70, 0x0055, 0x1e76, 0x0064, 0x1e13, 0x0065, 0x1e19, + 0x006c, 0x1e3d, 0x006e, 0x1e4b, 0x0074, 0x1e71, 0x0075, 0x1e77, + /* 0x032e */ + 0x0048, 0x1e2a, 0x0068, 0x1e2b, + /* 0x0330 */ + 0x0045, 0x1e1a, 0x0049, 0x1e2c, 0x0055, 0x1e74, 0x0065, 0x1e1b, + 0x0069, 0x1e2d, 0x0075, 0x1e75, + /* 0x0331 */ + 0x0042, 0x1e06, 0x0044, 0x1e0e, 0x004b, 0x1e34, 0x004c, 0x1e3a, + 0x004e, 0x1e48, 0x0052, 0x1e5e, 0x0054, 0x1e6e, 0x005a, 0x1e94, + 0x0062, 0x1e07, 0x0064, 0x1e0f, 0x0068, 0x1e96, 0x006b, 0x1e35, + 0x006c, 0x1e3b, 0x006e, 0x1e49, 0x0072, 0x1e5f, 0x0074, 0x1e6f, + 0x007a, 0x1e95, + /* 0x0338 */ + 0x003c, 0x226e, 0x003d, 0x2260, 0x003e, 0x226f, 0x2190, 0x219a, + 0x2192, 0x219b, 0x2194, 0x21ae, 0x21d0, 0x21cd, 0x21d2, 0x21cf, + 0x21d4, 0x21ce, 0x2203, 0x2204, 0x2208, 0x2209, 0x220b, 0x220c, + 0x2223, 0x2224, 0x2225, 0x2226, 0x223c, 0x2241, 0x2243, 0x2244, + 0x2245, 0x2247, 0x2248, 0x2249, 0x224d, 0x226d, 0x2261, 0x2262, + 0x2264, 0x2270, 0x2265, 0x2271, 0x2272, 0x2274, 0x2273, 0x2275, + 0x2276, 0x2278, 0x2277, 0x2279, 0x227a, 0x2280, 0x227b, 0x2281, + 0x227c, 0x22e0, 0x227d, 0x22e1, 0x2282, 0x2284, 0x2283, 0x2285, + 0x2286, 0x2288, 0x2287, 0x2289, 0x2291, 0x22e2, 0x2292, 0x22e3, + 0x22a2, 0x22ac, 0x22a8, 0x22ad, 0x22a9, 0x22ae, 0x22ab, 0x22af, + 0x22b2, 0x22ea, 0x22b3, 0x22eb, 0x22b4, 0x22ec, 0x22b5, 0x22ed, + /* 0x0342 */ + 0x00a8, 0x1fc1, 0x03b1, 0x1fb6, 0x03b7, 0x1fc6, 0x03b9, 0x1fd6, + 0x03c5, 0x1fe6, 0x03c9, 0x1ff6, 0x03ca, 0x1fd7, 0x03cb, 0x1fe7, + 0x1f00, 0x1f06, 0x1f01, 0x1f07, 0x1f08, 0x1f0e, 0x1f09, 0x1f0f, + 0x1f20, 0x1f26, 0x1f21, 0x1f27, 0x1f28, 0x1f2e, 0x1f29, 0x1f2f, + 0x1f30, 0x1f36, 0x1f31, 0x1f37, 0x1f38, 0x1f3e, 0x1f39, 0x1f3f, + 0x1f50, 0x1f56, 0x1f51, 0x1f57, 0x1f59, 0x1f5f, 0x1f60, 0x1f66, + 0x1f61, 0x1f67, 0x1f68, 0x1f6e, 0x1f69, 0x1f6f, 0x1fbf, 0x1fcf, + 0x1ffe, 0x1fdf, + /* 0x0345 */ + 0x0391, 0x1fbc, 0x0397, 0x1fcc, 0x03a9, 0x1ffc, 0x03ac, 0x1fb4, + 0x03ae, 0x1fc4, 0x03b1, 0x1fb3, 0x03b7, 0x1fc3, 0x03c9, 0x1ff3, + 0x03ce, 0x1ff4, 0x1f00, 0x1f80, 0x1f01, 0x1f81, 0x1f02, 0x1f82, + 0x1f03, 0x1f83, 0x1f04, 0x1f84, 0x1f05, 0x1f85, 0x1f06, 0x1f86, + 0x1f07, 0x1f87, 0x1f08, 0x1f88, 0x1f09, 0x1f89, 0x1f0a, 0x1f8a, + 0x1f0b, 0x1f8b, 0x1f0c, 0x1f8c, 0x1f0d, 0x1f8d, 0x1f0e, 0x1f8e, + 0x1f0f, 0x1f8f, 0x1f20, 0x1f90, 0x1f21, 0x1f91, 0x1f22, 0x1f92, + 0x1f23, 0x1f93, 0x1f24, 0x1f94, 0x1f25, 0x1f95, 0x1f26, 0x1f96, + 0x1f27, 0x1f97, 0x1f28, 0x1f98, 0x1f29, 0x1f99, 0x1f2a, 0x1f9a, + 0x1f2b, 0x1f9b, 0x1f2c, 0x1f9c, 0x1f2d, 0x1f9d, 0x1f2e, 0x1f9e, + 0x1f2f, 0x1f9f, 0x1f60, 0x1fa0, 0x1f61, 0x1fa1, 0x1f62, 0x1fa2, + 0x1f63, 0x1fa3, 0x1f64, 0x1fa4, 0x1f65, 0x1fa5, 0x1f66, 0x1fa6, + 0x1f67, 0x1fa7, 0x1f68, 0x1fa8, 0x1f69, 0x1fa9, 0x1f6a, 0x1faa, + 0x1f6b, 0x1fab, 0x1f6c, 0x1fac, 0x1f6d, 0x1fad, 0x1f6e, 0x1fae, + 0x1f6f, 0x1faf, 0x1f70, 0x1fb2, 0x1f74, 0x1fc2, 0x1f7c, 0x1ff2, + 0x1fb6, 0x1fb7, 0x1fc6, 0x1fc7, 0x1ff6, 0x1ff7, + /* 0x05b4 */ + 0x05d9, 0xfb1d, + /* 0x05b7 */ + 0x05d0, 0xfb2e, 0x05f2, 0xfb1f, + /* 0x05b8 */ + 0x05d0, 0xfb2f, + /* 0x05b9 */ + 0x05d5, 0xfb4b, + /* 0x05bc */ + 0x05d0, 0xfb30, 0x05d1, 0xfb31, 0x05d2, 0xfb32, 0x05d3, 0xfb33, + 0x05d4, 0xfb34, 0x05d5, 0xfb35, 0x05d6, 0xfb36, 0x05d8, 0xfb38, + 0x05d9, 0xfb39, 0x05da, 0xfb3a, 0x05db, 0xfb3b, 0x05dc, 0xfb3c, + 0x05de, 0xfb3e, 0x05e0, 0xfb40, 0x05e1, 0xfb41, 0x05e3, 0xfb43, + 0x05e4, 0xfb44, 0x05e6, 0xfb46, 0x05e7, 0xfb47, 0x05e8, 0xfb48, + 0x05e9, 0xfb49, 0x05ea, 0xfb4a, + /* 0x05bf */ + 0x05d1, 0xfb4c, 0x05db, 0xfb4d, 0x05e4, 0xfb4e, + /* 0x05c1 */ + 0x05e9, 0xfb2a, 0xfb49, 0xfb2c, + /* 0x05c2 */ + 0x05e9, 0xfb2b, 0xfb49, 0xfb2d, + /* 0x0653 */ + 0x0627, 0x0622, + /* 0x0654 */ + 0x0627, 0x0623, 0x0648, 0x0624, 0x064a, 0x0626, 0x06c1, 0x06c2, + 0x06d2, 0x06d3, 0x06d5, 0x06c0, + /* 0x0655 */ + 0x0627, 0x0625, + /* 0x093c */ + 0x0915, 0x0958, 0x0916, 0x0959, 0x0917, 0x095a, 0x091c, 0x095b, + 0x0921, 0x095c, 0x0922, 0x095d, 0x0928, 0x0929, 0x092b, 0x095e, + 0x092f, 0x095f, 0x0930, 0x0931, 0x0933, 0x0934, + /* 0x09bc */ + 0x09a1, 0x09dc, 0x09a2, 0x09dd, 0x09af, 0x09df, + /* 0x09be */ + 0x09c7, 0x09cb, + /* 0x09d7 */ + 0x09c7, 0x09cc, + /* 0x0a3c */ + 0x0a16, 0x0a59, 0x0a17, 0x0a5a, 0x0a1c, 0x0a5b, 0x0a2b, 0x0a5e, + 0x0a32, 0x0a33, 0x0a38, 0x0a36, + /* 0x0b3c */ + 0x0b21, 0x0b5c, 0x0b22, 0x0b5d, + /* 0x0b3e */ + 0x0b47, 0x0b4b, + /* 0x0b56 */ + 0x0b47, 0x0b48, + /* 0x0b57 */ + 0x0b47, 0x0b4c, + /* 0x0bbe */ + 0x0bc6, 0x0bca, 0x0bc7, 0x0bcb, + /* 0x0bd7 */ + 0x0b92, 0x0b94, 0x0bc6, 0x0bcc, + /* 0x0c56 */ + 0x0c46, 0x0c48, + /* 0x0cc2 */ + 0x0cc6, 0x0cca, + /* 0x0cd5 */ + 0x0cbf, 0x0cc0, 0x0cc6, 0x0cc7, 0x0cca, 0x0ccb, + /* 0x0cd6 */ + 0x0cc6, 0x0cc8, + /* 0x0d3e */ + 0x0d46, 0x0d4a, 0x0d47, 0x0d4b, + /* 0x0d57 */ + 0x0d46, 0x0d4c, + /* 0x0dca */ + 0x0dd9, 0x0dda, 0x0ddc, 0x0ddd, + /* 0x0dcf */ + 0x0dd9, 0x0ddc, + /* 0x0ddf */ + 0x0dd9, 0x0dde, + /* 0x0f72 */ + 0x0f71, 0x0f73, + /* 0x0f74 */ + 0x0f71, 0x0f75, + /* 0x0f80 */ + 0x0f71, 0x0f81, 0x0fb2, 0x0f76, 0x0fb3, 0x0f78, + /* 0x0fb5 */ + 0x0f40, 0x0f69, 0x0f90, 0x0fb9, + /* 0x0fb7 */ + 0x0f42, 0x0f43, 0x0f4c, 0x0f4d, 0x0f51, 0x0f52, 0x0f56, 0x0f57, + 0x0f5b, 0x0f5c, 0x0f92, 0x0f93, 0x0f9c, 0x0f9d, 0x0fa1, 0x0fa2, + 0x0fa6, 0x0fa7, 0x0fab, 0x0fac, + /* 0x102e */ + 0x1025, 0x1026, + /* 0x3099 */ + 0x3046, 0x3094, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, + 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, + 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, + 0x3061, 0x3062, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, 0x3069, + 0x306f, 0x3070, 0x3072, 0x3073, 0x3075, 0x3076, 0x3078, 0x3079, + 0x307b, 0x307c, 0x309d, 0x309e, 0x30a6, 0x30f4, 0x30ab, 0x30ac, + 0x30ad, 0x30ae, 0x30af, 0x30b0, 0x30b1, 0x30b2, 0x30b3, 0x30b4, + 0x30b5, 0x30b6, 0x30b7, 0x30b8, 0x30b9, 0x30ba, 0x30bb, 0x30bc, + 0x30bd, 0x30be, 0x30bf, 0x30c0, 0x30c1, 0x30c2, 0x30c4, 0x30c5, + 0x30c6, 0x30c7, 0x30c8, 0x30c9, 0x30cf, 0x30d0, 0x30d2, 0x30d3, + 0x30d5, 0x30d6, 0x30d8, 0x30d9, 0x30db, 0x30dc, 0x30ef, 0x30f7, + 0x30f0, 0x30f8, 0x30f1, 0x30f9, 0x30f2, 0x30fa, 0x30fd, 0x30fe, + /* 0x309a */ + 0x306f, 0x3071, 0x3072, 0x3074, 0x3075, 0x3077, 0x3078, 0x307a, + 0x307b, 0x307d, 0x30cf, 0x30d1, 0x30d2, 0x30d4, 0x30d5, 0x30d7, + 0x30d8, 0x30da, 0x30db, 0x30dd +}; + +const unsigned int unicode_compose_table_size = 69; + +const WCHAR unicode_decompose_table[4512] = +{ + /* index */ + 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0100, 0x0160, 0x0100, + 0x0100, 0x0170, 0x0180, 0x0190, 0x01a0, 0x01b0, 0x0100, 0x01c0, + 0x01d0, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x01e0, 0x01f0, + 0x0100, 0x0200, 0x0210, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0220, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0230, 0x0100, 0x0100, 0x0100, 0x0100, + /* null sub-index */ + 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + /* sub-index 00 */ + 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x0260, 0x0280, 0x02a0, 0x02c0, + /* sub-index 01 */ + 0x02e0, 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0, + 0x0240, 0x0240, 0x03e0, 0x0400, 0x0420, 0x0440, 0x0460, 0x0480, + /* sub-index 02 */ + 0x04a0, 0x04c0, 0x04e0, 0x0500, 0x0240, 0x0240, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + /* sub-index 03 */ + 0x0240, 0x0240, 0x0240, 0x0240, 0x0520, 0x0240, 0x0240, 0x0240, + 0x0540, 0x0560, 0x0580, 0x05a0, 0x05c0, 0x05e0, 0x0240, 0x0240, + /* sub-index 04 */ + 0x0600, 0x0620, 0x0240, 0x0640, 0x0240, 0x0660, 0x0240, 0x0680, + 0x0240, 0x0240, 0x0240, 0x0240, 0x06a0, 0x06c0, 0x06e0, 0x0700, + /* sub-index 06 */ + 0x0240, 0x0240, 0x0720, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x0740, 0x0760, 0x0240, 0x0240, + /* sub-index 09 */ + 0x0240, 0x0240, 0x0780, 0x07a0, 0x0240, 0x07c0, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x07e0, 0x0800, 0x0240, 0x0240, + /* sub-index 0a */ + 0x0240, 0x0240, 0x0240, 0x0820, 0x0240, 0x0840, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + /* sub-index 0b */ + 0x0240, 0x0240, 0x0240, 0x0240, 0x0860, 0x0880, 0x0240, 0x0240, + 0x0240, 0x08a0, 0x0240, 0x0240, 0x08c0, 0x0240, 0x0240, 0x0240, + /* sub-index 0c */ + 0x0240, 0x0240, 0x0240, 0x0240, 0x08e0, 0x0240, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x0900, 0x0240, 0x0240, 0x0240, + /* sub-index 0d */ + 0x0240, 0x0240, 0x0240, 0x0240, 0x0920, 0x0240, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0940, 0x0240, 0x0240, + /* sub-index 0f */ + 0x0240, 0x0240, 0x0240, 0x0240, 0x0960, 0x0980, 0x09a0, 0x09c0, + 0x09e0, 0x0a00, 0x0a20, 0x0a40, 0x0240, 0x0240, 0x0240, 0x0240, + /* sub-index 10 */ + 0x0240, 0x0240, 0x0a60, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + /* sub-index 1e */ + 0x0a80, 0x0aa0, 0x0ac0, 0x0ae0, 0x0b00, 0x0b20, 0x0b40, 0x0b60, + 0x0b80, 0x0ba0, 0x0bc0, 0x0be0, 0x0c00, 0x0c20, 0x0c40, 0x0c60, + /* sub-index 1f */ + 0x0c80, 0x0ca0, 0x0cc0, 0x0ce0, 0x0d00, 0x0d20, 0x0d40, 0x0d60, + 0x0d80, 0x0da0, 0x0dc0, 0x0de0, 0x0e00, 0x0e20, 0x0e40, 0x0e60, + /* sub-index 21 */ + 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + 0x0240, 0x0e80, 0x0ea0, 0x0240, 0x0ec0, 0x0240, 0x0240, 0x0240, + /* sub-index 22 */ + 0x0ee0, 0x0240, 0x0f00, 0x0240, 0x0f20, 0x0240, 0x0f40, 0x0f60, + 0x0f80, 0x0240, 0x0fa0, 0x0240, 0x0240, 0x0240, 0x0fc0, 0x0240, + /* sub-index 30 */ + 0x0240, 0x0240, 0x0240, 0x0240, 0x0fe0, 0x1000, 0x1020, 0x1040, + 0x0240, 0x1060, 0x1080, 0x10a0, 0x10c0, 0x10e0, 0x0240, 0x1100, + /* sub-index fb */ + 0x0240, 0x1120, 0x1140, 0x1160, 0x1180, 0x0240, 0x0240, 0x0240, + 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, 0x0240, + /* null mapping */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x00c0 .. 0x00cf */ + 0x0041, 0x0300, 0x0041, 0x0301, 0x0041, 0x0302, 0x0041, 0x0303, + 0x0041, 0x0308, 0x0041, 0x030a, 0x0000, 0x0000, 0x0043, 0x0327, + 0x0045, 0x0300, 0x0045, 0x0301, 0x0045, 0x0302, 0x0045, 0x0308, + 0x0049, 0x0300, 0x0049, 0x0301, 0x0049, 0x0302, 0x0049, 0x0308, + /* 0x00d0 .. 0x00df */ + 0x0000, 0x0000, 0x004e, 0x0303, 0x004f, 0x0300, 0x004f, 0x0301, + 0x004f, 0x0302, 0x004f, 0x0303, 0x004f, 0x0308, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0055, 0x0300, 0x0055, 0x0301, 0x0055, 0x0302, + 0x0055, 0x0308, 0x0059, 0x0301, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x00e0 .. 0x00ef */ + 0x0061, 0x0300, 0x0061, 0x0301, 0x0061, 0x0302, 0x0061, 0x0303, + 0x0061, 0x0308, 0x0061, 0x030a, 0x0000, 0x0000, 0x0063, 0x0327, + 0x0065, 0x0300, 0x0065, 0x0301, 0x0065, 0x0302, 0x0065, 0x0308, + 0x0069, 0x0300, 0x0069, 0x0301, 0x0069, 0x0302, 0x0069, 0x0308, + /* 0x00f0 .. 0x00ff */ + 0x0000, 0x0000, 0x006e, 0x0303, 0x006f, 0x0300, 0x006f, 0x0301, + 0x006f, 0x0302, 0x006f, 0x0303, 0x006f, 0x0308, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0075, 0x0300, 0x0075, 0x0301, 0x0075, 0x0302, + 0x0075, 0x0308, 0x0079, 0x0301, 0x0000, 0x0000, 0x0079, 0x0308, + /* 0x0100 .. 0x010f */ + 0x0041, 0x0304, 0x0061, 0x0304, 0x0041, 0x0306, 0x0061, 0x0306, + 0x0041, 0x0328, 0x0061, 0x0328, 0x0043, 0x0301, 0x0063, 0x0301, + 0x0043, 0x0302, 0x0063, 0x0302, 0x0043, 0x0307, 0x0063, 0x0307, + 0x0043, 0x030c, 0x0063, 0x030c, 0x0044, 0x030c, 0x0064, 0x030c, + /* 0x0110 .. 0x011f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0045, 0x0304, 0x0065, 0x0304, + 0x0045, 0x0306, 0x0065, 0x0306, 0x0045, 0x0307, 0x0065, 0x0307, + 0x0045, 0x0328, 0x0065, 0x0328, 0x0045, 0x030c, 0x0065, 0x030c, + 0x0047, 0x0302, 0x0067, 0x0302, 0x0047, 0x0306, 0x0067, 0x0306, + /* 0x0120 .. 0x012f */ + 0x0047, 0x0307, 0x0067, 0x0307, 0x0047, 0x0327, 0x0067, 0x0327, + 0x0048, 0x0302, 0x0068, 0x0302, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0049, 0x0303, 0x0069, 0x0303, 0x0049, 0x0304, 0x0069, 0x0304, + 0x0049, 0x0306, 0x0069, 0x0306, 0x0049, 0x0328, 0x0069, 0x0328, + /* 0x0130 .. 0x013f */ + 0x0049, 0x0307, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x004a, 0x0302, 0x006a, 0x0302, 0x004b, 0x0327, 0x006b, 0x0327, + 0x0000, 0x0000, 0x004c, 0x0301, 0x006c, 0x0301, 0x004c, 0x0327, + 0x006c, 0x0327, 0x004c, 0x030c, 0x006c, 0x030c, 0x0000, 0x0000, + /* 0x0140 .. 0x014f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x004e, 0x0301, + 0x006e, 0x0301, 0x004e, 0x0327, 0x006e, 0x0327, 0x004e, 0x030c, + 0x006e, 0x030c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x004f, 0x0304, 0x006f, 0x0304, 0x004f, 0x0306, 0x006f, 0x0306, + /* 0x0150 .. 0x015f */ + 0x004f, 0x030b, 0x006f, 0x030b, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0052, 0x0301, 0x0072, 0x0301, 0x0052, 0x0327, 0x0072, 0x0327, + 0x0052, 0x030c, 0x0072, 0x030c, 0x0053, 0x0301, 0x0073, 0x0301, + 0x0053, 0x0302, 0x0073, 0x0302, 0x0053, 0x0327, 0x0073, 0x0327, + /* 0x0160 .. 0x016f */ + 0x0053, 0x030c, 0x0073, 0x030c, 0x0054, 0x0327, 0x0074, 0x0327, + 0x0054, 0x030c, 0x0074, 0x030c, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0055, 0x0303, 0x0075, 0x0303, 0x0055, 0x0304, 0x0075, 0x0304, + 0x0055, 0x0306, 0x0075, 0x0306, 0x0055, 0x030a, 0x0075, 0x030a, + /* 0x0170 .. 0x017f */ + 0x0055, 0x030b, 0x0075, 0x030b, 0x0055, 0x0328, 0x0075, 0x0328, + 0x0057, 0x0302, 0x0077, 0x0302, 0x0059, 0x0302, 0x0079, 0x0302, + 0x0059, 0x0308, 0x005a, 0x0301, 0x007a, 0x0301, 0x005a, 0x0307, + 0x007a, 0x0307, 0x005a, 0x030c, 0x007a, 0x030c, 0x0000, 0x0000, + /* 0x01a0 .. 0x01af */ + 0x004f, 0x031b, 0x006f, 0x031b, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0055, 0x031b, + /* 0x01b0 .. 0x01bf */ + 0x0075, 0x031b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x01c0 .. 0x01cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0041, 0x030c, 0x0061, 0x030c, 0x0049, 0x030c, + /* 0x01d0 .. 0x01df */ + 0x0069, 0x030c, 0x004f, 0x030c, 0x006f, 0x030c, 0x0055, 0x030c, + 0x0075, 0x030c, 0x00dc, 0x0304, 0x00fc, 0x0304, 0x00dc, 0x0301, + 0x00fc, 0x0301, 0x00dc, 0x030c, 0x00fc, 0x030c, 0x00dc, 0x0300, + 0x00fc, 0x0300, 0x0000, 0x0000, 0x00c4, 0x0304, 0x00e4, 0x0304, + /* 0x01e0 .. 0x01ef */ + 0x0226, 0x0304, 0x0227, 0x0304, 0x00c6, 0x0304, 0x00e6, 0x0304, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0047, 0x030c, 0x0067, 0x030c, + 0x004b, 0x030c, 0x006b, 0x030c, 0x004f, 0x0328, 0x006f, 0x0328, + 0x01ea, 0x0304, 0x01eb, 0x0304, 0x01b7, 0x030c, 0x0292, 0x030c, + /* 0x01f0 .. 0x01ff */ + 0x006a, 0x030c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0047, 0x0301, 0x0067, 0x0301, 0x0000, 0x0000, 0x0000, 0x0000, + 0x004e, 0x0300, 0x006e, 0x0300, 0x00c5, 0x0301, 0x00e5, 0x0301, + 0x00c6, 0x0301, 0x00e6, 0x0301, 0x00d8, 0x0301, 0x00f8, 0x0301, + /* 0x0200 .. 0x020f */ + 0x0041, 0x030f, 0x0061, 0x030f, 0x0041, 0x0311, 0x0061, 0x0311, + 0x0045, 0x030f, 0x0065, 0x030f, 0x0045, 0x0311, 0x0065, 0x0311, + 0x0049, 0x030f, 0x0069, 0x030f, 0x0049, 0x0311, 0x0069, 0x0311, + 0x004f, 0x030f, 0x006f, 0x030f, 0x004f, 0x0311, 0x006f, 0x0311, + /* 0x0210 .. 0x021f */ + 0x0052, 0x030f, 0x0072, 0x030f, 0x0052, 0x0311, 0x0072, 0x0311, + 0x0055, 0x030f, 0x0075, 0x030f, 0x0055, 0x0311, 0x0075, 0x0311, + 0x0053, 0x0326, 0x0073, 0x0326, 0x0054, 0x0326, 0x0074, 0x0326, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0048, 0x030c, 0x0068, 0x030c, + /* 0x0220 .. 0x022f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0041, 0x0307, 0x0061, 0x0307, + 0x0045, 0x0327, 0x0065, 0x0327, 0x00d6, 0x0304, 0x00f6, 0x0304, + 0x00d5, 0x0304, 0x00f5, 0x0304, 0x004f, 0x0307, 0x006f, 0x0307, + /* 0x0230 .. 0x023f */ + 0x022e, 0x0304, 0x022f, 0x0304, 0x0059, 0x0304, 0x0079, 0x0304, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0340 .. 0x034f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0308, 0x0301, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0380 .. 0x038f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x00a8, 0x0301, 0x0391, 0x0301, 0x0000, 0x0000, + 0x0395, 0x0301, 0x0397, 0x0301, 0x0399, 0x0301, 0x0000, 0x0000, + 0x039f, 0x0301, 0x0000, 0x0000, 0x03a5, 0x0301, 0x03a9, 0x0301, + /* 0x0390 .. 0x039f */ + 0x03ca, 0x0301, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x03a0 .. 0x03af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0399, 0x0308, 0x03a5, 0x0308, + 0x03b1, 0x0301, 0x03b5, 0x0301, 0x03b7, 0x0301, 0x03b9, 0x0301, + /* 0x03b0 .. 0x03bf */ + 0x03cb, 0x0301, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x03c0 .. 0x03cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03b9, 0x0308, 0x03c5, 0x0308, + 0x03bf, 0x0301, 0x03c5, 0x0301, 0x03c9, 0x0301, 0x0000, 0x0000, + /* 0x03d0 .. 0x03df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03d2, 0x0301, + 0x03d2, 0x0308, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0400 .. 0x040f */ + 0x0415, 0x0300, 0x0415, 0x0308, 0x0000, 0x0000, 0x0413, 0x0301, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0406, 0x0308, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x041a, 0x0301, 0x0418, 0x0300, 0x0423, 0x0306, 0x0000, 0x0000, + /* 0x0410 .. 0x041f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0418, 0x0306, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0430 .. 0x043f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0438, 0x0306, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0450 .. 0x045f */ + 0x0435, 0x0300, 0x0435, 0x0308, 0x0000, 0x0000, 0x0433, 0x0301, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0456, 0x0308, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x043a, 0x0301, 0x0438, 0x0300, 0x0443, 0x0306, 0x0000, 0x0000, + /* 0x0470 .. 0x047f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0474, 0x030f, 0x0475, 0x030f, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x04c0 .. 0x04cf */ + 0x0000, 0x0000, 0x0416, 0x0306, 0x0436, 0x0306, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x04d0 .. 0x04df */ + 0x0410, 0x0306, 0x0430, 0x0306, 0x0410, 0x0308, 0x0430, 0x0308, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0415, 0x0306, 0x0435, 0x0306, + 0x0000, 0x0000, 0x0000, 0x0000, 0x04d8, 0x0308, 0x04d9, 0x0308, + 0x0416, 0x0308, 0x0436, 0x0308, 0x0417, 0x0308, 0x0437, 0x0308, + /* 0x04e0 .. 0x04ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0418, 0x0304, 0x0438, 0x0304, + 0x0418, 0x0308, 0x0438, 0x0308, 0x041e, 0x0308, 0x043e, 0x0308, + 0x0000, 0x0000, 0x0000, 0x0000, 0x04e8, 0x0308, 0x04e9, 0x0308, + 0x042d, 0x0308, 0x044d, 0x0308, 0x0423, 0x0304, 0x0443, 0x0304, + /* 0x04f0 .. 0x04ff */ + 0x0423, 0x0308, 0x0443, 0x0308, 0x0423, 0x030b, 0x0443, 0x030b, + 0x0427, 0x0308, 0x0447, 0x0308, 0x0000, 0x0000, 0x0000, 0x0000, + 0x042b, 0x0308, 0x044b, 0x0308, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0620 .. 0x062f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0627, 0x0653, 0x0627, 0x0654, + 0x0648, 0x0654, 0x0627, 0x0655, 0x064a, 0x0654, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x06c0 .. 0x06cf */ + 0x06d5, 0x0654, 0x0000, 0x0000, 0x06c1, 0x0654, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x06d0 .. 0x06df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x06d2, 0x0654, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0920 .. 0x092f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0928, 0x093c, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0930 .. 0x093f */ + 0x0000, 0x0000, 0x0930, 0x093c, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0933, 0x093c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0950 .. 0x095f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0915, 0x093c, 0x0916, 0x093c, 0x0917, 0x093c, 0x091c, 0x093c, + 0x0921, 0x093c, 0x0922, 0x093c, 0x092b, 0x093c, 0x092f, 0x093c, + /* 0x09c0 .. 0x09cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x09c7, 0x09be, + 0x09c7, 0x09d7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x09d0 .. 0x09df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x09a1, 0x09bc, 0x09a2, 0x09bc, 0x0000, 0x0000, 0x09af, 0x09bc, + /* 0x0a30 .. 0x0a3f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a32, 0x0a3c, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0a38, 0x0a3c, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0a50 .. 0x0a5f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0a16, 0x0a3c, 0x0a17, 0x0a3c, 0x0a1c, 0x0a3c, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0a2b, 0x0a3c, 0x0000, 0x0000, + /* 0x0b40 .. 0x0b4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0b47, 0x0b56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b47, 0x0b3e, + 0x0b47, 0x0b57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0b50 .. 0x0b5f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0b21, 0x0b3c, 0x0b22, 0x0b3c, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0b90 .. 0x0b9f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0b92, 0x0bd7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0bc0 .. 0x0bcf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0bc6, 0x0bbe, 0x0bc7, 0x0bbe, + 0x0bc6, 0x0bd7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0c40 .. 0x0c4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0c46, 0x0c56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0cc0 .. 0x0ccf */ + 0x0cbf, 0x0cd5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0cc6, 0x0cd5, + 0x0cc6, 0x0cd6, 0x0000, 0x0000, 0x0cc6, 0x0cc2, 0x0cca, 0x0cd5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0d40 .. 0x0d4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0d46, 0x0d3e, 0x0d47, 0x0d3e, + 0x0d46, 0x0d57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0dd0 .. 0x0ddf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0dd9, 0x0dca, 0x0000, 0x0000, + 0x0dd9, 0x0dcf, 0x0ddc, 0x0dca, 0x0dd9, 0x0ddf, 0x0000, 0x0000, + /* 0x0f40 .. 0x0f4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f42, 0x0fb7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0f4c, 0x0fb7, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f50 .. 0x0f5f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0f51, 0x0fb7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f56, 0x0fb7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0f5b, 0x0fb7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f60 .. 0x0f6f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0f40, 0x0fb5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f70 .. 0x0f7f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f71, 0x0f72, + 0x0000, 0x0000, 0x0f71, 0x0f74, 0x0fb2, 0x0f80, 0x0000, 0x0000, + 0x0fb3, 0x0f80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f80 .. 0x0f8f */ + 0x0000, 0x0000, 0x0f71, 0x0f80, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f90 .. 0x0f9f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f92, 0x0fb7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0f9c, 0x0fb7, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0fa0 .. 0x0faf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0fa1, 0x0fb7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0fa6, 0x0fb7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0fab, 0x0fb7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0fb0 .. 0x0fbf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0f90, 0x0fb5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1020 .. 0x102f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1025, 0x102e, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1e00 .. 0x1e0f */ + 0x0041, 0x0325, 0x0061, 0x0325, 0x0042, 0x0307, 0x0062, 0x0307, + 0x0042, 0x0323, 0x0062, 0x0323, 0x0042, 0x0331, 0x0062, 0x0331, + 0x00c7, 0x0301, 0x00e7, 0x0301, 0x0044, 0x0307, 0x0064, 0x0307, + 0x0044, 0x0323, 0x0064, 0x0323, 0x0044, 0x0331, 0x0064, 0x0331, + /* 0x1e10 .. 0x1e1f */ + 0x0044, 0x0327, 0x0064, 0x0327, 0x0044, 0x032d, 0x0064, 0x032d, + 0x0112, 0x0300, 0x0113, 0x0300, 0x0112, 0x0301, 0x0113, 0x0301, + 0x0045, 0x032d, 0x0065, 0x032d, 0x0045, 0x0330, 0x0065, 0x0330, + 0x0228, 0x0306, 0x0229, 0x0306, 0x0046, 0x0307, 0x0066, 0x0307, + /* 0x1e20 .. 0x1e2f */ + 0x0047, 0x0304, 0x0067, 0x0304, 0x0048, 0x0307, 0x0068, 0x0307, + 0x0048, 0x0323, 0x0068, 0x0323, 0x0048, 0x0308, 0x0068, 0x0308, + 0x0048, 0x0327, 0x0068, 0x0327, 0x0048, 0x032e, 0x0068, 0x032e, + 0x0049, 0x0330, 0x0069, 0x0330, 0x00cf, 0x0301, 0x00ef, 0x0301, + /* 0x1e30 .. 0x1e3f */ + 0x004b, 0x0301, 0x006b, 0x0301, 0x004b, 0x0323, 0x006b, 0x0323, + 0x004b, 0x0331, 0x006b, 0x0331, 0x004c, 0x0323, 0x006c, 0x0323, + 0x1e36, 0x0304, 0x1e37, 0x0304, 0x004c, 0x0331, 0x006c, 0x0331, + 0x004c, 0x032d, 0x006c, 0x032d, 0x004d, 0x0301, 0x006d, 0x0301, + /* 0x1e40 .. 0x1e4f */ + 0x004d, 0x0307, 0x006d, 0x0307, 0x004d, 0x0323, 0x006d, 0x0323, + 0x004e, 0x0307, 0x006e, 0x0307, 0x004e, 0x0323, 0x006e, 0x0323, + 0x004e, 0x0331, 0x006e, 0x0331, 0x004e, 0x032d, 0x006e, 0x032d, + 0x00d5, 0x0301, 0x00f5, 0x0301, 0x00d5, 0x0308, 0x00f5, 0x0308, + /* 0x1e50 .. 0x1e5f */ + 0x014c, 0x0300, 0x014d, 0x0300, 0x014c, 0x0301, 0x014d, 0x0301, + 0x0050, 0x0301, 0x0070, 0x0301, 0x0050, 0x0307, 0x0070, 0x0307, + 0x0052, 0x0307, 0x0072, 0x0307, 0x0052, 0x0323, 0x0072, 0x0323, + 0x1e5a, 0x0304, 0x1e5b, 0x0304, 0x0052, 0x0331, 0x0072, 0x0331, + /* 0x1e60 .. 0x1e6f */ + 0x0053, 0x0307, 0x0073, 0x0307, 0x0053, 0x0323, 0x0073, 0x0323, + 0x015a, 0x0307, 0x015b, 0x0307, 0x0160, 0x0307, 0x0161, 0x0307, + 0x1e62, 0x0307, 0x1e63, 0x0307, 0x0054, 0x0307, 0x0074, 0x0307, + 0x0054, 0x0323, 0x0074, 0x0323, 0x0054, 0x0331, 0x0074, 0x0331, + /* 0x1e70 .. 0x1e7f */ + 0x0054, 0x032d, 0x0074, 0x032d, 0x0055, 0x0324, 0x0075, 0x0324, + 0x0055, 0x0330, 0x0075, 0x0330, 0x0055, 0x032d, 0x0075, 0x032d, + 0x0168, 0x0301, 0x0169, 0x0301, 0x016a, 0x0308, 0x016b, 0x0308, + 0x0056, 0x0303, 0x0076, 0x0303, 0x0056, 0x0323, 0x0076, 0x0323, + /* 0x1e80 .. 0x1e8f */ + 0x0057, 0x0300, 0x0077, 0x0300, 0x0057, 0x0301, 0x0077, 0x0301, + 0x0057, 0x0308, 0x0077, 0x0308, 0x0057, 0x0307, 0x0077, 0x0307, + 0x0057, 0x0323, 0x0077, 0x0323, 0x0058, 0x0307, 0x0078, 0x0307, + 0x0058, 0x0308, 0x0078, 0x0308, 0x0059, 0x0307, 0x0079, 0x0307, + /* 0x1e90 .. 0x1e9f */ + 0x005a, 0x0302, 0x007a, 0x0302, 0x005a, 0x0323, 0x007a, 0x0323, + 0x005a, 0x0331, 0x007a, 0x0331, 0x0068, 0x0331, 0x0074, 0x0308, + 0x0077, 0x030a, 0x0079, 0x030a, 0x0000, 0x0000, 0x017f, 0x0307, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1ea0 .. 0x1eaf */ + 0x0041, 0x0323, 0x0061, 0x0323, 0x0041, 0x0309, 0x0061, 0x0309, + 0x00c2, 0x0301, 0x00e2, 0x0301, 0x00c2, 0x0300, 0x00e2, 0x0300, + 0x00c2, 0x0309, 0x00e2, 0x0309, 0x00c2, 0x0303, 0x00e2, 0x0303, + 0x1ea0, 0x0302, 0x1ea1, 0x0302, 0x0102, 0x0301, 0x0103, 0x0301, + /* 0x1eb0 .. 0x1ebf */ + 0x0102, 0x0300, 0x0103, 0x0300, 0x0102, 0x0309, 0x0103, 0x0309, + 0x0102, 0x0303, 0x0103, 0x0303, 0x1ea0, 0x0306, 0x1ea1, 0x0306, + 0x0045, 0x0323, 0x0065, 0x0323, 0x0045, 0x0309, 0x0065, 0x0309, + 0x0045, 0x0303, 0x0065, 0x0303, 0x00ca, 0x0301, 0x00ea, 0x0301, + /* 0x1ec0 .. 0x1ecf */ + 0x00ca, 0x0300, 0x00ea, 0x0300, 0x00ca, 0x0309, 0x00ea, 0x0309, + 0x00ca, 0x0303, 0x00ea, 0x0303, 0x1eb8, 0x0302, 0x1eb9, 0x0302, + 0x0049, 0x0309, 0x0069, 0x0309, 0x0049, 0x0323, 0x0069, 0x0323, + 0x004f, 0x0323, 0x006f, 0x0323, 0x004f, 0x0309, 0x006f, 0x0309, + /* 0x1ed0 .. 0x1edf */ + 0x00d4, 0x0301, 0x00f4, 0x0301, 0x00d4, 0x0300, 0x00f4, 0x0300, + 0x00d4, 0x0309, 0x00f4, 0x0309, 0x00d4, 0x0303, 0x00f4, 0x0303, + 0x1ecc, 0x0302, 0x1ecd, 0x0302, 0x01a0, 0x0301, 0x01a1, 0x0301, + 0x01a0, 0x0300, 0x01a1, 0x0300, 0x01a0, 0x0309, 0x01a1, 0x0309, + /* 0x1ee0 .. 0x1eef */ + 0x01a0, 0x0303, 0x01a1, 0x0303, 0x01a0, 0x0323, 0x01a1, 0x0323, + 0x0055, 0x0323, 0x0075, 0x0323, 0x0055, 0x0309, 0x0075, 0x0309, + 0x01af, 0x0301, 0x01b0, 0x0301, 0x01af, 0x0300, 0x01b0, 0x0300, + 0x01af, 0x0309, 0x01b0, 0x0309, 0x01af, 0x0303, 0x01b0, 0x0303, + /* 0x1ef0 .. 0x1eff */ + 0x01af, 0x0323, 0x01b0, 0x0323, 0x0059, 0x0300, 0x0079, 0x0300, + 0x0059, 0x0323, 0x0079, 0x0323, 0x0059, 0x0309, 0x0079, 0x0309, + 0x0059, 0x0303, 0x0079, 0x0303, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1f00 .. 0x1f0f */ + 0x03b1, 0x0313, 0x03b1, 0x0314, 0x1f00, 0x0300, 0x1f01, 0x0300, + 0x1f00, 0x0301, 0x1f01, 0x0301, 0x1f00, 0x0342, 0x1f01, 0x0342, + 0x0391, 0x0313, 0x0391, 0x0314, 0x1f08, 0x0300, 0x1f09, 0x0300, + 0x1f08, 0x0301, 0x1f09, 0x0301, 0x1f08, 0x0342, 0x1f09, 0x0342, + /* 0x1f10 .. 0x1f1f */ + 0x03b5, 0x0313, 0x03b5, 0x0314, 0x1f10, 0x0300, 0x1f11, 0x0300, + 0x1f10, 0x0301, 0x1f11, 0x0301, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0395, 0x0313, 0x0395, 0x0314, 0x1f18, 0x0300, 0x1f19, 0x0300, + 0x1f18, 0x0301, 0x1f19, 0x0301, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1f20 .. 0x1f2f */ + 0x03b7, 0x0313, 0x03b7, 0x0314, 0x1f20, 0x0300, 0x1f21, 0x0300, + 0x1f20, 0x0301, 0x1f21, 0x0301, 0x1f20, 0x0342, 0x1f21, 0x0342, + 0x0397, 0x0313, 0x0397, 0x0314, 0x1f28, 0x0300, 0x1f29, 0x0300, + 0x1f28, 0x0301, 0x1f29, 0x0301, 0x1f28, 0x0342, 0x1f29, 0x0342, + /* 0x1f30 .. 0x1f3f */ + 0x03b9, 0x0313, 0x03b9, 0x0314, 0x1f30, 0x0300, 0x1f31, 0x0300, + 0x1f30, 0x0301, 0x1f31, 0x0301, 0x1f30, 0x0342, 0x1f31, 0x0342, + 0x0399, 0x0313, 0x0399, 0x0314, 0x1f38, 0x0300, 0x1f39, 0x0300, + 0x1f38, 0x0301, 0x1f39, 0x0301, 0x1f38, 0x0342, 0x1f39, 0x0342, + /* 0x1f40 .. 0x1f4f */ + 0x03bf, 0x0313, 0x03bf, 0x0314, 0x1f40, 0x0300, 0x1f41, 0x0300, + 0x1f40, 0x0301, 0x1f41, 0x0301, 0x0000, 0x0000, 0x0000, 0x0000, + 0x039f, 0x0313, 0x039f, 0x0314, 0x1f48, 0x0300, 0x1f49, 0x0300, + 0x1f48, 0x0301, 0x1f49, 0x0301, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1f50 .. 0x1f5f */ + 0x03c5, 0x0313, 0x03c5, 0x0314, 0x1f50, 0x0300, 0x1f51, 0x0300, + 0x1f50, 0x0301, 0x1f51, 0x0301, 0x1f50, 0x0342, 0x1f51, 0x0342, + 0x0000, 0x0000, 0x03a5, 0x0314, 0x0000, 0x0000, 0x1f59, 0x0300, + 0x0000, 0x0000, 0x1f59, 0x0301, 0x0000, 0x0000, 0x1f59, 0x0342, + /* 0x1f60 .. 0x1f6f */ + 0x03c9, 0x0313, 0x03c9, 0x0314, 0x1f60, 0x0300, 0x1f61, 0x0300, + 0x1f60, 0x0301, 0x1f61, 0x0301, 0x1f60, 0x0342, 0x1f61, 0x0342, + 0x03a9, 0x0313, 0x03a9, 0x0314, 0x1f68, 0x0300, 0x1f69, 0x0300, + 0x1f68, 0x0301, 0x1f69, 0x0301, 0x1f68, 0x0342, 0x1f69, 0x0342, + /* 0x1f70 .. 0x1f7f */ + 0x03b1, 0x0300, 0x0000, 0x0000, 0x03b5, 0x0300, 0x0000, 0x0000, + 0x03b7, 0x0300, 0x0000, 0x0000, 0x03b9, 0x0300, 0x0000, 0x0000, + 0x03bf, 0x0300, 0x0000, 0x0000, 0x03c5, 0x0300, 0x0000, 0x0000, + 0x03c9, 0x0300, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1f80 .. 0x1f8f */ + 0x1f00, 0x0345, 0x1f01, 0x0345, 0x1f02, 0x0345, 0x1f03, 0x0345, + 0x1f04, 0x0345, 0x1f05, 0x0345, 0x1f06, 0x0345, 0x1f07, 0x0345, + 0x1f08, 0x0345, 0x1f09, 0x0345, 0x1f0a, 0x0345, 0x1f0b, 0x0345, + 0x1f0c, 0x0345, 0x1f0d, 0x0345, 0x1f0e, 0x0345, 0x1f0f, 0x0345, + /* 0x1f90 .. 0x1f9f */ + 0x1f20, 0x0345, 0x1f21, 0x0345, 0x1f22, 0x0345, 0x1f23, 0x0345, + 0x1f24, 0x0345, 0x1f25, 0x0345, 0x1f26, 0x0345, 0x1f27, 0x0345, + 0x1f28, 0x0345, 0x1f29, 0x0345, 0x1f2a, 0x0345, 0x1f2b, 0x0345, + 0x1f2c, 0x0345, 0x1f2d, 0x0345, 0x1f2e, 0x0345, 0x1f2f, 0x0345, + /* 0x1fa0 .. 0x1faf */ + 0x1f60, 0x0345, 0x1f61, 0x0345, 0x1f62, 0x0345, 0x1f63, 0x0345, + 0x1f64, 0x0345, 0x1f65, 0x0345, 0x1f66, 0x0345, 0x1f67, 0x0345, + 0x1f68, 0x0345, 0x1f69, 0x0345, 0x1f6a, 0x0345, 0x1f6b, 0x0345, + 0x1f6c, 0x0345, 0x1f6d, 0x0345, 0x1f6e, 0x0345, 0x1f6f, 0x0345, + /* 0x1fb0 .. 0x1fbf */ + 0x03b1, 0x0306, 0x03b1, 0x0304, 0x1f70, 0x0345, 0x03b1, 0x0345, + 0x03ac, 0x0345, 0x0000, 0x0000, 0x03b1, 0x0342, 0x1fb6, 0x0345, + 0x0391, 0x0306, 0x0391, 0x0304, 0x0391, 0x0300, 0x0000, 0x0000, + 0x0391, 0x0345, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1fc0 .. 0x1fcf */ + 0x0000, 0x0000, 0x00a8, 0x0342, 0x1f74, 0x0345, 0x03b7, 0x0345, + 0x03ae, 0x0345, 0x0000, 0x0000, 0x03b7, 0x0342, 0x1fc6, 0x0345, + 0x0395, 0x0300, 0x0000, 0x0000, 0x0397, 0x0300, 0x0000, 0x0000, + 0x0397, 0x0345, 0x1fbf, 0x0300, 0x1fbf, 0x0301, 0x1fbf, 0x0342, + /* 0x1fd0 .. 0x1fdf */ + 0x03b9, 0x0306, 0x03b9, 0x0304, 0x03ca, 0x0300, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03b9, 0x0342, 0x03ca, 0x0342, + 0x0399, 0x0306, 0x0399, 0x0304, 0x0399, 0x0300, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1ffe, 0x0300, 0x1ffe, 0x0301, 0x1ffe, 0x0342, + /* 0x1fe0 .. 0x1fef */ + 0x03c5, 0x0306, 0x03c5, 0x0304, 0x03cb, 0x0300, 0x0000, 0x0000, + 0x03c1, 0x0313, 0x03c1, 0x0314, 0x03c5, 0x0342, 0x03cb, 0x0342, + 0x03a5, 0x0306, 0x03a5, 0x0304, 0x03a5, 0x0300, 0x0000, 0x0000, + 0x03a1, 0x0314, 0x00a8, 0x0300, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1ff0 .. 0x1fff */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x1f7c, 0x0345, 0x03c9, 0x0345, + 0x03ce, 0x0345, 0x0000, 0x0000, 0x03c9, 0x0342, 0x1ff6, 0x0345, + 0x039f, 0x0300, 0x0000, 0x0000, 0x03a9, 0x0300, 0x0000, 0x0000, + 0x03a9, 0x0345, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2190 .. 0x219f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2190, 0x0338, 0x2192, 0x0338, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x21a0 .. 0x21af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2194, 0x0338, 0x0000, 0x0000, + /* 0x21c0 .. 0x21cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x21d0, 0x0338, 0x21d4, 0x0338, 0x21d2, 0x0338, + /* 0x2200 .. 0x220f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2203, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2208, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + 0x220b, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2220 .. 0x222f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2223, 0x0338, 0x0000, 0x0000, 0x2225, 0x0338, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2240 .. 0x224f */ + 0x0000, 0x0000, 0x223c, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2243, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, 0x2245, 0x0338, + 0x0000, 0x0000, 0x2248, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2260 .. 0x226f */ + 0x003d, 0x0338, 0x0000, 0x0000, 0x2261, 0x0338, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x224d, 0x0338, 0x003c, 0x0338, 0x003e, 0x0338, + /* 0x2270 .. 0x227f */ + 0x2264, 0x0338, 0x2265, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2272, 0x0338, 0x2273, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2276, 0x0338, 0x2277, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2280 .. 0x228f */ + 0x227a, 0x0338, 0x227b, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2282, 0x0338, 0x2283, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2286, 0x0338, 0x2287, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x22a0 .. 0x22af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x22a2, 0x0338, 0x22a8, 0x0338, 0x22a9, 0x0338, 0x22ab, 0x0338, + /* 0x22e0 .. 0x22ef */ + 0x227c, 0x0338, 0x227d, 0x0338, 0x2291, 0x0338, 0x2292, 0x0338, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x22b2, 0x0338, 0x22b3, 0x0338, + 0x22b4, 0x0338, 0x22b5, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x3040 .. 0x304f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x304b, 0x3099, 0x0000, 0x0000, 0x304d, 0x3099, 0x0000, 0x0000, + /* 0x3050 .. 0x305f */ + 0x304f, 0x3099, 0x0000, 0x0000, 0x3051, 0x3099, 0x0000, 0x0000, + 0x3053, 0x3099, 0x0000, 0x0000, 0x3055, 0x3099, 0x0000, 0x0000, + 0x3057, 0x3099, 0x0000, 0x0000, 0x3059, 0x3099, 0x0000, 0x0000, + 0x305b, 0x3099, 0x0000, 0x0000, 0x305d, 0x3099, 0x0000, 0x0000, + /* 0x3060 .. 0x306f */ + 0x305f, 0x3099, 0x0000, 0x0000, 0x3061, 0x3099, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3064, 0x3099, 0x0000, 0x0000, 0x3066, 0x3099, + 0x0000, 0x0000, 0x3068, 0x3099, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x3070 .. 0x307f */ + 0x306f, 0x3099, 0x306f, 0x309a, 0x0000, 0x0000, 0x3072, 0x3099, + 0x3072, 0x309a, 0x0000, 0x0000, 0x3075, 0x3099, 0x3075, 0x309a, + 0x0000, 0x0000, 0x3078, 0x3099, 0x3078, 0x309a, 0x0000, 0x0000, + 0x307b, 0x3099, 0x307b, 0x309a, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x3090 .. 0x309f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3046, 0x3099, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x309d, 0x3099, 0x0000, 0x0000, + /* 0x30a0 .. 0x30af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x30ab, 0x3099, 0x0000, 0x0000, 0x30ad, 0x3099, 0x0000, 0x0000, + /* 0x30b0 .. 0x30bf */ + 0x30af, 0x3099, 0x0000, 0x0000, 0x30b1, 0x3099, 0x0000, 0x0000, + 0x30b3, 0x3099, 0x0000, 0x0000, 0x30b5, 0x3099, 0x0000, 0x0000, + 0x30b7, 0x3099, 0x0000, 0x0000, 0x30b9, 0x3099, 0x0000, 0x0000, + 0x30bb, 0x3099, 0x0000, 0x0000, 0x30bd, 0x3099, 0x0000, 0x0000, + /* 0x30c0 .. 0x30cf */ + 0x30bf, 0x3099, 0x0000, 0x0000, 0x30c1, 0x3099, 0x0000, 0x0000, + 0x0000, 0x0000, 0x30c4, 0x3099, 0x0000, 0x0000, 0x30c6, 0x3099, + 0x0000, 0x0000, 0x30c8, 0x3099, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x30d0 .. 0x30df */ + 0x30cf, 0x3099, 0x30cf, 0x309a, 0x0000, 0x0000, 0x30d2, 0x3099, + 0x30d2, 0x309a, 0x0000, 0x0000, 0x30d5, 0x3099, 0x30d5, 0x309a, + 0x0000, 0x0000, 0x30d8, 0x3099, 0x30d8, 0x309a, 0x0000, 0x0000, + 0x30db, 0x3099, 0x30db, 0x309a, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x30f0 .. 0x30ff */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x30a6, 0x3099, 0x0000, 0x0000, 0x0000, 0x0000, 0x30ef, 0x3099, + 0x30f0, 0x3099, 0x30f1, 0x3099, 0x30f2, 0x3099, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x30fd, 0x3099, 0x0000, 0x0000, + /* 0xfb10 .. 0xfb1f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x05d9, 0x05b4, 0x0000, 0x0000, 0x05f2, 0x05b7, + /* 0xfb20 .. 0xfb2f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x05e9, 0x05c1, 0x05e9, 0x05c2, + 0xfb49, 0x05c1, 0xfb49, 0x05c2, 0x05d0, 0x05b7, 0x05d0, 0x05b8, + /* 0xfb30 .. 0xfb3f */ + 0x05d0, 0x05bc, 0x05d1, 0x05bc, 0x05d2, 0x05bc, 0x05d3, 0x05bc, + 0x05d4, 0x05bc, 0x05d5, 0x05bc, 0x05d6, 0x05bc, 0x0000, 0x0000, + 0x05d8, 0x05bc, 0x05d9, 0x05bc, 0x05da, 0x05bc, 0x05db, 0x05bc, + 0x05dc, 0x05bc, 0x0000, 0x0000, 0x05de, 0x05bc, 0x0000, 0x0000, + /* 0xfb40 .. 0xfb4f */ + 0x05e0, 0x05bc, 0x05e1, 0x05bc, 0x0000, 0x0000, 0x05e3, 0x05bc, + 0x05e4, 0x05bc, 0x0000, 0x0000, 0x05e6, 0x05bc, 0x05e7, 0x05bc, + 0x05e8, 0x05bc, 0x05e9, 0x05bc, 0x05ea, 0x05bc, 0x05d5, 0x05b9, + 0x05d1, 0x05bf, 0x05db, 0x05bf, 0x05e4, 0x05bf, 0x0000, 0x0000 +}; diff --git a/unicode/cpmap.pl b/unicode/cpmap.pl index 4e4d6ce4921..208907b9a16 100755 --- a/unicode/cpmap.pl +++ b/unicode/cpmap.pl @@ -166,6 +166,7 @@ $DEF_CHAR = ord '?'; READ_DEFAULTS(); DUMP_CASE_MAPPINGS(); +DUMP_COMPOSE_TABLES(); DUMP_CTYPE_TABLES(); foreach $file (@allfiles) { HANDLE_FILE( @$file ); } @@ -185,6 +186,8 @@ sub READ_DEFAULTS @toupper_table = (); @category_table = (); @direction_table = (); + @decomp_table = (); + @compose_table = (); # first setup a few default mappings @@ -285,6 +288,12 @@ sub READ_DEFAULTS # decomposition contains only char values without prefix -> use first char $dst = hex $1; $category_table[$src] |= $category_table[$dst]; + # store decomposition if it contains two chars + if ($decomp =~ /^([0-9a-fA-F]+)\s+([0-9a-fA-F]+)$/) + { + $decomp_table[$src] = [ hex $1, hex $2 ]; + push @compose_table, [ hex $1, hex $2, $src ]; + } } else { @@ -465,7 +474,7 @@ sub DUMP_SBCS_TABLE next unless defined $uni2cp[$i]; $filled[$i >> 8] = 1; $subtables++; - $i = ($i & ~255) + 256; + $i |= 255; } # output all the subtables into a single array @@ -572,7 +581,7 @@ sub DUMP_DBCS_TABLE next unless defined $uni2cp[$i]; $filled[$i >> 8] = 1; $subtables++; - $i = ($i & ~255) + 256; + $i |= 255; } # output all the subtables into a single array @@ -669,7 +678,7 @@ sub DUMP_CASE_TABLE next unless defined $table[$i]; $filled[$i >> 8] = $pos; $pos += 256; - $i = ($i & ~255) + 256; + $i |= 255; } for ($i = 0; $i < 65536; $i++) { @@ -737,6 +746,144 @@ sub DUMP_CTYPE_TABLES close OUTPUT; } + +################################################################ +# dump the char composition tables +sub DUMP_COMPOSE_TABLES +{ + open OUTPUT,">compose.c" or die "Cannot create compose.c"; + printf "Building compose.c\n"; + printf OUTPUT "/* Unicode char composition */\n"; + printf OUTPUT "/* Automatically generated; DO NOT EDIT!! */\n\n"; + printf OUTPUT "#include \"wine/unicode.h\"\n\n"; + + ######### composition table + + my @filled = (); + foreach $i (@compose_table) + { + my @comp = @$i; + push @{$filled[$comp[1]]}, [ $comp[0], $comp[2] ]; + } + + # count how many different second chars we have + + for ($i = $count = 0; $i < 65536; $i++) + { + next unless defined $filled[$i]; + $count++; + } + + # build the table of second chars and offsets + + my $pos = $count + 1; + for ($i = 0; $i < 65536; $i++) + { + next unless defined $filled[$i]; + push @table, $i, $pos; + $pos += @{$filled[$i]}; + } + # terminator with last position + push @table, 0, $pos; + printf OUTPUT "const WCHAR unicode_compose_table[0x%x] =\n{\n", 2*$pos; + printf OUTPUT " /* second chars + offsets */\n%s", DUMP_ARRAY( "0x%04x", 0, @table ); + + # build the table of first chars and mappings + + for ($i = 0; $i < 65536; $i++) + { + next unless defined $filled[$i]; + my @table = (); + my @list = sort { $a->[0] <=> $b->[0] } @{$filled[$i]}; + for ($j = 0; $j <= $#list; $j++) + { + push @table, $list[$j][0], $list[$j][1]; + } + printf OUTPUT ",\n /* 0x%04x */\n%s", $i, DUMP_ARRAY( "0x%04x", 0, @table ); + } + printf OUTPUT "\n};\n\nconst unsigned int unicode_compose_table_size = %d;\n\n", $count; + + ######### decomposition table + + # first determine all the 16-char subsets that contain something + + my @filled = (0) x 4096; + my $pos = 16*2; # for the null subset + for ($i = 0; $i < 65536; $i++) + { + next unless defined $decomp_table[$i]; + $filled[$i >> 4] = $pos; + $pos += 16*2; + $i |= 15; + } + my $total = $pos; + + # now count the 256-char subsets that contain something + + my @filled_idx = (256) x 256; + $pos = 256 + 16; + for ($i = 0; $i < 4096; $i++) + { + next unless $filled[$i]; + $filled_idx[$i >> 4] = $pos; + $pos += 16; + $i |= 15; + } + my $null_offset = $pos; # null mapping + $total += $pos; + + # add the index offsets to the subsets positions + + for ($i = 0; $i < 4096; $i++) + { + next unless $filled[$i]; + $filled[$i] += $null_offset; + } + + # dump the main index + + printf OUTPUT "const WCHAR unicode_decompose_table[%d] =\n", $total; + printf OUTPUT "{\n /* index */\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @filled_idx ); + printf OUTPUT ",\n /* null sub-index */\n%s", DUMP_ARRAY( "0x%04x", 0, ($null_offset) x 16 ); + + # dump the second-level indexes + + for ($i = 0; $i < 256; $i++) + { + next unless ($filled_idx[$i] > 256); + my @table = @filled[($i<<4)..($i<<4)+15]; + for ($j = 0; $j < 16; $j++) { $table[$j] ||= $null_offset; } + printf OUTPUT ",\n /* sub-index %02x */\n", $i; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @table ); + } + + # dump the 16-char subsets + + printf OUTPUT ",\n /* null mapping */\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, (0) x 32 ); + + for ($i = 0; $i < 4096; $i++) + { + next unless $filled[$i]; + my @table = (0) x 32; + for ($j = 0; $j < 16; $j++) + { + if (defined $decomp_table[($i<<4) + $j]) + { + $table[2 * $j] = ${$decomp_table[($i << 4) + $j]}[0]; + $table[2 * $j + 1] = ${$decomp_table[($i << 4) + $j]}[1]; + } + } + printf OUTPUT ",\n /* 0x%03x0 .. 0x%03xf */\n", $i, $i; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @table ); + } + + printf OUTPUT "\n};\n"; + close OUTPUT; +} + + ################################################################ # read an input file and generate the corresponding .c file sub HANDLE_FILE diff --git a/unicode/mbtowc.c b/unicode/mbtowc.c index 77d62c4bc77..9f6407b2f5f 100644 --- a/unicode/mbtowc.c +++ b/unicode/mbtowc.c @@ -9,6 +9,23 @@ #include "winnls.h" #include "wine/unicode.h" +/* get the decomposition of a Unicode char */ +static int get_decomposition( WCHAR src, WCHAR *dst, unsigned int dstlen ) +{ + extern const WCHAR unicode_decompose_table[]; + const WCHAR *ptr = unicode_decompose_table; + int res; + + *dst = src; + ptr = unicode_decompose_table + ptr[src >> 8]; + ptr = unicode_decompose_table + ptr[(src >> 4) & 0x0f] + 2 * (src & 0x0f); + if (!*ptr) return 1; + if (dstlen <= 1) return 0; + /* apply the decomposition recursively to the first char */ + if ((res = get_decomposition( *ptr, dst, dstlen-1 ))) dst[res++] = ptr[1]; + return res; +} + /* check src string for invalid chars; return non-zero if invalid char found */ static inline int check_invalid_chars_sbcs( const struct sbcs_table *table, const unsigned char *src, unsigned int srclen ) @@ -70,6 +87,33 @@ static inline int mbstowcs_sbcs( const struct sbcs_table *table, } } +/* mbstowcs for single-byte code page with char decomposition */ +static int mbstowcs_sbcs_decompose( const struct sbcs_table *table, + const unsigned char *src, unsigned int srclen, + WCHAR *dst, unsigned int dstlen ) +{ + const WCHAR * const cp2uni = table->cp2uni; + unsigned int len; + + if (!dstlen) /* compute length */ + { + WCHAR dummy[4]; /* no decomposition is larger than 4 chars */ + for (len = 0; srclen; srclen--, src++) + len += get_decomposition( cp2uni[*src], dummy, 4 ); + return len; + } + + for (len = dstlen; srclen && len; srclen--, src++) + { + int res = get_decomposition( cp2uni[*src], dst, len ); + if (!res) break; + len -= res; + dst += res; + } + if (srclen) return -1; /* overflow */ + return dstlen - len; +} + /* query necessary dst length for src string */ static inline int get_length_dbcs( const struct dbcs_table *table, const unsigned char *src, unsigned int srclen ) @@ -122,7 +166,9 @@ static inline int mbstowcs_dbcs( const struct dbcs_table *table, { const WCHAR * const cp2uni = table->cp2uni; const unsigned char * const cp2uni_lb = table->cp2uni_leadbytes; - int len; + unsigned int len; + + if (!dstlen) return get_length_dbcs( table, src, srclen ); for (len = dstlen; srclen && len; len--, srclen--, src++, dst++) { @@ -140,6 +186,54 @@ static inline int mbstowcs_dbcs( const struct dbcs_table *table, } +/* mbstowcs for double-byte code page with character decomposition */ +static int mbstowcs_dbcs_decompose( const struct dbcs_table *table, + const unsigned char *src, unsigned int srclen, + WCHAR *dst, unsigned int dstlen ) +{ + const WCHAR * const cp2uni = table->cp2uni; + const unsigned char * const cp2uni_lb = table->cp2uni_leadbytes; + unsigned int len; + WCHAR ch; + int res; + + if (!dstlen) /* compute length */ + { + WCHAR dummy[4]; /* no decomposition is larger than 4 chars */ + for (len = 0; srclen; srclen--, src++) + { + unsigned char off = cp2uni_lb[*src]; + if (off) + { + if (!--srclen) break; /* partial char, ignore it */ + src++; + ch = cp2uni[(off << 8) + *src]; + } + else ch = cp2uni[*src]; + len += get_decomposition( ch, dummy, 4 ); + } + return len; + } + + for (len = dstlen; srclen && len; srclen--, src++) + { + unsigned char off = cp2uni_lb[*src]; + if (off) + { + if (!--srclen) break; /* partial char, ignore it */ + src++; + ch = cp2uni[(off << 8) + *src]; + } + else ch = cp2uni[*src]; + if (!(res = get_decomposition( ch, dst, len ))) break; + dst += res; + len -= res; + } + if (srclen) return -1; /* overflow */ + return dstlen - len; +} + + /* return -1 on dst buffer overflow, -2 on invalid input char */ int cp_mbstowcs( const union cptable *table, int flags, const char *src, int srclen, @@ -151,8 +245,12 @@ int cp_mbstowcs( const union cptable *table, int flags, { if (check_invalid_chars_sbcs( &table->sbcs, src, srclen )) return -2; } - if (!dstlen) return srclen; - return mbstowcs_sbcs( &table->sbcs, src, srclen, dst, dstlen ); + if (!(flags & MB_COMPOSITE)) + { + if (!dstlen) return srclen; + return mbstowcs_sbcs( &table->sbcs, src, srclen, dst, dstlen ); + } + return mbstowcs_sbcs_decompose( &table->sbcs, src, srclen, dst, dstlen ); } else /* mbcs */ { @@ -160,7 +258,9 @@ int cp_mbstowcs( const union cptable *table, int flags, { if (check_invalid_chars_dbcs( &table->dbcs, src, srclen )) return -2; } - if (!dstlen) return get_length_dbcs( &table->dbcs, src, srclen ); - return mbstowcs_dbcs( &table->dbcs, src, srclen, dst, dstlen ); + if (!(flags & MB_COMPOSITE)) + return mbstowcs_dbcs( &table->dbcs, src, srclen, dst, dstlen ); + else + return mbstowcs_dbcs_decompose( &table->dbcs, src, srclen, dst, dstlen ); } } diff --git a/unicode/wctomb.c b/unicode/wctomb.c index fd8b694c695..e80c253b89e 100644 --- a/unicode/wctomb.c +++ b/unicode/wctomb.c @@ -9,6 +9,90 @@ #include "winnls.h" #include "wine/unicode.h" +/* search for a character in the unicode_compose_table; helper for compose() */ +static inline int binary_search( WCHAR ch, int low, int high ) +{ + extern const WCHAR unicode_compose_table[]; + while (low <= high) + { + int pos = (low + high) / 2; + if (unicode_compose_table[2*pos] < ch) + { + low = pos + 1; + continue; + } + if (unicode_compose_table[2*pos] > ch) + { + high = pos - 1; + continue; + } + return pos; + } + return -1; +} + +/* return the result of the composition of two Unicode chars, or 0 if none */ +static WCHAR compose( const WCHAR *str ) +{ + extern const WCHAR unicode_compose_table[]; + extern const unsigned int unicode_compose_table_size; + + int idx = 1, low = 0, high = unicode_compose_table_size - 1; + for (;;) + { + int pos = binary_search( str[idx], low, high ); + if (pos == -1) return 0; + if (!idx--) return unicode_compose_table[2*pos+1]; + low = unicode_compose_table[2*pos+1]; + high = unicode_compose_table[2*pos+3] - 1; + } +} + + +/****************************************************************/ +/* sbcs support */ + +/* check if 'ch' is an acceptable sbcs mapping for 'wch' */ +static inline int is_valid_sbcs_mapping( const struct sbcs_table *table, int flags, + WCHAR wch, unsigned char ch ) +{ + if (flags & WC_NO_BEST_FIT_CHARS) return (table->cp2uni[ch] == wch); + if (ch != (unsigned char)table->info.def_char) return 1; + return (wch == table->info.def_unicode_char); +} + +/* query necessary dst length for src string */ +static inline int get_length_sbcs( const struct sbcs_table *table, int flags, + const WCHAR *src, unsigned int srclen ) +{ + unsigned int ret = srclen; + + if (flags & WC_COMPOSITECHECK) + { + const unsigned char * const uni2cp_low = table->uni2cp_low; + const unsigned short * const uni2cp_high = table->uni2cp_high; + WCHAR composed; + + for (ret = 0; srclen > 1; ret++, srclen--, src++) + { + if (!(composed = compose(src))) continue; + /* check if we should skip the next char */ + + /* in WC_DEFAULTCHAR and WC_DISCARDNS mode, we always skip */ + /* the next char no matter if the composition is valid or not */ + if (!(flags & (WC_DEFAULTCHAR|WC_DISCARDNS))) + { + unsigned char ch = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)]; + if (!is_valid_sbcs_mapping( table, flags, composed, ch )) continue; + } + src++; + srclen--; + } + if (srclen) ret++; /* last char */ + } + return ret; +} + /* wcstombs for single-byte code page */ static inline int wcstombs_sbcs( const struct sbcs_table *table, const WCHAR *src, unsigned int srclen, @@ -61,49 +145,139 @@ static int wcstombs_sbcs_slow( const struct sbcs_table *table, int flags, char *dst, unsigned int dstlen, const char *defchar, int *used ) { - const WCHAR * const cp2uni = table->cp2uni; const unsigned char * const uni2cp_low = table->uni2cp_low; const unsigned short * const uni2cp_high = table->uni2cp_high; const unsigned char table_default = table->info.def_char & 0xff; - int ret = srclen, tmp; - - if (dstlen < srclen) - { - /* buffer too small: fill it up to dstlen and return error */ - srclen = dstlen; - ret = -1; - } + unsigned int len; + int tmp; + WCHAR composed; if (!defchar) defchar = &table_default; if (!used) used = &tmp; /* avoid checking on every char */ - while (srclen) + for (len = dstlen; srclen && len; dst++, len--, src++, srclen--) { - unsigned char ch = uni2cp_low[uni2cp_high[*src >> 8] + (*src & 0xff)]; - if (((flags & WC_NO_BEST_FIT_CHARS) && (cp2uni[ch] != *src)) || - (ch == table_default && *src != table->info.def_unicode_char)) + WCHAR wch = *src; + + if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = compose(src))) { - ch = *defchar; + /* now check if we can use the composed char */ + *dst = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)]; + if (is_valid_sbcs_mapping( table, flags, composed, *dst )) + { + /* we have a good mapping, use it */ + src++; + srclen--; + continue; + } + /* no mapping for the composed char, check the other flags */ + if (flags & WC_DEFAULTCHAR) /* use the default char instead */ + { + *dst = *defchar; + *used = 1; + src++; /* skip the non-spacing char */ + srclen--; + continue; + } + if (flags & WC_DISCARDNS) /* skip the second char of the composition */ + { + src++; + srclen--; + } + /* WC_SEPCHARS is the default */ + } + + *dst = uni2cp_low[uni2cp_high[wch >> 8] + (wch & 0xff)]; + if (!is_valid_sbcs_mapping( table, flags, wch, *dst )) + { + *dst = *defchar; *used = 1; } - *dst++ = ch; - src++; - srclen--; } - return ret; + if (srclen) return -1; /* overflow */ + return dstlen - len; +} + + +/****************************************************************/ +/* dbcs support */ + +/* check if 'ch' is an acceptable dbcs mapping for 'wch' */ +static inline int is_valid_dbcs_mapping( const struct dbcs_table *table, int flags, + WCHAR wch, unsigned short ch ) +{ + if (ch == table->info.def_char && wch != table->info.def_unicode_char) return 0; + if (flags & WC_NO_BEST_FIT_CHARS) + { + /* check if char maps back to the same Unicode value */ + if (ch & 0xff00) + { + unsigned char off = table->cp2uni_leadbytes[ch >> 8]; + return (table->cp2uni[(off << 8) + (ch & 0xff)] == wch); + } + return (table->cp2uni[ch & 0xff] == wch); + } + return 1; } /* query necessary dst length for src string */ -static inline int get_length_dbcs( const struct dbcs_table *table, - const WCHAR *src, unsigned int srclen ) +static int get_length_dbcs( const struct dbcs_table *table, int flags, + const WCHAR *src, unsigned int srclen, + const char *defchar ) { const unsigned short * const uni2cp_low = table->uni2cp_low; const unsigned short * const uni2cp_high = table->uni2cp_high; + WCHAR defchar_value = table->info.def_char; + WCHAR composed; int len; - for (len = 0; srclen; srclen--, src++, len++) + if (!defchar && !(flags & WC_COMPOSITECHECK)) { - if (uni2cp_low[uni2cp_high[*src >> 8] + (*src & 0xff)] & 0xff00) len++; + for (len = 0; srclen; srclen--, src++, len++) + { + if (uni2cp_low[uni2cp_high[*src >> 8] + (*src & 0xff)] & 0xff00) len++; + } + return len; + } + + if (defchar) defchar_value = defchar[1] ? ((defchar[0] << 8) | defchar[1]) : defchar[0]; + for (len = 0; srclen; len++, srclen--, src++) + { + unsigned short res; + WCHAR wch = *src; + + if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = compose(src))) + { + /* now check if we can use the composed char */ + res = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)]; + + if (is_valid_dbcs_mapping( table, flags, composed, res )) + { + /* we have a good mapping for the composed char, use it */ + if (res & 0xff00) len++; + src++; + srclen--; + continue; + } + /* no mapping for the composed char, check the other flags */ + if (flags & WC_DEFAULTCHAR) /* use the default char instead */ + { + if (defchar_value & 0xff00) len++; + src++; /* skip the non-spacing char */ + srclen--; + continue; + } + if (flags & WC_DISCARDNS) /* skip the second char of the composition */ + { + src++; + srclen--; + } + /* WC_SEPCHARS is the default */ + } + + res = uni2cp_low[uni2cp_high[wch >> 8] + (wch & 0xff)]; + if (!is_valid_dbcs_mapping( table, flags, wch, res )) res = defchar_value; + if (res & 0xff00) len++; } return len; } @@ -138,11 +312,10 @@ static int wcstombs_dbcs_slow( const struct dbcs_table *table, int flags, char *dst, unsigned int dstlen, const char *defchar, int *used ) { - const WCHAR * const cp2uni = table->cp2uni; const unsigned short * const uni2cp_low = table->uni2cp_low; const unsigned short * const uni2cp_high = table->uni2cp_high; - const unsigned char * const cp2uni_lb = table->cp2uni_leadbytes; WCHAR defchar_value = table->info.def_char; + WCHAR composed; int len, tmp; if (defchar) defchar_value = defchar[1] ? ((defchar[0] << 8) | defchar[1]) : defchar[0]; @@ -150,32 +323,46 @@ static int wcstombs_dbcs_slow( const struct dbcs_table *table, int flags, for (len = dstlen; srclen && len; len--, srclen--, src++) { - unsigned short res = uni2cp_low[uni2cp_high[*src >> 8] + (*src & 0xff)]; + unsigned short res; + WCHAR wch = *src; - if (res == table->info.def_char && *src != table->info.def_unicode_char) + if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = compose(src))) + { + /* now check if we can use the composed char */ + res = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)]; + + if (is_valid_dbcs_mapping( table, flags, composed, res )) + { + /* we have a good mapping for the composed char, use it */ + src++; + srclen--; + goto output_char; + } + /* no mapping for the composed char, check the other flags */ + if (flags & WC_DEFAULTCHAR) /* use the default char instead */ + { + res = defchar_value; + *used = 1; + src++; /* skip the non-spacing char */ + srclen--; + goto output_char; + } + if (flags & WC_DISCARDNS) /* skip the second char of the composition */ + { + src++; + srclen--; + } + /* WC_SEPCHARS is the default */ + } + + res = uni2cp_low[uni2cp_high[wch >> 8] + (wch & 0xff)]; + if (!is_valid_dbcs_mapping( table, flags, wch, res )) { res = defchar_value; *used = 1; } - else if (flags & WC_NO_BEST_FIT_CHARS) - { - /* check if char maps back to the same Unicode value */ - if (res & 0xff00) - { - unsigned char off = cp2uni_lb[res >> 8]; - if (cp2uni[(off << 8) + (res & 0xff)] != *src) - { - res = defchar_value; - *used = 1; - } - } - else if (cp2uni[res & 0xff] != *src) - { - res = defchar_value; - *used = 1; - } - } + output_char: if (res & 0xff00) { if (len == 1) break; /* do not output a partial char */ @@ -196,7 +383,7 @@ int cp_wcstombs( const union cptable *table, int flags, { if (table->info.char_size == 1) { - if (!dstlen) return srclen; + if (!dstlen) return get_length_sbcs( &table->sbcs, flags, src, srclen ); if (flags || defchar || used) return wcstombs_sbcs_slow( &table->sbcs, flags, src, srclen, dst, dstlen, defchar, used ); @@ -204,7 +391,7 @@ int cp_wcstombs( const union cptable *table, int flags, } else /* mbcs */ { - if (!dstlen) return get_length_dbcs( &table->dbcs, src, srclen ); + if (!dstlen) return get_length_dbcs( &table->dbcs, flags, src, srclen, defchar ); if (flags || defchar || used) return wcstombs_dbcs_slow( &table->dbcs, flags, src, srclen, dst, dstlen, defchar, used );