2020-09-23 18:58:13 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2022-02-20 13:59:11 +00:00
|
|
|
* Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
2020-09-23 18:58:13 +00:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation, either version 3 of the License, or (at your
|
|
|
|
* option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Plotting engine (HPGL)
|
|
|
|
*
|
|
|
|
* @file plotter_hpgl.h
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-12-13 23:38:44 +00:00
|
|
|
#include <list>
|
2020-12-14 02:01:24 +00:00
|
|
|
|
2021-08-18 20:38:14 +00:00
|
|
|
#include "plotter.h"
|
2020-09-23 18:58:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
class HPGL_PLOTTER : public PLOTTER
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
HPGL_PLOTTER();
|
|
|
|
|
|
|
|
virtual PLOT_FORMAT GetPlotterType() const override
|
|
|
|
{
|
|
|
|
return PLOT_FORMAT::HPGL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static wxString GetDefaultFileExtension()
|
|
|
|
{
|
|
|
|
return wxString( wxT( "plt" ) );
|
|
|
|
}
|
|
|
|
|
2021-08-17 17:44:11 +00:00
|
|
|
/**
|
|
|
|
* Set the target length of chords used to draw approximated circles and arcs.
|
|
|
|
*
|
|
|
|
* @param chord_len the chord length in IUs.
|
|
|
|
*/
|
2020-12-14 02:01:24 +00:00
|
|
|
void SetTargetChordLength( double chord_len );
|
|
|
|
|
2020-12-21 23:27:31 +00:00
|
|
|
/// Switch to the user coordinate system
|
2022-06-28 18:21:00 +00:00
|
|
|
void SetUserCoords( bool user_coords ) { m_useUserCoords = user_coords; }
|
2020-12-21 23:27:31 +00:00
|
|
|
|
|
|
|
/// Set whether the user coordinate system is fit to content
|
2022-06-28 18:21:00 +00:00
|
|
|
void SetUserCoordsFit( bool user_coords_fit ) { m_fitUserCoords = user_coords_fit; }
|
2020-12-21 23:27:31 +00:00
|
|
|
|
2021-06-07 18:31:53 +00:00
|
|
|
/**
|
|
|
|
* At the start of the HPGL plot pen speed and number are requested.
|
|
|
|
*/
|
2020-09-23 18:58:13 +00:00
|
|
|
virtual bool StartPlot() override;
|
2021-06-07 18:31:53 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* HPGL end of plot: sort and emit graphics, pen return and release.
|
|
|
|
*/
|
2020-09-23 18:58:13 +00:00
|
|
|
virtual bool EndPlot() override;
|
|
|
|
|
|
|
|
/// HPGL doesn't handle line thickness or color
|
2021-06-07 18:31:53 +00:00
|
|
|
virtual void SetCurrentLineWidth( int width, void* aData = nullptr ) override
|
2020-09-23 18:58:13 +00:00
|
|
|
{
|
|
|
|
// This is the truth
|
2022-06-28 18:21:00 +00:00
|
|
|
m_currentPenWidth = userToDeviceSize( m_penDiameter );
|
2020-09-23 18:58:13 +00:00
|
|
|
}
|
|
|
|
|
2021-06-07 18:31:53 +00:00
|
|
|
/**
|
|
|
|
* HPGL supports dashed lines.
|
|
|
|
*/
|
2022-06-28 18:06:17 +00:00
|
|
|
virtual void SetDash( int aLineWidth, PLOT_DASH_TYPE aLineStyle ) override;
|
2020-09-23 18:58:13 +00:00
|
|
|
|
2021-06-07 18:31:53 +00:00
|
|
|
virtual void SetColor( const COLOR4D& color ) override {}
|
2020-09-23 18:58:13 +00:00
|
|
|
|
|
|
|
virtual void SetPenSpeed( int speed )
|
|
|
|
{
|
2022-06-28 18:21:00 +00:00
|
|
|
m_penSpeed = speed;
|
2020-09-23 18:58:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void SetPenNumber( int number )
|
|
|
|
{
|
2022-06-28 18:21:00 +00:00
|
|
|
m_penNumber = number;
|
2020-09-23 18:58:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void SetPenDiameter( double diameter );
|
|
|
|
|
2021-12-29 19:02:50 +00:00
|
|
|
virtual void SetViewport( const VECTOR2I& aOffset, double aIusPerDecimil,
|
2021-01-13 16:23:09 +00:00
|
|
|
double aScale, bool aMirror ) override;
|
2022-01-16 01:06:25 +00:00
|
|
|
virtual void Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T aFill,
|
|
|
|
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
|
|
|
virtual void Circle( const VECTOR2I& aCenter, int aDiameter, FILL_T aFill,
|
|
|
|
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
2021-12-29 19:02:50 +00:00
|
|
|
virtual void PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill,
|
2021-07-18 23:08:54 +00:00
|
|
|
int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override;
|
2020-09-23 18:58:13 +00:00
|
|
|
|
2021-12-29 19:02:50 +00:00
|
|
|
virtual void ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int width,
|
2020-10-15 23:33:18 +00:00
|
|
|
OUTLINE_MODE tracemode, void* aData ) override;
|
2021-06-07 18:31:53 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Plot an arc.
|
|
|
|
*
|
|
|
|
* Command
|
|
|
|
* PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, NbSegm; PU;
|
|
|
|
* Or PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, PU;
|
|
|
|
*
|
|
|
|
* center is the center of the arc.
|
|
|
|
* StAngled is the start angle of the arc.
|
2022-01-16 01:06:25 +00:00
|
|
|
* aEndAngle is end angle the arc.
|
2021-06-07 18:31:53 +00:00
|
|
|
* Radius is the radius of the arc.
|
|
|
|
*/
|
2022-01-16 01:06:25 +00:00
|
|
|
virtual void Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
|
|
|
|
const EDA_ANGLE& aEndAngle, int aRadius, FILL_T aFill,
|
|
|
|
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
2022-02-20 13:59:11 +00:00
|
|
|
|
|
|
|
virtual void Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
|
|
|
FILL_T aFill, int aWidth, int aMaxError ) override;
|
|
|
|
|
2021-12-29 19:02:50 +00:00
|
|
|
virtual void PenTo( const VECTOR2I& pos, char plume ) override;
|
2022-02-20 13:59:11 +00:00
|
|
|
|
2021-12-29 19:02:50 +00:00
|
|
|
virtual void FlashPadCircle( const VECTOR2I& aPadPos, int aDiameter,
|
2020-10-15 23:33:18 +00:00
|
|
|
OUTLINE_MODE aTraceMode, void* aData ) override;
|
2022-01-16 01:06:25 +00:00
|
|
|
virtual void FlashPadOval( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
|
|
|
|
const EDA_ANGLE& aPadOrient, OUTLINE_MODE aTraceMode,
|
|
|
|
void* aData ) override;
|
2021-12-29 19:02:50 +00:00
|
|
|
virtual void FlashPadRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
|
2022-01-16 01:06:25 +00:00
|
|
|
const EDA_ANGLE& aOrient, OUTLINE_MODE aTraceMode,
|
|
|
|
void* aData ) override;
|
2021-12-29 19:02:50 +00:00
|
|
|
virtual void FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
|
2022-01-16 01:06:25 +00:00
|
|
|
int aCornerRadius, const EDA_ANGLE& aOrient,
|
2020-10-15 23:33:18 +00:00
|
|
|
OUTLINE_MODE aTraceMode, void* aData ) override;
|
2022-01-16 01:06:25 +00:00
|
|
|
virtual void FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
|
|
|
|
const EDA_ANGLE& aOrient, SHAPE_POLY_SET* aPolygons,
|
2020-10-15 23:33:18 +00:00
|
|
|
OUTLINE_MODE aTraceMode, void* aData ) override;
|
2021-12-29 19:02:50 +00:00
|
|
|
virtual void FlashPadTrapez( const VECTOR2I& aPadPos, const VECTOR2I* aCorners,
|
2022-01-16 01:06:25 +00:00
|
|
|
const EDA_ANGLE& aPadOrient, OUTLINE_MODE aTraceMode,
|
2020-09-23 18:58:13 +00:00
|
|
|
void* aData ) override;
|
2021-12-29 19:02:50 +00:00
|
|
|
virtual void FlashRegularPolygon( const VECTOR2I& aShapePos, int aDiameter, int aCornerCount,
|
2022-01-16 01:06:25 +00:00
|
|
|
const EDA_ANGLE& aOrient, OUTLINE_MODE aTraceMode,
|
2021-01-13 16:23:09 +00:00
|
|
|
void* aData ) override;
|
2020-09-23 18:58:13 +00:00
|
|
|
|
|
|
|
protected:
|
2021-08-17 17:44:11 +00:00
|
|
|
/**
|
|
|
|
* Start a new HPGL_ITEM if necessary, keeping the current one if it exists.
|
|
|
|
*
|
|
|
|
* @param location is the location of the item.
|
|
|
|
* @return whether a new item was made.
|
|
|
|
*/
|
2022-01-20 00:17:44 +00:00
|
|
|
bool startItem( const VECTOR2D& location );
|
2020-12-13 23:38:44 +00:00
|
|
|
|
|
|
|
/// Flush the current HPGL_ITEM and clear out the current item pointer.
|
2020-12-14 02:01:24 +00:00
|
|
|
void flushItem();
|
2020-12-13 23:38:44 +00:00
|
|
|
|
2021-08-17 17:44:11 +00:00
|
|
|
/**
|
|
|
|
* Start a new HPGL_ITEM with the given string if necessary, or append the
|
|
|
|
* string to the current item.
|
|
|
|
*
|
|
|
|
* @param location is the location of the item, if a new one is made.
|
|
|
|
* @param content is the content substring.
|
|
|
|
* @return whether a new item was made.
|
|
|
|
*/
|
2022-01-20 00:17:44 +00:00
|
|
|
bool startOrAppendItem( const VECTOR2D& location, const wxString& content );
|
2020-12-13 23:38:44 +00:00
|
|
|
|
|
|
|
struct HPGL_ITEM
|
|
|
|
{
|
2021-01-13 16:23:09 +00:00
|
|
|
HPGL_ITEM() :
|
|
|
|
lift_before( false ),
|
|
|
|
lift_after( false ),
|
|
|
|
pen_returns( false ),
|
|
|
|
pen( 0 ),
|
|
|
|
dashType( PLOT_DASH_TYPE::SOLID ) {}
|
2020-12-21 23:27:31 +00:00
|
|
|
|
2020-12-14 02:01:24 +00:00
|
|
|
/// Location the pen should start at
|
2022-01-20 00:17:44 +00:00
|
|
|
VECTOR2D loc_start;
|
2020-12-14 02:01:24 +00:00
|
|
|
|
|
|
|
/// Location the pen will be at when it finishes. If this is not known,
|
|
|
|
/// leave it equal to loc_start and set lift_after.
|
2022-01-20 00:17:44 +00:00
|
|
|
VECTOR2D loc_end;
|
2020-12-14 02:01:24 +00:00
|
|
|
|
2020-12-21 23:27:31 +00:00
|
|
|
/// Bounding box of this item
|
|
|
|
BOX2D bbox;
|
|
|
|
|
2020-12-14 02:01:24 +00:00
|
|
|
/// Whether the command should be executed with the pen lifted
|
|
|
|
bool lift_before;
|
|
|
|
|
|
|
|
/// Whether the pen must be lifted after the command. If the location of the pen
|
|
|
|
/// is not known, this must be set (so that another command starting at loc_end
|
|
|
|
/// is not immediately executed with no lift).
|
|
|
|
bool lift_after;
|
|
|
|
|
|
|
|
/// Whether the pen returns to its original state after the command. Otherwise,
|
|
|
|
/// the pen is assumed to be down following the command.
|
|
|
|
bool pen_returns;
|
|
|
|
|
2022-01-20 00:17:44 +00:00
|
|
|
int pen; /// Pen number for this command
|
|
|
|
PLOT_DASH_TYPE dashType; /// Line style for this command
|
|
|
|
wxString content; /// Text of the command
|
2020-12-13 23:38:44 +00:00
|
|
|
};
|
|
|
|
|
2020-12-14 02:01:24 +00:00
|
|
|
/// Sort a list of HPGL items to improve plotting speed on mechanical plotters.
|
|
|
|
///
|
|
|
|
/// @param items - items to sort
|
|
|
|
static void sortItems( std::list<HPGL_ITEM>& items );
|
|
|
|
|
|
|
|
/// Return the plot command corresponding to a line type
|
2022-06-28 18:21:00 +00:00
|
|
|
static const char* lineStyleCommand( PLOT_DASH_TYPE aLineStyle );
|
2020-12-14 02:01:24 +00:00
|
|
|
|
2022-06-28 18:06:17 +00:00
|
|
|
protected:
|
2022-06-28 18:21:00 +00:00
|
|
|
int m_penSpeed;
|
|
|
|
int m_penNumber;
|
|
|
|
double m_penDiameter;
|
|
|
|
double m_arcTargetChordLength;
|
|
|
|
EDA_ANGLE m_arcMinChordDegrees;
|
2022-06-28 18:06:17 +00:00
|
|
|
PLOT_DASH_TYPE m_lineStyle;
|
2022-06-28 18:21:00 +00:00
|
|
|
bool m_useUserCoords;
|
|
|
|
bool m_fitUserCoords;
|
2022-06-28 18:06:17 +00:00
|
|
|
|
2020-12-13 23:38:44 +00:00
|
|
|
std::list<HPGL_ITEM> m_items;
|
2020-12-14 02:01:24 +00:00
|
|
|
HPGL_ITEM* m_current_item;
|
2020-09-23 18:58:13 +00:00
|
|
|
};
|