diff --git a/common/plotters/HPGL_plotter.cpp b/common/plotters/HPGL_plotter.cpp index 748ea8ca0e..c64ae285d5 100644 --- a/common/plotters/HPGL_plotter.cpp +++ b/common/plotters/HPGL_plotter.cpp @@ -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; diff --git a/common/plotters/plotter_hpgl.h b/common/plotters/plotter_hpgl.h index c288f89707..b7cea75f13 100644 --- a/common/plotters/plotter_hpgl.h +++ b/common/plotters/plotter_hpgl.h @@ -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; @@ -133,15 +145,24 @@ protected: /// @return whether a new item was made bool startOrAppendItem( DPOINT location, wxString const& content ); - int penSpeed; - int penNumber; - double penDiameter; + int penSpeed; + int penNumber; + double penDiameter; 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; diff --git a/eeschema/dialogs/dialog_plot_schematic.cpp b/eeschema/dialogs/dialog_plot_schematic.cpp index 61976e04b1..0473d3addd 100644 --- a/eeschema/dialogs/dialog_plot_schematic.cpp +++ b/eeschema/dialogs/dialog_plot_schematic.cpp @@ -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( 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 diff --git a/eeschema/dialogs/dialog_plot_schematic.h b/eeschema/dialogs/dialog_plot_schematic.h index ab0c9cc686..8cb5f4f7ad 100644 --- a/eeschema/dialogs/dialog_plot_schematic.h +++ b/eeschema/dialogs/dialog_plot_schematic.h @@ -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 ); diff --git a/eeschema/dialogs/dialog_plot_schematic_base.cpp b/eeschema/dialogs/dialog_plot_schematic_base.cpp index 7fc290bd71..49da7e0c24 100644 --- a/eeschema/dialogs/dialog_plot_schematic_base.cpp +++ b/eeschema/dialogs/dialog_plot_schematic_base.cpp @@ -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 ); diff --git a/eeschema/dialogs/dialog_plot_schematic_base.fbp b/eeschema/dialogs/dialog_plot_schematic_base.fbp index 0566136a6f..6c041559cb 100644 --- a/eeschema/dialogs/dialog_plot_schematic_base.fbp +++ b/eeschema/dialogs/dialog_plot_schematic_base.fbp @@ -1164,7 +1164,7 @@ 0 0 wxID_ANY - Position: + Position and units: 0 0 @@ -1214,7 +1214,7 @@ 1 0 - "Bottom left" "Center on page" + "Bottom left, plotter units" "Centered, plotter units" "Page fit, user units" "Content fit, user units" 1 1 diff --git a/eeschema/eeschema_settings.cpp b/eeschema/eeschema_settings.cpp index fded693786..d0a01eab61 100644 --- a/eeschema/eeschema_settings.cpp +++ b/eeschema/eeschema_settings.cpp @@ -258,8 +258,8 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() : m_params.emplace_back( new PARAM( "plot.hpgl_pen_size", &m_PlotPanel.hpgl_pen_size, 0.5 ) ); - m_params.emplace_back( new PARAM( "plot.hpgl_origin", - &m_PlotPanel.hpgl_origin, false ) ); + m_params.emplace_back( new PARAM( "plot.hpgl_origin", + &m_PlotPanel.hpgl_origin, 0 ) ); m_params.emplace_back( new PARAM( "simulator.window.pos_x", &m_Simulator.window.state.pos_x, 0 ) ); diff --git a/eeschema/eeschema_settings.h b/eeschema/eeschema_settings.h index 3b33fadfe8..e837617d51 100644 --- a/eeschema/eeschema_settings.h +++ b/eeschema/eeschema_settings.h @@ -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 diff --git a/eeschema/plotters/plot_schematic_HPGL.cpp b/eeschema/plotters/plot_schematic_HPGL.cpp index bddb558261..3de19a2b58 100644 --- a/eeschema/plotters/plot_schematic_HPGL.cpp +++ b/eeschema/plotters/plot_schematic_HPGL.cpp @@ -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" ) );