Add user coordinate support to HPGL plotter
This commit is contained in:
parent
5676117d0b
commit
f5b7595675
|
@ -223,6 +223,8 @@ HPGL_PLOTTER::HPGL_PLOTTER()
|
|||
: arcTargetChordLength( 0 ),
|
||||
arcMinChordDegrees( 5.0 ),
|
||||
dashType( PLOT_DASH_TYPE::SOLID ),
|
||||
useUserCoords( false ),
|
||||
fitUserCoords( false ),
|
||||
m_current_item( nullptr )
|
||||
{
|
||||
SetPenSpeed( 40 ); // Default pen speed = 40 cm/s; Pen speed is *always* in cm
|
||||
|
@ -273,13 +275,34 @@ bool HPGL_PLOTTER::StartPlot()
|
|||
bool HPGL_PLOTTER::EndPlot()
|
||||
{
|
||||
wxASSERT( m_outputFile );
|
||||
fputs( "PU;", m_outputFile );
|
||||
|
||||
fputs( "PU;\n", m_outputFile );
|
||||
|
||||
flushItem();
|
||||
sortItems( m_items );
|
||||
|
||||
if( m_items.size() > 0 )
|
||||
{
|
||||
if( useUserCoords )
|
||||
{
|
||||
if( fitUserCoords )
|
||||
{
|
||||
BOX2D bbox = m_items.front().bbox;
|
||||
for( HPGL_ITEM const& item: m_items )
|
||||
{
|
||||
bbox.Merge( item.bbox );
|
||||
}
|
||||
|
||||
fprintf( m_outputFile, "SC%.0f,%.0f,%.0f,%.0f;\n", bbox.GetX(), bbox.GetX() + bbox.GetWidth(),
|
||||
bbox.GetY(), bbox.GetY() + bbox.GetHeight() );
|
||||
}
|
||||
else
|
||||
{
|
||||
DPOINT pagesize_dev( m_paperSize * m_iuPerDeviceUnit );
|
||||
fprintf( m_outputFile, "SC%.0f,%.0f,%.0f,%.0f;\n", 0., pagesize_dev.x, 0., pagesize_dev.y );
|
||||
}
|
||||
}
|
||||
|
||||
DPOINT loc = m_items.begin()->loc_start;
|
||||
bool pen_up = true;
|
||||
PLOT_DASH_TYPE current_dash = PLOT_DASH_TYPE::SOLID;
|
||||
|
@ -376,6 +399,7 @@ void HPGL_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, i
|
|||
startOrAppendItem( p1dev, wxString::Format( "EA %.0f,%.0f;", p2dev.x, p2dev.y ) );
|
||||
|
||||
m_current_item->loc_end = m_current_item->loc_start;
|
||||
m_current_item->bbox.Merge( p2dev );
|
||||
PenFinish();
|
||||
}
|
||||
|
||||
|
@ -410,6 +434,9 @@ void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill,
|
|||
hpgl_end_polygon_cmd ) );
|
||||
m_current_item->lift_before = true;
|
||||
m_current_item->pen_returns = true;
|
||||
m_current_item->bbox.Merge(
|
||||
BOX2D( center_dev - radius, VECTOR2D( 2 * radius, 2 * radius ) )
|
||||
);
|
||||
PenFinish();
|
||||
}
|
||||
|
||||
|
@ -419,6 +446,9 @@ void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill,
|
|||
startOrAppendItem( center_dev, wxString::Format( "CI %g,%g;", radius, chord_degrees ) );
|
||||
m_current_item->lift_before = true;
|
||||
m_current_item->pen_returns = true;
|
||||
m_current_item->bbox.Merge(
|
||||
BOX2D( center_dev - radius, VECTOR2D( 2 * radius, 2 * radius ) )
|
||||
);
|
||||
PenFinish();
|
||||
}
|
||||
}
|
||||
|
@ -514,6 +544,7 @@ void HPGL_PLOTTER::PenTo( const wxPoint& pos, char plume )
|
|||
)
|
||||
);
|
||||
m_current_item->loc_end = pos_dev;
|
||||
m_current_item->bbox.Merge( pos_dev );
|
||||
}
|
||||
|
||||
m_penLastpos = pos;
|
||||
|
@ -565,9 +596,10 @@ void HPGL_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle,
|
|||
if( radius <= 0 )
|
||||
return;
|
||||
|
||||
double const circumf = 2.0 * M_PI * userToDeviceSize( radius );
|
||||
double const radius_dev = userToDeviceSize( radius );
|
||||
double const circumf_dev = 2.0 * M_PI * radius_dev;
|
||||
double const target_chord_length = arcTargetChordLength;
|
||||
double chord_degrees = 360.0 * target_chord_length / circumf;
|
||||
double chord_degrees = 360.0 * target_chord_length / circumf_dev;
|
||||
|
||||
if( chord_degrees < arcMinChordDegrees )
|
||||
{
|
||||
|
@ -597,7 +629,10 @@ void HPGL_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle,
|
|||
startOrAppendItem( cmap_dev, wxString::Format( "AA %.0f,%.0f,%.0f,%g", centre_dev.x,
|
||||
centre_dev.y, angle, chord_degrees ) );
|
||||
|
||||
// TODO We could compute the final position instead...
|
||||
// TODO We could compute the final position and full bounding box instead...
|
||||
m_current_item->bbox.Merge( BOX2D(
|
||||
centre_dev - radius_dev, VECTOR2D( radius_dev * 2, radius_dev * 2 )
|
||||
) );
|
||||
m_current_item->lift_after = true;
|
||||
flushItem();
|
||||
}
|
||||
|
@ -832,7 +867,13 @@ bool HPGL_PLOTTER::startOrAppendItem( DPOINT location, wxString const& content )
|
|||
{
|
||||
if( m_current_item == nullptr )
|
||||
{
|
||||
HPGL_ITEM item = { location, location, false, false, false, penNumber, dashType, content };
|
||||
HPGL_ITEM item;
|
||||
item.loc_start = location;
|
||||
item.loc_end = location;
|
||||
item.bbox = BOX2D( location );
|
||||
item.pen = penNumber;
|
||||
item.dashType = dashType;
|
||||
item.content = content;
|
||||
m_items.push_back( item );
|
||||
m_current_item = &m_items.back();
|
||||
return true;
|
||||
|
|
|
@ -54,6 +54,18 @@ public:
|
|||
/// @param chord_len - chord length in IUs
|
||||
void SetTargetChordLength( double chord_len );
|
||||
|
||||
/// Switch to the user coordinate system
|
||||
void SetUserCoords( bool user_coords )
|
||||
{
|
||||
useUserCoords = user_coords;
|
||||
}
|
||||
|
||||
/// Set whether the user coordinate system is fit to content
|
||||
void SetUserCoordsFit( bool user_coords_fit )
|
||||
{
|
||||
fitUserCoords = user_coords_fit;
|
||||
}
|
||||
|
||||
virtual bool StartPlot() override;
|
||||
virtual bool EndPlot() override;
|
||||
|
||||
|
@ -139,9 +151,18 @@ protected:
|
|||
double arcTargetChordLength;
|
||||
double arcMinChordDegrees;
|
||||
PLOT_DASH_TYPE dashType;
|
||||
bool useUserCoords;
|
||||
bool fitUserCoords;
|
||||
|
||||
struct HPGL_ITEM
|
||||
{
|
||||
HPGL_ITEM()
|
||||
: lift_before( false ),
|
||||
lift_after( false ),
|
||||
pen_returns( false ),
|
||||
pen( 0 )
|
||||
{}
|
||||
|
||||
/// Location the pen should start at
|
||||
DPOINT loc_start;
|
||||
|
||||
|
@ -149,6 +170,9 @@ protected:
|
|||
/// leave it equal to loc_start and set lift_after.
|
||||
DPOINT loc_end;
|
||||
|
||||
/// Bounding box of this item
|
||||
BOX2D bbox;
|
||||
|
||||
/// Whether the command should be executed with the pen lifted
|
||||
bool lift_before;
|
||||
|
||||
|
|
|
@ -96,8 +96,8 @@ void DIALOG_PLOT_SCHEMATIC::initDlg()
|
|||
// Set plot or not frame reference option
|
||||
setPlotFrameRef( cfg->m_PlotPanel.frame_reference );
|
||||
|
||||
// Set HPGL plot origin to center of paper of left bottom corner
|
||||
SetPlotOriginCenter( cfg->m_PlotPanel.hpgl_origin );
|
||||
// HPGL plot origin and unit system configuration
|
||||
m_plotOriginOpt->SetSelection( cfg->m_PlotPanel.hpgl_origin );
|
||||
|
||||
m_HPGLPaperSizeSelect = cfg->m_PlotPanel.hpgl_paper_size;
|
||||
|
||||
|
@ -279,7 +279,7 @@ void DIALOG_PLOT_SCHEMATIC::getPlotOptions( RENDER_SETTINGS* aSettings )
|
|||
cfg->m_PlotPanel.color_theme = colors->GetFilename();
|
||||
cfg->m_PlotPanel.frame_reference = getPlotFrameRef();
|
||||
cfg->m_PlotPanel.format = static_cast<int>( GetPlotFileFormat() );
|
||||
cfg->m_PlotPanel.hpgl_origin = GetPlotOriginCenter();
|
||||
cfg->m_PlotPanel.hpgl_origin = m_plotOriginOpt->GetSelection();
|
||||
cfg->m_PlotPanel.hpgl_paper_size = m_HPGLPaperSizeSelect;
|
||||
|
||||
// HPGL Pen Size is stored in mm in config
|
||||
|
|
|
@ -40,6 +40,13 @@ enum PageFormatReq {
|
|||
PAGE_SIZE_A
|
||||
};
|
||||
|
||||
enum class HPGL_PLOT_ORIGIN_AND_UNITS {
|
||||
PLOTTER_BOT_LEFT,
|
||||
PLOTTER_CENTER,
|
||||
USER_FIT_PAGE,
|
||||
USER_FIT_CONTENT,
|
||||
};
|
||||
|
||||
class PDF_PLOTTER;
|
||||
|
||||
class DIALOG_PLOT_SCHEMATIC : public DIALOG_PLOT_SCHEMATIC_BASE
|
||||
|
@ -112,21 +119,48 @@ private:
|
|||
wxPoint aPlot0ffset, double aScale, bool aPlotFrameRef );
|
||||
|
||||
// HPGL
|
||||
bool GetPlotOriginCenter()
|
||||
HPGL_PLOT_ORIGIN_AND_UNITS GetPlotOriginAndUnits()
|
||||
{
|
||||
return m_plotOriginOpt->GetSelection() == 1;
|
||||
switch( m_plotOriginOpt->GetSelection() )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
return HPGL_PLOT_ORIGIN_AND_UNITS::PLOTTER_BOT_LEFT;
|
||||
case 1:
|
||||
return HPGL_PLOT_ORIGIN_AND_UNITS::PLOTTER_CENTER;
|
||||
case 2:
|
||||
return HPGL_PLOT_ORIGIN_AND_UNITS::USER_FIT_PAGE;
|
||||
case 3:
|
||||
return HPGL_PLOT_ORIGIN_AND_UNITS::USER_FIT_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
void SetPlotOriginCenter( bool aCenter )
|
||||
void SetPlotOriginAndUnits( HPGL_PLOT_ORIGIN_AND_UNITS aOriginAndUnits )
|
||||
{
|
||||
m_plotOriginOpt->SetSelection( aCenter ? 1 : 0 );
|
||||
switch( aOriginAndUnits )
|
||||
{
|
||||
case HPGL_PLOT_ORIGIN_AND_UNITS::PLOTTER_BOT_LEFT:
|
||||
default:
|
||||
m_plotOriginOpt->SetSelection( 0 );
|
||||
break;
|
||||
case HPGL_PLOT_ORIGIN_AND_UNITS::PLOTTER_CENTER:
|
||||
m_plotOriginOpt->SetSelection( 1 );
|
||||
break;
|
||||
case HPGL_PLOT_ORIGIN_AND_UNITS::USER_FIT_PAGE:
|
||||
m_plotOriginOpt->SetSelection( 2 );
|
||||
break;
|
||||
case HPGL_PLOT_ORIGIN_AND_UNITS::USER_FIT_CONTENT:
|
||||
m_plotOriginOpt->SetSelection( 3 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void createHPGLFile( bool aPlotAll, bool aPlotFrameRef, RENDER_SETTINGS* aRenderSettings );
|
||||
void SetHPGLPenWidth();
|
||||
bool Plot_1_Page_HPGL( const wxString& aFileName, SCH_SCREEN* aScreen,
|
||||
const PAGE_INFO& aPageInfo, RENDER_SETTINGS* aRenderSettings,
|
||||
wxPoint aPlot0ffset, double aScale, bool aPlotFrameRef );
|
||||
wxPoint aPlot0ffset, double aScale, bool aPlotFrameRef,
|
||||
HPGL_PLOT_ORIGIN_AND_UNITS aOriginAndUnits );
|
||||
|
||||
// PS
|
||||
void createPSFile( bool aPlotAll, bool aPlotFrameRef, RENDER_SETTINGS* aSettings );
|
||||
|
|
|
@ -123,11 +123,11 @@ DIALOG_PLOT_SCHEMATIC_BASE::DIALOG_PLOT_SCHEMATIC_BASE( wxWindow* parent, wxWind
|
|||
gbSizer2->SetFlexibleDirection( wxBOTH );
|
||||
gbSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_plotOriginTitle = new wxStaticText( m_HPGLOptionsSizer->GetStaticBox(), wxID_ANY, _("Position:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_plotOriginTitle = new wxStaticText( m_HPGLOptionsSizer->GetStaticBox(), wxID_ANY, _("Position and units:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_plotOriginTitle->Wrap( -1 );
|
||||
gbSizer2->Add( m_plotOriginTitle, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
wxString m_plotOriginOptChoices[] = { _("Bottom left"), _("Center on page") };
|
||||
wxString m_plotOriginOptChoices[] = { _("Bottom left, plotter units"), _("Centered, plotter units"), _("Page fit, user units"), _("Content fit, user units") };
|
||||
int m_plotOriginOptNChoices = sizeof( m_plotOriginOptChoices ) / sizeof( wxString );
|
||||
m_plotOriginOpt = new wxChoice( m_HPGLOptionsSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_plotOriginOptNChoices, m_plotOriginOptChoices, 0 );
|
||||
m_plotOriginOpt->SetSelection( 0 );
|
||||
|
|
|
@ -1164,7 +1164,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Position:</property>
|
||||
<property name="label">Position and units:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
|
@ -1214,7 +1214,7 @@
|
|||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="choices">"Bottom left" "Center on page"</property>
|
||||
<property name="choices">"Bottom left, plotter units" "Centered, plotter units" "Page fit, user units" "Content fit, user units"</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
|
|
|
@ -258,8 +258,8 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
|
|||
m_params.emplace_back( new PARAM<double>( "plot.hpgl_pen_size",
|
||||
&m_PlotPanel.hpgl_pen_size, 0.5 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "plot.hpgl_origin",
|
||||
&m_PlotPanel.hpgl_origin, false ) );
|
||||
m_params.emplace_back( new PARAM<int>( "plot.hpgl_origin",
|
||||
&m_PlotPanel.hpgl_origin, 0 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "simulator.window.pos_x",
|
||||
&m_Simulator.window.state.pos_x, 0 ) );
|
||||
|
|
|
@ -159,7 +159,7 @@ public:
|
|||
bool frame_reference;
|
||||
int hpgl_paper_size;
|
||||
double hpgl_pen_size;
|
||||
bool hpgl_origin;
|
||||
int hpgl_origin;
|
||||
};
|
||||
|
||||
struct PANEL_SYM_CHOOSER
|
||||
|
|
|
@ -141,7 +141,7 @@ void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef,
|
|||
wxPoint plotOffset;
|
||||
wxString msg;
|
||||
|
||||
if( GetPlotOriginCenter() )
|
||||
if( GetPlotOriginAndUnits() == HPGL_PLOT_ORIGIN_AND_UNITS::PLOTTER_CENTER )
|
||||
{
|
||||
plotOffset.x = plotPage.GetWidthIU() / 2;
|
||||
plotOffset.y = -plotPage.GetHeightIU() / 2;
|
||||
|
@ -161,7 +161,7 @@ void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef,
|
|||
LOCALE_IO toggle;
|
||||
|
||||
if( Plot_1_Page_HPGL( plotFileName.GetFullPath(), screen, plotPage, aRenderSettings,
|
||||
plotOffset, plot_scale, aPlotFrameRef ) )
|
||||
plotOffset, plot_scale, aPlotFrameRef, GetPlotOriginAndUnits() ) )
|
||||
{
|
||||
msg.Printf( _( "Plot: \"%s\" OK.\n" ), plotFileName.GetFullPath() );
|
||||
reporter.Report( msg, RPT_SEVERITY_ACTION );
|
||||
|
@ -192,7 +192,8 @@ bool DIALOG_PLOT_SCHEMATIC::Plot_1_Page_HPGL( const wxString& aFileName,
|
|||
RENDER_SETTINGS* aRenderSettings,
|
||||
wxPoint aPlot0ffset,
|
||||
double aScale,
|
||||
bool aPlotFrameRef )
|
||||
bool aPlotFrameRef,
|
||||
HPGL_PLOT_ORIGIN_AND_UNITS aOriginAndUnits )
|
||||
{
|
||||
HPGL_PLOTTER* plotter = new HPGL_PLOTTER();
|
||||
// Currently, plot units are in decimil
|
||||
|
@ -206,6 +207,23 @@ bool DIALOG_PLOT_SCHEMATIC::Plot_1_Page_HPGL( const wxString& aFileName,
|
|||
// TODO this could be configurable
|
||||
plotter->SetTargetChordLength( Millimeter2iu( 0.6 ) );
|
||||
|
||||
switch( aOriginAndUnits )
|
||||
{
|
||||
case HPGL_PLOT_ORIGIN_AND_UNITS::PLOTTER_BOT_LEFT:
|
||||
case HPGL_PLOT_ORIGIN_AND_UNITS::PLOTTER_CENTER:
|
||||
default:
|
||||
plotter->SetUserCoords( false );
|
||||
break;
|
||||
case HPGL_PLOT_ORIGIN_AND_UNITS::USER_FIT_PAGE:
|
||||
plotter->SetUserCoords( true );
|
||||
plotter->SetUserCoordsFit( false );
|
||||
break;
|
||||
case HPGL_PLOT_ORIGIN_AND_UNITS::USER_FIT_CONTENT:
|
||||
plotter->SetUserCoords( true );
|
||||
plotter->SetUserCoordsFit( true );
|
||||
break;
|
||||
}
|
||||
|
||||
// Init :
|
||||
plotter->SetCreator( wxT( "Eeschema-HPGL" ) );
|
||||
|
||||
|
|
Loading…
Reference in New Issue