public void GetTableAreas() { var l0 = TestHelper.MakeTextLine(new float[] { 72.0f, 702.8702f, 527.555f, 717.87f }, "l0"); var l1 = TestHelper.MakeTextLine(new float[] { 93.59f, 685.65f, 229.41f, 700.65f }, "l1"); var l2 = TestHelper.MakeTextLine(new float[] { 71.99f, 660.03469f, 90.34772f, 671.0147f }, "l2"); var l3 = TestHelper.MakeTextLine(new float[] { 100.799f, 659.82f, 392.513f, 671.8205f }, "l3"); var l4 = TestHelper.MakeTextLine(new float[] { 71.995f, 641.1378f, 99.5225f, 652.1178f }, "l4"); var l5 = TestHelper.MakeTextLine(new float[] { 107.999f, 641.1378f, 401.308f, 652.1178f }, "l5"); // generate TextEdges tes = new TextEdges(); tes.Generate(new TextLine[] { l0, l1, l2, l3, l4, l5 }); tes.TextedgesForTest["left"][0].IsValid = true; // force one valid var relevant = tes.GetRelevant(); var l6 = TestHelper.MakeTextLine(new float[] { 100.799f, 650f, 392.513f, 660f }, "l6"); var areas = tes.GetTableAreas(new TextLine[] { l0, l1, l2, l3, l4, l5, l6 }, relevant); Assert.Single(areas); Assert.Equal(61.98999f, areas.Keys.First().Item1, 4); Assert.Equal(631.1378f, areas.Keys.First().Item2, 4); Assert.Equal(537.555f, areas.Keys.First().Item3, 4); Assert.Equal(778.54165f, areas.Keys.First().Item4, 4); Assert.Null(areas.Values.First()); }
public void Generate() { var l0 = TestHelper.MakeTextLine(new float[] { 72.0f, 702.8702f, 527.555f, 717.87f }, "l0"); var l1 = TestHelper.MakeTextLine(new float[] { 93.59f, 685.65f, 229.41f, 700.65f }, "l1"); var l2 = TestHelper.MakeTextLine(new float[] { 71.99f, 660.03469f, 90.34772f, 671.0147f }, "l2"); var l3 = TestHelper.MakeTextLine(new float[] { 100.799f, 659.82f, 392.513f, 671.8205f }, "l3"); var l4 = TestHelper.MakeTextLine(new float[] { 71.995f, 641.1378f, 99.5225f, 652.1178f }, "l4"); var l5 = TestHelper.MakeTextLine(new float[] { 107.999f, 641.1378f, 401.308f, 652.1178f }, "l5"); // generate TextEdges tes = new TextEdges(); tes.Generate(new TextLine[] { l0, l1, l2, l3, l4, l5 }); foreach (var align in new string[] { "left", "right", "middle" }) { var te = tes.TextedgesForTest[align]; var expected = FooTextEdges[align]; Assert.Equal(expected.Count, te.Count); for (int t = 0; t < expected.Count; t++) { Assert.Equal(expected[t], te[t].ToString()); } } }
public void Create() { TextEdges te0 = new TextEdges(); Assert.Equal(50, te0.EdgeTol); TextEdges te1 = new TextEdges(1.025f); Assert.Equal(1.025f, te1.EdgeTol); TextEdges te2 = new TextEdges(3.14f); Assert.Equal(3.14f, te2.EdgeTol); }
public void Find() { var l0 = TestHelper.MakeTextLine(new float[] { 72.0f, 702.8702f, 527.555f, 717.87f }, "l0"); var l1 = TestHelper.MakeTextLine(new float[] { 93.59f, 685.65f, 229.41f, 700.65f }, "l1"); var l2 = TestHelper.MakeTextLine(new float[] { 71.99f, 660.03469f, 90.34772f, 671.0147f }, "l2"); var l3 = TestHelper.MakeTextLine(new float[] { 100.799f, 659.82f, 392.513f, 671.8205f }, "l3"); var l4 = TestHelper.MakeTextLine(new float[] { 71.995f, 641.1378f, 99.5225f, 652.1178f }, "l4"); var l5 = TestHelper.MakeTextLine(new float[] { 107.999f, 641.1378f, 401.308f, 652.1178f }, "l5"); TextEdges tes = new TextEdges(); tes.Generate(new TextLine[] { l0, l1, l2, l3, l4, l5 }); // find Assert.Equal(2, tes.Find(81, "middle")); Assert.Equal(3, tes.Find(246.2f, "middle")); Assert.Null(tes.Find(246, "middle")); Assert.Equal(1, tes.Find(94, "left")); Assert.Equal(1, tes.Find(229, "right")); Assert.Throws <KeyNotFoundException>(() => tes.Find(229, "right ")); }
public void GetRelevant() { var l0 = TestHelper.MakeTextLine(new float[] { 72.0f, 702.8702f, 527.555f, 717.87f }, "l0"); var l1 = TestHelper.MakeTextLine(new float[] { 93.59f, 685.65f, 229.41f, 700.65f }, "l1"); var l2 = TestHelper.MakeTextLine(new float[] { 71.99f, 660.03469f, 90.34772f, 671.0147f }, "l2"); var l3 = TestHelper.MakeTextLine(new float[] { 100.799f, 659.82f, 392.513f, 671.8205f }, "l3"); var l4 = TestHelper.MakeTextLine(new float[] { 71.995f, 641.1378f, 99.5225f, 652.1178f }, "l4"); var l5 = TestHelper.MakeTextLine(new float[] { 107.999f, 641.1378f, 401.308f, 652.1178f }, "l5"); // generate TextEdges tes = new TextEdges(); tes.Generate(new TextLine[] { l0, l1, l2, l3, l4, l5 }); var relevant = tes.GetRelevant(); Assert.Equal(FooTextEdgesRelevant.Length, relevant.Count); for (int r = 0; r < relevant.Count; r++) { Assert.Equal(FooTextEdgesRelevant[r], relevant[r].ToString()); } }
/// <summary> /// Detects the tables in the page. /// </summary> /// <param name="page"></param> public List <TableRectangle> Detect(PageArea page) { // get horizontal & vertical lines // we get these from an image of the PDF and not the PDF itself because sometimes there are invisible PDF // instructions that are interpreted incorrectly as visible elements - we really want to capture what a // person sees when they look at the PDF // BobLd: hack here, we don't convert to an image var pageRulings = page.GetRulings(); List <Ruling> horizontalRulings = this.getHorizontalRulings(pageRulings); List <Ruling> verticalRulings = this.getVerticalRulings(pageRulings); // end hack here List <Ruling> allEdges = new List <Ruling>(horizontalRulings); allEdges.AddRange(verticalRulings); List <TableRectangle> tableAreas = new List <TableRectangle>(); // if we found some edges, try to find some tables based on them if (allEdges.Count > 0) { // now we need to snap edge endpoints to a grid Utils.SnapPoints(allEdges, POINT_SNAP_DISTANCE_THRESHOLD, POINT_SNAP_DISTANCE_THRESHOLD); // normalize the rulings to make sure snapping didn't create any wacky non-horizontal/vertical rulings foreach (List <Ruling> rulings in new[] { horizontalRulings, verticalRulings }) //Arrays.asList(horizontalRulings, verticalRulings)) { //for (Iterator<Ruling> iterator = rulings.iterator(); iterator.hasNext();) foreach (var ruling in rulings.ToList()) // use ToList to be able to remove { ruling.Normalize(); if (ruling.IsOblique) { rulings.Remove(ruling); } } } // merge the edge lines into rulings - this makes finding edges between crossing points in the next step easier // we use a larger pixel expansion than the normal spreadsheet extraction method to cover gaps in the // edge detection/pixel snapping steps horizontalRulings = Ruling.CollapseOrientedRulings(horizontalRulings, 5); verticalRulings = Ruling.CollapseOrientedRulings(verticalRulings, 5); // use the rulings and points to find cells List <TableRectangle> cells = SpreadsheetExtractionAlgorithm.FindCells(horizontalRulings, verticalRulings).Cast <TableRectangle>().ToList(); // then use those cells to make table areas tableAreas = getTableAreasFromCells(cells); } // next find any vertical rulings that intersect tables - sometimes these won't have completely been captured as // cells if there are missing horizontal lines (which there often are) // let's assume though that these lines should be part of the table foreach (Ruling verticalRuling in verticalRulings) // Line2D.Float { foreach (TableRectangle tableArea in tableAreas) { if (verticalRuling.Intersects(tableArea) && !(tableArea.Contains(verticalRuling.P1) && tableArea.Contains(verticalRuling.P2))) { tableArea.SetTop(Math.Ceiling(Math.Max(tableArea.Top, verticalRuling.Y2))); // bobld: Floor and Min, Y1 tableArea.SetBottom(Math.Floor(Math.Min(tableArea.Bottom, verticalRuling.Y1))); // bobld: Ceiling and Max, Y2 break; } } } /* BobLd: not sure this is the case in tabula-sharp/PdfPig * // the tabula Page coordinate space is half the size of the PDFBox image coordinate space * // so halve the table area size before proceeding and add a bit of padding to make sure we capture everything * foreach (TableRectangle area in tableAreas) * { * area.x = (float)Math.floor(area.x / 2) - TABLE_PADDING_AMOUNT; * area.y = (float)Math.floor(area.y / 2) - TABLE_PADDING_AMOUNT; * area.width = (float)Math.ceil(area.width / 2) + TABLE_PADDING_AMOUNT; * area.height = (float)Math.ceil(area.height / 2) + TABLE_PADDING_AMOUNT; * } * * // we're going to want halved horizontal lines later too * foreach (Ruling ruling in horizontalRulings) // Line2D.Float * { * ruling.x1 = ruling.x1 / 2; * ruling.y1 = ruling.y1 / 2; * ruling.x2 = ruling.x2 / 2; * ruling.y2 = ruling.y2 / 2; * } */ // now look at text rows to help us find more tables and flesh out existing ones List <TextChunk> textChunks = TextElement.MergeWords(page.GetText()); List <TableLine> lines = TextChunk.GroupByLines(textChunks); // first look for text rows that intersect an existing table - those lines should probably be part of the table foreach (TableLine textRow in lines) { foreach (TableRectangle tableArea in tableAreas) { if (!tableArea.Contains(textRow) && textRow.Intersects(tableArea)) { tableArea.SetLeft(Math.Floor(Math.Min(textRow.Left, tableArea.Left))); tableArea.SetRight(Math.Ceiling(Math.Max(textRow.Right, tableArea.Right))); } } } // get rid of tables that DO NOT intersect any text areas - these are likely graphs or some sort of graphic //for (Iterator<Rectangle> iterator = tableAreas.iterator(); iterator.hasNext();) foreach (TableRectangle table in tableAreas.ToList()) // use tolist to be able to remove { bool intersectsText = false; foreach (TableLine textRow in lines) { if (table.Intersects(textRow)) { intersectsText = true; break; } } if (!intersectsText) { tableAreas.Remove(table); } } // lastly, there may be some tables that don't have any vertical rulings at all // we'll use text edges we've found to try and guess which text rows are part of a table // in his thesis nurminen goes through every row to try to assign a probability that the line is in a table // we're going to try a general heuristic instead, trying to find what type of edge (left/right/mid) intersects // the most text rows, and then use that magic number of "relevant" edges to decide what text rows should be // part of a table. bool foundTable; do { foundTable = false; // get rid of any text lines contained within existing tables, this allows us to find more tables //for (Iterator<TableLine> iterator = lines.iterator(); iterator.hasNext();) foreach (var textRow in lines.ToList()) { foreach (TableRectangle table in tableAreas) { if (table.Contains(textRow)) { lines.Remove(textRow); break; } } } // get text edges from remaining lines in the document TextEdges textEdges = getTextEdges(lines); //List<TextEdge> leftTextEdges = textEdges[TextEdge.LEFT]; //List<TextEdge> midTextEdges = textEdges[TextEdge.MID]; //List<TextEdge> rightTextEdges = textEdges[TextEdge.RIGHT]; // find the relevant text edges (the ones we think define where a table is) RelevantEdges relevantEdgeInfo = getRelevantEdges(textEdges, lines); // we found something relevant so let's look for rows that fit our criteria if (relevantEdgeInfo.edgeType != -1) { List <TextEdge> relevantEdges = null; switch (relevantEdgeInfo.edgeType) { case TextEdge.LEFT: relevantEdges = textEdges[TextEdge.LEFT]; // leftTextEdges; break; case TextEdge.MID: relevantEdges = textEdges[TextEdge.MID]; // midTextEdges; break; case TextEdge.RIGHT: relevantEdges = textEdges[TextEdge.RIGHT]; // rightTextEdges; break; } TableRectangle table = getTableFromText(lines, relevantEdges, relevantEdgeInfo.edgeCount, horizontalRulings); if (table != null) { foundTable = true; tableAreas.Add(table); } } } while (foundTable); // create a set of our current tables that will eliminate duplicate tables SortedSet <TableRectangle> tableSet = new SortedSet <TableRectangle>(new TreeSetComparer()); //Set<Rectangle> tableSet = new TreeSet<>(new Comparator<Rectangle>() {... foreach (var table in tableAreas.OrderByDescending(t => t.Area)) { tableSet.Add(table); } return(tableSet.ToList()); }
private RelevantEdges getRelevantEdges(TextEdges textEdges, List <TableLine> lines) { List <TextEdge> leftTextEdges = textEdges[TextEdge.LEFT]; List <TextEdge> midTextEdges = textEdges[TextEdge.MID]; List <TextEdge> rightTextEdges = textEdges[TextEdge.RIGHT]; // first we'll find the number of lines each type of edge crosses int[][] edgeCountsPerLine = new int[lines.Count][]; for (int i = 0; i < edgeCountsPerLine.Length; i++) { edgeCountsPerLine[i] = new int[TextEdge.NUM_TYPES]; } foreach (TextEdge edge in leftTextEdges) { edgeCountsPerLine[edge.intersectingTextRowCount - 1][TextEdge.LEFT]++; } foreach (TextEdge edge in midTextEdges) { edgeCountsPerLine[edge.intersectingTextRowCount - 1][TextEdge.MID]++; } foreach (TextEdge edge in rightTextEdges) { edgeCountsPerLine[edge.intersectingTextRowCount - 1][TextEdge.RIGHT]++; } // now let's find the relevant edge type and the number of those edges we should look for // we'll only take a minimum of two edges to look for tables int relevantEdgeType = -1; int relevantEdgeCount = 0; for (int i = edgeCountsPerLine.Length - 1; i > 2; i--) { if (edgeCountsPerLine[i][TextEdge.LEFT] > 2 && edgeCountsPerLine[i][TextEdge.LEFT] >= edgeCountsPerLine[i][TextEdge.RIGHT] && edgeCountsPerLine[i][TextEdge.LEFT] >= edgeCountsPerLine[i][TextEdge.MID]) { relevantEdgeCount = edgeCountsPerLine[i][TextEdge.LEFT]; relevantEdgeType = TextEdge.LEFT; break; } if (edgeCountsPerLine[i][TextEdge.RIGHT] > 1 && edgeCountsPerLine[i][TextEdge.RIGHT] >= edgeCountsPerLine[i][TextEdge.LEFT] && edgeCountsPerLine[i][TextEdge.RIGHT] >= edgeCountsPerLine[i][TextEdge.MID]) { relevantEdgeCount = edgeCountsPerLine[i][TextEdge.RIGHT]; relevantEdgeType = TextEdge.RIGHT; break; } if (edgeCountsPerLine[i][TextEdge.MID] > 1 && edgeCountsPerLine[i][TextEdge.MID] >= edgeCountsPerLine[i][TextEdge.RIGHT] && edgeCountsPerLine[i][TextEdge.MID] >= edgeCountsPerLine[i][TextEdge.LEFT]) { relevantEdgeCount = edgeCountsPerLine[i][TextEdge.MID]; relevantEdgeType = TextEdge.MID; break; } } return(new RelevantEdges(relevantEdgeType, relevantEdgeCount)); }
public void GetXCoord() { var fd = new FontDetails(string.Empty, false, 1, false); Assert.Throws <ArgumentOutOfRangeException>(() => TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.0f, 702.8702f, 527.5550679849999f, 717.8702f }, string.Empty), "left1")); Assert.Throws <ArgumentOutOfRangeException>(() => TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.0f, 702.8702f, 527.5550679849999f, 717.8702f }, string.Empty), "RIGHT")); Assert.Equal(72.0, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.0f, 702.8702f, 527.5550679849999f, 717.8702f }, string.Empty), "left"), 3); Assert.Equal(527.5550679849999, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.0f, 702.8702f, 527.5550679849999f, 717.8702f }, string.Empty), "right"), 3); Assert.Equal(299.77753399249997, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.0f, 702.8702f, 527.5550679849999f, 717.8702f }, string.Empty), "middle"), 3); Assert.Equal(93.59997999999996, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 93.59997999999996f, 685.6502999999999f, 229.40997999999993f, 700.6502999999999f }, string.Empty), "left"), 3); Assert.Equal(229.40997999999993, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 93.59997999999996f, 685.6502999999999f, 229.40997999999993f, 700.6502999999999f }, string.Empty), "right"), 3); Assert.Equal(161.50497999999993, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 93.59997999999996f, 685.6502999999999f, 229.40997999999993f, 700.6502999999999f }, string.Empty), "middle"), 3); Assert.Equal(71.99997999999994, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99997999999994f, 660.0346999999999f, 90.34771999999994f, 671.0147f }, string.Empty), "left"), 3); Assert.Equal(90.34771999999994, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99997999999994f, 660.0346999999999f, 90.34771999999994f, 671.0147f }, string.Empty), "right"), 3); Assert.Equal(81.17384999999993, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99997999999994f, 660.0346999999999f, 90.34771999999994f, 671.0147f }, string.Empty), "middle"), 3); Assert.Equal(100.79997999999993, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 100.79997999999993f, 659.8204999999999f, 392.5128999999999f, 671.8204999999999f }, string.Empty), "left"), 3); Assert.Equal(392.5128999999999, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 100.79997999999993f, 659.8204999999999f, 392.5128999999999f, 671.8204999999999f }, string.Empty), "right"), 3); Assert.Equal(246.65643999999992, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 100.79997999999993f, 659.8204999999999f, 392.5128999999999f, 671.8204999999999f }, string.Empty), "middle"), 3); Assert.Equal(71.99545999999992, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99545999999992f, 641.1378f, 99.52249999999992f, 652.1178f }, string.Empty), "left"), 3); Assert.Equal(99.52249999999992, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99545999999992f, 641.1378f, 99.52249999999992f, 652.1178f }, string.Empty), "right"), 3); Assert.Equal(85.75897999999992, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99545999999992f, 641.1378f, 99.52249999999992f, 652.1178f }, string.Empty), "middle"), 3); Assert.Equal(107.99895999999993, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 107.99895999999993f, 641.1378f, 401.3076499999999f, 652.1178f }, string.Empty), "left"), 3); Assert.Equal(401.3076499999999, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 107.99895999999993f, 641.1378f, 401.3076499999999f, 652.1178f }, string.Empty), "right"), 3); Assert.Equal(254.6533049999999, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 107.99895999999993f, 641.1378f, 401.3076499999999f, 652.1178f }, string.Empty), "middle"), 3); Assert.Equal(72.00020999999992, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00020999999992f, 621.4201999999999f, 522.696463168f, 633.4201999999999f }, string.Empty), "left"), 3); Assert.Equal(522.696463168, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00020999999992f, 621.4201999999999f, 522.696463168f, 633.4201999999999f }, string.Empty), "right"), 3); Assert.Equal(297.348336584, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00020999999992f, 621.4201999999999f, 522.696463168f, 633.4201999999999f }, string.Empty), "middle"), 3); Assert.Equal(72.00012999999993, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00012999999993f, 607.6202f, 528.9215913119999f, 619.6202f }, string.Empty), "left"), 3); Assert.Equal(528.9215913119999, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00012999999993f, 607.6202f, 528.9215913119999f, 619.6202f }, string.Empty), "right"), 3); Assert.Equal(300.4608606559999, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00012999999993f, 607.6202f, 528.9215913119999f, 619.6202f }, string.Empty), "middle"), 3); Assert.Equal(72.00014999999996, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00014999999996f, 593.8202f, 506.539544f, 605.8202f }, string.Empty), "left"), 3); Assert.Equal(506.539544, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00014999999996f, 593.8202f, 506.539544f, 605.8202f }, string.Empty), "right"), 3); Assert.Equal(289.26984699999997, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00014999999996f, 593.8202f, 506.539544f, 605.8202f }, string.Empty), "middle"), 3); Assert.Equal(72.00037999999995, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00037999999995f, 580.0202f, 526.5470508200001f, 592.0202f }, string.Empty), "left"), 3); Assert.Equal(526.5470508200001, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00037999999995f, 580.0202f, 526.5470508200001f, 592.0202f }, string.Empty), "right"), 3); Assert.Equal(299.27371541, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00037999999995f, 580.0202f, 526.5470508200001f, 592.0202f }, string.Empty), "middle"), 3); Assert.Equal(72.00037999999995, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00037999999995f, 566.2202000000001f, 529.820239408f, 578.2202000000001f }, string.Empty), "left"), 3); Assert.Equal(529.820239408, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00037999999995f, 566.2202000000001f, 529.820239408f, 578.2202000000001f }, string.Empty), "right"), 3); Assert.Equal(300.910309704, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00037999999995f, 566.2202000000001f, 529.820239408f, 578.2202000000001f }, string.Empty), "middle"), 3); Assert.Equal(72.00021999999996, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00021999999996f, 552.4202000000001f, 527.4595964399999f, 564.4202000000001f }, string.Empty), "left"), 3); Assert.Equal(527.4595964399999, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00021999999996f, 552.4202000000001f, 527.4595964399999f, 564.4202000000001f }, string.Empty), "right"), 3); Assert.Equal(299.72990821999997, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 72.00021999999996f, 552.4202000000001f, 527.4595964399999f, 564.4202000000001f }, string.Empty), "middle"), 3); Assert.Equal(71.99927999999994, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99927999999994f, 538.6202000000002f, 539.94603048f, 550.6202000000002f }, string.Empty), "left"), 3); Assert.Equal(539.94603048, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99927999999994f, 538.6202000000002f, 539.94603048f, 550.6202000000002f }, string.Empty), "right"), 3); Assert.Equal(305.97265524, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99927999999994f, 538.6202000000002f, 539.94603048f, 550.6202000000002f }, string.Empty), "middle"), 3); Assert.Equal(71.99880000000002, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99880000000002f, 524.8202000000002f, 396.5388f, 536.8202000000002f }, string.Empty), "left"), 3); Assert.Equal(396.5388, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99880000000002f, 524.8202000000002f, 396.5388f, 536.8202000000002f }, string.Empty), "right"), 3); Assert.Equal(234.2688, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99880000000002f, 524.8202000000002f, 396.5388f, 536.8202000000002f }, string.Empty), "middle"), 3); Assert.Equal(89.99879999999996, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99879999999996f, 505.0202000000003f, 333.53877375999997f, 517.2242000000002f }, string.Empty), "left"), 3); Assert.Equal(333.53877375999997, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99879999999996f, 505.0202000000003f, 333.53877375999997f, 517.2242000000002f }, string.Empty), "right"), 3); Assert.Equal(211.76878687999996, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99879999999996f, 505.0202000000003f, 333.53877375999997f, 517.2242000000002f }, string.Empty), "middle"), 3); Assert.Equal(89.99893, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99893f, 485.22020000000026f, 353.63877f, 497.42420000000027f }, string.Empty), "left"), 3); Assert.Equal(353.63877, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99893f, 485.22020000000026f, 353.63877f, 497.42420000000027f }, string.Empty), "right"), 3); Assert.Equal(221.81885000000003, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99893f, 485.22020000000026f, 353.63877f, 497.42420000000027f }, string.Empty), "middle"), 3); Assert.Equal(89.99877000000004, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99877000000004f, 465.42020000000025f, 285.6896339120001f, 477.62420000000026f }, string.Empty), "left"), 3); Assert.Equal(285.6896339120001, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99877000000004f, 465.42020000000025f, 285.6896339120001f, 477.62420000000026f }, string.Empty), "right"), 3); Assert.Equal(187.84420195600006, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99877000000004f, 465.42020000000025f, 285.6896339120001f, 477.62420000000026f }, string.Empty), "middle"), 3); Assert.Equal(89.99877000000004, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99877000000004f, 445.62020000000024f, 270.6591262400001f, 457.82420000000025f }, string.Empty), "left"), 3); Assert.Equal(270.6591262400001, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99877000000004f, 445.62020000000024f, 270.6591262400001f, 457.82420000000025f }, string.Empty), "right"), 3); Assert.Equal(180.32894812000006, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99877000000004f, 445.62020000000024f, 270.6591262400001f, 457.82420000000025f }, string.Empty), "middle"), 3); Assert.Equal(89.99897000000007, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99897000000007f, 425.8202000000002f, 406.61893000000003f, 438.02420000000023f }, string.Empty), "left"), 3); Assert.Equal(406.61893000000003, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99897000000007f, 425.8202000000002f, 406.61893000000003f, 438.02420000000023f }, string.Empty), "right"), 3); Assert.Equal(248.30895000000007, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 89.99897000000007f, 425.8202000000002f, 406.61893000000003f, 438.02420000000023f }, string.Empty), "middle"), 3); Assert.Equal(71.99893000000003f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99893000000003f, 400.0804000000002f, 531.6005566360001f, 412.0804000000002f }, string.Empty), "left"), 3); Assert.Equal(531.6005566360001f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99893000000003f, 400.0804000000002f, 531.6005566360001f, 412.0804000000002f }, string.Empty), "right"), 3); Assert.Equal(301.7997433180001, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99893000000003f, 400.0804000000002f, 531.6005566360001f, 412.0804000000002f }, string.Empty), "middle"), 3); Assert.Equal(71.99875000000009f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99875000000009f, 386.2804000000002f, 524.9551519680001f, 398.2804000000002f }, string.Empty), "left"), 3); Assert.Equal(524.9551519680001f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99875000000009f, 386.2804000000002f, 524.9551519680001f, 398.2804000000002f }, string.Empty), "right"), 3); Assert.Equal(298.4769509840001, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99875000000009f, 386.2804000000002f, 524.9551519680001f, 398.2804000000002f }, string.Empty), "middle"), 3); Assert.Equal(71.99865000000005f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000005f, 372.4804000000002f, 527.58299376f, 384.4804000000002f }, string.Empty), "left"), 3); Assert.Equal(527.58299376f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000005f, 372.4804000000002f, 527.58299376f, 384.4804000000002f }, string.Empty), "right"), 3); Assert.Equal(299.79082188000007, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000005f, 372.4804000000002f, 527.58299376f, 384.4804000000002f }, string.Empty), "middle"), 3); Assert.Equal(71.99865000000005f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000005f, 358.6804000000002f, 506.2175500000001f, 506.2175500000001f }, string.Empty), "left"), 3); Assert.Equal(506.2175500000001f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000005f, 358.6804000000002f, 506.2175500000001f, 370.6804000000002f }, string.Empty), "right"), 3); Assert.Equal(289.10810000000004, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000005f, 358.6804000000002f, 506.2175500000001f, 370.6804000000002f }, string.Empty), "middle"), 3); Assert.Equal(71.99855000000008f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99855000000008f, 332.8804000000002f, 498.2013570600001f, 344.8804000000002f }, string.Empty), "left"), 3); Assert.Equal(498.2013570600001f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99855000000008f, 332.8804000000002f, 498.2013570600001f, 344.8804000000002f }, string.Empty), "right"), 3); Assert.Equal(285.0999535300001, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99855000000008f, 332.8804000000002f, 498.2013570600001f, 344.8804000000002f }, string.Empty), "middle"), 3); Assert.Equal(71.99865000000011f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000011f, 319.08040000000017f, 530.5899569680001f, 331.08040000000017f }, string.Empty), "left"), 3); Assert.Equal(530.5899569680001f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000011f, 319.08040000000017f, 530.5899569680001f, 331.08040000000017f }, string.Empty), "right"), 3); Assert.Equal(301.2943034840001, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000011f, 319.08040000000017f, 530.5899569680001f, 331.08040000000017f }, string.Empty), "middle"), 3); Assert.Equal(71.99875000000009f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99875000000009f, 305.28040000000016f, 537.907089496f, 317.28040000000016f }, string.Empty), "left"), 3); Assert.Equal(537.907089496f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99875000000009f, 305.28040000000016f, 537.907089496f, 317.28040000000016f }, string.Empty), "right"), 3); Assert.Equal(304.95291974800006, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99875000000009f, 305.28040000000016f, 537.907089496f, 317.28040000000016f }, string.Empty), "middle"), 3); Assert.Equal(71.99865000000005f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000005f, 291.48040000000015f, 523.79965f, 303.48040000000015f }, string.Empty), "left"), 3); Assert.Equal(523.79965f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000005f, 291.48040000000015f, 523.79965f, 303.48040000000015f }, string.Empty), "right"), 3); Assert.Equal(297.8991500000001, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99865000000005f, 291.48040000000015f, 523.79965f, 303.48040000000015f }, string.Empty), "middle"), 3); Assert.Equal(71.99965000000003f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99965000000003f, 277.68040000000013f, 516.334961864f, 289.68040000000013f }, string.Empty), "left"), 3); Assert.Equal(516.334961864f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99965000000003f, 277.68040000000013f, 516.334961864f, 289.68040000000013f }, string.Empty), "right"), 3); Assert.Equal(294.167305932, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99965000000003f, 277.68040000000013f, 516.334961864f, 289.68040000000013f }, string.Empty), "middle"), 3); Assert.Equal(71.99965000000003f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99965000000003f, 263.8804000000001f, 540.41949376f, 275.8804000000001f }, string.Empty), "left"), 3); Assert.Equal(540.41949376f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99965000000003f, 263.8804000000001f, 540.41949376f, 275.8804000000001f }, string.Empty), "right"), 3); Assert.Equal(306.20957188, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 71.99965000000003f, 263.8804000000001f, 540.41949376f, 275.8804000000001f }, string.Empty), "middle"), 3); Assert.Equal(145.07965000000002f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 145.07965000000002f, 240.2960000000001f, 469.63326095968006f, 250.3160000000001f }, string.Empty), "left"), 3); Assert.Equal(469.63326095968006f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 145.07965000000002f, 240.2960000000001f, 469.63326095968006f, 250.3160000000001f }, string.Empty), "right"), 3); Assert.Equal(307.35645547984006, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 145.07965000000002f, 240.2960000000001f, 469.63326095968006f, 250.3160000000001f }, string.Empty), "middle"), 3); Assert.Equal(323.9270190000001f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 323.9270190000001f, 220.5468000000001f, 427.81457900000004f, 230.5668000000001f }, string.Empty), "left"), 3); Assert.Equal(427.81457900000004f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 323.9270190000001f, 220.5468000000001f, 427.81457900000004f, 230.5668000000001f }, string.Empty), "right"), 3); Assert.Equal(375.87079900000003, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 323.9270190000001f, 220.5468000000001f, 427.81457900000004f, 230.5668000000001f }, string.Empty), "middle"), 3); Assert.Equal(129.22863000000007f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 129.22863000000007f, 214.5546000000001f, 158.64270587028008f, 224.5746000000001f }, string.Empty), "left"), 3); Assert.Equal(158.64270587028008f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 129.22863000000007f, 214.5546000000001f, 158.64270587028008f, 224.5746000000001f }, string.Empty), "right"), 3); Assert.Equal(143.9356679351401, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 129.22863000000007f, 214.5546000000001f, 158.64270587028008f, 224.5746000000001f }, string.Empty), "middle"), 3); Assert.Equal(179.80944900000006f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 179.80944900000006f, 214.5546000000001f, 192.61491921078007f, 224.5746000000001f }, string.Empty), "left"), 3); Assert.Equal(192.61491921078007f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 179.80944900000006f, 214.5546000000001f, 192.61491921078007f, 224.5746000000001f }, string.Empty), "right"), 3); Assert.Equal(186.21218410539007, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 179.80944900000006f, 214.5546000000001f, 192.61491921078007f, 224.5746000000001f }, string.Empty), "middle"), 3); Assert.Equal(210.41061900000008f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 210.41061900000008f, 214.5546000000001f, 254.89504272492007f, 224.5746000000001f }, string.Empty), "left"), 3); Assert.Equal(254.89504272492007f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 210.41061900000008f, 214.5546000000001f, 254.89504272492007f, 224.5746000000001f }, string.Empty), "right"), 3); Assert.Equal(232.65283086246006, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 210.41061900000008f, 214.5546000000001f, 254.89504272492007f, 224.5746000000001f }, string.Empty), "middle"), 3); Assert.Equal(262.92f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 262.92f, 206.75580000000002f, 310.70575064982f, 216.7758f }, string.Empty), "left"), 3); Assert.Equal(310.70575064982f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 262.92f, 206.75580000000002f, 310.70575064982f, 216.7758f }, string.Empty), "right"), 3); Assert.Equal(286.81287532491, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 262.92f, 206.75580000000002f, 310.70575064982f, 216.7758f }, string.Empty), "middle"), 3); Assert.Equal(318.78f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 318.78f, 206.75580000000002f, 372.13558169705993f, 216.7758f }, string.Empty), "left"), 3); Assert.Equal(372.13558169705993f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 318.78f, 206.75580000000002f, 372.13558169705993f, 216.7758f }, string.Empty), "right"), 3); Assert.Equal(345.45779084852995, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 318.78f, 206.75580000000002f, 372.13558169705993f, 216.7758f }, string.Empty), "middle"), 3); Assert.Equal(380.16f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 380.16f, 206.75580000000002f, 427.39639533222f, 216.7758f }, string.Empty), "left"), 3); Assert.Equal(427.39639533222f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 380.16f, 206.75580000000002f, 427.39639533222f, 216.7758f }, string.Empty), "right"), 3); Assert.Equal(403.77819766611003, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 380.16f, 206.75580000000002f, 427.39639533222f, 216.7758f }, string.Empty), "middle"), 3); Assert.Equal(435.42f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 435.42f, 206.75580000000002f, 488.77558163694f, 216.7758f }, string.Empty), "left"), 3); Assert.Equal(488.77558163694f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 435.42f, 206.75580000000002f, 488.77558163694f, 216.7758f }, string.Empty), "right"), 3); Assert.Equal(462.09779081847, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 435.42f, 206.75580000000002f, 488.77558163694f, 216.7758f }, string.Empty), "middle"), 3); Assert.Equal(128.92784900000007f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 128.92784900000007f, 203.0316000000001f, 158.95790900000006f, 213.0516000000001f }, string.Empty), "left"), 3); Assert.Equal(158.95790900000006f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 128.92784900000007f, 203.0316000000001f, 158.95790900000006f, 213.0516000000001f }, string.Empty), "right"), 3); Assert.Equal(143.94287900000006, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 128.92784900000007f, 203.0316000000001f, 158.95790900000006f, 213.0516000000001f }, string.Empty), "middle"), 3); Assert.Equal(170.08991900000007f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 170.08991900000007f, 203.0316000000001f, 202.33447900000007f, 213.0516000000001f }, string.Empty), "left"), 3); Assert.Equal(202.33447900000007f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 170.08991900000007f, 203.0316000000001f, 202.33447900000007f, 213.0516000000001f }, string.Empty), "right"), 3); Assert.Equal(186.21219900000006, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 170.08991900000007f, 203.0316000000001f, 202.33447900000007f, 213.0516000000001f }, string.Empty), "middle"), 3); Assert.Equal(222.1137190000001f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 222.1137190000001f, 203.0316000000001f, 243.1957790000001f, 213.0516000000001f }, string.Empty), "left"), 3); Assert.Equal(243.1957790000001f, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 222.1137190000001f, 203.0316000000001f, 243.1957790000001f, 213.0516000000001f }, string.Empty), "right"), 3); Assert.Equal(232.6547490000001, TextEdges.GetXCoord(TestHelper.MakeTextLine(new float[] { 222.1137190000001f, 203.0316000000001f, 243.1957790000001f, 213.0516000000001f }, string.Empty), "middle"), 3); }