protected SpatialComparison _InvertSpatialComparison(SpatialComparison comparison) { SpatialComparison result = comparison; switch (comparison) { case SpatialComparison.Before: result = SpatialComparison.After; break; case SpatialComparison.After: result = SpatialComparison.Before; break; case SpatialComparison.OverlapBefore: result = SpatialComparison.OverlapAfter; break; case SpatialComparison.OverlapAfter: result = SpatialComparison.OverlapBefore; break; default: break; } return(result); }
protected int _SpatialToAbsoluteComparison(SpatialComparison comparison) { int result = 0; switch (comparison) { case SpatialComparison.Before: case SpatialComparison.OverlapBefore: result = -1; break; case SpatialComparison.After: case SpatialComparison.OverlapAfter: result = 1; break; case SpatialComparison.Equal: result = 0; break; default: Debug.Assert(false); break; } return(result); }
//Method that compares horizontally according to specific reading order //In the future we should take into account the document language and plug it into this algorithm protected SpatialComparison _CompareVertical(FixedSOMSemanticBox otherBox) { SpatialComparison result = SpatialComparison.None; Rect thisRect = this.BoundingRect; Rect otherRect = otherBox.BoundingRect; if (thisRect.Top == otherRect.Top) { result = SpatialComparison.Equal; } else if (thisRect.Bottom <= otherRect.Top) { //Clearly before the other object result = SpatialComparison.Before; } else if (otherRect.Bottom <= thisRect.Top) { //Clearly after the other object result = SpatialComparison.After; } else { //Objects overlap if (thisRect.Top < otherRect.Top) { result = SpatialComparison.OverlapBefore; } else { result = SpatialComparison.OverlapAfter; } } return(result); }
//-------------------------------------------------------------------- // // Protected Methods // //--------------------------------------------------------------------- #region Private Methods //Method that compares horizontally according to specific reading order protected SpatialComparison _CompareHorizontal(FixedSOMSemanticBox otherBox, bool RTL) { SpatialComparison result = SpatialComparison.None; Rect thisRect = this.BoundingRect; Rect otherRect = otherBox.BoundingRect; double thisRectRefX = RTL ? thisRect.Right : thisRect.Left; double otherRectRefX = RTL ? otherRect.Right : otherRect.Left; if (thisRectRefX == otherRectRefX) { result = SpatialComparison.Equal; } //Easiest way: calculate as if it's LTR and invert the result if RTL else if (thisRect.Right < otherRect.Left) { //Clearly before the other object result = SpatialComparison.Before; } else if (otherRect.Right < thisRect.Left) { //Clearly after the other object result = SpatialComparison.After; } else { double overlap = Math.Abs(thisRectRefX - otherRectRefX); double longerWidth = thisRect.Width > otherRect.Width ? thisRect.Width : otherRect.Width; if (overlap / longerWidth < 0.1) { //If less than 10% overlap then assume these are equal in horizontal comparison result = SpatialComparison.Equal; } //Objects overlap else if (thisRect.Left < otherRect.Left) { result = SpatialComparison.OverlapBefore; } else { result = SpatialComparison.OverlapAfter; } } if (RTL && result != SpatialComparison.Equal) { result = _InvertSpatialComparison(result); } return(result); }
int IComparable.CompareTo(object comparedObj) { int result = Int32.MinValue; FixedSOMPageElement compared = comparedObj as FixedSOMPageElement; FixedSOMPageElement This = this as FixedSOMPageElement; Debug.Assert(compared != null); Debug.Assert(This != null); if (compared == null) { throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, comparedObj.GetType(), typeof(FixedSOMContainer)), "comparedObj"); } SpatialComparison compareHor = base._CompareHorizontal(compared, false); SpatialComparison compareVer = base._CompareVertical(compared); Debug.Assert(compareHor != SpatialComparison.None); Debug.Assert(compareVer != SpatialComparison.None); switch (compareHor) { case SpatialComparison.Before: if (compareVer != SpatialComparison.After) { result = -1; } break; case SpatialComparison.After: if (compareVer != SpatialComparison.Before) { result = 1; } break; case SpatialComparison.OverlapBefore: if (compareVer == SpatialComparison.Before) { result = -1; } else if (compareVer == SpatialComparison.After) { result = 1; } break; case SpatialComparison.OverlapAfter: if (compareVer == SpatialComparison.After) { result = 1; } else if (compareVer == SpatialComparison.Before) { result = -1; } break; case SpatialComparison.Equal: switch (compareVer) { case SpatialComparison.After: case SpatialComparison.OverlapAfter: result = 1; break; case SpatialComparison.Before: case SpatialComparison.OverlapBefore: result = -1; break; case SpatialComparison.Equal: result = 0; break; default: Debug.Assert(false); break; } break; default: //Shouldn't happen Debug.Assert(false); break; } if (result == Int32.MinValue) { //Indecisive. Does markup order help? if (This.FixedNodes.Count == 0 || compared.FixedNodes.Count == 0) { result = 0; } else { FixedNode thisObjFirstNode = This.FixedNodes[0]; FixedNode thisObjLastNode = This.FixedNodes[This.FixedNodes.Count - 1]; FixedNode otherObjFirstNode = compared.FixedNodes[0]; FixedNode otherObjLastNode = compared.FixedNodes[compared.FixedNodes.Count - 1]; if (This.FixedSOMPage.MarkupOrder.IndexOf(otherObjFirstNode) - This.FixedSOMPage.MarkupOrder.IndexOf(thisObjLastNode) == 1) { result = -1; } else if (This.FixedSOMPage.MarkupOrder.IndexOf(otherObjLastNode) - This.FixedSOMPage.MarkupOrder.IndexOf(thisObjFirstNode) == 1) { result = 1; } else { //Indecisive. Whichever is below comes after; if same whichever is on the right comes after int absVerComparison = _SpatialToAbsoluteComparison(compareVer); result = absVerComparison != 0 ? absVerComparison : _SpatialToAbsoluteComparison(compareHor); } } } return(result); }
protected SpatialComparison _InvertSpatialComparison(SpatialComparison comparison) { SpatialComparison result = comparison; switch (comparison) { case SpatialComparison.Before: result = SpatialComparison.After; break; case SpatialComparison.After: result = SpatialComparison.Before; break; case SpatialComparison.OverlapBefore: result = SpatialComparison.OverlapAfter; break; case SpatialComparison.OverlapAfter: result = SpatialComparison.OverlapBefore; break; default: break; } return result; }
protected int _SpatialToAbsoluteComparison(SpatialComparison comparison) { int result=0; switch (comparison) { case SpatialComparison.Before: case SpatialComparison.OverlapBefore: result = -1; break; case SpatialComparison.After: case SpatialComparison.OverlapAfter: result = 1; break; case SpatialComparison.Equal: result = 0; break; default: Debug.Assert(false); break; } return result; }
public int CompareTo(object o) { Debug.Assert(o != null); if (!(o is FixedSOMSemanticBox)) { throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, o.GetType(), typeof(FixedSOMSemanticBox)), "o"); } SpatialComparison compareHor = _CompareHorizontal(o as FixedSOMSemanticBox, false); SpatialComparison compareVer = _CompareVertical(o as FixedSOMSemanticBox); Debug.Assert(compareHor != SpatialComparison.None && compareVer != SpatialComparison.None); int result; if (compareHor == SpatialComparison.Equal && compareVer == SpatialComparison.Equal) { result = 0; } else if (compareHor == SpatialComparison.Equal) { if (compareVer == SpatialComparison.Before || compareVer == SpatialComparison.OverlapBefore) { result = -1; } else { result = 1; } } else if (compareVer == SpatialComparison.Equal) { if (compareHor == SpatialComparison.Before || compareHor == SpatialComparison.OverlapBefore) { result = -1; } else { result = 1; } } else if (compareHor == SpatialComparison.Before) { result = -1; } else if (compareHor == SpatialComparison.After) { result = 1; } else { //Objects overlap if (compareVer == SpatialComparison.Before) { result = -1; } else if (compareVer == SpatialComparison.After) { result = 1; } //These objects intersect. else if (compareHor == SpatialComparison.OverlapBefore) { result = -1; } else { result = 1; } } return(result); }
int IComparable.CompareTo(object comparedObj) { int result = Int32.MinValue; FixedSOMGroup compared = comparedObj as FixedSOMGroup; Debug.Assert(compared != null); if (compared == null) { throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, comparedObj.GetType(), typeof(FixedSOMGroup)), "comparedObj"); } bool RTL = this.IsRTL && compared.IsRTL; SpatialComparison compareHor = base._CompareHorizontal(compared, RTL); SpatialComparison compareVer = base._CompareVertical(compared); Debug.Assert(compareHor != SpatialComparison.None); Debug.Assert(compareVer != SpatialComparison.None); switch (compareVer) { case SpatialComparison.Before: result = -1; break; case SpatialComparison.After: result = 1; break; case SpatialComparison.OverlapBefore: if ((int)compareHor <= (int)SpatialComparison.Equal) { result = -1; } else { result = 1; } break; case SpatialComparison.OverlapAfter: if ((int)compareHor >= (int)SpatialComparison.Equal) { result = 1; } else { result = -1; } break; case SpatialComparison.Equal: switch (compareHor) { case SpatialComparison.After: case SpatialComparison.OverlapAfter: result = 1; break; case SpatialComparison.Before: case SpatialComparison.OverlapBefore: result = -1; break; case SpatialComparison.Equal: result = 0; break; default: Debug.Assert(false); break; } break; default: //Shouldn't happen Debug.Assert(false); break; } return(result); }