void TraceOutlineCcw(Remaining toReadNext, RawOutline output, bool outside) { output.BeginContour(outside); //if we starts on left-side of the column ColumnWalkerCcw ccw = new ColumnWalkerCcw(_verticalGroupList); ccw.Bind(output); //------------------------------- for (; ;) { switch (toReadNext.unreadSide) { default: throw new System.NotSupportedException(); case ReadSide.Left: ccw.Bind(toReadNext.column); ccw.ReadLeftSide(); break; case ReadSide.Right: ccw.Bind(toReadNext.column); ccw.ReadRightSide(); break; case ReadSide.None: //complete output.EndContour(); return; } toReadNext = ccw.FindReadNextColumn(); } }
/// <summary> /// trace outline counter-clockwise /// </summary> /// <param name="output"></param> void TraceOutline(HSpan[] sortedHSpans, RawOutline output) { if (sortedHSpans == null) { return; } // var sep = new VerticalGroupSeparator(_verticalGroupList); sep.Separate(sortedHSpans); int vertGroupCount = _verticalGroupList.Count; if (vertGroupCount == 0) { return; } _verticalGroupList.EvaluateCorners(); List <Remaining> incompleteReadList = new List <Remaining>(); TraceOutlineCcw(new Remaining(_verticalGroupList.GetGroup(0).GetColumn(0), ReadSide.Left), output, true); TRACE_AGAIN: //** //check if the shape have hole(s) _verticalGroupList.CollectIncompleteColumns(incompleteReadList); if (incompleteReadList.Count > 0) { //this should be a hole Remaining incompleteRead = incompleteReadList[0]; switch (incompleteRead.unreadSide) { //?should not occur case ReadSide.LeftAndRight: { TraceOutlineCcw(new Remaining(incompleteRead.column, ReadSide.Left), output, false); incompleteReadList.Clear(); goto TRACE_AGAIN; } case ReadSide.Left: case ReadSide.Right: { TraceOutlineCcw(incompleteRead, output, false); incompleteReadList.Clear(); goto TRACE_AGAIN; } } } else { //complete all } }