/// <summary>
        /// Merge two line to one line.
        /// </summary>
        /// <param name="mergeLines">Line to be merged.</param>
        void  MergeLines(FormLineList mergeLines, FormLineList sameLevelLines)
        {
            if (mergeLines == null || mergeLines.Count < 2)
            {
                return;
            }

            FormLine firstLine    = mergeLines[0];
            bool     isHorizontal = firstLine.IsTransverseLine;

            if (isHorizontal)
            {
                List <double> xValues = mergeLines.Select(line => line.StartPoint.x).
                                        Concat(mergeLines.Select(line => line.EndPoint.x)).ToList();
                firstLine.StartPoint.x = xValues.Min();
                firstLine.EndPoint.x   = xValues.Max();
            }
            else
            {
                List <double> yValues = mergeLines.Select(line => line.StartPoint.y).
                                        Concat(mergeLines.Select(line => line.EndPoint.y)).ToList();
                firstLine.StartPoint.y = yValues.Min();
                firstLine.EndPoint.y   = yValues.Max();
            }
            for (int i = 1; i < mergeLines.Count; i++)
            {
                sameLevelLines.Remove(mergeLines[i]);
            }
        }
        /// <summary>
        /// Add a new line to line dictionary.
        /// </summary>
        /// <param name="newLine">A new line.</param>
        /// <param name="lineDic">Line dictionary</param>
        void AddLineToList(ref FormLine newLine, ref SortedDictionary <double, FormLineList> lineDic)
        {
            double newAxisValue = newLine.IsTransverseLine ? newLine.StartPoint.y : newLine.StartPoint.x;

            double[] existAxisValues = lineDic.Keys.ToArray();
            double   findResult      = HalfFind(0, existAxisValues.Length - 1, newAxisValue, existAxisValues);

            if (findResult == -1)
            {
                FormLineList newList = new FormLineList()
                {
                    newLine
                };
                lineDic.Add(newAxisValue, newList);
            }
            else
            {
                FormLineList lineList = lineDic[findResult];
                lineList.Add(newLine);

                FormLineList matchLines = new FormLineList();
                foreach (FormLine line in lineList)
                {
                    if (HasRepeatPart(line, newLine))
                    {
                        matchLines.Add(line);
                    }
                }

                MergeLines(matchLines, lineList);
            }
        }
 void RemoveLittleLines(SortedDictionary <double, FormLineList> diclines)
 {
     foreach (double key in diclines.Keys)
     {
         FormLineList lines = diclines[key];
         lines.Where(line => line.Length < 1).ToList().ForEach(line => lines.Remove(line));
     }
     diclines.Where(pair => pair.Value.Count == 0).ToList().ForEach(pair => diclines.Remove(pair.Key));
 }
 public static void RemoveLinesNotInRect(Rect rect, params SortedDictionary <double, FormLineList>[] lines)
 {
     foreach (SortedDictionary <double, FormLineList> lineDic in lines)
     {
         for (int j = 0; j < lineDic.Count; j++)
         {
             FormLineList lineList = lineDic[lineDic.Keys.ToArray()[j]];
             for (int i = 0; i < lineList.Count;)
             {
                 if (!rect.ContainFormLine(lineList[i]))
                 {
                     lineList.RemoveAt(i);
                 }
                 else
                 {
                     i++;
                 }
             }
         }
         GenericMethods <double, FormLineList> .RemoveZeroAmountValueItems(lineDic);
     }
 }
        /// <summary>
        /// Remove short lines from line dictionary.
        /// </summary>
        /// <param name="diclines">Line dictionary</param>
        void RemoveTooShortAndTooLongLines(Page page, SortedDictionary <double, FormLineList> diclines, bool isHorizontial, Rect posRect)
        {
            double[] pageSize = PdfTronHelper.GetPageSize(page);

            double maxLength = isHorizontial ? pageSize[0] : pageSize[1];

            diclines.Where(pair => pair.Value.Exists(line => Math.Abs(line.Length - maxLength) < 3))
            .Select(pair => pair.Key).ToList()
            .ForEach(key => diclines.Remove(key));
            FormLineList _lines = new FormLineList(diclines.SelectMany(pair => pair.Value).ToList());

            if (_lines.Count > 1)
            {
                if (isHorizontial)
                {
                    double[] textLeftRightXValue = pdfTronHelper.GetLeftRightTextBounds(page);
                    maxLength = (textLeftRightXValue[1] - textLeftRightXValue[0]);
                    diclines.Where(x => x.Value.Sum(line => line.Length) < maxLength * 0.5
                                   ).Select(x => x.Key).ToList().ForEach(key => diclines.Remove(key));
                    foreach (double key in diclines.Keys.ToArray())
                    {
                        FormLineList lines = diclines[key];
                        if (lines.Count < 2)
                        {
                            continue;
                        }
                        double   _maxLength    = lines.Max(line => line.Length);
                        FormLine maxLengthLine = lines.Find(line => line.Length == _maxLength);
                        lines.Where(line => line.Length < (_maxLength * 0.7)).ToList().ForEach(line => lines.Remove(line));
                    }
                    FormLineList templines = new FormLineList(diclines.SelectMany(pair => pair.Value).ToList());

                    if (templines.Count > 1)
                    {
                        maxLength = templines.Select(line => line.Length).Max();
                        double scale     = 0.4;
                        double minLength = maxLength * scale;
                        IEnumerable <double> shortLineKeys = diclines.Where(
                            x => x.Value.Sum(line => line.Length) < minLength
                            ).Select(x => x.Key);
                        shortLineKeys.ToList().ForEach(key => diclines.Remove(key));
                    }
                }
                else
                {
                    maxLength = posRect.Height();
                    if (posRect.Height() < 300)
                    {
                        maxLength = _lines.Select(line => line.Length).Max();
                    }
                    double minLength = maxLength * 0.4;

                    if (minLength < 9)
                    {
                        minLength = 9;
                    }

                    IEnumerable <double> shortLineKeys = diclines.Where(
                        x => x.Value.Sum(line => line.Length) < minLength
                        ).Select(x => x.Key);
                    shortLineKeys.ToList().ForEach(key => diclines.Remove(key));
                }
            }
            else
            {
                diclines.Clear();
            }
        }