223 m_arcTargetChordLength( 0 ),
226 m_useUserCoords( false ),
227 m_fitUserCoords( false ),
228 m_current_item( nullptr )
237 double aScale,
bool aMirror )
289 bbox.
Merge( item.bbox );
315 if( item.loc_start != loc || pen_up )
323 fprintf(
m_outputFile,
"PA %.0f,%.0f;", item.loc_start.x, item.loc_start.y );
326 if( item.dashType != current_dash )
328 current_dash = item.dashType;
332 if( item.pen != current_pen )
341 current_pen = item.pen;
344 if( pen_up && !item.lift_before )
349 else if( !pen_up && item.lift_before )
355 fputs(
static_cast<const char*
>( item.content.utf8_str() ),
m_outputFile );
357 if( !item.pen_returns )
363 if( item.lift_after )
395 std::vector<VECTOR2I> cornerList;
397 cornerList.emplace_back( p1.
x, p1.
y );
398 cornerList.emplace_back( p2.
x, p1.
y );
399 cornerList.emplace_back( p2.
x, p2.
y );
400 cornerList.emplace_back( p1.
x, p2.
y );
401 cornerList.emplace_back( p1.
x, p1.
y );
403 PlotPoly( cornerList, aFill, aWidth,
nullptr );
414 double const circumf = 2.0 * M_PI * radius;
420 if( aFill == FILL_T::FILLED_SHAPE )
430 VECTOR2D( 2 * radius, 2 * radius ) ) );
442 VECTOR2D( 2 * radius, 2 * radius ) ) );
451 if( aFill == FILL_T::NO_FILL && aWidth <= 0 )
454 if( aCornerList.size() <= 1 )
468 if( aFill != FILL_T::NO_FILL )
475 for(
unsigned ii = 1; ii < aCornerList.size(); ++ii )
476 LineTo( aCornerList[ii] );
478 int ii = aCornerList.size() - 1;
480 if( aCornerList[ii] != aCornerList[0] )
486 else if( aWidth != 0 )
489 for(
unsigned ii = 1; ii < aCornerList.size(); ii++ )
490 LineTo( aCornerList[ii] );
493 if( aFill != FILL_T::NO_FILL )
495 int ii = aCornerList.size() - 1;
497 if( aCornerList[ii] != aCornerList[0] )
525 else if( plume ==
'D' )
528 startOrAppendItem( lastpos_dev, wxString::Format(
"PA %.0f,%.0f;", pos_dev.
x, pos_dev.
y ) );
571 polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
576 double const circumf_device = 2.0 * M_PI * radius_device;
592 KiROUND( aCenter.
y - aRadius * startAngle.
Sin() ) );
603 VECTOR2D( radius_device * 2, radius_device * 2 ) ) );
618 if( size.
x > size.
y )
620 std::swap( size.
x, size.
y );
624 if( aTraceMode ==
FILLED )
626 int deltaxy = size.
y - size.
x;
651 int radius = diametre / 2;
653 if( trace_mode ==
FILLED )
665 if( trace_mode ==
FILLED )
673 wxString::Format(
"PM 0; PA %.0f,%.0f;CI %.0f;%s",
694 std::vector<VECTOR2I> corners;
696 int dx = aPadSize.
x / 2;
697 int dy = aPadSize.
y / 2;
699 if( aTraceMode ==
FILLED )
704 dx = std::max( dx, 0);
706 dy = std::max( dy, 0);
710 corners.emplace_back( - dx, - dy );
711 corners.emplace_back( - dx, + dy );
712 corners.emplace_back( + dx, + dy );
713 corners.emplace_back( + dx, - dy );
716 corners.emplace_back( - dx, - dy );
718 for(
unsigned ii = 0; ii < corners.size(); ii++ )
724 PlotPoly( corners, aTraceMode ==
FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL );
729 int aCornerRadius,
const EDA_ANGLE& aOrient,
736 if( aTraceMode ==
FILLED )
740 size.
x = std::max( size.
x, 0);
742 size.
y = std::max( size.
y, 0);
745 aCornerRadius = std::min( aCornerRadius, std::min( size.
x, size.
y ) /2 );
752 std::vector<VECTOR2I> cornerList;
756 for(
int ii = 0; ii < poly.
PointCount(); ++ii )
757 cornerList.emplace_back( poly.
CPoint( ii ).
x, poly.
CPoint( ii ).
y );
759 if( cornerList.back() != cornerList.front() )
760 cornerList.push_back( cornerList.front() );
762 PlotPoly( cornerList, aTraceMode ==
FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL );
770 std::vector<VECTOR2I> cornerList;
772 for(
int cnt = 0; cnt < aPolygons->
OutlineCount(); ++cnt )
779 for(
int ii = 0; ii < poly.
PointCount(); ++ii )
780 cornerList.emplace_back( poly.
CPoint( ii ).
x, poly.
CPoint( ii ).
y );
782 if( cornerList.back() != cornerList.front() )
783 cornerList.push_back( cornerList.front() );
785 PlotPoly( cornerList, aTraceMode ==
FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL );
794 std::vector<VECTOR2I> cornerList;
795 cornerList.reserve( 5 );
797 for(
int ii = 0; ii < 4; ii++ )
802 cornerList.push_back( coord );
806 cornerList.push_back( cornerList.front() );
808 PlotPoly( cornerList, aTraceMode ==
FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL );
858 if( items.size() < 2 )
861 std::list<HPGL_ITEM> target;
884 target.emplace_back( last_item );
886 while( !items.empty() )
888 auto best_it = items.begin();
891 for(
auto search_it = best_it; search_it != items.end(); search_it++ )
894 if( best_it->pen != last_item.
pen && search_it->pen == last_item.
pen )
902 if( dist < best_dist )
910 target.emplace_back( *best_it );
911 last_item = *best_it;
912 items.erase( best_it );
915 items.splice( items.begin(), target );
923 case LINE_STYLE::DASH:
return "LT 2 4 1;";
924 case LINE_STYLE::DOT:
return "LT 1 1 1;";
925 case LINE_STYLE::DASHDOT:
return "LT 4 6 1;";
926 case LINE_STYLE::DASHDOTDOT:
return "LT 7 8 1;";
927 default:
return "LT;";
935 return sqrt( diff.
x * diff.
x + diff.
y * diff.
y );
static const double PLUsPERDECIMIL
static double dpoint_dist(const VECTOR2D &a, const VECTOR2D &b)
Compute the distance between two VECTOR2D points.
static const char hpgl_end_polygon_cmd[]
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr coord_type GetX() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr size_type GetHeight() const
virtual void FlashPadRoundRect(const VECTOR2I &aPadPos, const VECTOR2I &aSize, int aCornerRadius, const EDA_ANGLE &aOrient, OUTLINE_MODE aTraceMode, void *aData) override
HPGL_ITEM * m_current_item
virtual void SetDash(int aLineWidth, LINE_STYLE aLineStyle) override
HPGL supports dashed lines.
virtual void SetPenSpeed(int speed)
bool startItem(const VECTOR2D &location)
Start a new HPGL_ITEM if necessary, keeping the current one if it exists.
double m_arcTargetChordLength
void flushItem()
Flush the current HPGL_ITEM and clear out the current item pointer.
virtual void FlashPadTrapez(const VECTOR2I &aPadPos, const VECTOR2I *aCorners, const EDA_ANGLE &aPadOrient, OUTLINE_MODE aTraceMode, void *aData) override
Flash a trapezoidal pad.
void SetTargetChordLength(double chord_len)
Set the target length of chords used to draw approximated circles and arcs.
virtual void SetPenNumber(int number)
static void sortItems(std::list< HPGL_ITEM > &items)
Sort a list of HPGL items to improve plotting speed on mechanical plotters.
virtual void FlashPadCircle(const VECTOR2I &aPadPos, int aDiameter, OUTLINE_MODE aTraceMode, void *aData) override
virtual bool StartPlot(const wxString &aPageNumber) override
At the start of the HPGL plot pen speed and number are requested.
EDA_ANGLE m_arcMinChordDegrees
virtual void SetCurrentLineWidth(int width, void *aData=nullptr) override
HPGL doesn't handle line thickness or color.
virtual void FlashRegularPolygon(const VECTOR2I &aShapePos, int aDiameter, int aCornerCount, const EDA_ANGLE &aOrient, OUTLINE_MODE aTraceMode, void *aData) override
Flash a regular polygon.
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr) override
Draw a polygon ( filled or not ).
static const char * lineStyleCommand(LINE_STYLE aLineStyle)
Return the plot command corresponding to a line type.
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH) override
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
std::list< HPGL_ITEM > m_items
virtual void FlashPadCustom(const VECTOR2I &aPadPos, const VECTOR2I &aSize, const EDA_ANGLE &aOrient, SHAPE_POLY_SET *aPolygons, OUTLINE_MODE aTraceMode, void *aData) override
virtual void SetPenDiameter(double diameter)
virtual void FlashPadOval(const VECTOR2I &aPadPos, const VECTOR2I &aSize, const EDA_ANGLE &aPadOrient, OUTLINE_MODE aTraceMode, void *aData) override
virtual void Arc(const VECTOR2D &aCenter, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aAngle, double aRadius, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH) override
Plot an arc.
virtual void PenTo(const VECTOR2I &pos, char plume) override
Moveto/lineto primitive, moves the 'pen' to the specified direction.
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, OUTLINE_MODE tracemode, void *aData) override
bool startOrAppendItem(const VECTOR2D &location, const wxString &content)
Start a new HPGL_ITEM with the given string if necessary, or append the string to the current item.
virtual void Circle(const VECTOR2I &aCenter, int aDiameter, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH) override
virtual bool EndPlot() override
HPGL end of plot: sort and emit graphics, pen return and release.
virtual void FlashPadRect(const VECTOR2I &aPadPos, const VECTOR2I &aSize, const EDA_ANGLE &aOrient, OUTLINE_MODE aTraceMode, void *aData) override
const VECTOR2D & GetSizeMils() const
static const int USE_DEFAULT_LINE_WIDTH
virtual void polyArc(const VECTOR2D &aCentre, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aAngle, double aRadius, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH)
Generic fallback: arc rendered as a polyline.
void MoveTo(const VECTOR2I &pos)
void FinishTo(const VECTOR2I &pos)
virtual VECTOR2D userToDeviceCoordinates(const VECTOR2I &aCoordinate)
Modify coordinates according to the orientation, scale factor, and offsets trace.
virtual VECTOR2D userToDeviceSize(const VECTOR2I &size)
Modify size according to the plotter scale factors (VECTOR2I version, returns a VECTOR2D).
void sketchOval(const VECTOR2I &aPos, const VECTOR2I &aSize, const EDA_ANGLE &aOrient, int aWidth)
int GetPlotterArcHighDef() const
double m_plotScale
Plot scale - chosen by the user (even implicitly with 'fit in a4')
FILE * m_outputFile
Output file.
void LineTo(const VECTOR2I &pos)
void segmentAsOval(const VECTOR2I &start, const VECTOR2I &end, int width, OUTLINE_MODE tracemode)
Convert a thick segment and plot it as an oval.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
static constexpr EDA_ANGLE ANGLE_360
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
LINE_STYLE
Dashed line types.
wxString content
Line style for this command.
bool pen_returns
Whether the pen returns to its original state after the command.
BOX2D bbox
Bounding box of this item.
LINE_STYLE dashType
Pen number for this command.
bool lift_after
Whether the pen must be lifted after the command.
bool lift_before
Whether the command should be executed with the pen lifted.
VECTOR2D loc_start
Location the pen should start at.
VECTOR2D loc_end
Location the pen will be at when it finishes.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D