37 std::function<
const float&(
const float&,
const float& ) > comparator );
40 float aStep,
const float* aCurvePoints,
float aSegmentationThreshold,
41 std::vector< VECTOR2D >& aGeneratedPoints );
43 const VECTOR2D& aEnd,
float aOffset,
float aStep,
const float* aCurvePoints,
44 float aSegmentationThreshold, std::vector< VECTOR2D >& aGeneratedPoints );
61 FILE* fp = wxFopen( aFileName, wxT(
"rb" ) );
77 [](
unsigned int color )
82 for( NSVGshape* shape =
m_parsedImage->shapes; shape !=
nullptr; shape = shape->next )
84 double lineWidth = shape->strokeWidth;
85 bool filled = shape->fill.type != NSVG_PAINT_NONE && alpha( shape->fill.color ) > 0;
89 switch( shape->fillRule )
118 wxASSERT_MSG(
false, wxT(
"Image must have been loaded before checking height" ) );
130 wxASSERT_MSG(
false, wxT(
"Image must have been loaded before checking width" ) );
141 std::vector< VECTOR2D > collectedPathPoints;
146 if( aPoly && aFilled )
154 std::vector< VECTOR2D >& aGeneratedPoints )
156 const int pointsPerSegment = 4;
157 const int curveSpecificPointsPerSegment = 3;
158 const int curveSpecificCoordinatesPerSegment = 2 * curveSpecificPointsPerSegment;
159 const float* currentPoints = aPoints;
160 int remainingPoints = aNumPoints;
162 while( remainingPoints >= pointsPerSegment )
165 currentPoints += curveSpecificCoordinatesPerSegment;
166 remainingPoints -= curveSpecificPointsPerSegment;
172 std::vector< VECTOR2D >& aGeneratedPoints )
178 aGeneratedPoints.push_back( start );
179 segmentBezierCurve( start, end, 0.0f, 0.5f, aPoints, segmentationThreshold, aGeneratedPoints );
180 aGeneratedPoints.push_back( end );
192 unsigned int numLineStartPoints = aPoints.size() - 1;
194 for(
unsigned int pointIndex = 0; pointIndex < numLineStartPoints; ++pointIndex )
201 return VECTOR2D( aPointCoordinates[0], aPointCoordinates[1] );
207 const int coordinatesPerPoint = 2;
209 auto firstCubicPoint =
getPoint( aPoints );
210 auto secondCubicPoint =
getPoint( aPoints + 1 * coordinatesPerPoint );
211 auto thirdCubicPoint =
getPoint( aPoints + 2 * coordinatesPerPoint );
212 auto fourthCubicPoint =
getPoint( aPoints + 3 * coordinatesPerPoint );
214 auto firstQuadraticPoint =
getPointInLine( firstCubicPoint, secondCubicPoint, aStep );
215 auto secondQuadraticPoint =
getPointInLine( secondCubicPoint, thirdCubicPoint, aStep );
216 auto thirdQuadraticPoint =
getPointInLine( thirdCubicPoint, fourthCubicPoint, aStep );
218 auto firstLinearPoint =
getPointInLine( firstQuadraticPoint, secondQuadraticPoint, aStep );
219 auto secondLinearPoint =
getPointInLine( secondQuadraticPoint, thirdQuadraticPoint, aStep );
221 return getPointInLine( firstLinearPoint, secondLinearPoint, aStep );
228 return aLineStart + ( aLineEnd - aLineStart ) * aDistance;
234 using comparatorFunction =
const float&(*)(
const float&,
const float& );
236 auto minimumComparator =
static_cast< comparatorFunction
>( &std::min );
237 auto maximumComparator =
static_cast< comparatorFunction
>( &std::max );
241 VECTOR2D boundingBoxDimensions = maximum - minimum;
243 return 0.001 * std::max( boundingBoxDimensions.
x, boundingBoxDimensions.
y );
248 std::function<
const float&(
const float&,
const float& ) > comparator )
250 float x = aCurvePoints[0];
251 float y = aCurvePoints[1];
253 for(
int pointIndex = 1; pointIndex < 3; ++pointIndex )
255 x = comparator( x, aCurvePoints[ 2 * pointIndex ] );
256 y = comparator( y, aCurvePoints[ 2 * pointIndex + 1 ] );
264 float aStep,
const float* aCurvePoints,
265 float aSegmentationThreshold,
266 std::vector< VECTOR2D >& aGeneratedPoints )
271 if( distanceToPreviousSegment > aSegmentationThreshold )
274 aSegmentationThreshold, aGeneratedPoints );
280 const VECTOR2D& aEnd,
float aOffset,
float aStep,
281 const float* aCurvePoints,
float aSegmentationThreshold,
282 std::vector< VECTOR2D >& aGeneratedPoints )
284 float newStep = aStep / 2.f;
285 float offsetAfterMiddle = aOffset + aStep;
287 segmentBezierCurve( aStart, aMiddle, aOffset, newStep, aCurvePoints, aSegmentationThreshold,
290 aGeneratedPoints.push_back( aMiddle );
293 aSegmentationThreshold, aGeneratedPoints );
300 auto lineDirection = aLineEnd - aLineStart;
302 auto lineStartToPoint = aPoint - aLineStart;
304 auto distance = lineNormal.Dot( lineStartToPoint );
void PostprocessNestedPolygons()
void ImportTo(GRAPHICS_IMPORTER &aImporter)
void AddPolygon(const std::vector< VECTOR2D > &aVertices, double aWidth) override
void AddLine(const VECTOR2D &aStart, const VECTOR2D &aEnd, double aWidth) override
Create an object representing a line segment.
virtual void NewShape(POLY_FILL_RULE aFillRule=PF_NONZERO)
GRAPHICS_IMPORTER * m_importer
< Importer used to create objects representing the imported shapes.
void DrawCubicBezierPath(const float *aPoints, int aNumPoints, std::vector< VECTOR2D > &aGeneratedPoints)
void DrawLineSegments(const std::vector< VECTOR2D > &aPoints, double aWidth)
GRAPHICS_IMPORTER_BUFFER m_internalImporter
struct NSVGimage * m_parsedImage
void DrawPath(const float *aPoints, int aNumPoints, bool aClosedPath, bool aFilled, double aLineWidth)
bool Import() override
Actually imports the file.
virtual double GetImageWidth() const override
Return image width from original imported file.
bool Load(const wxString &aFileName) override
Load file for import.
void DrawCubicBezierCurve(const float *aPoints, std::vector< VECTOR2D > &aGeneratedPoints)
virtual double GetImageHeight() const override
Return image height from original imported file.
void DrawPolygon(const std::vector< VECTOR2D > &aPoints, double aWidth)
VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
static void segmentBezierCurve(const VECTOR2D &aStart, const VECTOR2D &aEnd, float aOffset, float aStep, const float *aCurvePoints, float aSegmentationThreshold, std::vector< VECTOR2D > &aGeneratedPoints)
static float distanceFromPointToLine(const VECTOR2D &aPoint, const VECTOR2D &aLineStart, const VECTOR2D &aLineEnd)
static VECTOR2D getPointInLine(const VECTOR2D &aLineStart, const VECTOR2D &aLineEnd, float aDistance)
static VECTOR2D getBezierPoint(const float *aCurvePoints, float aStep)
static VECTOR2D calculateBezierBoundingBoxExtremity(const float *aCurvePoints, std::function< const float &(const float &, const float &) > comparator)
static void createNewBezierCurveSegments(const VECTOR2D &aStart, const VECTOR2D &aMiddle, const VECTOR2D &aEnd, float aOffset, float aStep, const float *aCurvePoints, float aSegmentationThreshold, std::vector< VECTOR2D > &aGeneratedPoints)
static VECTOR2D getPoint(const float *aPointCoordinates)
static float calculateBezierSegmentationThreshold(const float *aCurvePoints)
VECTOR2< double > VECTOR2D