}
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;
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
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
{