1 /****************************************************************************************************** 2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released * 3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file * 4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. * 5 ******************************************************************************************************/ 6 7 #ifndef SEGMENT_FACTORY_H 8 #define SEGMENT_FACTORY_H 9 10 #include <QList> 11 #include <QPointF> 12 #include <vector> 13 14 class ColorFilter; 15 class DocumentModelSegments; 16 class QGraphicsScene; 17 class QImage; 18 class Segment; 19 20 typedef std::vector<Segment*> SegmentVector; 21 22 /// Factory class for Segment objects. The input is the filtered image. 23 /// 24 /// The strategy is to fill out the segments output array as each segment finishes. This makes it easy to 25 /// keep too-short Segments out of the output array, versus adding every new Segment to the output array 26 /// as soon as it is created 27 class SegmentFactory 28 { 29 public: 30 /// Single constructor. 31 SegmentFactory(QGraphicsScene &scene, 32 bool isGnuplot); 33 34 /// Remove the segments created by makeSegments 35 void clearSegments(QList<Segment*> &segments); 36 37 /// Return segment fill points for all segments, for previewing 38 QList<QPoint> fillPoints(const DocumentModelSegments &modelSegments, 39 QList<Segment*> segments); 40 41 /// Main entry point for creating all Segments for the filtered image. 42 void makeSegments (const QImage &imageFiltered, 43 const DocumentModelSegments &modelSegments, 44 QList<Segment*> &segments, 45 bool useDlg = true); 46 47 private: 48 SegmentFactory(); 49 50 // Return the number of runs adjacent to the pixels from yStart to yStop (inclusive) 51 int adjacentRuns(bool *columnBool, 52 int yStart, 53 int yStop, 54 int height); 55 56 // Find the single segment pointer among the adjacent pixels from yStart-1 to yStop+1 57 Segment *adjacentSegment(SegmentVector &lastSegment, 58 int yStart, 59 int yStop, 60 int height); 61 62 // Return the number of segments adjacent to the pixels from yStart to yStop (inclusive) 63 int adjacentSegments(SegmentVector &lastSegment, 64 int yStart, 65 int yStop, 66 int height); 67 68 // Process a run of pixels. If there are fewer than two adjacent pixel runs on 69 // either side, this run will be added to an existing segment, or the start of 70 // a new segment 71 void finishRun(bool *lastBool, 72 bool *nextBool, 73 SegmentVector &lastSegment, 74 SegmentVector &currSegment, 75 int x, 76 int yStart, 77 int yStop, 78 int height, 79 const DocumentModelSegments &modelSegments, 80 int* madeLines); 81 82 // Initialize one column of boolean flags using the pixels of the specified column 83 void loadBool (const ColorFilter &filter, 84 bool *columnBool, 85 const QImage &image, 86 int x); 87 88 // Initialize one column of segment pointers 89 void loadSegment (SegmentVector &columnSegment, 90 int height); 91 92 // Identify the runs in a column, and connect them to segments 93 void matchRunsToSegments (int x, 94 int height, 95 bool *lastBool, 96 SegmentVector &lastSegment, 97 bool *currBool, 98 SegmentVector &currSegment, 99 bool *nextBool, 100 const DocumentModelSegments &modelSegments, 101 int *madeLines, 102 int *foldedLines, 103 int *shortLine, 104 QList<Segment*> &segments); 105 106 /// Remove any Segment with no lines. This prevents crashes in Segment::firstPoint which requires at least one line in each Segment 107 void removeEmptySegments (QList<Segment*> &segments) const; 108 109 // Remove unneeded lines belonging to segments that just finished in the previous column. 110 // The results of this function are displayed in the debug spew of makeSegments 111 void removeUnneededLines(SegmentVector &lastSegment, 112 SegmentVector &currSegment, 113 int height, 114 int *foldedLines, 115 int *shortLines, 116 const DocumentModelSegments &modelSegments, 117 QList<Segment*> &segments); 118 119 // Scroll the boolean flags of the right column into the left column 120 void scrollBool(bool *left, 121 bool *right, 122 int height); 123 124 // Scroll the segment pointers of the right column into the left column 125 void scrollSegment(SegmentVector &left, 126 SegmentVector &right, 127 int height); 128 129 QGraphicsScene &m_scene; 130 131 bool m_isGnuplot; 132 }; 133 134 #endif // SEGMENT_FACTORY_H 135