From: handa Date: Tue, 24 Mar 2009 13:08:50 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=1e2136ba1fadf50be20c47c5c2e20259d356372c;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MText.cs b/MText.cs index 7e574ce..a610507 100644 --- a/MText.cs +++ b/MText.cs @@ -20,25 +20,47 @@ namespace M17N.Core public class MTextProperty { + private enum MTextPropertyFlagMask + { + FRONT_STICKY = 1, + REAR_STICKY = 2 + }; + internal MProperty prop; - internal bool front_sticky; - internal bool rear_sticky; - internal bool merginable; - public MProperty Prop { get { return prop; } } - public bool FrontSticky { get { return front_sticky; } } - public bool RearSticky { get { return rear_sticky; } } - public bool Merginable { get { return merginable; } } + internal byte flags; + internal MText mtext; + internal from; + internal to; - public MTextProperty (bool front_sticky, bool rear_sticky) + public MProperty Prop + { + get { return prop; } + } + public bool FrontSticky + { + get { return (flags & MTextPropertyFlagMask.FRONT_STICKY) != 0; } + } + public bool RearSticky + { + get { return (flags & MTextPropertyFlagMask.REAR_STICKY) != 0; } + } + public MText mtext { - this.front_sticky = front_sticky; - this.rear_sticky = rear_sticky; + get { return mtext; } } - public MTextProperty (bool front_sticky, bool rear_sticky, bool merginable) + public int from { - this.front_sticky = front_sticky; - this.rear_sticky = rear_sticky; - this.merginable = merginable; + get { return from; } + } + public int to + { + get { return to; } + } + + public MTextProperty (bool front_sticky, bool rear_sticky) + { + this.flags = ((front_sticky ? MTextPropertyFlagMask.FRONT_STICKY : 0) + | (rear_sticky ? MTextPropertyFlagMask.REAR_STICKY : 0)); } } @@ -48,11 +70,18 @@ namespace M17N.Core public enum MTextFormat format; #endif + private struct KeyIntervalPair + { + object key; + MInterval interval; + }; + private StringBuilder sb; private int nchars; private int cache_pos; private int cache_idx; - private MInterval root_interval; + private stack root_intervals; + private MProperty default_property; private bool read_only; private static UTF8Encoding utf8 = new UTF8Encoding (); @@ -276,78 +305,62 @@ namespace M17N.Core private class MInterval { - // position: 0 1 2 3 - // index: -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 - // | | A | | B | | C | | - // interval |<--------->|<--->|<--------------->|<----| + // position: 0 1 2 3 + // | A | B | C | + // interval |<--------->|<--------->|<--------->| // - // [-1 99 (9 89)] - // [0 10 (-1 9)] [-10 0 (89 99)] - // [0 4 (-1 3)] [-4 0 (5 9)] [0 4 (89 93)] [-2 0 (97 99)] - // - // Start and end positions of this interval and its children. - // If this is the left node, the values are relative to the - // parent's total_start. Otherwise, the values are relative to - // the parent's total_end. So: - // total_start total_end - // left-side interval 0 positive even - // right-side interval negative even 0 - // top-most interval -1 positive odd - private int total_start, total_end; - // Stack of MTextProperty + // [3 (1 2)] + // [1 (0 1)] [1 (2 3)] + private int total_length; + private int from, to; + private object key; private Stack stack; private MInterval left, right, parent; - private MText mt; - - private static int adjust_position (int pos, bool front_inclusive) - { - return (pos << 2) + (front_inclusive ? -1 : 1); - } + private MText mtext; - private static bool before_point_p (int pos) + public MInterval (object key, int length) { - return ((pos + 1) % 4) == 0; + if (length <= 0) + throw new Exception ("Invalid interval length"); + this.key = key; + total_length = length; + stack = new Stack (); } - public MInterval (int start, bool front_inclusive, - int end, bool rear_inclusive) + private MInterval (object key, int length, Stack stack) { - if (start > end) - throw new Exception ("Invalid Interval Range"); - this.total_start = (start << 2) + (front_inclusive ? -1 : 1); - this.total_end = (end << 2) + (rear_inclusive ? 1 : -1); - this.stack = new Stack (); + this.key = key; + total_length = length; + from = 0; + to = total_length; + stack = new Stack (stack); } - public MInterval (MText mt) - { - this.mt = mt; - this.total_start = -1; - this.total_end = (mt.sb.Length << 2) + 1; - this.stack = new Stack (); - } - - private MInterval () { } - - private MInterval (int start, int end, Stack stack) + public MInterval (object key, MText mt) { - this.total_start = start; - this.total_end = end; - this.stack = new Stack (stack); + this.key = key; + mtext = mt; + total_length = mt.sb.Length; + from = 0; + to = total_length; + stack = new Stack (); } - private MInterval find (int pos, out int offset) + private MInterval find (int pos) { - if (pos < total_start || total_end < pos) + if (parent != null) { - offset = 0; - return null; + from = parent.from - total_length; + if (left != null) + from += left.total_length; + to = parent.from; + if (right != null) + to -= right.total_length; } - if (pos < Start) - return left.find (pos, out offset); - if (End < pos) - return right.find (pos - total_end, out offset); - offset = pos - Start; + if (pos < from) + return left.find (pos); + if (pos >= to) + return right.find (pos); return this; } @@ -357,12 +370,12 @@ namespace M17N.Core // c1 c2 left c1 private MInterval promote_right () { - int right_length = - right.total_start; + int right_length = right.total_length; MInterval c1; if (parent == null) - mt.root_interval = right; - else if (total_start == 0) + mtext.update_root_interval (key, right); + else if (parent.left == this) parent.left = right; else parent.right = right; @@ -372,18 +385,13 @@ namespace M17N.Core parent = right; right = c1; - if (c1 != null) - c1.parent = this; - - parent.total_start = total_start; - parent.total_end = total_end; - total_start = 0; - total_end -= right_length - (c1 == null ? 0 : c1.total_end); - + parent.total_length += total_length; + total_length -= right_length; if (c1 != null) { - c1.total_end = - c1.total_start; - c1.total_start = 0; + c1.parent = this; + parent.total_length -= c1.total_length; + total_length += c1.total_length; } return parent; } @@ -394,33 +402,28 @@ namespace M17N.Core // c1 c2 c2 right private MInterval promote_left () { - int left_length = left.total_end; - MInterval c2; + int left_length = left.total_length; + MInterval c1; if (parent == null) - mt.root_interval = left; - else if (total_start == 0) + mtext.update_root_interval (key, left); + else if (parent.left == this) parent.left = left; else parent.right = left; left.parent = parent; - c2 = left.right; + c1 = left.left; left.right = this; parent = left; - left = c2; - if (c2 != null) - c2.parent = this; - - parent.total_start = total_start; - parent.total_end = total_end; - total_start -= left_length + (c2 == null ? 0 : c2.total_end);; - total_end = 0; - - if (c2 != null) + left = c1; + parent.total_length += total_length; + total_length -= left_length; + if (c1 != null) { - c2.total_start = - c2.total_end; - c2.total_end = 0; + c1.parent = this; + parent.total_length -= c1.total_length; + total_length += c1.total_length; } return parent; } @@ -431,12 +434,18 @@ namespace M17N.Core while (true) { - int this_start = interval.Start; - int this_end = interval.End; - int diff = ((this_start - interval.total_start) + // .-this-. + // .-left-. .-right-. + int left_length = (left == null ? 0 : left.total_length); + int right_length = (right == null ? 0 : right.total_length); + int length = total_length - left_length - right_length; + int diff = ((left_length + length) - - (interval.total_end - this_end)); int abs = Math.Abs (diff); + if (left == null) + diff = + if (abs < this_end - this_start) break; if (diff < 0)