From: handa Date: Tue, 6 Jan 2009 00:09:01 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ab7f7b930295548e4dd2f08bd51f588f243d9954;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MText.cs b/MText.cs index cd9b9db..7b7a9d5 100644 --- a/MText.cs +++ b/MText.cs @@ -43,43 +43,81 @@ namespace M17N.Core } private StringBuilder sb; + private int nchars; private int cache_pos; private int cache_idx; private MTextPlist plist; private static UTF8Encoding utf8 = new UTF8Encoding (); - private static UTF32Encoding utf32 = new UTF8Encoding (); + private static UTF32Encoding utf32 = new UTF32Encoding (true, false); + + private static int count_chars (String str) + { + int len = str.Length, n = 0; + + for (int i = 0; i < len; i++) + n += surrogate_high_p (str[i]) ? 2 : 1; + return n; + } + + private static int count_chars (StringBuilder str) + { + int len = str.Length, n = 0; + + for (int i = 0; i < len; i++) + n += surrogate_high_p (str[i]) ? 2 : 1; + return n; + } public MText () { - cache_pos = cache_idx = 0; - plist = null; sb = new StringBuilder (); } public MText (byte[] str) { sb = new StringBuilder (utf8.GetString (str)); + nchars = count_chars (sb); } public MText (String str) { sb = new StringBuilder (str); + nchars = count_chars (str); + } + + public MText (StringBuilder str) + { + sb = str; + nchars = count_chars (str); + } + + public static MText operator+ (MText mt1, MText mt2) + { + return new MText (mt1.sb + mt2.sb); + } + + private static bool surrogate_high_p (char c) + { + return (c >= 0xD800 && c < 0xDC00); + } + + private static bool surrogate_low_p (char c) + { + return (c >= 0xDC00 && c < 0xE000); } - private static int inc_idx (int i) + private int inc_idx (int i) { - return ((sb[i] >= 0xD800 && sb[i] < 0xDC00) - ? i + 2 : i + 1); + return (i + (surrogate_high_p (sb[i]) ? 2 : 1)); } - private static int dec_idx (int i) + private int dec_idx (int i) { - return ((sb[i - 1] >= 0xDC00 && sb[i - 1] < 0xE000) - ? i - 2 : i - 1); + return (i - (surrogate_low_p (sb[i - 1]) ? 2 : 1)); } - private static int pos_to_idx (int pos) + private int pos_to_idx (int pos) { int p, i; bool forward; @@ -105,7 +143,7 @@ namespace M17N.Core return (cache_idx + pos - cache_pos); if (pos - cache_pos < nchars - pos) { - p = char_pos; i = char_idx; + p = cache_pos; i = cache_idx; forward = true; } else @@ -129,14 +167,27 @@ namespace M17N.Core if (i != cache_pos) i = pos_to_idx (i); if (value < 0x10000) - this.sb[i] = (char) value; + sb[i] = (char) value; else { - + char high = (char) (0xD800 + ((i - 0x10000) >> 10)); + char low = (char) (0xDC00 + ((i - 0x10000) & 0x3FF)); + + if (! surrogate_high_p (sb[i])) + sb.Insert (i, 0); + sb[i++] = high; + sb[i] = low; } } - get { return this.sb[i]; } + get { + if (i != cache_pos) + i = pos_to_idx (i); + return (surrogate_high_p (sb[i]) + ? i = ((sb[i] - 0xD800) << 10) + (sb[i + 1] - 0xDC00) + 0x10000 + : sb[i]); + } } + } public class MTextProperty {