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 )
399 if( aFill == FILL_T::FILLED_SHAPE )
423 double const circumf = 2.0 * M_PI * radius;
429 if( aFill == FILL_T::FILLED_SHAPE )
440 VECTOR2D( 2 * radius, 2 * radius ) ) );
453 VECTOR2D( 2 * radius, 2 * radius ) ) );
462 if( aCornerList.size() <= 1 )
476 if( aFill == FILL_T::FILLED_SHAPE )
483 for(
unsigned ii = 1; ii < aCornerList.size(); ++ii )
484 LineTo( aCornerList[ii] );
486 int ii = aCornerList.size() - 1;
488 if( aCornerList[ii] != aCornerList[0] )
494 else if( aWidth != 0 )
497 for(
unsigned ii = 1; ii < aCornerList.size(); ii++ )
498 LineTo( aCornerList[ii] );
501 if( aFill != FILL_T::NO_FILL )
503 int ii = aCornerList.size() - 1;
505 if( aCornerList[ii] != aCornerList[0] )
533 else if( plume ==
'D' )
536 startOrAppendItem( lastpos_dev, wxString::Format(
"PA %.0f,%.0f;", pos_dev.
x, pos_dev.
y ) );
577 double const circumf_device = 2.0 * M_PI * radius_device;
587 angle = aStartAngle - aEndAngle;
589 angle = aEndAngle - aStartAngle;
595 aCenter.
y -
KiROUND( aRadius * aStartAngle.
Sin() ) );
606 VECTOR2D( radius_device * 2, radius_device * 2 ) ) );
614 FILL_T aFill,
int aWidth,
int aMaxError )
616 EDA_ANGLE startAngle( aStart - aCenter );
620 Arc( aCenter, -endAngle, -startAngle, radius, aFill, aWidth );
633 if( size.
x > size.
y )
635 std::swap( size.
x, size.
y );
639 if( aTraceMode ==
FILLED )
641 int deltaxy = size.
y - size.
x;
666 int radius = diametre / 2;
668 if( trace_mode ==
FILLED )
680 if( trace_mode ==
FILLED )
688 wxString::Format(
"PM 0; PA %.0f,%.0f;CI %.0f;%s",
709 std::vector<VECTOR2I> corners;
711 int dx = aPadSize.
x / 2;
712 int dy = aPadSize.
y / 2;
714 if( aTraceMode ==
FILLED )
719 dx = std::max( dx, 0);
721 dy = std::max( dy, 0);
725 corners.emplace_back( - dx, - dy );
726 corners.emplace_back( - dx, + dy );
727 corners.emplace_back( + dx, + dy );
728 corners.emplace_back( + dx, - dy );
731 corners.emplace_back( - dx, - dy );
733 for(
unsigned ii = 0; ii < corners.size(); ii++ )
739 PlotPoly( corners, aTraceMode ==
FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL );
744 int aCornerRadius,
const EDA_ANGLE& aOrient,
751 if( aTraceMode ==
FILLED )
755 size.
x = std::max( size.
x, 0);
757 size.
y = std::max( size.
y, 0);
760 aCornerRadius = std::min( aCornerRadius, std::min( size.
x, size.
y ) /2 );
767 std::vector<VECTOR2I> cornerList;
771 for(
int ii = 0; ii < poly.
PointCount(); ++ii )
772 cornerList.emplace_back( poly.
CPoint( ii ).
x, poly.
CPoint( ii ).
y );
774 if( cornerList.back() != cornerList.front() )
775 cornerList.push_back( cornerList.front() );
777 PlotPoly( cornerList, aTraceMode ==
FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL );
785 std::vector<VECTOR2I> cornerList;
787 for(
int cnt = 0; cnt < aPolygons->
OutlineCount(); ++cnt )
794 for(
int ii = 0; ii < poly.
PointCount(); ++ii )
795 cornerList.emplace_back( poly.
CPoint( ii ).
x, poly.
CPoint( ii ).
y );
797 if( cornerList.back() != cornerList.front() )
798 cornerList.push_back( cornerList.front() );
800 PlotPoly( cornerList, aTraceMode ==
FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL );
809 std::vector<VECTOR2I> cornerList;
810 cornerList.reserve( 5 );
812 for(
int ii = 0; ii < 4; ii++ )
817 cornerList.push_back( coord );
821 cornerList.push_back( cornerList.front() );
823 PlotPoly( cornerList, aTraceMode ==
FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL );
873 if( items.size() < 2 )
876 std::list<HPGL_ITEM> target;
899 target.emplace_back( last_item );
901 while( !items.empty() )
903 auto best_it = items.begin();
906 for(
auto search_it = best_it; search_it != items.end(); search_it++ )
909 if( best_it->pen != last_item.
pen && search_it->pen == last_item.
pen )
917 if( dist < best_dist )
925 target.emplace_back( *best_it );
926 last_item = *best_it;
927 items.erase( best_it );
930 items.splice( items.begin(), target );
938 case PLOT_DASH_TYPE::DASH:
return "LT 2 4 1;";
939 case PLOT_DASH_TYPE::DOT:
return "LT 1 1 1;";
940 case PLOT_DASH_TYPE::DASHDOT:
return "LT 4 6 1;";
941 case PLOT_DASH_TYPE::DASHDOTDOT:
return "LT 7 8 1;";
942 default:
return "LT;";
950 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[]
coord_type GetHeight() const
coord_type GetWidth() const
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
virtual void FlashPadRoundRect(const VECTOR2I &aPadPos, const VECTOR2I &aSize, int aCornerRadius, const EDA_ANGLE &aOrient, OUTLINE_MODE aTraceMode, void *aData) override
static const char * lineStyleCommand(PLOT_DASH_TYPE aLineStyle)
Return the plot command corresponding to a line type.
HPGL_ITEM * m_current_item
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.
virtual void Arc(const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aEnd, FILL_T aFill, int aWidth, int aMaxError) override
Generic fallback: arc rendered as a polyline.
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 ).
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 SetDash(int aLineWidth, PLOT_DASH_TYPE aLineStyle) override
HPGL supports dashed lines.
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 PenTo(const VECTOR2I &pos, char plume) override
Moveto/lineto primitive, moves the 'pen' to the specified direction.
PLOT_DASH_TYPE m_lineStyle
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 VECTOR2I & GetSizeMils() const
static const int USE_DEFAULT_LINE_WIDTH
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_360
static constexpr EDA_ANGLE & ANGLE_45
static constexpr EDA_ANGLE & ANGLE_90
PLOT_DASH_TYPE
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.
bool lift_after
Whether the pen must be lifted after the command.
PLOT_DASH_TYPE dashType
Pen number for this 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)
double EuclideanNorm(const VECTOR2I &vector)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
VECTOR2< double > VECTOR2D