Commit 2a801170 authored by charras's avatar charras

Commit patch for plot functions from Lorenzo

parent ed71f4b7
......@@ -329,7 +329,7 @@ bool EDA_TextStruct::TextHitTest( EDA_Rect& refArea )
void EDA_TextStruct::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, EDA_Colors aColor,
int aDrawMode,
GRFillMode aFillMode, EDA_Colors aAnchor_color )
GRTraceMode aFillMode, EDA_Colors aAnchor_color )
/***************************************************************/
/** Function Draw
......@@ -399,7 +399,7 @@ void EDA_TextStruct::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
void EDA_TextStruct::DrawOneLineOfText( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, EDA_Colors aColor,
int aDrawMode,
GRFillMode aFillMode, EDA_Colors aAnchor_color,
GRTraceMode aFillMode, EDA_Colors aAnchor_color,
wxString& aText, wxPoint aPos )
{
int width = m_Width;
......
......@@ -14,129 +14,271 @@
/***************************************************************************/
void InitPlotParametresGERBER( wxPoint aOffset, double aXScale, double aYScale )
void Gerber_Plotter::set_viewport( wxPoint offset,
double aScale, int orient )
/***************************************************************************/
/** function InitPlotParametresGERBER
/** function set_viewport
* Set the plot offset for the current plotting
* @param aOffset = plot offset
* @param aXScale,aYScale = coordinate scale (scale coefficient for coordinates)
* @param aScale = coordinate scale (scale coefficient for coordinates)
*/
{
g_Plot_PlotOrientOptions = 0;
g_Plot_PlotOffset = aOffset;
g_Plot_XScale = aXScale;
g_Plot_YScale = aYScale;
g_Plot_DefaultPenWidth = 120; /* epaisseur du trait standard en 1/1000 pouce */
g_Plot_CurrentPenWidth = -1;
wxASSERT(!output_file);
wxASSERT(orient == 0);
plot_orient_options = 0;
plot_offset = offset;
wxASSERT(aScale == 1);
plot_scale = 1;
device_scale = 1;
set_default_line_width(100); /* epaisseur du trait standard en 1/1000 pouce */
}
/******************************************************************/
void Write_Header_GERBER( const wxString aTitle, FILE* aFile )
/******************************************************************/
/** Function Write_Header_GERBER
void Gerber_Plotter::start_plot( FILE *aFile )
/*****************************************************************/
/** Function start_plot
* Write GERBER header to file
* initialize global variable g_Plot_PlotOutputFile
* @param aTitle: the name of creator (comment)
* @param aFile: an opened file to write to
*/
{
char Line[1024];
g_Plot_PlotOutputFile = aFile;
wxASSERT(!output_file);
final_file = aFile;
work_file = tmpfile();
output_file = work_file;
DateAndTime( Line );
wxString Title = aTitle + wxT( " " ) + GetBuildVersion();
fprintf( g_Plot_PlotOutputFile, "G04 (created by %s) date %s*\n", CONV_TO_UTF8( Title ), Line );
wxString Title = creator + wxT( " " ) + GetBuildVersion();
fprintf( output_file, "G04 (created by %s) date %s*\n", CONV_TO_UTF8( Title ), Line );
// Specify linear interpol (G01), unit = INCH (G70), abs format (G90):
fputs( "G01*\nG70*\nG90*\n", g_Plot_PlotOutputFile );
fputs( "%MOIN*%\n", g_Plot_PlotOutputFile ); // set unites = INCHES
fputs( "G01*\nG70*\nG90*\n", output_file );
fputs( "%MOIN*%\n", output_file ); // set unites = INCHES
/* Set gerber format to 3.4 */
fputs( "G04 Gerber Fmt 3.4, Leading zero omitted, Abs format*\n%FSLAX34Y34*%\n",
g_Plot_PlotOutputFile);
output_file);
fputs( "G04 APERTURE LIST*\n", g_Plot_PlotOutputFile );
fputs( "G04 APERTURE LIST*\n", output_file );
/* Select the default aperture */
set_current_line_width(-1);
}
/******************************************************************/
void Gerber_Plotter::end_plot( )
/*****************************************************************/
{
char line[1024];
wxString msg;
wxASSERT(output_file);
/* Outfile is actually a temporary file! */
fputs( "M02*\n", output_file );
fflush(output_file);
rewind( work_file ); // work_file == output_file !!!
output_file = final_file;
/**********************************************/
void LineTo_GERBER( wxPoint aPos, int aCommand )
/**********************************************/
/** Function LineTo_GERBER
* if aCommand = 'U' initialise the starting point of a line
* if aCommand = 'D' draw a line from the starting point, or last point to aPos
* @param aPos = end of the current line.
* @param aCommand = 'U' or 'D' or 'Z' (Pen up , no moving )
// Placement des Apertures en RS274X
while( fgets( line, 1024, work_file ) )
{
fputs( line, output_file );
if( strcmp( strtok( line, "\n\r" ), "G04 APERTURE LIST*" ) == 0 )
{
write_aperture_list();
fputs( "G04 APERTURE END LIST*\n", output_file );
}
}
fclose( work_file );
fclose( final_file );
output_file = 0;
}
/*************************************************************************************/
void Gerber_Plotter::set_default_line_width( int width )
/*************************************************************************************/
/* Set the default line width (in 1/1000 inch) for the current plotting
*/
{
default_pen_width = width; // epaisseur du trait standard en 1/1000 pouce
current_aperture = apertures.end();
}
/***************************************/
void Gerber_Plotter::set_current_line_width( int width )
/***************************************/
/* Set the Current line width (in 1/1000 inch) for the next plot
*/
{
static wxPoint LastPoint;
switch ( aCommand )
int pen_width;
if( width > 0 )
pen_width = width;
else
pen_width = default_pen_width;
select_aperture(wxSize(pen_width, pen_width), Aperture::Plotting);
current_pen_width = pen_width;
}
/******************************************************/
vector<Aperture>::iterator Gerber_Plotter::get_aperture(const wxSize &size,
Aperture::Aperture_Type type)
/******************************************************/
{
int last_D_code = 9;
// Search an existing aperture
vector<Aperture>::iterator tool = apertures.begin();
while (tool != apertures.end()) {
last_D_code = tool->D_code;
if ((tool->type == type)
&& (tool->size == size))
return tool;
tool++;
}
// Allocate a new aperture
Aperture new_tool;
new_tool.size = size;
new_tool.type = type;
new_tool.D_code = last_D_code+1;
apertures.push_back(new_tool);
return apertures.end()-1;
}
/******************************************************/
void Gerber_Plotter::select_aperture(const wxSize &size, Aperture::Aperture_Type type)
/******************************************************/
{
wxASSERT(output_file);
if ((current_aperture == apertures.end())
|| (current_aperture->type != type)
|| (current_aperture->size != size)) {
/* Pick an existing aperture or create a new one */
current_aperture = get_aperture(size, type);
fprintf( output_file, "G54D%d*\n", current_aperture->D_code );
}
}
/******************************************************/
void Gerber_Plotter::write_aperture_list( )
/******************************************************/
/* Genere la liste courante des D_CODES
* Retourne le nombre de D_Codes utilises
* Genere une sequence RS274X
*/
{
wxASSERT(output_file);
char cbuf[1024];
/* Init : */
for (vector<Aperture>::iterator tool=apertures.begin();
tool != apertures.end(); tool++)
{
const float fscale = 0.0001f * plot_scale; // For 3.4 format
char* text;
text = cbuf + sprintf( cbuf, "%%ADD%d", tool->D_code);
switch( tool->type )
{
case Aperture::Circle:
sprintf( text, "C,%f*%%\n", tool->size.x * fscale );
break;
case Aperture::Rect:
sprintf( text, "R,%fX%f*%%\n", tool->size.x * fscale,
tool->size.y * fscale );
break;
case Aperture::Plotting:
sprintf( text, "C,%f*%%\n", tool->size.x * fscale );
break;
case Aperture::Oval:
sprintf( text, "O,%fX%f*%%\n", tool->size.x * fscale,
tool->size.y * fscale );
break;
}
fputs( cbuf, output_file );
}
}
/**********************************************/
void Gerber_Plotter::pen_to( wxPoint aPos, char plume )
{
wxASSERT(output_file);
user_to_device_coordinates( aPos );
switch ( plume )
{
case 'Z':
return;
break;
case 'U':
fprintf( output_file, "X%5.5dY%5.5dD02*\n", aPos.x, aPos.y );
break;
case 'D':
PlotGERBERLine( LastPoint, aPos, g_Plot_CurrentPenWidth );
fprintf( output_file, "X%5.5dY%5.5dD01*\n", aPos.x, aPos.y );
}
LastPoint = aPos;
pen_state = plume;
}
/** Function PlotGERBERLine
* Plot a line
* the D_CODE **MUST** have already selected (this is just the line plot)
* @param aStartPos = starting point of the line
* @param aEndPos = ending point of the line
* @param aThickness = line thickness (not used here)
*/
void PlotGERBERLine( wxPoint aStartPos, wxPoint aEndPos, int aThickness )
/************************************************************/
void Gerber_Plotter::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width )
/************************************************************/
{
UserToDeviceCoordinate( aStartPos );
UserToDeviceCoordinate( aEndPos );
fprintf( g_Plot_PlotOutputFile, "X%5.5dY%5.5dD02*\n", aStartPos.x, aStartPos.y );
fprintf( g_Plot_PlotOutputFile, "X%5.5dY%5.5dD01*\n", aEndPos.x, aEndPos.y );
wxASSERT(output_file);
int coord[10] = {
p1.x, p1.y,
p1.x, p2.y,
p2.x, p2.y,
p2.x, p1.y,
p1.x, p1.y
};
poly( 5, coord, fill, width);
}
/********************************************************************/
void PlotCircle_GERBER( wxPoint aCentre, int aRadius, int aWidth )
void Gerber_Plotter::circle( wxPoint pos, int diametre, FILL_T fill, int width )
/********************************************************************/
/** Function PlotCircle_GERBER
* writes a non filled circle to output file
* Plot one circle as segments (6 to 16 depending on its radius
* @param aCentre = centre coordintes
* @param aRadius = radius of the circle
* @param aWidth = line width (noc currently used, D_CODEs must be selected before)
* @param aWidth = line width
*/
{
int ii;
wxPoint start, end;
int delta; /* increment (in 0.1 degrees) to draw circles */
delta = 3600/32; /* there are delta segments for draw a circle */
wxASSERT(output_file);
wxPoint start,end;
double aRadius = diametre / 2;
const int delta = 3600/32; /* increment (in 0.1 degrees) to draw circles */
start.x = aCentre.x + aRadius;
start.y = aCentre.y;
for( ii = delta; ii < 3600; ii += delta )
start.x = pos.x + aRadius;
start.y = pos.y;
set_current_line_width(width);
move_to(start);
for(int ii = delta; ii < 3600; ii += delta )
{
end.x = aCentre.x + (int) (aRadius * fcosinus[ii]);
end.y = aCentre.y + (int) (aRadius * fsinus[ii]);
PlotGERBERLine( start, end, aWidth );
start = end;
end.x = pos.x + (int) (aRadius * fcosinus[ii]);
end.y = pos.y + (int) (aRadius * fsinus[ii]);
line_to(end);
}
end.x = aCentre.x + aRadius;
end.y = aCentre.y;
PlotGERBERLine( start, end, aWidth );
finish_to( start );
}
/***************************************************************/
void PlotFilledPolygon_GERBER( int aCornersCount, int* aCoord )
void Gerber_Plotter::poly( int nb_segm, int* coord, FILL_T fill, int width )
/***************************************************************/
/** Function PlotFilledPolygon_GERBER
* writes a filled polyline to output file
......@@ -144,59 +286,231 @@ void PlotFilledPolygon_GERBER( int aCornersCount, int* aCoord )
* @param aCoord = buffer of corners coordinates
*/
{
int ii;
wxASSERT(output_file);
wxPoint pos, startpos;
set_current_line_width(width);
fputs( "G36*\n", g_Plot_PlotOutputFile );
pos.x = *aCoord;
aCoord++;
pos.y = *aCoord;
aCoord++;
UserToDeviceCoordinate( pos );
startpos = pos;
fprintf( g_Plot_PlotOutputFile, "X%5.5dY%5.5dD02*\n", pos.x, pos.y );
for( ii = 1; ii < aCornersCount; ii++ )
if (fill)
fputs( "G36*\n", output_file );
startpos.x = *coord++;
startpos.y = *coord++;
move_to(startpos);
for(int ii = 1; ii < nb_segm; ii++ )
{
pos.x = *aCoord;
aCoord++;
pos.y = *aCoord;
aCoord++;
UserToDeviceCoordinate( pos );
fprintf( g_Plot_PlotOutputFile, "X%5.5dY%5.5dD01*\n", pos.x, pos.y );
pos.x = *coord++;
pos.y = *coord++;
line_to( pos );
}
if (fill)
{
finish_to(startpos);
fputs( "G37*\n", output_file );
}
else
{
pen_finish();
}
fprintf( g_Plot_PlotOutputFile, "X%5.5dY%5.5dD01*\n", startpos.x, startpos.y );
fputs( "G37*\n", g_Plot_PlotOutputFile );
}
void Gerber_Plotter::flash_pad_circle(wxPoint pos, int diametre,
GRTraceMode trace_mode)
/* Plot a circular pad or via at the user position pos
*/
{
wxASSERT(output_file);
wxSize size( diametre, diametre );
/*******************************************************************/
void PlotPolygon_GERBER( int aCornersCount, int* aCoord, int aWidth )
/*******************************************************************/
/** Function PlotPolygon_GERBER
* writes a closed polyline (not a filled polygon) to output file
* @param aCornersCount = numer of corners
* @param aCoord = buffer of corners coordinates
* @param aWidth = line width (not currently used, D_CODEs must be selected before)
*/
switch (trace_mode)
{
case FILAIRE:
case SKETCH:
set_current_line_width(-1);
circle(pos, diametre-current_pen_width, NO_FILL);
break;
case FILLED:
user_to_device_coordinates( pos );
select_aperture(size, Aperture::Circle);
fprintf( output_file, "X%5.5dY%5.5dD03*\n", pos.x, pos.y );
break;
}
}
void Gerber_Plotter::flash_pad_oval(wxPoint pos, wxSize size, int orient,
GRTraceMode trace_mode)
/* Trace 1 pastille PAD_OVAL en position pos_X,Y:
* dimensions dx, dy,
* orientation orient
* Pour une orientation verticale ou horizontale, la forme est flashee
* Pour une orientation quelconque la forme est tracee comme un segment
*/
{
wxPoint start, end, startpoint;
startpoint.x = *aCoord++;
startpoint.y = *aCoord++;
start = startpoint;
for( int ii = 0; ii < aCornersCount-1; ii++ )
wxASSERT(output_file);
int x0, y0, x1, y1, delta;
/* Trace de la forme flashee */
if(( orient == 0 || orient == 900 || orient == 1800 || orient == 2700 )
&& trace_mode == FILLED)
{
if( orient == 900 || orient == 2700 ) /* orient tournee de 90 deg */
EXCHG( size.x, size.y );
user_to_device_coordinates( pos );
select_aperture(size, Aperture::Oval);
fprintf( output_file, "X%5.5dY%5.5dD03*\n", pos.x, pos.y );
}
else /* Forme tracee comme un segment */
{
end.x = *aCoord;
aCoord++;
end.y = *aCoord;
aCoord++;
PlotGERBERLine(start, end, aWidth );
start = end;
if( size.x > size.y )
{
EXCHG( size.x, size.y );
if( orient < 2700 )
orient += 900;
else
orient -= 2700;
}
if (trace_mode == FILLED)
{
/* la pastille est ramenee a une pastille ovale avec dy > dx */
delta = size.y - size.x;
x0 = 0;
y0 = -delta / 2;
x1 = 0;
y1 = delta / 2;
RotatePoint( &x0, &y0, orient );
RotatePoint( &x1, &y1, orient );
thick_segment( wxPoint( pos.x + x0, pos.y + y0 ),
wxPoint( pos.x + x1, pos.y + y1 ),
size.x, trace_mode );
} else
sketch_oval(pos, size, orient, -1);
}
}
void Gerber_Plotter::flash_pad_rect(wxPoint pos, wxSize size,
int orient, GRTraceMode trace_mode)
/* Plot 1 rectangular pad
* donne par son centre, ses dimensions, et son orientation
* For a vertical or horizontal shape, the shape is an aperture (Dcode) and it is flashed
* For others orientations the shape is plotted as a polygon
*/
{
wxASSERT(output_file);
/* Trace de la forme flashee */
switch( orient )
{
case 900:
case 2700: /* la rotation de 90 ou 270 degres revient a permutter des dimensions */
EXCHG( size.x, size.y );
if ( startpoint != end ) // Close poly
PlotGERBERLine(end, startpoint, aWidth );
// Pass through
case 0:
case 1800:
switch (trace_mode) {
case FILAIRE:
case SKETCH:
set_current_line_width(-1);
rect(wxPoint(pos.x-(size.x-current_pen_width)/2,
pos.y-(size.y-current_pen_width)/2),
wxPoint(pos.x+(size.x-current_pen_width)/2,
pos.y+(size.y-current_pen_width)/2),
NO_FILL);
break;
case FILLED:
user_to_device_coordinates( pos );
select_aperture(size, Aperture::Rect);
fprintf( output_file, "X%5.5dY%5.5dD03*\n", pos.x, pos.y );
break;
}
break;
default: /* plot pad shape as polygon */
flash_pad_trapez( pos, size, wxSize( 0, 0 ), orient, trace_mode );
break;
}
}
void Gerber_Plotter::flash_pad_trapez(wxPoint pos, wxSize size, wxSize delta,
int orient, GRTraceMode trace_mode)
/* Trace 1 pad trapezoidal donne par :
* son centre pos.x,pos.y
* ses dimensions size.x et size.y
* les variations delta.x et delta.y ( 1 des deux au moins doit etre nulle)
* son orientation orient en 0.1 degres
* le mode de trace (FILLED, SKETCH, FILAIRE)
*
* Le trace n'est fait que pour un trapeze, c.a.d que delta.x ou delta.y
* = 0.
*
* les notation des sommets sont ( vis a vis de la table tracante )
*
* " 0 ------------- 3 "
* " . . "
* " . O . "
* " . . "
* " 1 ---- 2 "
*
*
* exemple de Disposition pour delta.y > 0, delta.x = 0
* " 1 ---- 2 "
* " . . "
* " . O . "
* " . . "
* " 0 ------------- 3 "
*
*
* exemple de Disposition pour delta.y = 0, delta.x > 0
* " 0 "
* " . . "
* " . . "
* " . 3 "
* " . . "
* " . O . "
* " . . "
* " . 2 "
* " . . "
* " . . "
* " 1 "
*/
{
wxASSERT(output_file);
int ii, jj;
int dx, dy;
wxPoint polygon[4]; /* polygon corners */
int coord[10];
int ddx, ddy;
/* calcul des dimensions optimales du spot choisi = 1/4 plus petite dim */
dx = size.x - abs( delta.y );
dy = size.y - abs( delta.x );
dx = size.x / 2;
dy = size.y / 2;
ddx = delta.x / 2;
ddy = delta.y / 2;
polygon[0].x = -dx - ddy;
polygon[0].y = +dy + ddx;
polygon[1].x = -dx + ddy;
polygon[1].y = -dy - ddx;
polygon[2].x = +dx - ddy;
polygon[2].y = -dy + ddx;
polygon[3].x = +dx + ddy;
polygon[3].y = +dy - ddx;
/* Dessin du polygone et Remplissage eventuel de l'interieur */
for( ii = 0, jj = 0; ii < 4; ii++ )
{
RotatePoint( &polygon[ii].x, &polygon[ii].y, orient );
coord[jj] = polygon[ii].x += pos.x;
jj++;
coord[jj] = polygon[ii].y += pos.y;
jj++;
}
coord[8]=coord[0];
coord[9]=coord[1];
set_current_line_width(-1);
poly( 5, coord, trace_mode==FILLED?FILLED_SHAPE:NO_FILL );
}
......@@ -11,96 +11,189 @@
#include "macros.h"
#include "kicad_string.h"
/* parametre HPGL pour trace de cercle: */
#define CHORD_ANGLE 10
//Variables locales
void Move_Plume_HPGL( wxPoint pos, int plume );
void Plume_HPGL( int plume );
/* From decimils to plu */
const double SCALE_HPGL = 0.102041;
/***********************************************************************************/
void InitPlotParametresHPGL( wxPoint offset, double aXScale, double aYScale, int orient )
void HPGL_Plotter::set_viewport( wxPoint offset,
double aScale, int orient )
/***********************************************************************************/
/* Set the plot offset for the current plotting
* g_Plot_XScale,g_Plot_YScale = coordinate scale (scale coefficient for coordinates)
* device_g_Plot_XScale,device_g_Plot_YScale = device coordinate scale (i.e scale used by plot device)
*/
{
g_Plot_PlotOffset = offset;
g_Plot_XScale = aXScale;
g_Plot_YScale = aYScale;
g_Plot_DefaultPenWidth = 6; /* epaisseur du trait standard en 1/1000 pouce */
g_Plot_PlotOrientOptions = orient;
g_Plot_CurrentPenWidth = -1;
wxASSERT(!output_file);
plot_offset = offset;
plot_scale = aScale;
device_scale = SCALE_HPGL;
set_default_line_width(100); /* epaisseur du trait standard en 1/1000 pouce */
plot_orient_options = orient;
}
/*****************************************************************/
bool PrintHeaderHPGL( FILE* plot_file, int pen_speed, int pen_num )
void HPGL_Plotter::start_plot( FILE *fout )
/*****************************************************************/
{
char Line[256];
g_Plot_PlotOutputFile = plot_file;
g_Plot_PenState = 'U';
sprintf( Line, "IN;VS%d;PU;PA;SP%d;\n", pen_speed, pen_num );
fputs( Line, plot_file );
return TRUE;
wxASSERT(!output_file);
output_file = fout;
fprintf( output_file, "IN;VS%d;PU;PA;SP%d;\n", pen_speed, pen_number );
}
/**********************************/
bool CloseFileHPGL( FILE* plot_file )
void HPGL_Plotter::end_plot()
/**********************************/
{
fputs( "PU;PA;SP0;\n", plot_file );
fclose( plot_file );
return TRUE;
wxASSERT(output_file);
fputs( "PU;PA;SP0;\n", output_file );
fclose( output_file );
output_file = 0;
}
/************************************************************/
void HPGL_Plotter::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width )
/************************************************************/
{
wxASSERT(output_file);
user_to_device_coordinates( p2 );
move_to(p1);
fprintf( output_file, "EA %d,%d;\n", p2.x, p2.y );
pen_finish();
}
/************************************************************/
void PlotRectHPGL( wxPoint p1, wxPoint p2, bool fill, int width )
void HPGL_Plotter::circle( wxPoint centre, int diameter, FILL_T fill, int width )
/************************************************************/
{
char Line[256];
wxASSERT(output_file);
double rayon = user_to_device_size(diameter / 2);
UserToDeviceCoordinate( p1 );
UserToDeviceCoordinate( p2 );
if( rayon > 0 )
{
move_to(centre);
fprintf( output_file, "CI %g;\n", rayon);
pen_finish();
}
}
Plume_HPGL( 'U' );
sprintf( Line, "PA %d,%d;EA %d,%d;\n", p1.x, p1.y, p2.x, p2.y );
fputs( Line, g_Plot_PlotOutputFile );
/*****************************************************/
void HPGL_Plotter::poly( int nb, int* coord, FILL_T fill, int width )
/*****************************************************/
Plume_HPGL( 'U' ); return;
/* Trace un polygone (ferme si rempli) en format HPGL
* coord = tableau des coord des sommets
* nb = nombre de coord ( 1 coord = 2 elements: X et Y du tableau )
* fill : si != 0 polygone rempli
*/
{
wxASSERT(output_file);
if( nb <= 1 )
return;
move_to( wxPoint( coord[0], coord[1] ) );
for(int ii = 1; ii < nb; ii++ )
line_to( wxPoint( coord[ii * 2], coord[(ii * 2) + 1] ) );
/* Fermeture eventuelle du polygone */
if( fill )
{
int ii = (nb - 1) * 2;
if( (coord[ii] != coord[0] ) || (coord[ii + 1] != coord[1]) )
line_to( wxPoint( coord[0], coord[1] ) );
}
pen_finish();
}
/***************************/
void HPGL_Plotter::pen_control( int plume )
/***************************/
/************************************************************/
void PlotCircleHPGL( wxPoint centre, int diameter, bool fill, int width )
/************************************************************/
/* leve (plume = 'U') ou baisse (plume = 'D') la plume
*/
{
int rayon;
char Line[256];
wxASSERT(output_file);
switch (plume) {
case 'U':
if( pen_state != 'U' )
{
fputs( "PU;", output_file );
pen_state = 'U';
}
break;
case 'D':
if( pen_state != 'D' )
{
fputs( "PD;", output_file );
pen_state = 'D';
}
break;
case 'Z':
fputs( "PU;", output_file );
pen_state = 'U';
pen_lastpos.x = -1;
pen_lastpos.y = -1;
break;
}
}
UserToDeviceCoordinate( centre );
rayon = (int) (diameter / 2 * g_Plot_XScale);
/**********************************************/
void HPGL_Plotter::pen_to( wxPoint pos, char plume )
/**********************************************/
if( rayon < 0 )
rayon = 0;
/*
* deplace la plume levee (plume = 'U') ou baissee (plume = 'D')
* en position x,y
* Unites en Unites DESSIN
* Si plume = 'Z' lever de plume sans deplacement
*/
{
wxASSERT(output_file);
if( plume == 'Z' )
{
pen_control( 'Z' );
return;
}
pen_control( plume );
user_to_device_coordinates( pos );
Plume_HPGL( 'U' );
sprintf( Line, "PA %d,%d;CI %d,%d;\n", centre.x, centre.y, rayon, CHORD_ANGLE );
fputs( Line, g_Plot_PlotOutputFile );
if (pen_lastpos != pos)
fprintf( output_file, "PA %d,%d;\n", pos.x, pos.y );
pen_lastpos = pos;
}
Plume_HPGL( 'U' ); return;
void HPGL_Plotter::set_dash( bool dashed )
{
wxASSERT(output_file);
if (dashed)
fputs("LI 2;\n", stderr);
else
fputs("LI;\n", stderr);
}
void HPGL_Plotter::thick_segment( wxPoint start, wxPoint end, int width,
GRTraceMode tracemode)
/** Function Plot a filled segment (track)
* @param start = starting point
* @param end = ending point
* @param aWidth = segment width (thickness)
* @param aPlotMode = FILLED, SKETCH ..
*/
{
wxASSERT(output_file);
wxPoint center;
wxSize size;
if( (pen_diameter >= width) || (tracemode == FILAIRE) ) /* just a line is Ok */
{
move_to( start );
finish_to( end );
}
else
segment_as_oval(start, end, width, tracemode);
}
/********************************************************************/
void PlotArcHPGL( wxPoint centre, int StAngle, int EndAngle, int rayon, bool fill, int width )
void HPGL_Plotter::arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
FILL_T fill, int width )
/********************************************************************/
/* trace d'un arc de cercle:
......@@ -112,7 +205,7 @@ void PlotArcHPGL( wxPoint centre, int StAngle, int EndAngle, int rayon, bool fil
* ou PU;PA x,y;PD;AA start_arc_X, start_arc_Y, angle; PU;
*/
{
char Line[256];
wxASSERT(output_file);
wxPoint cmap; /* point de depart */
wxPoint cpos; /* centre */
float angle; /* angle de l'arc*/
......@@ -120,105 +213,320 @@ void PlotArcHPGL( wxPoint centre, int StAngle, int EndAngle, int rayon, bool fil
if( rayon <= 0 )
return;
cpos = centre; UserToDeviceCoordinate( cpos );
cpos = centre;
user_to_device_coordinates( cpos );
if( g_Plot_PlotOrientOptions == PLOT_MIROIR )
{
EndAngle = -EndAngle;
StAngle = -StAngle;
EXCHG( StAngle, EndAngle );
}
if( plot_orient_options == PLOT_MIROIR )
angle = (StAngle - EndAngle) / 10.0;
else
angle = (EndAngle - StAngle) / 10.0;
/* Calcul des coord du point de depart : */
cmap.x = (int) ( centre.x + ( rayon * cos( StAngle * M_PI / 1800 ) ) );
cmap.y = (int) ( centre.y + ( rayon * sin( StAngle * M_PI / 1800 ) ) );
UserToDeviceCoordinate( cmap );
Plume_HPGL( 'U' );
sprintf( Line, "PU;PA %d,%d;PD;AA %d,%d, ", cmap.x, cmap.y, cpos.x, cpos.y );
fputs( Line, g_Plot_PlotOutputFile );
sprintf( Line, "%f", -angle ); to_point( Line ); // Transforme , et . du separateur
fputs( Line, g_Plot_PlotOutputFile );
sprintf( Line, ", %d", CHORD_ANGLE ); fputs( Line, g_Plot_PlotOutputFile );
sprintf( Line, ";PU;\n" ); fputs( Line, g_Plot_PlotOutputFile );
Plume_HPGL( 'U' );
cmap.y = (int) ( centre.y - ( rayon * sin( StAngle * M_PI / 1800 ) ) );
user_to_device_coordinates( cmap );
fprintf( output_file, "PU;PA %d,%d;PD;AA %d,%d, ", cmap.x, cmap.y, cpos.x, cpos.y );
fprintf( output_file, "%f", angle );
fprintf( output_file, ";PU;\n" );
pen_finish();
}
/***********************************************************************************/
void HPGL_Plotter::flash_pad_oval( wxPoint pos, wxSize size, int orient,
GRTraceMode trace_mode )
/************************************************************************************/
/* Trace 1 pastille PAD_OVAL en position pos_X,Y , de dim size.x, size.y */
{
wxASSERT(output_file);
int rayon, deltaxy, cx, cy;
/*****************************************************/
void PlotPolyHPGL( int nb, int* coord, bool fill, int width )
/*****************************************************/
/* la pastille est ramenee a une pastille ovale avec size.y > size.x
* ( ovale vertical en orientation 0 ) */
if( size.x > size.y )
{
EXCHG( size.x, size.y ); orient += 900;
if( orient >= 3600 )
orient -= 3600;
}
deltaxy = size.y - size.x; /* = distance entre centres de l'ovale */
rayon = size.x / 2;
if( trace_mode == FILLED )
{
flash_pad_rect( pos, wxSize( size.x, deltaxy+pen_diameter ),
orient, trace_mode );
cx = 0; cy = deltaxy / 2;
RotatePoint( &cx, &cy, orient );
flash_pad_circle( wxPoint( cx + pos.x, cy + pos.y ), size.x, trace_mode );
cx = 0; cy = -deltaxy / 2;
RotatePoint( &cx, &cy, orient );
flash_pad_circle( wxPoint( cx + pos.x, cy + pos.y ), size.x, trace_mode );
}
else /* Trace en mode SKETCH */
{
sketch_oval(pos, size, orient, pen_diameter);
}
}
/* Trace un polygone (ferme si rempli) en format HPGL
* coord = tableau des coord des sommets
* nb = nombre de coord ( 1 coord = 2 elements: X et Y du tableau )
* fill : si != 0 polygone rempli
*/
/*******************************************************************************/
void HPGL_Plotter::flash_pad_circle(wxPoint pos, int diametre,
GRTraceMode trace_mode)
/*******************************************************************************/
/* Trace 1 pastille RONDE (via,pad rond) en position pos */
{
int ii;
wxASSERT(output_file);
int rayon, delta;
if( nb <= 1 )
return;
user_to_device_coordinates( pos );
Move_Plume_HPGL( wxPoint( coord[0], coord[1] ), 'U' );
for( ii = 1; ii < nb; ii++ )
delta = pen_diameter - pen_overlap;
rayon = diametre / 2;
if( trace_mode != FILAIRE )
{
Move_Plume_HPGL( wxPoint( coord[ii * 2], coord[(ii * 2) + 1] ), 'D' );
rayon = (diametre - pen_diameter ) / 2;
}
/* Fermeture eventuelle du polygone */
if( fill )
if( rayon < 0 )
{
ii = (nb - 1) * 2;
if( (coord[ii] != coord[0] ) || (coord[ii + 1] != coord[0]) )
Move_Plume_HPGL( wxPoint( coord[0], coord[1] ), 'D' );
rayon = 0;
}
Plume_HPGL( 'U' );
}
wxSize rsize( rayon, rayon );
user_to_device_size( rsize );
/**********************************************/
void Move_Plume_HPGL( wxPoint pos, int plume )
/**********************************************/
fprintf( output_file, "PA %d,%d;CI %d;\n", pos.x, pos.y, rsize.x );
if( trace_mode == FILLED ) /* Trace en mode Remplissage */
{
if( delta > 0 )
{
while( (rayon -= delta ) >= 0 )
{
rsize.x = rsize.y = rayon;
user_to_device_size( rsize );
fprintf( output_file, "PA %d,%d; CI %d;\n", pos.x, pos.y, rsize.x );
}
}
}
pen_finish();
return;
}
/**************************************************************************/
void HPGL_Plotter::flash_pad_rect(wxPoint pos, wxSize padsize,
int orient, GRTraceMode trace_mode)
/**************************************************************************/
/*
* deplace la plume levee (plume = 'U') ou baissee (plume = 'D')
* en position x,y
* Unites en Unites DESSIN
* Si plume = 'Z' lever de plume sans deplacement
* Trace 1 pad rectangulaire vertical ou horizontal ( Pad rectangulaire )
* donne par son centre et ses dimensions X et Y
* Units are user units
*/
{
char Line[256];
wxASSERT(output_file);
wxSize size;
int delta;
int ox, oy, fx, fy;
if( plume == 'Z' )
size.x = padsize.x / 2; size.y = padsize.y / 2;
if( trace_mode != FILAIRE )
{
Plume_HPGL( 'U' );
size.x = (padsize.x - (int) pen_diameter) / 2;
size.y = (padsize.y - (int) pen_diameter) / 2;
}
if( size.x < 0 )
size.x = 0;
if( size.y < 0 )
size.y = 0;
/* Si une des dimensions est nulle, le trace se reduit a 1 trait */
if( size.x == 0 )
{
ox = pos.x; oy = pos.y - size.y;
RotatePoint( &ox, &oy, pos.x, pos.y, orient );
fx = pos.x; fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
move_to( wxPoint( ox, oy ) );
finish_to( wxPoint( fx, fy ) );
return;
}
if( size.y == 0 )
{
ox = pos.x - size.x; oy = pos.y;
RotatePoint( &ox, &oy, pos.x, pos.y, orient );
fx = pos.x + size.x; fy = pos.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
move_to( wxPoint( ox, oy ) );
finish_to( wxPoint( fx, fy ) );
return;
}
Plume_HPGL( plume );
UserToDeviceCoordinate( pos );
sprintf( Line, "PA %d,%d;\n", pos.x, pos.y ); fputs( Line, g_Plot_PlotOutputFile );
}
ox = pos.x - size.x; oy = pos.y - size.y;
RotatePoint( &ox, &oy, pos.x, pos.y, orient );
move_to( wxPoint( ox, oy ) );
fx = pos.x - size.x; fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
line_to( wxPoint( fx, fy ) );
/***************************/
void Plume_HPGL( int plume )
/***************************/
fx = pos.x + size.x; fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
line_to( wxPoint( fx, fy ) );
/* leve (plume = 'U') ou baisse (plume = 'D') la plume
fx = pos.x + size.x; fy = pos.y - size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
line_to( wxPoint( fx, fy ) );
finish_to( wxPoint( ox, oy ) );
if( trace_mode == FILLED )
{
/* Trace en mode Remplissage */
delta = (int) (pen_diameter - pen_overlap);
if( delta > 0 )
while( (size.x > 0) && (size.y > 0) )
{
size.x -= delta; size.y -= delta;
if( size.x < 0 )
size.x = 0;
if( size.y < 0 )
size.y = 0;
ox = pos.x - size.x; oy = pos.y - size.y;
RotatePoint( &ox, &oy, pos.x, pos.y, orient );
move_to( wxPoint( ox, oy ) );
fx = pos.x - size.x; fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
line_to( wxPoint( fx, fy ) );
fx = pos.x + size.x; fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
line_to( wxPoint( fx, fy ) );
fx = pos.x + size.x; fy = pos.y - size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
line_to( wxPoint( fx, fy ) );
finish_to( wxPoint( ox, oy ) );
}
}
}
/*******************************************************************/
void HPGL_Plotter::flash_pad_trapez( wxPoint pos, wxSize size, wxSize delta,
int orient, GRTraceMode trace_mode )
/*******************************************************************/
/*
* Trace 1 pad trapezoidal donne par :
* son centre pos.x,pos.y
* ses dimensions dimX et dimY
* les variations deltaX et deltaY
* son orientation orient et 0.1 degres
* le mode de trace (FILLED, SKETCH, FILAIRE)
* Le trace n'est fait que pour un trapeze, c.a.d que deltaX ou deltaY
* = 0.
*
* les notation des sommets sont ( vis a vis de la table tracante )
* 0 ------------- 3
* . .
* . .
* . .
* 1 --- 2
*/
{
if( plume == 'U' )
wxASSERT(output_file);
wxPoint polygone[4]; /* coord des sommets / centre du pad */
wxPoint coord[4]; /* coord reelles des sommets du trapeze a tracer */
int moveX, moveY; /* variation de position plume selon axe X et Y , lors
* du remplissage du trapeze */
moveX = moveY = pen_diameter;
size.x /= 2; size.y /= 2;
delta.x /= 2; delta.y /= 2;
polygone[0].x = -size.x - delta.y; polygone[0].y = +size.y + delta.x;
polygone[1].x = -size.x + delta.y; polygone[1].y = -size.y - delta.x;
polygone[2].x = +size.x - delta.y; polygone[2].y = -size.y + delta.x;
polygone[3].x = +size.x + delta.y; polygone[3].y = +size.y - delta.x;
/* Trace du contour */
polygone[0].x += moveX; polygone[0].y -= moveY;
polygone[1].x += moveX; polygone[1].y += moveY;
polygone[2].x -= moveX; polygone[2].y += moveY;
polygone[3].x -= moveX; polygone[3].y -= moveY;
for(int ii = 0; ii < 4; ii++ )
{
if( g_Plot_PenState != 'U' )
fputs( "PU;", g_Plot_PlotOutputFile );
g_Plot_PenState = 'U';
coord[ii].x = polygone[ii].x + pos.x;
coord[ii].y = polygone[ii].y + pos.y;
RotatePoint( &coord[ii], pos, orient );
}
// Plot edge:
move_to( coord[0] );
line_to( coord[1] );
line_to( coord[2] );
line_to( coord[3] );
finish_to( coord[0] );
if( trace_mode == FILLED )
{
int jj;
/* Fill the shape */
moveX = moveY = pen_diameter - pen_overlap;
/* calcul de jj = hauteur du remplissage */
if( delta.y ) /* Trapeze horizontal */
{
jj = size.y - (int) ( pen_diameter + (2 * pen_overlap) );
}
else
{
if( g_Plot_PenState != 'D' )
fputs( "PD;", g_Plot_PlotOutputFile );
g_Plot_PenState = 'D';
jj = size.x - (int) ( pen_diameter + (2 * pen_overlap) );
}
/* Calcul de jj = nombre de segments a tracer pour le remplissage */
jj = jj / (int) (pen_diameter - pen_overlap);
/* Trace du contour */
for( ; jj > 0; jj-- )
{
polygone[0].x += moveX; polygone[0].y -= moveY;
polygone[1].x += moveX; polygone[1].y += moveY;
polygone[2].x -= moveX; polygone[2].y += moveY;
polygone[3].x -= moveX; polygone[3].y -= moveY;
/* Test de limitation de variation des dimensions :
* si les sommets se "croisent", il ne faut plus modifier les
* coordonnees correspondantes */
if( polygone[0].x > polygone[3].x )
{ /* croisement sur axe X des 2 sommets 0 et 3 */
polygone[0].x = polygone[3].x = 0;
}
if( polygone[1].x > polygone[2].x )
{ /* croisement sur axe X des 2 sommets 1 et 2 */
polygone[1].x = polygone[2].x = 0;
}
if( polygone[1].y > polygone[0].y )
{ /* croisement sur axe Y des 2 sommets 0 et 1 */
polygone[0].y = polygone[1].y = 0;
}
if( polygone[2].y > polygone[3].y )
{ /* croisement sur axe Y des 2 sommets 2 et 3 */
polygone[2].y = polygone[3].y = 0;
}
for(int ii = 0; ii < 4; ii++ )
{
coord[ii].x = polygone[ii].x + pos.x;
coord[ii].y = polygone[ii].y + pos.y;
RotatePoint( &coord[ii], pos, orient );
}
move_to( coord[0] );
line_to( coord[1] );
line_to( coord[2] );
line_to( coord[3] );
finish_to( coord[0] );
}
}
}
......@@ -11,65 +11,57 @@
#include "macros.h"
#include "kicad_string.h"
// Locales
static Ki_PageDescr* SheetPS;
/*************************************************************************************/
void InitPlotParametresPS( wxPoint offset, Ki_PageDescr* sheet,
double aXScale, double aYScale, int orient )
void PS_Plotter::set_viewport( wxPoint offset,
double aScale, int orient )
/*************************************************************************************/
/* Set the plot offset for the current plotting
* g_Plot_XScale,g_Plot_YScale = coordinate scale (scale coefficient for coordinates)
* device_g_Plot_XScale,device_g_Plot_YScale = device coordinate scale (i.e scale used by plot device)
*/
/* Set the plot offset for the current plotting */
{
g_Plot_PlotOrientOptions = orient;
g_Plot_PlotOffset = offset;
SheetPS = sheet;
g_Plot_XScale = aXScale;
g_Plot_YScale = aYScale;
g_Plot_CurrentPenWidth = -1;
g_Plot_PenState = 'Z';
wxASSERT(!output_file);
plot_orient_options = orient;
plot_offset = offset;
plot_scale = aScale;
device_scale = 1; /* PS references in decimils */
set_default_line_width(100); /* epaisseur du trait standard en 1/1000 pouce */
}
/*************************************************************************************/
void SetDefaultLineWidthPS( int width )
void PS_Plotter::set_default_line_width( int width )
/*************************************************************************************/
/* Set the default line width (in 1/1000 inch) for the current plotting
*/
{
g_Plot_DefaultPenWidth = width; // epaisseur du trait standard en 1/1000 pouce
g_Plot_CurrentPenWidth = -1;
default_pen_width = width; // epaisseur du trait standard en 1/1000 pouce
current_pen_width = -1;
}
/***************************************/
void SetCurrentLineWidthPS( int width )
void PS_Plotter::set_current_line_width( int width )
/***************************************/
/* Set the Current line width (in 1/1000 inch) for the next plot
*/
{
wxASSERT(output_file);
int pen_width;
if( width > 0 )
if( width >= 0 )
pen_width = width;
else
pen_width = g_Plot_DefaultPenWidth;
pen_width = default_pen_width;
if( pen_width != g_Plot_CurrentPenWidth )
fprintf( g_Plot_PlotOutputFile, "%d setlinewidth\n", (int) (g_Plot_XScale * pen_width) );
if( pen_width != current_pen_width )
fprintf( output_file, "%g setlinewidth\n",
user_to_device_size(pen_width));
g_Plot_CurrentPenWidth = pen_width;
current_pen_width = pen_width;
}
/******************************/
void SetColorMapPS( int color )
void PS_Plotter::set_color( int color )
/******************************/
/* Print the postscript set color command:
......@@ -79,97 +71,92 @@ void SetColorMapPS( int color )
* color = color index in ColorRefs[]
*/
{
char Line[1024];
sprintf( Line, "%.3f %.3f %.3f setrgbcolor\n",
(float) ColorRefs[color].m_Red / 255,
(float) ColorRefs[color].m_Green / 255,
(float) ColorRefs[color].m_Blue / 255 );
to_point( Line );
fputs( Line, g_Plot_PlotOutputFile );
wxASSERT(output_file);
if ((color >= 0 && color_mode)
|| (color == BLACK)
|| (color == WHITE))
{
if (negative_mode)
fprintf( output_file, "%.3g %.3g %.3g setrgbcolor\n",
(double) 1.0-ColorRefs[color].m_Red / 255,
(double) 1.0-ColorRefs[color].m_Green / 255,
(double) 1.0-ColorRefs[color].m_Blue / 255 );
else
fprintf( output_file, "%.3g %.3g %.3g setrgbcolor\n",
(double) ColorRefs[color].m_Red / 255,
(double) ColorRefs[color].m_Green / 255,
(double) ColorRefs[color].m_Blue / 255 );
}
}
/***************************************************************/
void PlotFilledSegmentPS( wxPoint start, wxPoint end, int width )
/***************************************************************/
/* Plot 1 segment like a track segment
*/
void PS_Plotter::set_dash( bool dashed )
{
UserToDeviceCoordinate( start );
UserToDeviceCoordinate( end );
SetCurrentLineWidthPS( width );
fprintf( g_Plot_PlotOutputFile, "%d %d %d %d line\n", start.x, start.y, end.x, end.y );
wxASSERT(output_file);
if (dashed)
fputs("dashedline\n", stderr);
else
fputs("solidline\n", stderr);
}
/***************************************************************/
void PlotRectPS( wxPoint p1, wxPoint p2, bool fill, int width )
void PS_Plotter::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width )
/***************************************************************/
{
UserToDeviceCoordinate( p1 );
UserToDeviceCoordinate( p2 );
user_to_device_coordinates( p1 );
user_to_device_coordinates( p2 );
SetCurrentLineWidthPS( width );
fprintf( g_Plot_PlotOutputFile, "%d %d %d %d rect%d\n", p1.x, p1.y,
set_current_line_width( width );
fprintf( output_file, "%d %d %d %d rect%d\n", p1.x, p1.y,
p2.x-p1.x, p2.y-p1.y, fill );
}
/******************************************************/
void PlotCirclePS( wxPoint pos, int diametre, bool fill, int width )
void PS_Plotter::circle( wxPoint pos, int diametre, FILL_T fill, int width )
/******************************************************/
{
int rayon;
char Line[256];
wxASSERT(output_file);
user_to_device_coordinates( pos );
double rayon = user_to_device_size(diametre / 2.0);
UserToDeviceCoordinate( pos );
rayon = (int) (g_Plot_XScale * diametre / 2);
if( rayon < 1 )
rayon = 1;
if( rayon < 0 )
rayon = 0;
SetCurrentLineWidthPS( width );
sprintf(Line, "%d %d %d cir%d\n", pos.x, pos.y, rayon, fill);
fputs( Line, g_Plot_PlotOutputFile );
set_current_line_width( width );
fprintf(output_file, "%d %d %g cir%d\n", pos.x, pos.y, rayon, fill);
}
/**************************************************************************************/
void PlotArcPS( wxPoint centre, int StAngle, int EndAngle, int rayon, bool fill, int width )
void PS_Plotter::arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
FILL_T fill, int width )
/**************************************************************************************/
/* Plot an arc:
* StAngle, EndAngle = start and end arc in 0.1 degree
*/
{
char Line[256];
wxASSERT(output_file);
if( rayon <= 0 )
return;
SetCurrentLineWidthPS( width );
set_current_line_width( width );
// Calcul des coord du point de depart :
UserToDeviceCoordinate( centre );
if( g_Plot_PlotOrientOptions == PLOT_MIROIR )
sprintf( Line, "%d %d %d %f %f arc%d\n", centre.x, centre.y,
(int) (rayon * g_Plot_XScale), (float) StAngle / 10, (float) EndAngle / 10,
user_to_device_coordinates( centre );
rayon = user_to_device_size(rayon);
if( plot_orient_options == PLOT_MIROIR )
fprintf( output_file, "%d %d %d %g %g arc%d\n", centre.x, centre.y,
rayon, (double) -EndAngle / 10, (double) -StAngle / 10,
fill);
else
sprintf( Line, "%d %d %d %f %f arc%d\n", centre.x, centre.y,
(int) (rayon * g_Plot_XScale), -(float) EndAngle / 10, -(float) StAngle / 10,
fprintf( output_file, "%d %d %d %g %g arc%d\n", centre.x, centre.y,
rayon, (double) StAngle / 10, (double) EndAngle / 10,
fill);
// Undo internationalization printf (float x.y printed x,y)
to_point( Line );
fputs( Line, g_Plot_PlotOutputFile );
}
/*****************************************************************/
void PlotPolyPS( int nb_segm, int* coord, bool fill, int width )
void PS_Plotter::poly( int nb_segm, int* coord, FILL_T fill, int width )
/*****************************************************************/
/* Draw a polygon ( a filled polygon if fill == 1 ) in POSTSCRIPT format
......@@ -179,62 +166,63 @@ void PlotPolyPS( int nb_segm, int* coord, bool fill, int width )
* @param width = line width
*/
{
int ii;
wxASSERT(output_file);
wxPoint pos;
if( nb_segm <= 1 )
return;
SetCurrentLineWidthPS( width );
set_current_line_width( width );
pos.x = coord[0];
pos.y = coord[1];
UserToDeviceCoordinate( pos );
fprintf( g_Plot_PlotOutputFile, "newpath %d %d moveto\n", pos.x, pos.y );
user_to_device_coordinates( pos );
fprintf( output_file, "newpath\n%d %d moveto\n", pos.x, pos.y );
for( ii = 1; ii < nb_segm; ii++ )
for(int ii = 1; ii < nb_segm; ii++ )
{
pos.x = coord[2 * ii];
pos.y = coord[2 * ii + 1];
UserToDeviceCoordinate( pos );
fprintf( g_Plot_PlotOutputFile, "%d %d lineto\n", pos.x, pos.y );
user_to_device_coordinates( pos );
fprintf( output_file, "%d %d lineto\n", pos.x, pos.y );
}
// Fermeture du polygone
fprintf(g_Plot_PlotOutputFile, "poly%d\n", fill);
fprintf(output_file, "poly%d\n", fill);
}
/*************************************/
void LineTo_PS( wxPoint pos, int plume )
void PS_Plotter::pen_to( wxPoint pos, char plume )
/*************************************/
/* Routine to draw to a new position
*/
{
char Line[256];
wxASSERT(output_file);
if( plume == 'Z' ) {
if (g_Plot_PenState != 'Z') {
fputs( "stroke\n", g_Plot_PlotOutputFile );
g_Plot_PenState = 'Z';
if (pen_state != 'Z') {
fputs( "stroke\n", output_file );
pen_state = 'Z';
pen_lastpos.x = -1;
pen_lastpos.y = -1;
}
return;
}
UserToDeviceCoordinate( pos );
if (g_Plot_PenState == 'Z') {
fputs( "newpath\n", g_Plot_PlotOutputFile );
user_to_device_coordinates( pos );
if (pen_state == 'Z') {
fputs( "newpath\n", output_file );
}
sprintf( Line, "%d %d %sto\n", pos.x, pos.y, (plume=='D')?"line":"move" );
fputs( Line, g_Plot_PlotOutputFile );
g_Plot_PenState = plume;
if (pen_state != plume || pos != pen_lastpos)
fprintf( output_file, "%d %d %sto\n", pos.x, pos.y, (plume=='D')?"line":"move" );
pen_state = plume;
pen_lastpos = pos;
}
/***********************************************************/
void PrintHeaderPS( FILE* file, const wxString& Creator,
const wxString& FileName, int PageCount,
int BBox[4], int PaperOrientation )
void PS_Plotter::start_plot( FILE *fout)
/***********************************************************/
/* The code within this function (and the CloseFilePS function)
......@@ -246,18 +234,14 @@ void PrintHeaderPS( FILE* file, const wxString& Creator,
* http://partners.adobe.com/public/developer/en/ps/5001.DSC_Spec.pdf
*
*
* The PageCount and PaperOrientation parameters have been provided to
* respectively cater for the production of multiple-page postscript
* files, and postscript files having either a portrait orientation
* or a landscape orientation.
*
* BBox is the boundary box (position and size of the "client rectangle"
* for drawings (page - margins) in mils (0.001 inch)
*/
{
wxASSERT(!output_file);
wxString msg;
char Line[1024];
output_file = fout;
static const char* PSMacro[] = {
"/line {\n",
" newpath\n",
......@@ -279,48 +263,37 @@ void PrintHeaderPS( FILE* file, const wxString& Creator,
"/rect2 { rectfill } bind def\n",
"/linemode0 { 0 setlinecap 0 setlinejoin 0 setlinewidth } bind def\n",
"/linemode1 { 1 setlinecap 1 setlinejoin } bind def\n",
"/dashedline { [50 50] 0 setdash } bind def\n",
"/solidline { [] 0 setdash } bind def\n",
"gsave\n",
"72 72 scale\t\t\t% Talk inches\n",
"0.0072 0.0072 scale\n", // Configure postscript for decimils
"linemode1\n",
NULL
};
const double MIL_TO_INCH = 0.001;
int ii;
const double DECIMIL_TO_INCH = 0.0001;
time_t time1970 = time( NULL );
g_Plot_PlotOutputFile = file;
fputs( "%!PS-Adobe-3.0\n", g_Plot_PlotOutputFile ); // Print header
fputs( "%!PS-Adobe-3.0\n", output_file ); // Print header
sprintf( Line, "%%%%Creator: %s\n", CONV_TO_UTF8( Creator ) );
fputs( Line, g_Plot_PlotOutputFile );
fprintf( output_file, "%%%%Creator: %s\n", CONV_TO_UTF8( creator ) );
// A "newline" character ("\n") is not included in the following string,
// because it is provided by the ctime() function.
sprintf( Line, "%%%%CreationDate: %s", ctime( &time1970 ) );
fputs( Line, g_Plot_PlotOutputFile );
sprintf( Line, "%%%%Title: %s\n", CONV_TO_UTF8( FileName ) );
fputs( Line, g_Plot_PlotOutputFile );
sprintf( Line, "%%%%Pages: %d\n", PageCount );
fputs( Line, g_Plot_PlotOutputFile );
sprintf( Line, "%%%%PageOrder: Ascend\n" );
fputs( Line, g_Plot_PlotOutputFile );
fprintf( output_file, "%%%%CreationDate: %s", ctime( &time1970 ) );
fprintf( output_file, "%%%%Title: %s\n", CONV_TO_UTF8( filename ) );
fprintf( output_file, "%%%%Pages: 1\n");
fprintf( output_file, "%%%%PageOrder: Ascend\n" );
// Print boundary box en 1/72 pouce, box is in mils
const double CONV_SCALE = MIL_TO_INCH * 72;
// Print boundary box en 1/72 pouce, box is in decimils
const double CONV_SCALE = DECIMIL_TO_INCH * 72;
// The coordinates of the lower left corner of the boundary
// box need to be "rounded down", but the coordinates of its
// upper right corner need to be "rounded up" instead.
sprintf( Line, "%%%%BoundingBox: %d %d %d %d\n",
(int) floor( (BBox[1] * CONV_SCALE) ), (int) floor( (BBox[0] * CONV_SCALE) ),
(int) ceil( (BBox[3] * CONV_SCALE) ), (int) ceil( (BBox[2] * CONV_SCALE) ) );
fputs( Line, g_Plot_PlotOutputFile );
fprintf( output_file, "%%%%BoundingBox: 0 0 %d %d\n",
(int) ceil( paper_size.y * CONV_SCALE),
(int) ceil( paper_size.x * CONV_SCALE));
// Specify the size of the sheet and the name associated with that size.
// (If the "User size" option has been selected for the sheet size,
......@@ -334,27 +307,20 @@ void PrintHeaderPS( FILE* file, const wxString& Creator,
//
// (NOTE: m_Size.y is *supposed* to be listed before m_Size.x;
// the order in which they are specified is not wrong!)
if( SheetPS->m_Name.Cmp( wxT( "User" ) ) == 0 )
sprintf( Line, "%%%%DocumentMedia: Custom %d %d 0 () ()\n",
wxRound( SheetPS->m_Size.y * CONV_SCALE ),
wxRound( SheetPS->m_Size.x * CONV_SCALE ) );
else // ( if SheetPS->m_Name does not equal "User" )
sprintf( Line, "%%%%DocumentMedia: %s %d %d 0 () ()\n",
CONV_TO_UTF8( SheetPS->m_Name ),
wxRound( SheetPS->m_Size.y * CONV_SCALE ),
wxRound( SheetPS->m_Size.x * CONV_SCALE ) );
fputs( Line, g_Plot_PlotOutputFile );
if( PaperOrientation == wxPORTRAIT )
sprintf( Line, "%%%%Orientation: Portrait\n" );
else
sprintf( Line, "%%%%Orientation: Landscape\n" );
if( sheet->m_Name.Cmp( wxT( "User" ) ) == 0 )
fprintf( output_file, "%%%%DocumentMedia: Custom %d %d 0 () ()\n",
wxRound( sheet->m_Size.y * CONV_SCALE ),
wxRound( sheet->m_Size.x * CONV_SCALE ) );
fputs( Line, g_Plot_PlotOutputFile );
else // ( if sheet->m_Name does not equal "User" )
fprintf( output_file, "%%%%DocumentMedia: %s %d %d 0 () ()\n",
CONV_TO_UTF8( sheet->m_Name ),
wxRound( sheet->m_Size.y * CONV_SCALE ),
wxRound( sheet->m_Size.x * CONV_SCALE ) );
sprintf( Line, "%%%%EndComments\n" );
fputs( Line, g_Plot_PlotOutputFile );
fprintf( output_file, "%%%%Orientation: Landscape\n" );
fprintf( output_file, "%%%%EndComments\n" );
// Now specify various other details.
......@@ -362,46 +328,208 @@ void PrintHeaderPS( FILE* file, const wxString& Creator,
// PSMacro[]) to highlight that it has been provided to ensure that the
// contents of the postscript file comply with the details specified
// within the Document Structuring Convention.
sprintf( Line, "%%%%Page: 1 1\n" );
fputs( Line, g_Plot_PlotOutputFile );
fprintf( output_file, "%%%%Page: 1 1\n" );
for( ii = 0; PSMacro[ii] != NULL; ii++ )
for(int ii = 0; PSMacro[ii] != NULL; ii++ )
{
fputs( PSMacro[ii], g_Plot_PlotOutputFile );
fputs( PSMacro[ii], output_file );
}
if( PaperOrientation == wxLANDSCAPE )
sprintf( Line, "%f %f translate 90 rotate\n",
(float) BBox[3] * MIL_TO_INCH, (float) BBox[0] * MIL_TO_INCH );
// (If support for creating postscript files with a portrait orientation
// is ever provided, determine whether it would be necessary to provide
// an "else" command and then an appropriate "sprintf" command here.)
fprintf( output_file, "%d 0 translate 90 rotate\n", paper_size.y);
// compensation internationalisation printf (float x.y gnr x,y)
to_point( Line );
fputs( Line, g_Plot_PlotOutputFile );
sprintf( Line, "%f %f scale\t\t%% Move to User coordinates\n",
g_Plot_XScale, g_Plot_YScale );
to_point( Line );
fputs( Line, g_Plot_PlotOutputFile );
// Apply the scale adjustments
if (plot_scale_adjX != 1.0 || plot_scale_adjY != 1.0)
fprintf( output_file, "%g %g scale\n",
plot_scale_adjX, plot_scale_adjY);
// Set default line width ( g_Plot_DefaultPenWidth is in user units )
fprintf( g_Plot_PlotOutputFile, "%d setlinewidth\n", g_Plot_DefaultPenWidth );
fprintf( output_file, "%g setlinewidth\n",
user_to_device_size(default_pen_width) );
}
/******************************************/
bool CloseFilePS( FILE* plot_file )
void PS_Plotter::end_plot()
/******************************************/
{
fputs( "showpage\n", plot_file );
fputs( "grestore\n", plot_file );
fputs( "%%EOF\n", plot_file );
wxASSERT(output_file);
fputs( "showpage\ngrestore\n%%EOF\n", output_file );
fclose( output_file );
output_file = 0;
}
/***********************************************************************************/
void PS_Plotter::flash_pad_oval( wxPoint pos, wxSize size, int orient,
GRTraceMode modetrace )
/************************************************************************************/
/* Trace 1 pastille PAD_OVAL en position pos_X,Y:
* dimensions dx,dy,
* orientation orient
* La forme est tracee comme un segment
*/
{
wxASSERT(output_file);
int x0, y0, x1, y1, delta;
fclose( plot_file );
// la pastille est ramenee a une pastille ovale avec dy > dx
if( size.x > size.y )
{
EXCHG( size.x, size.y );
orient += 900;
if( orient >= 3600 )
orient -= 3600;
}
delta = size.y - size.x ;
x0 = 0;
y0 = -delta / 2;
x1 = 0;
y1 = delta / 2;
RotatePoint( &x0, &y0, orient );
RotatePoint( &x1, &y1, orient );
if( modetrace == FILLED )
thick_segment( wxPoint( pos.x + x0, pos.y + y0 ),
wxPoint( pos.x + x1, pos.y + y1 ), size.x, modetrace );
else
sketch_oval(pos, size, orient, -1);
}
/*******************************************************************************/
void PS_Plotter::flash_pad_circle(wxPoint pos, int diametre,
GRTraceMode modetrace)
/*******************************************************************************/
/* Trace 1 pastille RONDE (via,pad rond) en position pos_X,Y
*/
{
wxASSERT(output_file);
if( modetrace == FILLED )
{
set_current_line_width( 0 );
circle(pos, diametre, FILLED_SHAPE);
}
else
{
set_current_line_width(-1);
int w = current_pen_width;
circle(pos, diametre-2*w, NO_FILL);
}
}
/**************************************************************************/
void PS_Plotter::flash_pad_rect(wxPoint pos, wxSize size,
int orient, GRTraceMode trace_mode)
/**************************************************************************/
/*
* Trace 1 pad rectangulaire d'orientation quelconque
* donne par son centre, ses dimensions,
* et son orientation orient
*/
{
wxASSERT(output_file);
set_current_line_width(-1);
int w = current_pen_width;
size.x -= w;
if( size.x < 1 )
size.x = 1;
size.y -= w;
if( size.y < 1 )
size.y = 1;
int dx = size.x / 2;
int dy = size.y / 2;
int coord[10] = {
pos.x - dx, pos.y + dy,
pos.x - dx, pos.y - dy,
pos.x + dx, pos.y - dy,
pos.x + dx, pos.y + dy,
0, 0
};
return TRUE;
for(int ii = 0; ii < 4; ii++ )
{
RotatePoint( &coord[ii*2], &coord[ii*2+1], pos.x, pos.y, orient );
}
coord[8] = coord[0];
coord[9] = coord[1];
poly(5, coord, trace_mode==FILLED?FILLED_SHAPE:NO_FILL);
}
/*******************************************************************/
void PS_Plotter::flash_pad_trapez( wxPoint centre, wxSize size, wxSize delta,
int orient, GRTraceMode modetrace )
/*******************************************************************/
/*
* Trace 1 pad trapezoidal donne par :
* son centre centre
* ses dimensions size
* les variations delta ( 1 des deux au moins doit etre nulle)
* son orientation orient en 0.1 degres
* le mode de trace (FILLED, SKETCH, FILAIRE)
*
* Le trace n'est fait que pour un trapeze, c.a.d que deltaX ou deltaY
* = 0.
*
* les notation des sommets sont ( vis a vis de la table tracante )
*
* " 0 ------------- 3 "
* " . . "
* " . O . "
* " . . "
* " 1 ---- 2 "
*
*
* exemple de Disposition pour deltaY > 0, deltaX = 0
* " 1 ---- 2 "
* " . . "
* " . O . "
* " . . "
* " 0 ------------- 3 "
*
*
* exemple de Disposition pour deltaY = 0, deltaX > 0
* " 0 "
* " . . "
* " . . "
* " . 3 "
* " . . "
* " . O . "
* " . . "
* " . 2 "
* " . . "
* " . . "
* " 1 "
*/
{
wxASSERT(output_file);
set_current_line_width(-1);
int w = current_pen_width;
int dx, dy;
int ddx, ddy;
dx = (size.x-w) / 2;
dy = (size.y-w) / 2;
ddx = delta.x / 2;
ddy = delta.y / 2;
int coord[10] = {
-dx - ddy, +dy + ddx,
-dx + ddy, -dy - ddx,
+dx - ddy, -dy + ddx,
+dx + ddy, +dy - ddx,
0, 0
};
for(int ii = 0; ii < 4; ii++ )
{
RotatePoint( &coord[ii*2], &coord[ii*2+1], orient );
coord[ii*2] += centre.x;
coord[ii*2+1] += centre.y;
}
poly(5, coord, modetrace==FILLED?FILLED_SHAPE:NO_FILL);
}
......@@ -14,52 +14,8 @@
#include "class_base_screen.h"
#include "drawtxt.h"
// Variables partagees avec Common plot Postscript et HPLG Routines
wxPoint g_Plot_PlotOffset;
FILE* g_Plot_PlotOutputFile;
double g_Plot_XScale, g_Plot_YScale;
int g_Plot_DefaultPenWidth;
int g_Plot_CurrentPenWidth = -1;
int g_Plot_PlotOrientOptions, g_Plot_PenState;
/*************************/
void ForcePenReinit()
/*************************/
/* set the flag g_Plot_CurrentPenWidth to -1 in order to force a pen width redefinition
* for the next draw command
*/
{
g_Plot_CurrentPenWidth = -1;
}
/**********************************************/
void SetPlotScale( double aXScale, double aYScale )
/**********************************************/
/* Set the plot scale for the current plotting)
*/
{
g_Plot_XScale = aXScale;
g_Plot_YScale = aYScale;
}
/*********************************/
void Setg_Plot_PlotOffset( wxPoint offset )
/*********************************/
/* Set the plot offset for the current plotting)
*/
{
g_Plot_PlotOffset = offset;
}
/**************************************************************************/
void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
void WinEDA_DrawFrame::PlotWorkSheet( Plotter *plotter, BASE_SCREEN* screen )
/**************************************************************************/
/* Plot sheet references
......@@ -68,40 +24,21 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
{
#define WSTEXTSIZE 50 // Text size in mils
Ki_PageDescr* Sheet = screen->m_CurrentSheetDesc;
int ii, jj, xg, yg, ipas, gxpas, gypas;
int xg, yg, ipas, gxpas, gypas;
wxSize PageSize;
wxPoint pos, ref;
EDA_Colors color;
Ki_WorkSheetData* WsItem;
int conv_unit = screen->GetInternalUnits() / 1000; /* Scale to convert dimension in 1/1000 in into internal units
* (1/1000 inc for EESchema, 1/10000 for pcbnew */
wxString msg;
wxSize text_size;
void (*FctPlume)( wxPoint pos, int state );
int UpperLimit = VARIABLE_BLOCK_START_POSITION;
bool italic = false;
bool bold = false;
bool thickness = 0; //@todo : use current pen
switch( format_plot )
{
case PLOT_FORMAT_POST:
FctPlume = LineTo_PS;
break;
case PLOT_FORMAT_HPGL:
FctPlume = Move_Plume_HPGL;
break;
case PLOT_FORMAT_GERBER:
FctPlume = LineTo_GERBER;
break;
default:
return;
}
color = BLACK;
plotter->set_color(color);
PageSize.x = Sheet->m_Size.x;
PageSize.y = Sheet->m_Size.y;
......@@ -113,31 +50,30 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
yg = (PageSize.y - Sheet->m_BottomMargin) * conv_unit; /* lower right corner */
#if defined(KICAD_GOST)
FctPlume(ref,'U');
plotter->move_to( ref );
pos.x = xg; pos.y = ref.y;
FctPlume(pos,'D');
plotter->line_to( pos );
pos.x = xg; pos.y = yg;
FctPlume(pos,'D');
plotter->line_to( pos );
pos.x = ref.x; pos.y = yg;
FctPlume( pos,'D' );
FctPlume(ref,'D');
FctPlume(ref,'Z');
plotter->line_to( pos );
plotter->finish_to( ref );
#else
for( ii = 0; ii < 2; ii++ )
for( unsigned ii = 0; ii < 2; ii++ )
{
FctPlume( ref, 'U' );
plotter->move_to( ref );
pos.x = xg; pos.y = ref.y;
FctPlume( pos, 'D' );
plotter->line_to( pos );
pos.x = xg; pos.y = yg;
FctPlume( pos, 'D' );
plotter->line_to( pos );
pos.x = ref.x; pos.y = yg;
FctPlume( pos, 'D' );
FctPlume( ref, 'D' );
ref.x += GRID_REF_W * conv_unit; ref.y += GRID_REF_W * conv_unit;
xg -= GRID_REF_W * conv_unit; yg -= GRID_REF_W * conv_unit;
plotter->line_to( pos );
plotter->finish_to( ref );
ref.x += GRID_REF_W * conv_unit;
ref.y += GRID_REF_W * conv_unit;
xg -= GRID_REF_W * conv_unit;
yg -= GRID_REF_W * conv_unit;
}
FctPlume(ref,'Z');
#endif
/* trace des reperes */
......@@ -150,7 +86,9 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
yg = (PageSize.y - Sheet->m_BottomMargin); /* lower right corner in 1/1000 inch */
#if defined(KICAD_GOST)
for ( WsItem = &WS_Segm1_LU; WsItem != NULL; WsItem = WsItem->Pnext )
for ( Ki_WorkSheetData* WsItem = &WS_Segm1_LU;
WsItem != NULL;
WsItem = WsItem->Pnext )
{
pos.x = (ref.x - WsItem->m_Posx) * conv_unit;
pos.y = (yg - WsItem->m_Posy) * conv_unit;
......@@ -161,22 +99,22 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
break;
case WS_PODPIS_LU:
if(WsItem->m_Legende) msg = WsItem->m_Legende;
PlotGraphicText(format_plot, pos, color,
plotter->text( pos, color,
msg, TEXT_ORIENT_VERT, text_size,
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_BOTTOM,
thickness, italic, false );
break;
case WS_SEGMENT_LU:
FctPlume(pos, 'U');
plotter->move_to(pos);
pos.x = (ref.x - WsItem->m_Endx) * conv_unit;
pos.y = (yg - WsItem->m_Endy) * conv_unit;
FctPlume(pos, 'D');
FctPlume(ref,'Z');
plotter->finish_to(pos);
break;
}
}
for ( WsItem = &WS_Segm1_LT; WsItem != NULL; WsItem = WsItem->Pnext )
for ( Ki_WorkSheetData* WsItem = &WS_Segm1_LT;
WsItem != NULL;
WsItem = WsItem->Pnext )
{
pos.x = (ref.x + WsItem->m_Posx) * conv_unit;
pos.y = (ref.y + WsItem->m_Posy) * conv_unit;
......@@ -184,11 +122,10 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
switch( WsItem->m_Type )
{
case WS_SEGMENT_LT:
FctPlume(pos, 'U');
plotter->move_to(pos);
pos.x = (ref.x + WsItem->m_Endx) * conv_unit;
pos.y = (ref.y + WsItem->m_Endy) * conv_unit;
FctPlume(pos, 'D');
FctPlume(ref,'Z');
plotter->finish_to(pos);
break;
}
}
......@@ -197,20 +134,19 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
/* Trace des reperes selon l'axe X */
ipas = (xg - ref.x) / PAS_REF;
gxpas = ( xg - ref.x) / ipas;
for( ii = ref.x + gxpas, jj = 1; ipas > 0; ii += gxpas, jj++, ipas-- )
for(int ii = ref.x + gxpas, jj = 1; ipas > 0; ii += gxpas, jj++, ipas-- )
{
msg.Empty(); msg << jj;
if( ii < xg - PAS_REF / 2 )
{
pos.x = ii * conv_unit; pos.y = ref.y * conv_unit;
FctPlume( pos, 'U' );
plotter->move_to(pos);
pos.x = ii * conv_unit; pos.y = (ref.y + GRID_REF_W) * conv_unit;
FctPlume( pos, 'D' );
FctPlume(ref,'Z');
plotter->finish_to(pos);
}
pos.x = (ii - gxpas / 2) * conv_unit;
pos.y = (ref.y + GRID_REF_W / 2) * conv_unit;
PlotGraphicText( format_plot, pos, color,
plotter->text( pos, color,
msg, TEXT_ORIENT_HORIZ, text_size,
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, false );
......@@ -218,14 +154,13 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
if( ii < xg - PAS_REF / 2 )
{
pos.x = ii * conv_unit; pos.y = yg * conv_unit;
FctPlume( pos, 'U' );
plotter->move_to( pos);
pos.x = ii * conv_unit; pos.y = (yg - GRID_REF_W) * conv_unit;
FctPlume( pos, 'D' );
FctPlume(ref,'Z');
plotter->finish_to(pos);
}
pos.x = (ii - gxpas / 2) * conv_unit;
pos.y = (yg - GRID_REF_W / 2) * conv_unit;
PlotGraphicText( format_plot, pos, color,
plotter->text( pos, color,
msg, TEXT_ORIENT_HORIZ, text_size,
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, false );
......@@ -234,7 +169,7 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
/* Trace des reperes selon l'axe Y */
ipas = (yg - ref.y) / PAS_REF;
gypas = ( yg - ref.y) / ipas;
for( ii = ref.y + gypas, jj = 0; ipas > 0; ii += gypas, jj++, ipas-- )
for( int ii = ref.y + gypas, jj = 0; ipas > 0; ii += gypas, jj++, ipas-- )
{
if( jj < 26 )
msg.Printf( wxT( "%c" ), jj + 'A' );
......@@ -243,14 +178,13 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
if( ii < yg - PAS_REF / 2 )
{
pos.x = ref.x * conv_unit; pos.y = ii * conv_unit;
FctPlume( pos, 'U' );
plotter->move_to(pos);
pos.x = (ref.x + GRID_REF_W) * conv_unit; pos.y = ii * conv_unit;
FctPlume( pos, 'D' );
FctPlume(ref,'Z');
plotter->finish_to(pos);
}
pos.x = (ref.x + GRID_REF_W / 2) * conv_unit;
pos.y = (ii - gypas / 2) * conv_unit;
PlotGraphicText( format_plot, pos, color,
plotter->text( pos, color,
msg, TEXT_ORIENT_HORIZ, text_size,
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, false );
......@@ -258,14 +192,13 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
if( ii < yg - PAS_REF / 2 )
{
pos.x = xg * conv_unit; pos.y = ii * conv_unit;
FctPlume( pos, 'U' );
plotter->move_to(pos);
pos.x = (xg - GRID_REF_W) * conv_unit; pos.y = ii * conv_unit;
FctPlume( pos, 'D' );
FctPlume(ref,'Z');
plotter->finish_to(pos);
}
pos.x = (xg - GRID_REF_W / 2) * conv_unit;
pos.y = (ii - gypas / 2) * conv_unit;
PlotGraphicText( format_plot, pos, color, msg, TEXT_ORIENT_HORIZ, text_size,
plotter->text( pos, color, msg, TEXT_ORIENT_HORIZ, text_size,
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, false );
}
......@@ -279,7 +212,9 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
ref.y = PageSize.y - Sheet->m_BottomMargin;
if (screen->m_ScreenNumber == 1)
{
for( WsItem = &WS_Date; WsItem != NULL; WsItem = WsItem->Pnext )
for(Ki_WorkSheetData* WsItem = &WS_Date;
WsItem != NULL;
WsItem = WsItem->Pnext )
{
pos.x = (ref.x - WsItem->m_Posx) * conv_unit;
pos.y = (ref.y - WsItem->m_Posy) * conv_unit;
......@@ -294,7 +229,7 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
break;
case WS_PODPIS:
if(WsItem->m_Legende) msg = WsItem->m_Legende;
PlotGraphicText(format_plot, pos, color, msg, TEXT_ORIENT_HORIZ,text_size,
plotter->text( pos, color, msg, TEXT_ORIENT_HORIZ,text_size,
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, false );
break;
......@@ -303,14 +238,14 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
case WS_IDENTSHEET:
if(WsItem->m_Legende) msg = WsItem->m_Legende;
msg << screen->m_ScreenNumber;
PlotGraphicText(format_plot, pos, color, msg, TEXT_ORIENT_HORIZ,text_size,
plotter->text( pos, color, msg, TEXT_ORIENT_HORIZ,text_size,
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, false );
break;
case WS_SHEETS:
if(WsItem->m_Legende) msg = WsItem->m_Legende;
msg << screen->m_NumberOfScreen;
PlotGraphicText(format_plot, pos, color, msg, TEXT_ORIENT_HORIZ, text_size,
plotter->text( pos, color, msg, TEXT_ORIENT_HORIZ, text_size,
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, false );
break;
......@@ -329,16 +264,17 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
case WS_UPPER_SEGMENT:
case WS_LEFT_SEGMENT:
case WS_SEGMENT:
FctPlume(pos, 'U');
plot->move_to(pos);
pos.x = (ref.x - WsItem->m_Endx) * conv_unit;
pos.y = (ref.y - WsItem->m_Endy) * conv_unit;
FctPlume(pos, 'D');
FctPlume(ref,'Z');
plot->finish_to(pos);
break;
}
}
} else {
for( WsItem = &WS_CADRE_D; WsItem != NULL; WsItem = WsItem->Pnext )
for(Ki_WorkSheetData* WsItem = &WS_CADRE_D;
WsItem != NULL;
WsItem = WsItem->Pnext )
{
pos.x = (ref.x - WsItem->m_Posx) * conv_unit;
pos.y = (ref.y - WsItem->m_Posy) * conv_unit;
......@@ -349,24 +285,23 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
/* Begin list number > 1 */
case WS_PODPIS_D:
if(WsItem->m_Legende) msg = WsItem->m_Legende;
PlotGraphicText(format_plot, pos, color, msg, TEXT_ORIENT_HORIZ, text_size,
plotter->text( pos, color, msg, TEXT_ORIENT_HORIZ, text_size,
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, false );
break;
case WS_IDENTSHEET_D:
if(WsItem->m_Legende) msg = WsItem->m_Legende;
msg << screen->m_ScreenNumber;
PlotGraphicText(format_plot, pos, color, msg, TEXT_ORIENT_HORIZ, text_size,
plotter->text( pos, color, msg, TEXT_ORIENT_HORIZ, text_size,
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, false );
break;
case WS_LEFT_SEGMENT_D:
case WS_SEGMENT_D:
FctPlume(pos, 'U');
plot->move_to(pos);
pos.x = (ref.x - WsItem->m_Endx) * conv_unit;
pos.y = (ref.y - WsItem->m_Endy) * conv_unit;
FctPlume(pos, 'D');
FctPlume(ref,'Z');
plot->finish_to(pos);
break;
}
}
......@@ -375,7 +310,9 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
ref.x = PageSize.x - GRID_REF_W - Sheet->m_RightMargin;
ref.y = PageSize.y - GRID_REF_W - Sheet->m_BottomMargin;
for( WsItem = &WS_Date; WsItem != NULL; WsItem = WsItem->Pnext )
for (Ki_WorkSheetData* WsItem = &WS_Date;
WsItem != NULL;
WsItem = WsItem->Pnext )
{
pos.x = (ref.x - WsItem->m_Posx) * conv_unit;
pos.y = (ref.y - WsItem->m_Posy) * conv_unit;
......@@ -472,63 +409,393 @@ void WinEDA_DrawFrame::PlotWorkSheet( int format_plot, BASE_SCREEN* screen )
wxPoint auxpos;
auxpos.x = (ref.x - WsItem->m_Endx) * conv_unit;;
auxpos.y = (ref.y - WsItem->m_Endy) * conv_unit;;
FctPlume( pos, 'U' );
FctPlume( auxpos, 'D' );
FctPlume(ref,'Z');
plotter->move_to( pos );
plotter->finish_to( auxpos );
}
break;
}
if( !msg.IsEmpty() )
{
PlotGraphicText( format_plot, pos, color,
plotter->text( pos, color,
msg.GetData(), TEXT_ORIENT_HORIZ, text_size,
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
thickness, italic, bold );
}
}
#endif
}
/******************************************/
void Plotter::user_to_device_coordinates( wxPoint& pos )
/******************************************/
switch( format_plot )
/* modifie les coord pos.x et pos.y pour le trace selon l'orientation,
* l'echelle, les offsets de trace */
{
pos.x = (int) ((pos.x - plot_offset.x) * plot_scale * device_scale);
if (plot_orient_options == PLOT_MIROIR)
pos.y = (int) ((pos.y - plot_offset.y) * plot_scale * device_scale);
else
pos.y = (int) ((paper_size.y - (pos.y - plot_offset.y) * plot_scale) * device_scale);
}
/********************************************************************/
void Plotter::arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
FILL_T fill, int width )
/********************************************************************/
/* Generic arc rendered as a polyline */
{
wxPoint start, end;
const int delta = 50; /* increment (in 0.1 degrees) to draw circles */
double alpha;
if (StAngle > EndAngle)
EXCHG(StAngle, EndAngle);
set_current_line_width(width);
/* Please NOTE the different sign due to Y-axis flip */
alpha = StAngle/1800.0*M_PI;
start.x = centre.x + (int) (rayon * cos(-alpha));
start.y = centre.y + (int) (rayon * sin(-alpha));
move_to(start);
for(int ii = StAngle+delta; ii < EndAngle; ii += delta )
{
case PLOT_FORMAT_HPGL:
Plume_HPGL( 'U' );
break;
alpha = ii/1800.0*M_PI;
end.x = centre.x + (int) (rayon * cos(-alpha));
end.y = centre.y + (int) (rayon * sin(-alpha));
line_to(end);
}
case PLOT_FORMAT_POST:
break;
alpha = EndAngle/1800.0*M_PI;
end.x = centre.x + (int) (rayon * cos(-alpha));
end.y = centre.y + (int) (rayon * sin(-alpha));
finish_to( end );
}
/************************************/
void Plotter::user_to_device_size( wxSize& size )
/************************************/
/* modifie les dimension size.x et size.y pour le trace selon l'echelle */
{
size.x = (int) (size.x * plot_scale * device_scale);
size.y = (int) (size.y * plot_scale * device_scale);
}
/************************************/
double Plotter::user_to_device_size( double size )
/************************************/
{
return size * plot_scale * device_scale;
}
/************************************************************************************/
void Plotter::center_square( const wxPoint& position, int diametre, FILL_T fill)
/************************************************************************************/
{
int rayon = diametre / 2.8284;
int coord[10] = {
position.x+rayon, position.y+rayon,
position.x+rayon, position.y-rayon,
position.x-rayon, position.y-rayon,
position.x-rayon, position.y+rayon,
position.x+rayon, position.y+rayon
};
if (fill)
{
poly(4, coord, fill);
}
else
{
poly(5, coord, fill);
}
}
/************************************************************************************/
void Plotter::center_lozenge( const wxPoint& position, int diametre, FILL_T fill)
/************************************************************************************/
{
int rayon = diametre / 2;
int coord[10] = {
position.x, position.y+rayon,
position.x+rayon, position.y,
position.x, position.y-rayon,
position.x-rayon, position.y,
position.x, position.y+rayon,
};
if (fill)
{
poly(4, coord, fill);
}
else
{
poly(5, coord, fill);
}
}
/******************************************/
void UserToDeviceCoordinate( wxPoint& pos )
/******************************************/
/************************************************************************************/
void Plotter::marker( const wxPoint& position, int diametre, int aShapeId)
/************************************************************************************/
/* modifie les coord pos.x et pos.y pour le trace selon l'orientation,
* l'echelle, les offsets de trace */
/* Trace un motif de numero de forme aShapeId, aux coord x0, y0.
* x0, y0 = coordonnees tables
* diametre = diametre (coord table) du trou
* aShapeId = index ( permet de generer des formes caract )
*/
{
pos.x = (int) (pos.x * g_Plot_XScale);
pos.y = (int) (pos.y * g_Plot_YScale);
int rayon = diametre / 2;
int x0, y0;
switch( g_Plot_PlotOrientOptions ) /* Calcul du cadrage */
x0 = position.x; y0 = position.y;
switch( aShapeId )
{
case 0: /* vias : forme en X */
move_to( wxPoint( x0 - rayon, y0 - rayon ) );
line_to( wxPoint( x0 + rayon, y0 + rayon ) );
move_to( wxPoint( x0 + rayon, y0 - rayon ) );
finish_to( wxPoint( x0 - rayon, y0 + rayon ) );
break;
case 1: /* Cercle */
circle(position, diametre, NO_FILL);
break;
case 2: /* forme en + */
move_to( wxPoint( x0, y0 - rayon ) );
line_to( wxPoint( x0, y0 + rayon ) );
move_to( wxPoint( x0 + rayon, y0 ) );
finish_to( wxPoint( x0 - rayon, y0 ) );
break;
case 3: /* forme en X cercle */
circle(position, diametre, NO_FILL);
move_to( wxPoint( x0 - rayon, y0 - rayon ) );
line_to( wxPoint( x0 + rayon, y0 + rayon ) );
move_to( wxPoint( x0 + rayon, y0 - rayon ) );
finish_to( wxPoint( x0 - rayon, y0 + rayon ) );
break;
case 4: /* forme en cercle barre de - */
circle(position, diametre, NO_FILL);
move_to( wxPoint( x0 - rayon, y0 ) );
finish_to( wxPoint( x0 + rayon, y0 ) );
break;
case 5: /* forme en cercle barre de | */
circle(position, diametre, NO_FILL);
move_to( wxPoint( x0, y0 - rayon ) );
finish_to( wxPoint( x0, y0 + rayon ) );
break;
case 6: /* forme en carre */
center_square(position, diametre, NO_FILL);
break;
case 7: /* forme en losange */
center_lozenge(position, diametre, NO_FILL);
break;
case 8: /* forme en carre barre par un X*/
center_square(position, diametre, NO_FILL);
move_to( wxPoint( x0 - rayon, y0 - rayon ) );
line_to( wxPoint( x0 + rayon, y0 + rayon ) );
move_to( wxPoint( x0 + rayon, y0 - rayon ) );
finish_to( wxPoint( x0 - rayon, y0 + rayon ) );
break;
case 9: /* forme en losange barre par un +*/
center_lozenge(position, diametre, NO_FILL);
move_to( wxPoint( x0, y0 - rayon ) );
line_to( wxPoint( x0, y0 + rayon ) );
move_to( wxPoint( x0 + rayon, y0 ) );
finish_to( wxPoint( x0 - rayon, y0 ) );
break;
case 10: /* forme en carre barre par un '/' */
center_square(position, diametre, NO_FILL);
move_to( wxPoint( x0 - rayon, y0 - rayon ) );
finish_to( wxPoint( x0 + rayon, y0 + rayon ) );
break;
case 11: /* forme en losange barre par un |*/
center_lozenge(position, diametre, NO_FILL);
move_to( wxPoint( x0, y0 - rayon ) );
finish_to( wxPoint( x0, y0 + rayon ) );
break;
case 12: /* forme en losange barre par un -*/
center_lozenge(position, diametre, NO_FILL);
move_to( wxPoint( x0 - rayon, y0 ) );
finish_to( wxPoint( x0 + rayon, y0 ) );
break;
default:
pos.x -= g_Plot_PlotOffset.x; pos.y = g_Plot_PlotOffset.y - pos.y;
circle(position, diametre, NO_FILL);
break;
}
}
case PLOT_MIROIR:
pos.x -= g_Plot_PlotOffset.x; pos.y = -g_Plot_PlotOffset.y + pos.y;
/***************************************************************/
void Plotter::segment_as_oval( wxPoint start, wxPoint end, int width,
GRTraceMode tracemode)
/***************************************************************/
{
/* Convert a thick segment and plot it as an oval */
wxPoint center( (start.x + end.x) / 2, (start.y + end.y) / 2);
wxSize size( end.x - start.x, end.y - start.y);
int orient;
if ( size.y == 0 )
orient = 0;
else if ( size.x == 0 )
orient = 900;
else orient = - (int) (atan2( (double)size.y, (double)size.x ) * 1800.0 / M_PI);
size.x = (int) sqrt( ((double)size.x * size.x) + ((double)size.y * size.y) ) + width;
size.y = width;
flash_pad_oval( center, size, orient, tracemode );
}
/***************************************************************/
void Plotter::sketch_oval(wxPoint pos, wxSize size, int orient,
int width)
/***************************************************************/
{
set_current_line_width(width);
width = current_pen_width;
int rayon, deltaxy, cx, cy;
if( size.x > size.y )
{
EXCHG( size.x, size.y ); orient += 900;
if( orient >= 3600 )
orient -= 3600;
}
deltaxy = size.y - size.x; /* = distance entre centres de l'ovale */
rayon = (size.x-width) / 2;
cx = -rayon; cy = -deltaxy / 2;
RotatePoint( &cx, &cy, orient );
move_to( wxPoint( cx + pos.x, cy + pos.y ) );
cx = -rayon; cy = deltaxy / 2;
RotatePoint( &cx, &cy, orient );
finish_to( wxPoint( cx + pos.x, cy + pos.y ) );
cx = rayon; cy = -deltaxy / 2;
RotatePoint( &cx, &cy, orient );
move_to( wxPoint( cx + pos.x, cy + pos.y ) );
cx = rayon; cy = deltaxy / 2;
RotatePoint( &cx, &cy, orient );
finish_to( wxPoint( cx + pos.x, cy + pos.y ) );
cx = 0; cy = deltaxy / 2;
RotatePoint( &cx, &cy, orient );
arc( wxPoint( cx + pos.x, cy + pos.y ),
orient + 1800 , orient + 3600,
rayon, NO_FILL);
cx = 0; cy = -deltaxy / 2;
RotatePoint( &cx, &cy, orient );
arc( wxPoint( cx + pos.x, cy + pos.y ),
orient, orient + 1800,
rayon, NO_FILL );
}
/***************************************************************/
void Plotter::thick_segment( wxPoint start, wxPoint end, int width,
GRTraceMode tracemode )
/***************************************************************/
/* Plot 1 segment like a track segment
*/
{
switch (tracemode)
{
case FILLED:
case FILAIRE:
set_current_line_width(tracemode==FILLED?width:-1);
move_to(start);
finish_to(end);
break;
case SKETCH:
set_current_line_width(-1);
segment_as_oval(start, end, width, tracemode);
break;
}
}
void Plotter::thick_arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
int width, GRTraceMode tracemode )
{
switch (tracemode)
{
case FILAIRE:
set_current_line_width(-1);
arc(centre, StAngle, EndAngle, rayon, NO_FILL,-1);
break;
case FILLED:
arc(centre, StAngle, EndAngle, rayon,NO_FILL, width);
break;
case SKETCH:
set_current_line_width(-1);
arc(centre, StAngle, EndAngle, rayon-(width-current_pen_width)/2,NO_FILL, -1);
arc(centre, StAngle, EndAngle, rayon+(width-current_pen_width)/2,NO_FILL, -1);
break;
}
}
/************************************/
void UserToDeviceSize( wxSize& size )
/************************************/
/* modifie les dimension size.x et size.y pour le trace selon l'echelle */
void Plotter::thick_rect( wxPoint p1, wxPoint p2, int width,
GRTraceMode tracemode)
{
size.x = (int) (size.x * g_Plot_XScale);
size.y = (int) (size.y * g_Plot_YScale);
switch (tracemode)
{
case FILAIRE:
rect(p1, p2,NO_FILL, -1);
break;
case FILLED:
rect(p1, p2,NO_FILL, width);
break;
case SKETCH:
set_current_line_width(-1);
p1.x -= (width-current_pen_width)/2;
p1.y -= (width-current_pen_width)/2;
p2.x += (width-current_pen_width)/2;
p2.y += (width-current_pen_width)/2;
rect(p1, p2,NO_FILL, -1);
p1.x += (width-current_pen_width);
p1.y += (width-current_pen_width);
p2.x -= (width-current_pen_width);
p2.y -= (width-current_pen_width);
rect(p1, p2,NO_FILL, -1);
break;
}
}
void Plotter::thick_circle( wxPoint pos, int diametre, int width,
GRTraceMode tracemode)
{
switch (tracemode)
{
case FILAIRE:
circle(pos, diametre,NO_FILL, -1);
break;
case FILLED:
circle(pos, diametre,NO_FILL, width);
break;
case SKETCH:
set_current_line_width(-1);
circle(pos, diametre-width+current_pen_width,NO_FILL, -1);
circle(pos, diametre+width-current_pen_width,NO_FILL, -1);
break;
}
}
/*************************************************************************************/
void Plotter::set_paper_size(Ki_PageDescr* asheet)
/*************************************************************************************/
{
wxASSERT(!output_file);
sheet = asheet;
// Sheets are in mils, plotter works with decimils
paper_size.x = sheet->m_Size.x * 10;
paper_size.y = sheet->m_Size.y * 10;
}
......@@ -19,6 +19,7 @@
#define EDA_DRAWBASE
#include "hershey_fonts.h"
#include "plot_common.h"
/* factor used to calculate actual size of shapes from hershey fonts (could be adjusted depending on the font name)
* Its value is choosen in order to have letters like M, P .. vertical size equal to the vertical char size parameter
......@@ -170,9 +171,19 @@ static void DrawGraphicTextPline(
bool sketch_mode,
int point_count,
wxPoint* coord,
void (* aCallback)( int x0, int y0, int xf, int yf ) )
void (* aCallback)(int x0, int y0, int xf, int yf ),
Plotter *plotter )
{
if( aCallback )
if( plotter )
{
plotter->move_to(coord[0]);
for( int ik = 1; ik < point_count; ik++ )
{
plotter->line_to( coord[ik] );
}
plotter->pen_finish();
}
else if (aCallback)
{
for( int ik = 0; ik < (point_count - 1); ik++ )
{
......@@ -216,8 +227,6 @@ static int overbar_position( int size_v, int thickness )
* Use a value min(aSize.x, aSize.y) / 5 for a bold text
* @param aItalic = true to simulate an italic font
* @param aBold = true to use a bold font. Useful only with default width value (aWidth = 0)
* @param aCallback() = function called (if non null) to draw each segment.
* used to draw 3D texts or for plotting, NULL for normal drawings
*/
/****************************************************************************************************/
void DrawGraphicText( WinEDA_DrawPanel* aPanel,
......@@ -232,13 +241,14 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel,
int aWidth,
bool aItalic,
bool aBold,
void (* aCallback)( int x0, int y0, int xf, int yf ) )
void (* aCallback)( int x0, int y0, int xf, int yf ),
Plotter *plotter )
/****************************************************************************************************/
{
int char_count, AsciiCode;
int AsciiCode;
int x0, y0;
int size_h, size_v;
int ptr;
unsigned ptr;
int dx, dy; // Draw coordinate for segments to draw. also used in some other calculation
wxPoint current_char_pos; // Draw coordinates for the current char
wxPoint overbar_pos; // Start point for the current overbar
......@@ -270,7 +280,7 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel,
if( size_h < 0 ) // text is mirrored using size.x < 0 (mirror / Y axis)
italic_reverse = true;
char_count = NegableTextLength( aText );
unsigned char_count = NegableTextLength( aText );
if( char_count == 0 )
return;
......@@ -351,8 +361,14 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel,
RotatePoint( &current_char_pos, aPos, aOrient );
RotatePoint( &end, aPos, aOrient );
if( aCallback )
if( plotter ) {
plotter->move_to(current_char_pos);
plotter->finish_to( end );
}
else if (aCallback)
{
aCallback( current_char_pos.x, current_char_pos.y, end.x, end.y );
}
else
GRLine( &aPanel->m_ClipBox, aDC,
current_char_pos.x, current_char_pos.y, end.x, end.y, aWidth, aColor );
......@@ -401,7 +417,7 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel,
coord[1] = overbar_pos;
/* Plot the overbar segment */
DrawGraphicTextPline( aPanel, aDC, aColor, aWidth,
sketch_mode, 2, coord, aCallback );
sketch_mode, 2, coord, aCallback, plotter );
}
continue; /* Skip ~ processing */
}
......@@ -439,7 +455,8 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel,
if( aWidth <= 1 )
aWidth = 0;
DrawGraphicTextPline( aPanel, aDC, aColor, aWidth,
sketch_mode, point_count, coord, aCallback );
sketch_mode, point_count, coord,
aCallback, plotter );
}
point_count = 0;
}
......@@ -481,54 +498,11 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel,
coord[1] = overbar_pos;
/* Plot the overbar segment */
DrawGraphicTextPline( aPanel, aDC, aColor, aWidth,
sketch_mode, 2, coord, aCallback );
sketch_mode, 2, coord, aCallback, plotter );
}
}
/* functions used to plot texts, using DrawGraphicText() with a call back function */
static void (*MovePenFct)( wxPoint pos, int state ); // a pointer to actual plot function (HPGL, PS, ..)
static bool s_Plotbegin; // Flag to init plot
/*
* The call back function
*/
/****************************************************************/
static void s_Callback_plot( int x0, int y0, int xf, int yf )
/****************************************************************/
{
static wxPoint PenLastPos;
wxPoint pstart;
pstart.x = x0;
pstart.y = y0;
wxPoint pend;
pend.x = xf;
pend.y = yf;
if( s_Plotbegin ) // First segment to plot
{
MovePenFct( pstart, 'U' );
MovePenFct( pend, 'D' );
s_Plotbegin = false;
}
else
{
if( PenLastPos == pstart ) // this is a next segment in a polyline
{
MovePenFct( pend, 'D' );
}
else // New segment to plot
{
MovePenFct( pstart, 'U' );
MovePenFct( pend, 'D' );
}
}
PenLastPos = pend;
}
/** Function PlotGraphicText
* same as DrawGraphicText, but plot graphic text insteed of draw it
* @param aFormat_plot = plot format (PLOT_FORMAT_POST, PLOT_FORMAT_HPGL, PLOT_FORMAT_GERBER)
......@@ -546,8 +520,7 @@ static void s_Callback_plot( int x0, int y0, int xf, int yf )
* @param aBold = true to use a bold font Useful only with default width value (aWidth = 0)
*/
/******************************************************************************************/
void PlotGraphicText( int aFormat_plot,
const wxPoint& aPos,
void Plotter::text( const wxPoint& aPos,
enum EDA_Colors aColor,
const wxString& aText,
int aOrient,
......@@ -562,45 +535,22 @@ void PlotGraphicText( int aFormat_plot,
if( aWidth == 0 && aBold ) // Use default values if aWidth == 0
aWidth = GetPenSizeForBold( MIN( aSize.x, aSize.y ) );
#ifdef CLIP_PEN // made by draw and plot functions
if ( aWidth >= 0 )
aWidth = Clamp_Text_PenSize( aWidth, aSize, aBold );
else
aWidth = - Clamp_Text_PenSize( -aWidth, aSize, aBold );
#endif
// Initialise the actual function used to plot lines:
switch( aFormat_plot )
{
case PLOT_FORMAT_POST:
MovePenFct = LineTo_PS;
SetCurrentLineWidthPS( aWidth );
break;
case PLOT_FORMAT_HPGL:
MovePenFct = Move_Plume_HPGL;
break;
case PLOT_FORMAT_GERBER:
MovePenFct = LineTo_GERBER;
/* Gerber tool has to be set outside... */
break;
set_current_line_width( aWidth );
default:
return;
}
if( aColor >= 0 && IsPostScript( aFormat_plot ) )
SetColorMapPS( aColor );
if( aColor >= 0 )
set_color( aColor );
s_Plotbegin = true;
DrawGraphicText( NULL, NULL, aPos, aColor, aText,
aOrient, aSize,
aH_justify, aV_justify,
aWidth, aItalic,
aBold,
s_Callback_plot );
/* end text : pen UP ,no move */
MovePenFct( wxPoint( 0, 0 ), 'Z' );
NULL,
this );
}
......@@ -704,7 +704,8 @@ void LibDrawPin::DrawPinTexts( WinEDA_DrawPanel* panel,
* If TextInside then the text is been put inside (moving from x1, y1 in *
* the opposite direction to x2,y2), otherwise all is drawn outside. *
*****************************************************************************/
void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
void LibDrawPin::PlotPinTexts( Plotter *plotter,
wxPoint& pin_pos,
int orient,
int TextInside,
bool DrawPinNum,
......@@ -716,12 +717,10 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
EDA_Colors NameColor, NumColor;
wxSize PinNameSize = wxSize( m_PinNameSize, m_PinNameSize );
wxSize PinNumSize = wxSize( m_PinNumSize, m_PinNumSize );
bool plot_color = (g_PlotFormat == PLOT_FORMAT_POST)
&& g_PlotPSColorOpt;
/* Get the num and name colors */
NameColor = (EDA_Colors) ( plot_color ? ReturnLayerColor( LAYER_PINNAM ) : -1 );
NumColor = (EDA_Colors) ( plot_color ? ReturnLayerColor( LAYER_PINNUM ) : -1 );
NameColor = ReturnLayerColor( LAYER_PINNAM );
NumColor = ReturnLayerColor( LAYER_PINNUM );
/* Create the pin num string */
ReturnPinStringNum( StringPinNum );
......@@ -754,7 +753,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
if( orient == PIN_RIGHT )
{
x = x1 + TextInside;
PlotGraphicText( g_PlotFormat, wxPoint( x, y1 ), NameColor,
plotter->text( wxPoint( x, y1 ), NameColor,
m_PinName,
TEXT_ORIENT_HORIZ,
PinNameSize,
......@@ -766,7 +765,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
{
x = x1 - TextInside;
if( DrawPinName )
PlotGraphicText( g_PlotFormat, wxPoint( x, y1 ),
plotter->text( wxPoint( x, y1 ),
NameColor, m_PinName, TEXT_ORIENT_HORIZ,
PinNameSize,
GR_TEXT_HJUSTIFY_RIGHT,
......@@ -775,8 +774,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
}
if( DrawPinNum )
{
PlotGraphicText( g_PlotFormat,
wxPoint( (x1 + pin_pos.x) / 2, y1 - TXTMARGE ),
plotter->text( wxPoint( (x1 + pin_pos.x) / 2, y1 - TXTMARGE ),
NumColor, StringPinNum,
TEXT_ORIENT_HORIZ, PinNumSize,
GR_TEXT_HJUSTIFY_CENTER,
......@@ -792,7 +790,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
y = y1 + TextInside;
if( DrawPinName )
PlotGraphicText( g_PlotFormat, wxPoint( x1, y ), NameColor,
plotter->text( wxPoint( x1, y ), NameColor,
m_PinName,
TEXT_ORIENT_VERT, PinNameSize,
GR_TEXT_HJUSTIFY_RIGHT,
......@@ -800,8 +798,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
aWidth, false, false );
if( DrawPinNum )
{
PlotGraphicText( g_PlotFormat,
wxPoint( x1 - TXTMARGE,
plotter->text( wxPoint( x1 - TXTMARGE,
(y1 + pin_pos.y) / 2 ),
NumColor, StringPinNum,
TEXT_ORIENT_VERT, PinNumSize,
......@@ -815,7 +812,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
y = y1 - TextInside;
if( DrawPinName )
PlotGraphicText( g_PlotFormat, wxPoint( x1, y ), NameColor,
plotter->text( wxPoint( x1, y ), NameColor,
m_PinName,
TEXT_ORIENT_VERT, PinNameSize,
GR_TEXT_HJUSTIFY_LEFT,
......@@ -823,8 +820,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
aWidth, false, false );
if( DrawPinNum )
{
PlotGraphicText( g_PlotFormat,
wxPoint( x1 - TXTMARGE,
plotter->text( wxPoint( x1 - TXTMARGE,
(y1 + pin_pos.y) / 2 ),
NumColor, StringPinNum,
TEXT_ORIENT_VERT, PinNumSize,
......@@ -843,8 +839,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
if( DrawPinName )
{
x = (x1 + pin_pos.x) / 2;
PlotGraphicText( g_PlotFormat, wxPoint( x,
y1 - TXTMARGE ),
plotter->text( wxPoint( x, y1 - TXTMARGE ),
NameColor, m_PinName,
TEXT_ORIENT_HORIZ, PinNameSize,
GR_TEXT_HJUSTIFY_CENTER,
......@@ -854,7 +849,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
if( DrawPinNum )
{
x = (x1 + pin_pos.x) / 2;
PlotGraphicText( g_PlotFormat, wxPoint( x, y1 + TXTMARGE ),
plotter->text( wxPoint( x, y1 + TXTMARGE ),
NumColor, StringPinNum,
TEXT_ORIENT_HORIZ, PinNumSize,
GR_TEXT_HJUSTIFY_CENTER,
......@@ -867,8 +862,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
if( DrawPinName )
{
y = (y1 + pin_pos.y) / 2;
PlotGraphicText( g_PlotFormat, wxPoint( x1 - TXTMARGE,
y ),
plotter->text( wxPoint( x1 - TXTMARGE, y ),
NameColor, m_PinName,
TEXT_ORIENT_VERT, PinNameSize,
GR_TEXT_HJUSTIFY_CENTER,
......@@ -878,9 +872,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos,
if( DrawPinNum )
{
PlotGraphicText( g_PlotFormat,
wxPoint( x1 + TXTMARGE,
(y1 + pin_pos.y) / 2 ),
plotter->text( wxPoint( x1 + TXTMARGE, (y1 + pin_pos.y) / 2 ),
NumColor, StringPinNum,
TEXT_ORIENT_VERT, PinNumSize,
GR_TEXT_HJUSTIFY_CENTER,
......
......@@ -26,21 +26,6 @@
#define IEEE_SYMBOL_PIN_DIM 40 /* Dim of special pin symbol. */
/**
* Enum FILL_T
* is the set of fill types used in plotting or drawing enclosed areas.
*/
enum FILL_T {
NO_FILL, // Poly, Square, Circle, Arc = option No Fill
FILLED_SHAPE, /* Poly, Square, Circle, Arc = option Fill
* with current color ("Solid shape") */
FILLED_WITH_BG_BODYCOLOR, /* Poly, Square, Circle, Arc = option Fill
* with background body color, translucent
* (texts inside this shape can be seen)
* not filled in B&W mode when plotting or
* printing */
};
/**
* Enum ElectricPinType
......@@ -290,7 +275,8 @@ public:
wxPoint& pin_pos, int orient,
int TextInside, bool DrawPinNum,
bool DrawPinName, int Color, int DrawMode );
void PlotPinTexts( wxPoint& pin_pos,
void PlotPinTexts( Plotter *plotter,
wxPoint& pin_pos,
int orient,
int TextInside,
bool DrawPinNum,
......
......@@ -403,10 +403,6 @@ PARAM_CFG_ARRAY& WinEDA_SchematicFrame::GetConfigurationSettings( void )
m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorGrid" ),
&g_GridColor,
DARKDARKGRAY ) );
m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "Pltmarg" ),
&g_PlotMargin,
300, 0, 10000 ) );
return m_configSettings;
}
......
......@@ -45,8 +45,6 @@ SCH_ITEM* g_BlockSaveDataList; // List of items to paste (Created by Block Save)
// Gestion d'options
bool g_HVLines = true; // Bool: force H or V directions (Wires, Bus ..)
int g_PlotPSColorOpt; // True = plot postcript color (see plotps.cpp)
struct EESchemaVariables g_EESchemaVar;
/* Variables globales pour Libview */
......@@ -65,11 +63,6 @@ int g_LastTextOrient = TEXT_ORIENT_HORIZ;
bool g_FlDrawSpecificUnit = FALSE;
bool g_FlDrawSpecificConvert = TRUE;
int g_PlotFormat; /* flag = TYPE_HPGL, TYPE_PS... */
int g_PlotMargin; /* Marge pour traces du cartouche */
double g_PlotScaleX;
double g_PlotScaleY; /* coeff d'echelle de trace en unites table tracante */
HPGL_Pen_Descr_Struct g_HPGL_Pen_Descr;
//SCH_SCREEN * ScreenSch;
......
......@@ -117,9 +117,6 @@ extern SCH_ITEM* g_BlockSaveDataList; // List of items to paste (Created by Bloc
// Gestion d'options
extern bool g_HVLines;
extern int g_PlotPSColorOpt; // True = plot postcript color (see plotps.cpp)
// Gestion de diverses variables, options... devant etre memorisees mais
// Remises a 0 lors d'un rechargement de projetc
struct EESchemaVariables
......@@ -152,11 +149,6 @@ extern bool g_FlDrawSpecificConvert;
/* Gestion des trace sur table tracante */
extern int g_PlotFormat; /* flag = TYPE_HPGL, TYPE_PS... */
extern int g_PlotMargin; /* Marge pour traces du cartouche */
extern double g_PlotScaleX, g_PlotScaleY; /* coeff d'echelle de trace en unites table tracante */
/* For HPGL plotting: Pen caract : */
struct HPGL_Pen_Descr_Struct
{
......
......@@ -17,156 +17,17 @@
#include "protos.h"
/* Local Variables : */
static void Plot_Hierarchical_PIN_Sheet( Hierarchical_PIN_Sheet_Struct* Struct );
static void PlotTextField( SCH_COMPONENT* DrawLibItem,
static void Plot_Hierarchical_PIN_Sheet(Plotter *plotter,
Hierarchical_PIN_Sheet_Struct* Struct );
static void PlotTextField(Plotter *plotter, SCH_COMPONENT* DrawLibItem,
int FieldNumber, int IsMulti, int DrawMode );
static void PlotPinSymbol( const wxPoint& pos, int len, int orient, int Shape );
static void PlotPinSymbol(Plotter *plotter, const wxPoint& pos,
int len, int orient, int Shape );
/***/
/* Defines for filling polygons in plot polygon functions */
#define FILL true
#define NOFILL false
/* routine de lever ou baisser de plume.
* si plume = 'U' les traces suivants se feront plume levee
* si plume = 'D' les traces suivants se feront plume levee
*/
void Plume( int plume )
{
switch( g_PlotFormat )
{
case PLOT_FORMAT_HPGL:
Plume_HPGL( plume );
break;
case PLOT_FORMAT_POST:
LineTo_PS( wxPoint(0,0), plume );
break;
}
}
/* routine de deplacement de plume de plume.
*/
void Move_Plume( wxPoint pos, int plume )
{
switch( g_PlotFormat )
{
case PLOT_FORMAT_HPGL:
Move_Plume_HPGL( pos, plume );
break;
case PLOT_FORMAT_POST:
LineTo_PS( pos, plume );
break;
}
}
void SetCurrentLineWidth( int width )
{
switch( g_PlotFormat )
{
case PLOT_FORMAT_HPGL:
break;
case PLOT_FORMAT_POST:
SetCurrentLineWidthPS( width );
break;
}
}
/*******************************************************************************/
void PlotRect( wxPoint p1, wxPoint p2, int fill, int width )
/*******************************************************************************/
{
switch( g_PlotFormat )
{
case PLOT_FORMAT_HPGL:
PlotRectHPGL( p1, p2, fill, width );
break;
case PLOT_FORMAT_POST:
PlotRectPS( p1, p2, fill, width );
break;
}
}
/*****************************************************************************************/
void PlotArc( wxPoint aCentre, int aStAngle, int aEndAngle, int aRadius, bool aFill, int aWidth )
/*****************************************************************************************/
/** Function PlotArc
* Plot an arc:
* @param aCentre = Arc centre
* @param aStAngle = begining of arc in 0.1 degrees
* @param aEndAngle = end of arc in 0.1 degrees
* @param aRadius = Arc radius
* @param aFill = fill option
* @param aWidth = Tickness of outlines
*/
{
switch( g_PlotFormat )
{
case PLOT_FORMAT_HPGL:
PlotArcHPGL( aCentre, aStAngle, aEndAngle, aRadius, aFill, aWidth );
break;
case PLOT_FORMAT_POST:
PlotArcPS( aCentre, aStAngle, aEndAngle, aRadius, aFill, aWidth );
break;
}
}
/*****************************************************************/
void PlotCercle( wxPoint pos, int diametre, bool fill, int width )
/*****************************************************************/
{
switch( g_PlotFormat )
{
case PLOT_FORMAT_HPGL:
PlotCircleHPGL( pos, diametre, fill, width );
break;
case PLOT_FORMAT_POST:
PlotCirclePS( pos, diametre, fill, width );
break;
}
}
/******************************************************************/
void PlotPoly( int nb, int* coord, bool fill, int width )
/******************************************************************/
/* Trace un polygone ferme
* coord = tableau des coord des sommets
* nb = nombre de coord ( 1 coord = 2 elements: X et Y du tableau )
* fill : si != 0 polygone rempli
*/
{
if( nb <= 1 )
return;
switch( g_PlotFormat )
{
case PLOT_FORMAT_HPGL:
PlotPolyHPGL( nb, coord, fill, width );
break;
case PLOT_FORMAT_POST:
PlotPolyPS( nb, coord, fill, width );
break;
}
}
/**********************************************************/
void PlotNoConnectStruct( DrawNoConnectStruct* Struct )
static void PlotNoConnectStruct(Plotter *plotter, DrawNoConnectStruct* Struct )
/**********************************************************/
/* Routine de dessin des symboles de "No Connexion" ..
......@@ -177,22 +38,20 @@ void PlotNoConnectStruct( DrawNoConnectStruct* Struct )
pX = Struct->m_Pos.x; pY = Struct->m_Pos.y;
SetCurrentLineWidth( -1 );
Move_Plume( wxPoint( pX - DELTA, pY - DELTA ), 'U' );
Move_Plume( wxPoint( pX + DELTA, pY + DELTA ), 'D' );
Move_Plume( wxPoint( pX + DELTA, pY - DELTA ), 'U' );
Move_Plume( wxPoint( pX - DELTA, pY + DELTA ), 'D' );
Plume( 'Z' );
plotter->set_current_line_width( -1 );
plotter->move_to( wxPoint( pX - DELTA, pY - DELTA ) );
plotter->finish_to( wxPoint( pX + DELTA, pY + DELTA ) );
plotter->move_to( wxPoint( pX + DELTA, pY - DELTA ) );
plotter->finish_to( wxPoint( pX - DELTA, pY + DELTA ) );
}
/*************************************************/
void PlotLibPart( SCH_COMPONENT* DrawLibItem )
static void PlotLibPart(Plotter *plotter, SCH_COMPONENT* DrawLibItem )
/*************************************************/
/* Polt a component */
{
int ii, t1, t2, * Poly, orient;
LibEDA_BaseStruct* DEntry;
EDA_LibComponentStruct* Entry;
int TransMat[2][2], Multi, convert;
EDA_Colors CharColor = UNSPECIFIED_COLOR;
......@@ -206,7 +65,8 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
Multi = DrawLibItem->m_Multi;
convert = DrawLibItem->m_Convert;
for( DEntry = Entry->m_Drawings; DEntry != NULL; DEntry = DEntry->Next() )
for(LibEDA_BaseStruct* DEntry = Entry->m_Drawings;
DEntry != NULL; DEntry = DEntry->Next() )
{
/* Elimination des elements non relatifs a l'unite */
if( Multi && DEntry->m_Unit && (DEntry->m_Unit != Multi) )
......@@ -214,12 +74,8 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
if( convert && DEntry->m_Convert && (DEntry->m_Convert != convert) )
continue;
Plume( 'U' );
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
{
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE ) );
draw_bgfill = true;
}
plotter->set_color( ReturnLayerColor( LAYER_DEVICE ) );
draw_bgfill = plotter->get_color_mode();
switch( DEntry->Type() )
{
......@@ -231,16 +87,15 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
MapAngles( &t1, &t2, TransMat );
if( draw_bgfill && Arc->m_Fill == FILLED_WITH_BG_BODYCOLOR )
{
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
PlotArc( pos, t1, t2, Arc->m_Rayon, true, 0 );
plotter->set_color( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
plotter->arc( pos, t1, t2, Arc->m_Rayon, FILLED_SHAPE, 0 );
}
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE ) );
PlotArc( pos,
plotter->set_color( ReturnLayerColor( LAYER_DEVICE ) );
plotter->arc( pos,
t1,
t2,
Arc->m_Rayon,
Arc->m_Fill == FILLED_SHAPE ? true : false,
Arc->m_Fill,
Arc->m_Width );
}
break;
......@@ -251,14 +106,13 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
pos = TransformCoordinate( TransMat, Circle->m_Pos ) + DrawLibItem->m_Pos;
if( draw_bgfill && Circle->m_Fill == FILLED_WITH_BG_BODYCOLOR )
{
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
PlotCercle( pos, Circle->m_Rayon * 2, true, 0 );
plotter->set_color( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
plotter->circle( pos, Circle->m_Rayon * 2, FILLED_SHAPE, 0 );
}
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE ) );
PlotCercle( pos,
plotter->set_color( ReturnLayerColor( LAYER_DEVICE ) );
plotter->circle( pos,
Circle->m_Rayon * 2,
Circle->m_Fill == FILLED_SHAPE ? true : false,
Circle->m_Fill,
Circle->m_Width );
}
break;
......@@ -271,11 +125,11 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
* transformation matrix causes xy axes to be flipped. */
t1 = (TransMat[0][0] != 0) ^ (Text->m_Orient != 0);
pos = TransformCoordinate( TransMat, Text->m_Pos ) + DrawLibItem->m_Pos;
SetCurrentLineWidth( -1 );
plotter->set_current_line_width( -1 );
int thickness = (Text->m_Width == 0) ? g_DrawDefaultLineThickness : Text->m_Width;
thickness = Clamp_Text_PenSize( thickness, Text->m_Size, Text->m_Bold );
PlotGraphicText( g_PlotFormat, pos, CharColor,
plotter->text( pos, CharColor,
Text->m_Text,
t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT,
Text->m_Size,
......@@ -293,12 +147,11 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
if( draw_bgfill && Square->m_Fill == FILLED_WITH_BG_BODYCOLOR )
{
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
PlotRect( pos, end, true, 0 );
plotter->set_color( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
plotter->rect( pos, end, FILLED_WITH_BG_BODYCOLOR, 0 );
}
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE ) );
PlotRect( pos, end, Square->m_Fill == FILLED_SHAPE ? true : false, Square->m_Width );
plotter->set_color( ReturnLayerColor( LAYER_DEVICE ) );
plotter->rect( pos, end, Square->m_Fill, Square->m_Width );
}
break;
......@@ -314,9 +167,9 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
pos = TransformCoordinate( TransMat, Pin->m_Pos ) + DrawLibItem->m_Pos;
/* Dessin de la pin et du symbole special associe */
PlotPinSymbol( pos, Pin->m_PinLen, orient, Pin->m_PinShape );
PlotPinSymbol(plotter, pos, Pin->m_PinLen, orient, Pin->m_PinShape );
int thickness = g_DrawDefaultLineThickness;
Pin->PlotPinTexts( pos, orient,
Pin->PlotPinTexts( plotter, pos, orient,
Entry->m_TextInside,
Entry->m_DrawPinNum, Entry->m_DrawPinName,
thickness );
......@@ -327,7 +180,7 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
{
LibDrawPolyline* polyline = (LibDrawPolyline*) DEntry;
Poly = (int*) MyMalloc( sizeof(int) * 2 * polyline->GetCornerCount() );
for( ii = 0; ii < (int) polyline->GetCornerCount(); ii++ )
for(ii = 0; ii < (int) polyline->GetCornerCount(); ii++ )
{
pos = polyline->m_PolyPoints[ii];
pos = TransformCoordinate( TransMat, pos ) + DrawLibItem->m_Pos;
......@@ -337,12 +190,11 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
if( draw_bgfill && polyline->m_Fill == FILLED_WITH_BG_BODYCOLOR )
{
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
PlotPoly( ii, Poly, true, 0 );
plotter->set_color( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
plotter->poly( ii, Poly, FILLED_WITH_BG_BODYCOLOR, 0 );
}
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE ) );
PlotPoly( ii, Poly, polyline->m_Fill == FILLED_SHAPE ? true : false, polyline->m_Width );
plotter->set_color( ReturnLayerColor( LAYER_DEVICE ) );
plotter->poly( ii, Poly, polyline->m_Fill, polyline->m_Width );
MyFree( Poly );
}
break;
......@@ -361,12 +213,11 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
if( draw_bgfill && polyline->m_Fill == FILLED_WITH_BG_BODYCOLOR )
{
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
PlotPoly( ii, Poly, true, 0 );
plotter->set_color( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
plotter->poly( ii, Poly, FILLED_WITH_BG_BODYCOLOR, 0 );
}
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE ) );
PlotPoly( ii, Poly, polyline->m_Fill == FILLED_SHAPE ? true : false, polyline->m_Width );
plotter->set_color( ReturnLayerColor( LAYER_DEVICE ) );
plotter->poly( ii, Poly, polyline->m_Fill, polyline->m_Width );
MyFree( Poly );
}
......@@ -375,7 +226,6 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
}
/* Fin Switch */
Plume( 'U' );
}
/* Fin Boucle de dessin */
......@@ -388,23 +238,23 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
if( (Entry->m_Prefix.m_Attributs & TEXT_NO_VISIBLE) == 0 )
{
if( Entry->m_UnitCount > 1 )
PlotTextField( DrawLibItem, REFERENCE, 1, 0 );
PlotTextField(plotter, DrawLibItem, REFERENCE, 1, 0 );
else
PlotTextField( DrawLibItem, REFERENCE, 0, 0 );
PlotTextField(plotter, DrawLibItem, REFERENCE, 0, 0 );
}
if( (Entry->m_Name.m_Attributs & TEXT_NO_VISIBLE) == 0 )
PlotTextField( DrawLibItem, VALUE, 0, 0 );
PlotTextField(plotter, DrawLibItem, VALUE, 0, 0 );
for( ii = 2; ii < NUMBER_OF_FIELDS; ii++ )
{
PlotTextField( DrawLibItem, ii, 0, 0 );
PlotTextField(plotter, DrawLibItem, ii, 0, 0 );
}
}
/*************************************************************/
static void PlotTextField( SCH_COMPONENT* DrawLibItem,
static void PlotTextField( Plotter *plotter, SCH_COMPONENT* DrawLibItem,
int FieldNumber, int IsMulti, int DrawMode )
/**************************************************************/
......@@ -424,7 +274,6 @@ static void PlotTextField( SCH_COMPONENT* DrawLibItem,
int orient;
EDA_Colors color = UNSPECIFIED_COLOR;
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
color = ReturnLayerColor( field->GetLayer() );
DrawMode = 0; /* Unused */
......@@ -521,11 +370,11 @@ static void PlotTextField( SCH_COMPONENT* DrawLibItem,
int thickness = (field->m_Width == 0) ? g_DrawDefaultLineThickness : field->m_Width;
thickness = Clamp_Text_PenSize( thickness, field->m_Size, field->m_Bold );
SetCurrentLineWidth( thickness );
plotter->set_current_line_width( thickness );
if( !IsMulti || (FieldNumber != REFERENCE) )
{
PlotGraphicText( g_PlotFormat, textpos, color, field->m_Text,
plotter->text( textpos, color, field->m_Text,
orient ? TEXT_ORIENT_VERT : TEXT_ORIENT_HORIZ,
field->m_Size,
hjustify, vjustify,
......@@ -544,7 +393,7 @@ static void PlotTextField( SCH_COMPONENT* DrawLibItem,
unit_id = 'A' - 1 + DrawLibItem->m_Multi;
#endif
Text.Append( unit_id );
PlotGraphicText( g_PlotFormat, textpos, color, Text,
plotter->text( textpos, color, Text,
orient ? TEXT_ORIENT_VERT : TEXT_ORIENT_HORIZ,
field->m_Size, hjustify, vjustify,
thickness, field->m_Italic, field->m_Bold );
......@@ -553,7 +402,8 @@ static void PlotTextField( SCH_COMPONENT* DrawLibItem,
/**************************************************************************/
static void PlotPinSymbol( const wxPoint& pos, int len, int orient, int Shape )
static void PlotPinSymbol(Plotter *plotter, const wxPoint& pos,
int len, int orient, int Shape )
/**************************************************************************/
/* Trace la pin du symbole en cours de trace
......@@ -564,10 +414,9 @@ static void PlotPinSymbol( const wxPoint& pos, int len, int orient, int Shape )
color = ReturnLayerColor( LAYER_PIN );
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( color );
plotter->set_color( color );
SetCurrentLineWidth( -1 );
plotter->set_current_line_width( -1 );
MapX1 = MapY1 = 0; x1 = pos.x; y1 = pos.y;
......@@ -592,35 +441,35 @@ static void PlotPinSymbol( const wxPoint& pos, int len, int orient, int Shape )
if( Shape & INVERT )
{
PlotCercle( wxPoint( MapX1 * INVERT_PIN_RADIUS + x1,
plotter->circle( wxPoint( MapX1 * INVERT_PIN_RADIUS + x1,
MapY1 * INVERT_PIN_RADIUS + y1 ),
INVERT_PIN_RADIUS * 2, // diameter
false, // fill
NO_FILL, // fill
-1 ); // width
Move_Plume( wxPoint( MapX1 * INVERT_PIN_RADIUS * 2 + x1,
MapY1 * INVERT_PIN_RADIUS * 2 + y1 ), 'U' );
Move_Plume( pos, 'D' );
plotter->move_to( wxPoint( MapX1 * INVERT_PIN_RADIUS * 2 + x1,
MapY1 * INVERT_PIN_RADIUS * 2 + y1 ));
plotter->finish_to( pos );
}
else
{
Move_Plume( wxPoint( x1, y1 ), 'U' );
Move_Plume( pos, 'D' );
plotter->move_to( wxPoint( x1, y1 ) );
plotter->finish_to( pos );
}
if( Shape & CLOCK )
{
if( MapY1 == 0 ) /* MapX1 = +- 1 */
{
Move_Plume( wxPoint( x1, y1 + CLOCK_PIN_DIM ), 'U' );
Move_Plume( wxPoint( x1 - MapX1 * CLOCK_PIN_DIM, y1 ), 'D' );
Move_Plume( wxPoint( x1, y1 - CLOCK_PIN_DIM ), 'D' );
plotter->move_to( wxPoint( x1, y1 + CLOCK_PIN_DIM ) );
plotter->line_to( wxPoint( x1 - MapX1 * CLOCK_PIN_DIM, y1 ) );
plotter->finish_to( wxPoint( x1, y1 - CLOCK_PIN_DIM ) );
}
else /* MapX1 = 0 */
{
Move_Plume( wxPoint( x1 + CLOCK_PIN_DIM, y1 ), 'U' );
Move_Plume( wxPoint( x1, y1 - MapY1 * CLOCK_PIN_DIM ), 'D' );
Move_Plume( wxPoint( x1 - CLOCK_PIN_DIM, y1 ), 'D' );
plotter->move_to( wxPoint( x1 + CLOCK_PIN_DIM, y1 ) );
plotter->line_to( wxPoint( x1, y1 - MapY1 * CLOCK_PIN_DIM ) );
plotter->finish_to( wxPoint( x1 - CLOCK_PIN_DIM, y1 ) );
}
}
......@@ -628,17 +477,17 @@ static void PlotPinSymbol( const wxPoint& pos, int len, int orient, int Shape )
{
if( MapY1 == 0 ) /* MapX1 = +- 1 */
{
Move_Plume( wxPoint( x1 + MapX1 * IEEE_SYMBOL_PIN_DIM * 2, y1 ), 'U' );
Move_Plume( wxPoint( x1 + MapX1 * IEEE_SYMBOL_PIN_DIM * 2,
y1 - IEEE_SYMBOL_PIN_DIM ), 'D' );
Move_Plume( wxPoint( x1, y1 ), 'D' );
plotter->move_to( wxPoint( x1 + MapX1 * IEEE_SYMBOL_PIN_DIM * 2, y1 ) );
plotter->line_to( wxPoint( x1 + MapX1 * IEEE_SYMBOL_PIN_DIM * 2,
y1 - IEEE_SYMBOL_PIN_DIM ) );
plotter->finish_to( wxPoint( x1, y1 ) );
}
else /* MapX1 = 0 */
{
Move_Plume( wxPoint( x1, y1 + MapY1 * IEEE_SYMBOL_PIN_DIM * 2 ), 'U' );
Move_Plume( wxPoint( x1 - IEEE_SYMBOL_PIN_DIM,
y1 + MapY1 * IEEE_SYMBOL_PIN_DIM * 2 ), 'D' );
Move_Plume( wxPoint( x1, y1 ), 'D' );
plotter->move_to( wxPoint( x1, y1 + MapY1 * IEEE_SYMBOL_PIN_DIM * 2 ) );
plotter->line_to( wxPoint( x1 - IEEE_SYMBOL_PIN_DIM,
y1 + MapY1 * IEEE_SYMBOL_PIN_DIM * 2 ) );
plotter->finish_to( wxPoint( x1, y1 ) );
}
}
......@@ -647,21 +496,20 @@ static void PlotPinSymbol( const wxPoint& pos, int len, int orient, int Shape )
{
if( MapY1 == 0 ) /* MapX1 = +- 1 */
{
Move_Plume( wxPoint( x1, y1 - IEEE_SYMBOL_PIN_DIM ), 'U' );
Move_Plume( wxPoint( x1 + MapX1 * IEEE_SYMBOL_PIN_DIM * 2, y1 ), 'D' );
plotter->move_to( wxPoint( x1, y1 - IEEE_SYMBOL_PIN_DIM ) );
plotter->finish_to( wxPoint( x1 + MapX1 * IEEE_SYMBOL_PIN_DIM * 2, y1 ) );
}
else /* MapX1 = 0 */
{
Move_Plume( wxPoint( x1 - IEEE_SYMBOL_PIN_DIM, y1 ), 'U' );
Move_Plume( wxPoint( x1, y1 + MapY1 * IEEE_SYMBOL_PIN_DIM * 2 ), 'D' );
plotter->move_to( wxPoint( x1 - IEEE_SYMBOL_PIN_DIM, y1 ) );
plotter->finish_to( wxPoint( x1, y1 + MapY1 * IEEE_SYMBOL_PIN_DIM * 2 ) );
}
}
Plume( 'Z' );
}
/*******************************************/
void PlotTextStruct( EDA_BaseStruct* Struct )
static void PlotTextStruct(Plotter *plotter, EDA_BaseStruct* Struct )
/*******************************************/
/*
......@@ -685,13 +533,12 @@ void PlotTextStruct( EDA_BaseStruct* Struct )
SCH_TEXT* schText = (SCH_TEXT*) Struct;
EDA_Colors color = UNSPECIFIED_COLOR;
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
color = ReturnLayerColor( schText->m_Layer );
wxPoint textpos = schText->m_Pos + schText->GetSchematicTextOffset();
int thickness = (schText->m_Width == 0) ? g_DrawDefaultLineThickness : schText->m_Width;
thickness = Clamp_Text_PenSize( thickness, schText->m_Size, schText->m_Bold );
SetCurrentLineWidth( thickness );
plotter->set_current_line_width( thickness );
if( schText->m_MultilineAllowed )
{
......@@ -705,7 +552,7 @@ void PlotTextStruct( EDA_BaseStruct* Struct )
for( unsigned i = 0; i<list->Count(); i++ )
{
wxString txt = list->Item( i );
PlotGraphicText( g_PlotFormat, pos,
plotter->text( pos,
color, txt, schText->m_Orient, schText->m_Size,
schText->m_HJustify, schText->m_VJustify,
thickness, schText->m_Italic, schText->m_Bold );
......@@ -716,7 +563,7 @@ void PlotTextStruct( EDA_BaseStruct* Struct )
}
else
PlotGraphicText( g_PlotFormat, textpos,
plotter->text( textpos,
color, schText->m_Text, schText->m_Orient, schText->m_Size,
schText->m_HJustify, schText->m_VJustify,
thickness, schText->m_Italic, schText->m_Bold );
......@@ -725,18 +572,19 @@ void PlotTextStruct( EDA_BaseStruct* Struct )
if( Struct->Type() == TYPE_SCH_GLOBALLABEL )
{
( (SCH_GLOBALLABEL*) Struct )->CreateGraphicShape( Poly, schText->m_Pos );
PlotPoly( Poly.size(), &Poly[0].x, NOFILL );
plotter->poly( Poly.size(), &Poly[0].x, NO_FILL );
}
if( Struct->Type() == TYPE_SCH_HIERLABEL )
{
( (SCH_HIERLABEL*) Struct )->CreateGraphicShape( Poly, schText->m_Pos );
PlotPoly( Poly.size(), &Poly[0].x, NOFILL );
plotter->poly( Poly.size(), &Poly[0].x, NO_FILL );
}
}
/*****************************************************************************************/
static void Plot_Hierarchical_PIN_Sheet( Hierarchical_PIN_Sheet_Struct* aHierarchical_PIN )
static void Plot_Hierarchical_PIN_Sheet(Plotter *plotter,
Hierarchical_PIN_Sheet_Struct* aHierarchical_PIN )
/****************************************************************************************/
/* Plot a Hierarchical_PIN_Sheet
......@@ -747,7 +595,6 @@ static void Plot_Hierarchical_PIN_Sheet( Hierarchical_PIN_Sheet_Struct* aHierarc
static std::vector <wxPoint> Poly;
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
txtcolor = ReturnLayerColor( aHierarchical_PIN->GetLayer() );
posx = aHierarchical_PIN->m_Pos.x;
......@@ -767,9 +614,9 @@ static void Plot_Hierarchical_PIN_Sheet( Hierarchical_PIN_Sheet_Struct* aHierarc
int thickness = (aHierarchical_PIN->m_Width == 0) ? g_DrawDefaultLineThickness : aHierarchical_PIN->m_Width;
thickness = Clamp_Text_PenSize( thickness, aHierarchical_PIN->m_Size, aHierarchical_PIN->m_Bold );
SetCurrentLineWidth( thickness );
plotter->set_current_line_width( thickness );
PlotGraphicText( g_PlotFormat, wxPoint( tposx, posy ), txtcolor,
plotter->text( wxPoint( tposx, posy ), txtcolor,
aHierarchical_PIN->m_Text, TEXT_ORIENT_HORIZ, wxSize( size, size ),
side, GR_TEXT_VJUSTIFY_CENTER,
thickness, aHierarchical_PIN->m_Italic, aHierarchical_PIN->m_Bold );
......@@ -777,12 +624,12 @@ static void Plot_Hierarchical_PIN_Sheet( Hierarchical_PIN_Sheet_Struct* aHierarc
/* Draw the associated graphic symbol */
aHierarchical_PIN->CreateGraphicShape( Poly, aHierarchical_PIN->m_Pos );
PlotPoly( Poly.size(), &Poly[0].x, NOFILL );
plotter->poly( Poly.size(), &Poly[0].x, NO_FILL );
}
/*************************************************/
void PlotSheetStruct( DrawSheetStruct* Struct )
static void PlotSheetStruct(Plotter *plotter, DrawSheetStruct* Struct )
/*************************************************/
/* Routine de dessin du bloc type hierarchie */
{
......@@ -792,25 +639,22 @@ void PlotSheetStruct( DrawSheetStruct* Struct )
wxString Text;
wxPoint pos;
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( Struct->m_Layer ) );
plotter->set_color( ReturnLayerColor( Struct->m_Layer ) );
int thickness = g_DrawDefaultLineThickness;
SetCurrentLineWidth( thickness );
plotter->set_current_line_width( thickness );
Move_Plume( Struct->m_Pos, 'U' );
plotter->move_to( Struct->m_Pos );
pos = Struct->m_Pos; pos.x += Struct->m_Size.x;
Move_Plume( pos, 'D' );
plotter->line_to( pos );
pos.y += Struct->m_Size.y;
Move_Plume( pos, 'D' );
plotter->line_to( pos );
pos = Struct->m_Pos; pos.y += Struct->m_Size.y;
Move_Plume( pos, 'D' );
Move_Plume( Struct->m_Pos, 'D' );
Plume( 'Z' );
plotter->line_to( pos );
plotter->finish_to( Struct->m_Pos );
/* Draw texts: SheetName */
Text = Struct->m_SheetName;
......@@ -819,11 +663,10 @@ void PlotSheetStruct( DrawSheetStruct* Struct )
thickness = g_DrawDefaultLineThickness;
thickness = Clamp_Text_PenSize( thickness, size, false );
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( LAYER_SHEETNAME ) );
plotter->set_color( ReturnLayerColor( LAYER_SHEETNAME ) );
bool italic = false;
PlotGraphicText( g_PlotFormat, pos, txtcolor,
plotter->text( pos, txtcolor,
Text, TEXT_ORIENT_HORIZ, size,
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM,
thickness, italic, false );
......@@ -834,11 +677,9 @@ void PlotSheetStruct( DrawSheetStruct* Struct )
thickness = g_DrawDefaultLineThickness;
thickness = Clamp_Text_PenSize( thickness, size, false );
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( LAYER_SHEETFILENAME ) );
plotter->set_color( ReturnLayerColor( LAYER_SHEETFILENAME ) );
PlotGraphicText( g_PlotFormat,
wxPoint( Struct->m_Pos.x, Struct->m_Pos.y + Struct->m_Size.y + 4 ),
plotter->text( wxPoint( Struct->m_Pos.x, Struct->m_Pos.y + Struct->m_Size.y + 4 ),
txtcolor,
Text, TEXT_ORIENT_HORIZ, size,
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP,
......@@ -846,12 +687,121 @@ void PlotSheetStruct( DrawSheetStruct* Struct )
/* Draw texts : SheetLabel */
SheetLabelStruct = Struct->m_Label;
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( Struct->m_Layer ) );
plotter->set_color( ReturnLayerColor( Struct->m_Layer ) );
while( SheetLabelStruct != NULL )
{
Plot_Hierarchical_PIN_Sheet( SheetLabelStruct );
Plot_Hierarchical_PIN_Sheet(plotter, SheetLabelStruct );
SheetLabelStruct = SheetLabelStruct->Next();
}
}
/*************************************************/
void PlotDrawlist(Plotter *plotter, SCH_ITEM* drawlist )
/*************************************************/
{
while( drawlist ) /* tracage */
{
SCH_COMPONENT* DrawLibItem;
int layer;
wxPoint StartPos, EndPos;
switch( drawlist->Type() )
{
case DRAW_BUSENTRY_STRUCT_TYPE: /* Struct Raccord et Segment sont identiques */
#undef STRUCT
#define STRUCT ( (DrawBusEntryStruct*) drawlist )
StartPos = STRUCT->m_Pos;
EndPos = STRUCT->m_End();
layer = STRUCT->GetLayer();
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (EDA_DrawLineStruct*) drawlist )
if( drawlist->Type() == DRAW_SEGMENT_STRUCT_TYPE )
{
StartPos = STRUCT->m_Start;
EndPos = STRUCT->m_End;
layer = STRUCT->GetLayer();
}
plotter->set_color( ReturnLayerColor( layer ) );
switch( layer )
{
case LAYER_NOTES: /* Trace en pointilles */
plotter->set_current_line_width( g_DrawDefaultLineThickness );
plotter->set_dash(true);
plotter->move_to( StartPos );
plotter->finish_to( EndPos );
plotter->set_dash(false);
break;
case LAYER_BUS: /* Trait large */
{
int thickness = wxRound( g_DrawDefaultLineThickness * 2 );
if ( thickness < 3 ) thickness = 3;
/* We NEED it to be thick, even on HPGL */
plotter->thick_segment(StartPos, EndPos, thickness, FILLED);
plotter->set_current_line_width( g_DrawDefaultLineThickness );
}
break;
default:
plotter->set_current_line_width( g_DrawDefaultLineThickness );
plotter->move_to( StartPos );
plotter->finish_to( EndPos );
break;
}
break;
case DRAW_JUNCTION_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawJunctionStruct*) drawlist )
plotter->set_color( ReturnLayerColor( STRUCT->GetLayer() ) );
plotter->circle( STRUCT->m_Pos, DRAWJUNCTION_SIZE, FILLED_SHAPE );
break;
case TYPE_SCH_TEXT:
case TYPE_SCH_LABEL:
case TYPE_SCH_GLOBALLABEL:
case TYPE_SCH_HIERLABEL:
PlotTextStruct(plotter, drawlist );
break;
case TYPE_SCH_COMPONENT:
DrawLibItem = (SCH_COMPONENT*) drawlist;
PlotLibPart(plotter, DrawLibItem );
break;
case DRAW_PICK_ITEM_STRUCT_TYPE:
break;
case DRAW_POLYLINE_STRUCT_TYPE:
break;
case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE:
break;
case DRAW_MARKER_STRUCT_TYPE:
break;
case DRAW_SHEET_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawSheetStruct*) drawlist )
PlotSheetStruct(plotter, STRUCT );
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawNoConnectStruct*) drawlist )
plotter->set_color( ReturnLayerColor( LAYER_NOCONNECT ) );
PlotNoConnectStruct(plotter, STRUCT );
break;
default:
break;
}
drawlist = drawlist->Next();
}
}
......@@ -28,24 +28,14 @@
#include "general.h"
#include "worksheet.h"
#include "plot_common.h"
#include "protos.h"
/* coeff de conversion dim en 1 mil -> dim en unite HPGL: */
#define SCALE_HPGL 1.02041
#include "plothpgl.h"
////@begin XPM images
////@end XPM images
extern void Move_Plume( wxPoint pos, int plume );
extern void Plume( int plume );
/* Variables locales : */
FILE* PlotOutput; /* exportee dans printps.cc */
static double Scale_X = 1;
static double Scale_Y = 1;
int HPGL_SizeSelect;
enum PageFormatReq {
......@@ -519,9 +509,6 @@ void WinEDA_PlotHPGLFrame::Plot_Schematic_HPGL( int Select_PlotAll, int HPGL_She
Ki_PageDescr* PlotSheet;
wxSize SheetSize;
wxPoint SheetOffset, PlotOffset;
int margin;
g_PlotFormat = PLOT_FORMAT_HPGL;
/* When printing all pages, the printed page is not the current page.
* In complex hierarchies, we must setup references and others parameters in the printed SCH_SCREEN
......@@ -532,7 +519,7 @@ void WinEDA_PlotHPGLFrame::Plot_Schematic_HPGL( int Select_PlotAll, int HPGL_She
sheetpath = SheetList.GetFirst();
DrawSheetPath list;
for( ; ; )
while (true)
{
if( Select_PlotAll )
{
......@@ -547,31 +534,27 @@ void WinEDA_PlotHPGLFrame::Plot_Schematic_HPGL( int Select_PlotAll, int HPGL_She
screen = schframe->m_CurrentSheet->LastScreen();
ActiveScreen = screen;
}
else // Should not occur
else // Should not happen
return;
sheetpath = SheetList.GetNext();
}
ReturnSheetDims( screen, SheetSize, SheetOffset );
/* Calcul des echelles de conversion */
g_PlotScaleX = Scale_X * SCALE_HPGL;
g_PlotScaleY = Scale_Y * SCALE_HPGL;
margin = 400; // Margin in mils
if (HPGL_SheetSize)
PlotSheet = Plot_sheet_list[HPGL_SheetSize];
else
PlotSheet = screen->m_CurrentSheetDesc;
g_PlotScaleX = g_PlotScaleX * (SheetSize.x - 2 * margin) / PlotSheet->m_Size.x;
g_PlotScaleY = g_PlotScaleY * (SheetSize.y - 2 * margin) / PlotSheet->m_Size.y;
/* 10x because eeschema works in mils, not decimils */
double plot_scale = 10 * (double)PlotSheet->m_Size.x / (double)SheetSize.x;
/* calcul des offsets */
PlotOffset.x = -(int) ( SheetOffset.x * SCALE_HPGL );
PlotOffset.y = (int) ( (SheetOffset.y + SheetSize.y) * SCALE_HPGL );
PlotOffset.x -= (int) ( margin * SCALE_HPGL );
PlotOffset.y += (int) ( margin * SCALE_HPGL );
PlotOffset.x = -SheetOffset.x;
PlotOffset.y = -SheetOffset.y;
PlotFileName = schframe->GetUniqueFilenameForCurrentSheet() + wxT( ".plt" );
SetLocaleTo_C_standard();
InitPlotParametresHPGL( PlotOffset, g_PlotScaleX, g_PlotScaleY );
Plot_1_Page_HPGL( PlotFileName, screen );
Plot_1_Page_HPGL( PlotFileName, screen, PlotSheet, PlotOffset, plot_scale );
SetLocaleTo_Default();
if( !Select_PlotAll )
......@@ -586,152 +569,54 @@ void WinEDA_PlotHPGLFrame::Plot_Schematic_HPGL( int Select_PlotAll, int HPGL_She
/**************************************************************************/
void WinEDA_PlotHPGLFrame::Plot_1_Page_HPGL( const wxString& FullFileName,
BASE_SCREEN* screen )
void WinEDA_PlotHPGLFrame::Plot_1_Page_HPGL( const wxString& FileName,
SCH_SCREEN* screen,
Ki_PageDescr* sheet,
wxPoint &offset,
double plot_scale)
/**************************************************************************/
/* Trace en format HPGL. d'une feuille de dessin
* 1 unite HPGL = 0.98 mils ( 1 mil = 1.02041 unite HPGL ) .
*/
{
EDA_BaseStruct* DrawList;
SCH_COMPONENT* DrawLibItem;
int x1 = 0, y1 = 0, x2 = 0, y2 = 0, layer;
wxString msg;
PlotOutput = wxFopen( FullFileName, wxT( "wt" ) );
if( PlotOutput == 0 )
FILE *output_file = wxFopen( FileName, wxT( "wt" ) );
if( output_file == NULL )
{
msg = _( "Unable to create " ) + FullFileName;
DisplayError( this, msg ); return;
msg = wxT( "\n** " );
msg += _( "Unable to create " ) + FileName + wxT( " **\n\n" );
m_MsgBox->AppendText( msg );
wxBell();
return;
}
msg = _( "Plot " ) + FullFileName + wxT( "\n" );
SetLocaleTo_C_standard();
msg.Printf( _( "Plot: %s\n" ), FileName.GetData() );
m_MsgBox->AppendText( msg );
HPGL_Plotter *plotter = new HPGL_Plotter();
plotter->set_paper_size(sheet);
plotter->set_viewport( offset, plot_scale, 0);
plotter->set_default_line_width( g_DrawDefaultLineThickness );
/* Init : */
PrintHeaderHPGL( PlotOutput, g_HPGL_Pen_Descr.m_Pen_Speed, g_HPGL_Pen_Descr.m_Pen_Num );
m_Parent->PlotWorkSheet( PLOT_FORMAT_HPGL, screen );
DrawList = screen->EEDrawList;
while( DrawList ) /* tracage */
{
Plume( 'U' );
layer = LAYER_NOTES;
switch( DrawList->Type() )
{
case DRAW_BUSENTRY_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawBusEntryStruct*) DrawList )
x1 = STRUCT->m_Pos.x; y1 = STRUCT->m_Pos.y;
x2 = STRUCT->m_End().x; y2 = STRUCT->m_End().y;
layer = STRUCT->GetLayer();
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (EDA_DrawLineStruct*) DrawList )
if( DrawList->Type() == DRAW_SEGMENT_STRUCT_TYPE )
{
x1 = STRUCT->m_Start.x; y1 = STRUCT->m_Start.y;
x2 = STRUCT->m_End.x; y2 = STRUCT->m_End.y;
layer = STRUCT->GetLayer();
}
switch( layer )
{
case LAYER_NOTES: /* Trace en pointilles */
Move_Plume( wxPoint( x1, y1 ), 'U' );
fprintf( PlotOutput, "LT 2;\n" );
Move_Plume( wxPoint( x2, y2 ), 'D' );
fprintf( PlotOutput, "LT;\n" );
break;
case LAYER_BUS: /* Trait large */
{
int deltaX = 0, deltaY = 0; double angle;
if( (x2 - x1) == 0 )
deltaX = 8;
else if( (y2 - y1) == 0 )
deltaY = 8;
else
{
angle = atan2( (double) ( x2 - x1 ), (double) ( y1 - y2 ) );
deltaX = (int) ( 8 * sin( angle ) );
deltaY = (int) ( 8 * cos( angle ) );
}
Move_Plume( wxPoint( x1 + deltaX, y1 - deltaY ), 'U' );
Move_Plume( wxPoint( x1 - deltaX, y1 + deltaY ), 'D' );
Move_Plume( wxPoint( x2 - deltaX, y2 + deltaY ), 'D' );
Move_Plume( wxPoint( x2 + deltaX, y2 - deltaY ), 'D' );
Move_Plume( wxPoint( x1 + deltaX, y1 - deltaY ), 'D' );
}
break;
default:
Move_Plume( wxPoint( x1, y1 ), 'U' );
Move_Plume( wxPoint( x2, y2 ), 'D' );
break;
}
plotter->set_creator(wxT("EESchema-HPGL"));
plotter->set_filename(FileName);
plotter->set_pen_speed(g_HPGL_Pen_Descr.m_Pen_Speed);
plotter->set_pen_number(g_HPGL_Pen_Descr.m_Pen_Num);
plotter->set_pen_diameter(g_HPGL_Pen_Descr.m_Pen_Diam);
plotter->set_pen_overlap(g_HPGL_Pen_Descr.m_Pen_Diam/2);
plotter->start_plot( output_file );
break;
case DRAW_JUNCTION_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawJunctionStruct*) DrawList )
x1 = STRUCT->m_Pos.x; y1 = STRUCT->m_Pos.y;
PlotCercle( wxPoint( x1, y1 ), DRAWJUNCTION_SIZE * 2, true );
break;
plotter->set_color( BLACK );
m_Parent->PlotWorkSheet( plotter, screen );
case TYPE_SCH_TEXT:
case TYPE_SCH_LABEL:
case TYPE_SCH_GLOBALLABEL:
case TYPE_SCH_HIERLABEL:
PlotTextStruct( DrawList );
break;
case TYPE_SCH_COMPONENT:
DrawLibItem = (SCH_COMPONENT*) DrawList;
PlotLibPart( DrawLibItem );
break;
case DRAW_PICK_ITEM_STRUCT_TYPE:
break;
case DRAW_POLYLINE_STRUCT_TYPE:
break;
case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE:
break;
case DRAW_MARKER_STRUCT_TYPE:
break;
case DRAW_SHEET_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawSheetStruct*) DrawList )
PlotSheetStruct( STRUCT );
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawNoConnectStruct*) DrawList )
PlotNoConnectStruct( STRUCT );
break;
default:
break;
}
Plume( 'U' );
DrawList = DrawList->Next();
}
PlotDrawlist(plotter, screen->EEDrawList);
/* fin */
CloseFileHPGL( PlotOutput );
}
plotter->end_plot();
delete plotter;
SetLocaleTo_Default();
m_MsgBox->AppendText( wxT( "Ok\n" ) );
}
/*!
* wxEVT_COMMAND_RADIOBOX_SELECTED event handler for ID_RADIOBOX
......
......@@ -132,7 +132,8 @@ public:
void SetPenWidth(wxSpinEvent& event);
void SetPenSpeed(wxSpinEvent& event);
void SetPenNum(wxSpinEvent& event);
void Plot_1_Page_HPGL(const wxString & FullFileName,BASE_SCREEN * screen);
void Plot_1_Page_HPGL(const wxString &FileName, SCH_SCREEN * screen,
Ki_PageDescr* paper, wxPoint& offset, double scale);
void Plot_Schematic_HPGL(int Select_PlotAll, int HPGL_SheetSize);
void ReturnSheetDims( BASE_SCREEN * screen, wxSize & SheetSize, wxPoint & SheetOffset);
void SetPageOffsetValue();
......
......@@ -18,8 +18,8 @@
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "confirm.h"
#include "program.h"
#include "libcmp.h"
#include "general.h"
......@@ -27,28 +27,16 @@
#include "plot_common.h"
#include "protos.h"
// coeff de conversion dim en 1 mil -> dim en unite PS:
const double SCALE_PS = 0.001;
extern void Move_Plume( wxPoint pos, int plume );
extern void Plume( int plume );
enum PageFormatReq {
PAGE_SIZE_AUTO,
PAGE_SIZE_A4,
PAGE_SIZE_A
};
/* Variables locales : */
static int PS_SizeSelect = PAGE_SIZE_AUTO;
extern FILE* PlotOutput;
static bool Plot_Sheet_Ref = TRUE;
////@begin includes
////@end includes
#include "plotps.h"
////@begin XPM images
......@@ -116,6 +104,7 @@ WinEDA_PlotPSFrame::WinEDA_PlotPSFrame( WinEDA_DrawFrame* parent,
long style )
{
m_Parent = parent;
PlotPSColorOpt = false;
Create( parent, id, caption, pos, size, style );
}
......@@ -223,7 +212,7 @@ void WinEDA_PlotPSFrame::CreateControls()
// Set validators
m_SizeOption->SetValidator( wxGenericValidator(& PS_SizeSelect) );
m_PlotPSColorOption->SetValidator( wxGenericValidator(& g_PlotPSColorOpt) );
m_PlotPSColorOption->SetValidator( wxGenericValidator(& PlotPSColorOpt) );
m_Plot_Sheet_Ref->SetValidator( wxGenericValidator(& Plot_Sheet_Ref) );
////@end WinEDA_PlotPSFrame content construction
......@@ -318,7 +307,7 @@ void WinEDA_PlotPSFrame::InitOptVars()
/*****************************************/
{
Plot_Sheet_Ref = m_Plot_Sheet_Ref->GetValue();
g_PlotPSColorOpt = m_PlotPSColorOption->GetSelection();
PlotPSColorOpt = m_PlotPSColorOption->GetSelection();
PS_SizeSelect = m_SizeOption->GetSelection();
g_DrawDefaultLineThickness = m_DefaultLineSizeCtrl->GetValue();
if( g_DrawDefaultLineThickness < 1 )
......@@ -335,12 +324,9 @@ void WinEDA_PlotPSFrame::CreatePSFile( int AllPages, int pagesize )
SCH_SCREEN* oldscreen = screen;
DrawSheetPath* sheetpath, *oldsheetpath = schframe->GetSheet();
wxString PlotFileName;
Ki_PageDescr* PlotSheet, * RealSheet;
int BBox[4];
Ki_PageDescr* PlotSheet, *RealSheet;
wxPoint plot_offset;
g_PlotFormat = PLOT_FORMAT_POST;
/* When printing all pages, the printed page is not the current page.
* In complex hierarchies, we must setup references and others parameters in the printed SCH_SCREEN
* because in complex hierarchies a SCH_SCREEN (a schematic drawings)
......@@ -350,7 +336,7 @@ void WinEDA_PlotPSFrame::CreatePSFile( int AllPages, int pagesize )
sheetpath = SheetList.GetFirst();
DrawSheetPath list;
for( ; ; )
while (true)
{
if( AllPages )
{
......@@ -370,28 +356,30 @@ void WinEDA_PlotPSFrame::CreatePSFile( int AllPages, int pagesize )
sheetpath = SheetList.GetNext();
}
PlotSheet = screen->m_CurrentSheetDesc;
switch (pagesize)
{
case PAGE_SIZE_A:
RealSheet = &g_Sheet_A;
break;
case PAGE_SIZE_A4:
RealSheet = &g_Sheet_A4;
if( pagesize == PAGE_SIZE_AUTO )
break;
case PAGE_SIZE_AUTO:
default:
RealSheet = PlotSheet;
else if( pagesize == PAGE_SIZE_A )
RealSheet = &g_Sheet_A;
break;
}
/* Calculate plot bouding box in 1/1000 inch */
BBox[0] = BBox[1] = g_PlotMargin; // Plot margin in 1/1000 inch
BBox[2] = RealSheet->m_Size.x - g_PlotMargin;
BBox[3] = RealSheet->m_Size.y - g_PlotMargin;
/* Calculate pcbnew to PS conversion scale */
g_PlotScaleX = SCALE_PS * (float) (BBox[2] - BBox[0]) / PlotSheet->m_Size.x;
g_PlotScaleY = SCALE_PS * (float) (BBox[3] - BBox[1]) / PlotSheet->m_Size.y;
double scalex = (double) RealSheet->m_Size.x / PlotSheet->m_Size.x;
double scaley = (double) RealSheet->m_Size.y / PlotSheet->m_Size.y;
double scale = 10 * MIN(scalex, scaley);
plot_offset.x = 0;
plot_offset.y = PlotSheet->m_Size.y;
plot_offset.y = 0;
PlotFileName = schframe->GetUniqueFilenameForCurrentSheet( ) + wxT( ".ps" );
PlotOneSheetPS( PlotFileName, screen, RealSheet, BBox, plot_offset );
PlotOneSheetPS( PlotFileName, screen, RealSheet, plot_offset, scale );
if( !AllPages )
break;
......@@ -408,163 +396,51 @@ void WinEDA_PlotPSFrame::CreatePSFile( int AllPages, int pagesize )
void WinEDA_PlotPSFrame::PlotOneSheetPS( const wxString& FileName,
SCH_SCREEN* screen,
Ki_PageDescr* sheet,
int BBox[4],
wxPoint plot_offset )
wxPoint plot_offset,
double scale)
/*****************************************************************************************/
/* Trace en format PS. d'une feuille de dessin
*/
{
wxString Line;
SCH_ITEM* DrawList;
SCH_COMPONENT* DrawLibItem;
int layer;
wxPoint StartPos, EndPos;
PlotOutput = wxFopen( FileName, wxT( "wt" ) );
if( PlotOutput == NULL )
wxString msg;
FILE *output_file = wxFopen( FileName, wxT( "wt" ) );
if( output_file == NULL )
{
Line = wxT( "\n** " );
Line += _( "Unable to create " ) + FileName + wxT( " **\n\n" );
m_MsgBox->AppendText( Line );
msg = wxT( "\n** " );
msg += _( "Unable to create " ) + FileName + wxT( " **\n\n" );
m_MsgBox->AppendText( msg );
wxBell();
return;
}
SetLocaleTo_C_standard();
Line.Printf( _( "Plot: %s\n" ), FileName.GetData() );
m_MsgBox->AppendText( Line );
msg.Printf( _( "Plot: %s\n" ), FileName.GetData() );
m_MsgBox->AppendText( msg );
InitPlotParametresPS( plot_offset, sheet, g_PlotScaleX, g_PlotScaleY );
SetDefaultLineWidthPS( g_DrawDefaultLineThickness );
PS_Plotter *plotter = new PS_Plotter();
plotter->set_paper_size(sheet);
plotter->set_viewport( plot_offset, scale, 0);
plotter->set_default_line_width( g_DrawDefaultLineThickness );
plotter->set_color_mode(PlotPSColorOpt);
/* Init : */
PrintHeaderPS( PlotOutput, wxT( "EESchema-PS" ), FileName, 1, BBox, wxLANDSCAPE );
InitPlotParametresPS( plot_offset, sheet, 1.0, 1.0 );
if( m_Plot_Sheet_Ref->GetValue() )
{
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( BLACK );
m_Parent->PlotWorkSheet( PLOT_FORMAT_POST, screen );
}
DrawList = screen->EEDrawList;
while( DrawList ) /* tracage */
{
layer = LAYER_NOTES;
plotter->set_creator(wxT("EESchema-PS"));
plotter->set_filename(FileName);
plotter->start_plot(output_file);
switch( DrawList->Type() )
{
case DRAW_BUSENTRY_STRUCT_TYPE: /* Struct Raccord et Segment sont identiques */
#undef STRUCT
#define STRUCT ( (DrawBusEntryStruct*) DrawList )
StartPos = STRUCT->m_Pos;
EndPos = STRUCT->m_End();
layer = STRUCT->GetLayer();
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (EDA_DrawLineStruct*) DrawList )
if( DrawList->Type() == DRAW_SEGMENT_STRUCT_TYPE )
if( Plot_Sheet_Ref )
{
StartPos = STRUCT->m_Start;
EndPos = STRUCT->m_End;
layer = STRUCT->GetLayer();
}
if( g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( layer ) );
switch( layer )
{
case LAYER_NOTES: /* Trace en pointilles */
SetCurrentLineWidth( g_DrawDefaultLineThickness );
fprintf( PlotOutput, "[50 50] 0 setdash\n" );
Move_Plume( StartPos, 'U' );
Move_Plume( EndPos, 'D' );
Plume( 'Z' );
fprintf( PlotOutput, "[] 0 setdash\n" );
break;
case LAYER_BUS: /* Trait large */
{
int thickness = wxRound( g_DrawDefaultLineThickness * 1.4 );
if ( thickness < 3 ) thickness = 3;
SetCurrentLineWidth( thickness );
fprintf( PlotOutput, "%d setlinewidth\n", thickness );
Move_Plume( StartPos, 'U' );
Move_Plume( EndPos, 'D' );
Plume( 'Z' );
SetCurrentLineWidth( g_DrawDefaultLineThickness );
fprintf( PlotOutput, "%d setlinewidth\n", g_DrawDefaultLineThickness );
}
break;
default:
SetCurrentLineWidth( g_DrawDefaultLineThickness );
Move_Plume( StartPos, 'U' );
Move_Plume( EndPos, 'D' );
Plume( 'Z' );
break;
}
break;
case DRAW_JUNCTION_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawJunctionStruct*) DrawList )
if( g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( STRUCT->GetLayer() ) );
PlotCercle( STRUCT->m_Pos, DRAWJUNCTION_SIZE, 1 );
break;
case TYPE_SCH_TEXT:
case TYPE_SCH_LABEL:
case TYPE_SCH_GLOBALLABEL:
case TYPE_SCH_HIERLABEL:
PlotTextStruct( DrawList );
break;
case TYPE_SCH_COMPONENT:
DrawLibItem = (SCH_COMPONENT*) DrawList;
PlotLibPart( DrawLibItem );
break;
case DRAW_PICK_ITEM_STRUCT_TYPE:
break;
case DRAW_POLYLINE_STRUCT_TYPE:
break;
case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE:
break;
case DRAW_MARKER_STRUCT_TYPE:
break;
case DRAW_SHEET_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawSheetStruct*) DrawList )
PlotSheetStruct( STRUCT );
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawNoConnectStruct*) DrawList )
if( g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( LAYER_NOCONNECT ) );
PlotNoConnectStruct( STRUCT );
break;
default:
break;
plotter->set_color( BLACK );
m_Parent->PlotWorkSheet( plotter, screen );
}
DrawList = DrawList->Next();
}
PlotDrawlist(plotter, screen->EEDrawList);
/* fin */
CloseFilePS( PlotOutput );
plotter->end_plot();
delete plotter;
SetLocaleTo_Default();
m_MsgBox->AppendText( wxT( "Ok\n" ) );
......
......@@ -106,7 +106,8 @@ public:
void InitOptVars();
void CreatePSFile(int AllPages, int pagesize);
void PlotOneSheetPS(const wxString & FileName,
SCH_SCREEN * screen, Ki_PageDescr * sheet, int BBox[4], wxPoint plot_offset);
SCH_SCREEN * screen, Ki_PageDescr * sheet,
wxPoint plot_offset, double scale);
/// Should we show tooltips?
static bool ShowToolTips();
......@@ -121,6 +122,7 @@ public:
////@end WinEDA_PlotPSFrame member variables
WinEDA_DrawFrame * m_Parent;
WinEDA_ValueCtrl * m_DefaultLineSizeCtrl;
int PlotPSColorOpt;
};
#endif
......
......@@ -244,18 +244,7 @@ int CheckAnnotate(WinEDA_SchematicFrame * frame, bool OneSheetOnly);
/************/
/* PLOT.CPP */
/************/
void SetCurrentLineWidth( int width);
void PlotArc(wxPoint centre, int StAngle, int EndAngle, int rayon, int width = -1);
void PlotCercle(wxPoint centre, int diametre, bool fill, int width = -1);
void PlotPoly( int nb, int * coord, bool fill, int width = -1);
void PlotNoConnectStruct(DrawNoConnectStruct * Struct);
void PlotLibPart( SCH_COMPONENT *DrawLibItem );
/* Genere le trace d'un composant */
void PlotSheetStruct(DrawSheetStruct *Struct);
/* Routine de dessin du bloc type hierarchie */
void PlotTextStruct(EDA_BaseStruct *Struct);
void PlotDrawlist(Plotter *plotter, SCH_ITEM* drawlist );
/***************/
/* DELSHEET.CPP */
......
......@@ -342,38 +342,6 @@ static PARAM_CFG_SETCOLOR ColorDCodesCfg
WHITE /* Valeur par defaut */
);
static PARAM_CFG_INT HPGLpenNumCfg
(
wxT("HPGLnum"), /* identification */
&g_HPGL_Pen_Num, /* Adresse du parametre */
1, /* Valeur par defaut */
1, 16 /* Valeurs extremes */
);
static PARAM_CFG_INT HPGLdiamCfg
(
wxT("HPGdiam"), /* identification */
&g_HPGL_Pen_Diam, /* Adresse du parametre */
15, /* Valeur par defaut */
0,0xFFFF /* Valeurs extremes */
);
static PARAM_CFG_INT HPGLspeedCfg
(
wxT("HPGLSpd"), /* identification */
&g_HPGL_Pen_Speed, /* Adresse du parametre */
25, /* Valeur par defaut */
0,100 /* Valeurs extremes */
);
static PARAM_CFG_INT HPGLrecouvrementCfg
(
wxT("HPGLrec"), /* identification */
&g_HPGL_Pen_Recouvrement, /* Adresse du parametre */
2, /* Valeur par defaut */
0, 100 /* Valeurs extremes */
);
static PARAM_CFG_INT GERBERSpotMiniCfg
(
wxT("GERBmin"), /* identification */
......
......@@ -10,6 +10,12 @@
#include "pcbplot.h"
#include "protos.h"
/* The group of plot options - sadly global XXX */
PCB_Plot_Options g_pcb_plot_options;
/* variables locale : */
/* Routines Locales */
......@@ -24,7 +30,3 @@ void WinEDA_BasePcbFrame::ToPlotter(wxCommandEvent& event)
// frame->ShowModal(); frame->Destroy();
}
void Plume(int state)
{
}
......@@ -12,5 +12,41 @@
#define OPTKEY_PRINT_Y_FINESCALE_ADJ wxT( "PrintYFineScaleAdj" )
#define OPTKEY_PRINT_SCALE wxT( "PrintScale" )
/* Plot Options : */
struct PCB_Plot_Options {
bool Exclude_Edges_Pcb;
int PlotLine_Width;
bool Plot_Frame_Ref; // True to plot/print frame references
bool DrawViaOnMaskLayer; // True if vias are drawn on Mask layer (ie protected by mask)
int Plot_Mode;
bool Plot_Set_MIROIR;
bool Sel_Rotate_Window;
int HPGL_Pen_Num;
int HPGL_Pen_Speed;
int HPGL_Pen_Diam;
int HPGL_Pen_Recouvrement;
bool HPGL_Org_Centre; // TRUE si en HPGL, l'origine le centre de la feuille
int PlotPSColorOpt; // True for color Postscript output
bool Plot_PS_Negative; // True to create a negative board ps plot
/* Autorisation de trace des divers items en serigraphie */
bool Sel_Texte_Reference;
bool Sel_Texte_Valeur;
bool Sel_Texte_Divers;
bool Sel_Texte_Invisible;
bool PlotPadsOnSilkLayer;
bool Plot_Pads_All_Layers; /* Plot pads meme n'appartenant pas a la
couche ( utile pour serigraphie) */
/* id for plot format (see enum PlotFormat in plot_common.h) */
int PlotFormat;
int PlotOrient;
int PlotScaleOpt;
int DrillShapeOpt;
double Scale_X;
double Scale_Y;
};
extern PCB_Plot_Options g_pcb_plot_options;
#endif // ifndef PCBPLOT_H
......@@ -472,12 +472,27 @@ enum GRTextVertJustifyType {
};
/* Options to show solid segments (segments, texts...) */
enum GRFillMode {
enum GRTraceMode {
FILAIRE = 0, // segments are drawn as lines
FILLED, // normal mode: segments have thickness
SKETCH // skect mode: segments have thickness, but are not filled
};
/**
* Enum FILL_T
* is the set of fill types used in plotting or drawing enclosed areas.
*/
enum FILL_T {
NO_FILL, // Poly, Square, Circle, Arc = option No Fill
FILLED_SHAPE, /* Poly, Square, Circle, Arc = option Fill
* with current color ("Solid shape") */
FILLED_WITH_BG_BODYCOLOR, /* Poly, Square, Circle, Arc = option Fill
* with background body color, translucent
* (texts inside this shape can be seen)
* not filled in B&W mode when plotting or
* printing */
};
#define DEFAULT_SIZE_TEXT 60 /* default text height (in mils or 1/1000") */
......@@ -516,12 +531,12 @@ public:
* @param aOffset = draw offset (usually (0,0))
* @param EDA_Colors aColor = text color
* @param aDrawMode = GR_OR, GR_XOR.., -1 to use the current mode.
* @param GRFillMode aDisplay_mode = FILAIRE, FILLED or SKETCH
* @param GRTraceMode aDisplay_mode = FILAIRE, FILLED or SKETCH
* @param EDA_Colors aAnchor_color = anchor color ( UNSPECIFIED_COLOR = do not draw anchor ).
*/
void Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, EDA_Colors aColor,
int aDrawMode, GRFillMode aDisplay_mode = FILAIRE,
int aDrawMode, GRTraceMode aDisplay_mode = FILAIRE,
EDA_Colors aAnchor_color = UNSPECIFIED_COLOR );
private:
......@@ -540,7 +555,7 @@ private:
*/
void DrawOneLineOfText( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, EDA_Colors aColor,
int aDrawMode, GRFillMode aFillMode,
int aDrawMode, GRTraceMode aFillMode,
EDA_Colors aAnchor_color, wxString& aText,
wxPoint aPos );
public:
......
......@@ -7,21 +7,24 @@
#ifndef __INCLUDE__DRAWTXT_H__
#define __INCLUDE__DRAWTXT_H__ 1
#include "base_struct.h"
class WinEDA_DrawPanel;
class Plotter;
/** Function Clamp_Text_PenSize
*As a rule, pen width should not be >1/4em, otherwise the character
* will be cluttered up in its own fatness
* The pen width max is aSize/4 for bold texts, and aSize/6 for normal texts
* The "best" pen width is aSize/5 for bold texts,
* so the clamp is consistant with bold option.
* @param aPenSize = the pen size to clamp
* @param aSize the char size (height or width, od its wxSize)
* @param aBold = true if text accept bold pen size
* @return the max pen size allowed
*/
int Clamp_Text_PenSize( int aPenSize, int aSize, bool aBold = true);
int Clamp_Text_PenSize( int aPenSize, wxSize aSize, bool aBold = true);
* will be cluttered up in its own fatness
* The pen width max is aSize/4 for bold texts, and aSize/6 for normal texts
* The "best" pen width is aSize/5 for bold texts,
* so the clamp is consistant with bold option.
* @param aPenSize = the pen size to clamp
* @param aSize the char size (height or width, od its wxSize)
* @param aBold = true if text accept bold pen size
* @return the max pen size allowed
*/
int Clamp_Text_PenSize( int aPenSize, int aSize, bool aBold = true );
int Clamp_Text_PenSize( int aPenSize, wxSize aSize, bool aBold = true );
/** Function GetPensizeForBold
* @return the "best" value for a pen size to draw/plot a bold text
......@@ -33,7 +36,7 @@ int GetPenSizeForBold( int aTextSize );
* @return the X size of the graphic text
* the full X size is ReturnGraphicTextWidth + the thickness of graphic lines
*/
int ReturnGraphicTextWidth(const wxString& aText, int size_h, bool italic, bool bold );
int ReturnGraphicTextWidth( const wxString& aText, int size_h, bool italic, bool bold );
/** Function NegableTextLength
* Return the text length of a negable string, excluding the ~ markers */
......@@ -70,34 +73,8 @@ void DrawGraphicText( WinEDA_DrawPanel * aPanel,
int aWidth,
bool aItalic,
bool aBold,
void (*aCallback)( int x0, int y0, int xf, int yf ) = NULL );
/** Function PlotGraphicText
* same as DrawGraphicText, but plot graphic text insteed of draw it
* @param aFormat_plot = plot format (PLOT_FORMAT_POST, PLOT_FORMAT_HPGL, PLOT_FORMAT_GERBER)
* @param aPos = text position (according to aH_justify, aV_justify)
* @param aColor (enum EDA_Colors) = text color
* @param aText = text to draw
* @param aOrient = angle in 0.1 degree
* @param aSize = text size (size.x or size.y can be < 0 for mirrored texts)
* @param aH_justify = horizontal justification (Left, center, right)
* @param aV_justify = vertical justification (bottom, center, top)
* @param aWidth = line width (pen width) (default = 0)
* if width < 0 : draw segments in sketch mode, width = abs(width)
* @param aItalic = true to simulate an italic font
* @param aBold = true to use a bold font
*/
void PlotGraphicText( int aFormat_plot,
const wxPoint& aPos,
enum EDA_Colors aColor,
const wxString& aText,
int aOrient,
const wxSize& aSize,
enum GRTextHorizJustifyType aH_justify,
enum GRTextVertJustifyType aV_justify,
int aWidth,
bool aItalic,
bool aBold );
void (*aCallback)( int x0, int y0, int xf, int yf ) = NULL,
Plotter * plotter = NULL );
#endif /* __INCLUDE__DRAWTXT_H__ */
......@@ -69,24 +69,4 @@ extern wxString g_Current_PadName; // Last used pad name (pad num)
extern D_PAD g_Pad_Master;
/* Gestion des plumes en plot format HPGL */
extern int g_HPGL_Pen_Num;
extern int g_HPGL_Pen_Speed;
extern int g_HPGL_Pen_Diam;
extern int g_HPGL_Pen_Recouvrement;
extern float Scale_X;
extern float Scale_Y;
extern wxPoint g_PlotOffset;
extern int g_PlotLine_Width;
extern int g_PlotFormat;
extern int g_PlotOrient;
/* id for plot format (see enum PlotFormat in plot_common.h) */
extern int g_PlotScaleOpt;
extern int g_DrillShapeOpt;
#endif /* __PCBCOMMON_H__ */
/**
* Common plot library \n
* Plot settings, postscript plotting, gerber plotting.
*
*
* @file plot_common.h
*/
#ifndef __INCLUDE__PLOT_COMMON_H__
#define __INCLUDE__PLOT_COMMON_H__ 1
#include <vector>
using namespace std;
#include "drawtxt.h"
/**
* Enum PlotFormat
* must be kept in order of the radio buttons in the plot panel/window.
*/
enum
PlotFormat
{
enum PlotFormat {
PLOT_FORMAT_HPGL,
PLOT_FORMAT_GERBER,
PLOT_FORMAT_POST
};
const int PLOT_MIROIR = 1;
static inline bool IsPostScript( int aFormat )
class Plotter
{
return aFormat == PLOT_FORMAT_POST;
}
public:
Plotter()
{
plot_scale = 1;
default_pen_width = 0;
current_pen_width = -1; /* To-be-set marker */
pen_state = 'Z'; /* End-of-path idle */
plot_orient_options = 0; /* Mirror flag */
output_file = 0;
color_mode = false; /* Start as a BW plot */
negative_mode = false;
sheet = NULL;
}
const int PLOT_MIROIR = 1;
virtual ~Plotter()
{
/* Emergency cleanup */
if( output_file )
{
fclose( output_file );
}
}
// Variables used in Common plot functions
extern wxPoint g_Plot_PlotOffset;
extern FILE* g_Plot_PlotOutputFile;
extern double g_Plot_XScale, g_Plot_YScale;
extern int g_Plot_DefaultPenWidth, g_Plot_CurrentPenWidth;
extern int g_Plot_PlotOrientOptions, g_Plot_PenState;
/*******************************/
/* common_plot_functions.cpp */
/*******************************/
void SetPlotScale( double aXScale, double aYScale ); // Set the plot scale for the current plotting)
void Setg_Plot_PlotOffset( wxPoint offset ); // Set the plot offset for the current plotting)
void InitPlotParametresGERBER( wxPoint offset, double aXScale, double aYScale );
// void PlotWorkSheet( int format_plot, BASE_SCREEN* screen ); now a member of WinEDA_DrawFrame
void UserToDeviceCoordinate( wxPoint& pos );
// modifie les coord pos.x et pos.y pour le trace selon l'orientation, l'echelle, les offsets de trace
void UserToDeviceSize( wxSize& size );
// modifie les dimension size.x et size.y pour le trace selon l'echelle
void ForcePenReinit();
// set the flag g_Plot_CurrentPenWidth to -1 in order
// to force a pen width redefinition for the next draw command
/*******************************/
/* common_plotPS_functions.cpp */
/*******************************/
void SetCurrentLineWidthPS( int width );
void InitPlotParametresPS( wxPoint offset,
Ki_PageDescr* sheet,
double aXScale,
double aYScale,
int orient = 0 );
void SetDefaultLineWidthPS( int width );
void PlotRectPS( wxPoint p1, wxPoint p2, bool fill, int width = -1 );
void PlotCirclePS( wxPoint pos, int diametre, bool fill, int width = -1 );
void PlotArcPS( wxPoint centre, int StAngle, int EndAngle, int rayon, bool fill, int width = -1 );
// Plot an arc: StAngle, EndAngle = start and end arc in 0.1 degree
void PlotPolyPS( int nb_segm, int* coord, bool fill, int width = -1 );
void PlotFilledSegmentPS( wxPoint start, wxPoint end, int width );
void LineTo_PS( wxPoint pos, int plume );
void PrintHeaderPS( FILE* file,
const wxString& Creator,
const wxString& FileName,
int PageCount,
int BBox[4],
int PaperOrientation );
bool CloseFilePS( FILE* plot_file );
void SetColorMapPS( int color );
/*********************************/
/* common_plotHPGL_functions.cpp */
/*********************************/
void InitPlotParametresHPGL( wxPoint offset,
double aXScale,
double aYScale,
int orient = 0 );
bool PrintHeaderHPGL( FILE* plot_file,
int pen_speed,
int pen_num );
bool CloseFileHPGL( FILE* plot_file );
void PlotCircleHPGL( wxPoint centre,
int diameter,
bool fill,
int width = -1 );
void PlotRectHPGL( wxPoint t1,
wxPoint t2,
bool fill,
int width = -1 );
void PlotArcHPGL( wxPoint centre,
int StAngle,
int EndAngle,
int rayon,
bool fill,
int width = -1 );
void PlotPolyHPGL( int nb,
int* coord,
bool fill,
int width = -1 );
void Move_Plume_HPGL( wxPoint pos,
int plume );
void Plume_HPGL( int plume );
/*********************************/
/* common_plotGERBER_functions.cpp */
/*********************************/
/** Function InitPlotParametresGERBER
* Set the plot offset for the current plotting
* @param aOffset = plot offset
* @param aXScale,aYScale = coordinate scale (scale coefficient for coordinates)
*/
void InitPlotParametresGERBER( wxPoint aOffset,
double aXScale,
double aYScale );
/** Function Write_Header_GERBER
* Write GERBER header to file
* initialize global variable g_Plot_PlotOutputFile
* @param aTitle: the name of creator (comment)
* @param aFile: an opened file to write to
*/
void Write_Header_GERBER( const wxString aTitle,
FILE* aFile );
/** Function LineTo_GERBER
* if aCommand = 'U' initialise the starting point of a line
* if aCommand = 'D' draw a line from the starting point, or last point to aPos
* @param aPos = end of the current line.
* @param aCommand = 'U' or 'D' or 'Z' (Pen up , no moving )
*/
void LineTo_GERBER( wxPoint aPos,
int aCommand );
/** Function PlotGERBERLine
* Plot a line
* @param aStartPos = starting point of the line
* @param aEndPos = ending point of the line
* @param aThickness = line thickness
*/
void PlotGERBERLine( wxPoint aStartPos,
wxPoint aEndPos,
int aThickness );
/** Function PlotCircle_GERBER
* writes a non filled circle to output file
* Plot one circle as segments (6 to 16 depending on its radius
* @param aCentre = centre coordintes
* @param aRadius = radius of the circle
* @param aWidth = line width (noc currently used, D_CODEs must be selected before)
*/
void PlotCircle_GERBER( wxPoint aCentre,
int aRadius,
int aWidth );
/** Function PlotPolygon_GERBER
* writes a closed polyline (not a filled polygon) to output file
* @param aCornersCount = numer of corners
* @param aCoord = buffer of corners coordinates
* @param aWidth = line width (noc currently used, D_CODEs must be selected before)
*/
void PlotPolygon_GERBER( int aCornersCount,
int* aCoord,
int aWidth );
/** Function PlotFilledPolygon_GERBER
* writes a filled polyline to output file
* @param aCornersCount = numer of corners
* @param aCoord = buffer of corners coordinates
*/
void PlotFilledPolygon_GERBER( int aCornersCount,
int* aCoord );
#endif /* __INCLUDE__PLOT_COMMON_H__ */
virtual void start_plot( FILE* fout ) = 0;
virtual void end_plot() = 0;
virtual void set_negative( bool _negative )
{
negative_mode = _negative;
}
virtual void set_color_mode( bool _color_mode )
{
color_mode = _color_mode;
}
bool get_color_mode() const
{
return color_mode;
}
virtual void set_paper_size( Ki_PageDescr* sheet );
virtual void set_current_line_width( int width ) = 0;
virtual void set_default_line_width( int width ) = 0;
virtual void set_color( int color ) = 0;
virtual void set_dash( bool dashed ) = 0;
virtual void set_creator( const wxString& _creator )
{
creator = _creator;
}
virtual void set_filename( const wxString& _filename )
{
filename = _filename;
}
virtual void set_viewport( wxPoint offset,
double scale, int orient ) = 0;
/* Standard primitives */
virtual void rect( wxPoint p1, wxPoint p2, FILL_T fill,
int width = -1 ) = 0;
virtual void circle( wxPoint pos, int diametre, FILL_T fill,
int width = -1 ) = 0;
virtual void arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
FILL_T fill, int width = -1 );
virtual void poly( int nb_segm, int* coord, FILL_T fill,
int width = -1 ) = 0;
virtual void thick_segment( wxPoint start, wxPoint end, int width,
GRTraceMode tracemode );
virtual void thick_arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
int width, GRTraceMode tracemode );
virtual void thick_rect( wxPoint p1, wxPoint p2, int width,
GRTraceMode tracemode );
virtual void thick_circle( wxPoint pos, int diametre, int width,
GRTraceMode tracemode );
virtual void pen_to( wxPoint pos, char plume ) = 0;
/* Flash primitives */
virtual void flash_pad_circle( wxPoint pos, int diametre,
GRTraceMode trace_mode ) = 0;
virtual void flash_pad_oval( wxPoint pos, wxSize size, int orient,
GRTraceMode trace_mode ) = 0;
virtual void flash_pad_rect( wxPoint pos, wxSize size,
int orient, GRTraceMode trace_mode ) = 0;
virtual void flash_pad_trapez( wxPoint pos, wxSize size, wxSize delta,
int orient, GRTraceMode trace_mode ) = 0;
/* Convenience functions */
void move_to( wxPoint pos )
{
pen_to( pos, 'U' );
}
void line_to( wxPoint pos )
{
pen_to( pos, 'D' );
}
void finish_to( wxPoint pos )
{
pen_to( pos, 'D' );
pen_to( pos, 'Z' );
}
void pen_finish()
{
/* Shortcut */
pen_to( wxPoint( 0, 0 ), 'Z' );
}
void text( const wxPoint& aPos,
enum EDA_Colors aColor,
const wxString& aText,
int aOrient,
const wxSize& aSize,
enum GRTextHorizJustifyType aH_justify,
enum GRTextVertJustifyType aV_justify,
int aWidth,
bool aItalic,
bool aBold );
void marker( const wxPoint& position, int diametre, int aShapeId );
protected:
/* These are marker subcomponents */
void center_square( const wxPoint& position, int diametre, FILL_T fill );
void center_lozenge( const wxPoint& position, int diametre, FILL_T fill );
/* Helper function for sketched filler segment */
void segment_as_oval( wxPoint start, wxPoint end, int width,
GRTraceMode tracemode );
void sketch_oval( wxPoint pos, wxSize size, int orient, int width );
virtual void user_to_device_coordinates( wxPoint& pos );
virtual void user_to_device_size( wxSize& size );
virtual double user_to_device_size( double size );
/* Plot scale */
double plot_scale;
/* Device scale (from decimils to device units) */
double device_scale;
/* Plot offset (in decimils) */
wxPoint plot_offset;
/* Output file */
FILE* output_file;
/* Pen handling */
bool color_mode, negative_mode;
int default_pen_width;
int current_pen_width;
char pen_state;
wxPoint pen_lastpos;
/* Other stuff */
int plot_orient_options; /* For now, mirror plot */
wxString creator;
wxString filename;
Ki_PageDescr* sheet;
wxSize paper_size;
};
class HPGL_Plotter : public Plotter
{
public:
virtual void start_plot( FILE* fout );
virtual void end_plot();
/* HPGL doesn't handle line thickness or color */
virtual void set_current_line_width( int width )
{
/* Handy override */
current_pen_width = pen_diameter;
};
virtual void set_default_line_width( int width ) {};
virtual void set_dash( bool dashed );
virtual void set_color( int color ) {};
virtual void set_pen_speed( int speed )
{
wxASSERT( output_file == 0 );
pen_speed = speed;
}
virtual void set_pen_number( int number )
{
wxASSERT( output_file == 0 );
pen_number = number;
}
virtual void set_pen_diameter( double diameter )
{
wxASSERT( output_file == 0 );
pen_diameter = diameter;
}
virtual void set_pen_overlap( double overlap )
{
wxASSERT( output_file == 0 );
pen_overlap = overlap;
}
virtual void set_viewport( wxPoint offset,
double scale, int orient );
virtual void rect( wxPoint p1, wxPoint p2, FILL_T fill, int width = -1 );
virtual void circle( wxPoint pos, int diametre, FILL_T fill, int width = -1 );
virtual void poly( int nb_segm, int* coord, FILL_T fill, int width = -1 );
virtual void thick_segment( wxPoint start, wxPoint end, int width,
GRTraceMode tracemode );
virtual void arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
FILL_T fill, int width = -1 );
virtual void pen_to( wxPoint pos, char plume );
virtual void flash_pad_circle( wxPoint pos, int diametre,
GRTraceMode trace_mode );
virtual void flash_pad_oval( wxPoint pos, wxSize size, int orient,
GRTraceMode trace_mode );
virtual void flash_pad_rect( wxPoint pos, wxSize size,
int orient, GRTraceMode trace_mode );
virtual void flash_pad_trapez( wxPoint pos, wxSize size, wxSize delta,
int orient, GRTraceMode trace_mode );
protected:
void pen_control( int plume );
int pen_speed;
int pen_number;
double pen_diameter;
double pen_overlap;
};
class PS_Plotter : public Plotter
{
public:
PS_Plotter()
{
plot_scale_adjX = 1;
plot_scale_adjY = 1;
}
virtual void start_plot( FILE* fout );
virtual void end_plot();
virtual void set_current_line_width( int width );
virtual void set_default_line_width( int width );
virtual void set_dash( bool dashed );
virtual void set_color( int color );
void set_scale_adjust( double scaleX, double scaleY )
{
plot_scale_adjX = scaleX;
plot_scale_adjY = scaleY;
}
virtual void set_viewport( wxPoint offset,
double scale, int orient );
virtual void rect( wxPoint p1, wxPoint p2, FILL_T fill, int width = -1 );
virtual void circle( wxPoint pos, int diametre, FILL_T fill, int width = -1 );
virtual void arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
FILL_T fill, int width = -1 );
virtual void poly( int nb_segm, int* coord, FILL_T fill, int width = -1 );
virtual void pen_to( wxPoint pos, char plume );
virtual void flash_pad_circle( wxPoint pos, int diametre,
GRTraceMode trace_mode );
virtual void flash_pad_oval( wxPoint pos, wxSize size, int orient,
GRTraceMode trace_mode );
virtual void flash_pad_rect( wxPoint pos, wxSize size,
int orient, GRTraceMode trace_mode );
virtual void flash_pad_trapez( wxPoint pos, wxSize size, wxSize delta,
int orient, GRTraceMode trace_mode );
protected:
double plot_scale_adjX, plot_scale_adjY;
};
/* Class to handle a D_CODE when plotting a board : */
#define FIRST_DCODE_VALUE 10 // D_CODE < 10 is a command, D_CODE >= 10 is a tool
struct Aperture
{
enum Aperture_Type {
Circle = 1,
Rect = 2,
Plotting = 3,
Oval = 4
};
wxSize size; /* horiz and Vert size*/
Aperture_Type type; /* Type ( Line, rect , circulaire , ovale .. ) */
int D_code; /* code number ( >= 10 ); */
/* Trivia question: WHY Gerber decided to use D instead of the usual T for
* tool change? */
};
class Gerber_Plotter : public Plotter
{
public:
Gerber_Plotter()
{
work_file = 0;
final_file = 0;
current_aperture = apertures.end();
}
virtual void start_plot( FILE* fout );
virtual void end_plot();
virtual void set_current_line_width( int width );
virtual void set_default_line_width( int width );
/* RS274X has no dashing, nor colours */
virtual void set_dash( bool dashed ) {};
virtual void set_color( int color ) {};
virtual void set_viewport( wxPoint offset,
double scale, int orient );
virtual void rect( wxPoint p1, wxPoint p2, FILL_T fill, int width = -1 );
virtual void circle( wxPoint pos, int diametre, FILL_T fill, int width = -1 );
virtual void poly( int nb_segm, int* coord, FILL_T fill, int width = -1 );
virtual void pen_to( wxPoint pos, char plume );
virtual void flash_pad_circle( wxPoint pos, int diametre,
GRTraceMode trace_mode );
virtual void flash_pad_oval( wxPoint pos, wxSize size, int orient,
GRTraceMode trace_mode );
virtual void flash_pad_rect( wxPoint pos, wxSize size,
int orient, GRTraceMode trace_mode );
virtual void flash_pad_trapez( wxPoint pos, wxSize size, wxSize delta,
int orient, GRTraceMode trace_mode );
protected:
void select_aperture( const wxSize& size, Aperture::Aperture_Type type );
vector<Aperture>::iterator get_aperture( const wxSize& size,
Aperture::Aperture_Type type );
FILE* work_file, * final_file;
void write_aperture_list();
vector<Aperture> apertures;
vector<Aperture>::iterator current_aperture;
};
#endif /* __INCLUDE__PLOT_COMMON_H__ */
......@@ -295,17 +295,20 @@ public:
// Plotting
void ToPlotter( wxCommandEvent& event );
void Plot_Serigraphie( int format_plot, FILE* File, int masque_layer );
void Genere_GERBER( const wxString& FullFileName, int Layer,
bool PlotOriginIsAuxAxis );
void Genere_HPGL( const wxString& FullFileName, int Layer );
void Genere_PS( const wxString& FullFileName, int Layer, bool useA4 );
void Plot_Layer_HPGL( FILE* File, int masque_layer,
int garde, int tracevia, int modetrace );
void Plot_Layer_GERBER( FILE* File, int masque_layer,
int garde, int tracevia );
void Plot_Layer_PS( FILE* File, int masque_layer,
int garde, int tracevia, int modetrace );
bool PlotOriginIsAuxAxis,
GRTraceMode trace_mode );
void Genere_HPGL( const wxString& FullFileName, int Layer,
GRTraceMode trace_mode);
void Genere_PS( const wxString& FullFileName, int Layer,
bool useA4, GRTraceMode trace_mode );
void Plot_Layer(Plotter *plotter, int Layer, GRTraceMode trace_mode );
void Plot_Standard_Layer( Plotter *plotter, int masque_layer,
int garde, bool trace_via,
GRTraceMode trace_mode );
void Plot_Serigraphie( Plotter *plotter, int masque_layer,
GRTraceMode trace_mode);
void PlotDrillMark(Plotter *plotter, GRTraceMode trace_mode );
/* Block operations: */
/**
......@@ -872,12 +875,12 @@ public:
void Genere_GERBER( const wxString& FullFileName, int Layers );
void Genere_PS( const wxString& FullFileName, int Layers );
void Plot_Layer_HPGL( FILE* File, int masque_layer,
int garde, int tracevia, int modetrace );
int garde, bool trace_via, GRTraceMode trace_mode );
void Plot_Layer_GERBER( FILE* File, int masque_layer,
int garde, int tracevia );
int garde, bool trace_via, GRTraceMode trace_mode );
int Gen_D_CODE_File( const wxString& Name_File );
void Plot_Layer_PS( FILE* File, int masque_layer,
int garde, int tracevia, int modetrace );
int garde, bool trace_via, GRTraceMode trace_mode );
void Files_io( wxCommandEvent& event );
void OnFileHistory( wxCommandEvent& event );
......
......@@ -45,6 +45,7 @@ class WinEDAChoiceBox;
class PARAM_CFG_BASE;
class Ki_PageDescr;
class Ki_HotkeyInfo;
class Plotter;
enum id_librarytype {
LIBRARY_TYPE_EESCHEMA,
......@@ -244,7 +245,7 @@ public:
void OnActivate( wxActivateEvent& event );
void ReDrawPanel();
void TraceWorkSheet( wxDC* DC, BASE_SCREEN* screen, int line_width );
void PlotWorkSheet( int format_plot, BASE_SCREEN* screen );
void PlotWorkSheet( Plotter *plotter, BASE_SCREEN* screen );
/** Function GetXYSheetReferences
* Return the X,Y sheet references where the point position is located
......
......@@ -199,7 +199,7 @@ void TEXTE_PCB::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
if( color & ITEM_NOT_SHOW )
return;
GRFillMode fillmode = FILLED;
GRTraceMode fillmode = FILLED;
if ( DisplayOpt.DisplayDrawItems == SKETCH)
fillmode = SKETCH;
......
......@@ -191,10 +191,12 @@ void WinEDA_DrillFrame::CreateControls()
wxArrayString m_Choice_Drill_OffsetStrings;
m_Choice_Drill_OffsetStrings.Add(_("absolute"));
m_Choice_Drill_OffsetStrings.Add(_("auxiliary axis"));
m_Choice_Drill_Offset = new wxRadioBox( itemDialog1, ID_SEL_DRILL_SHEET, _("Drill Origin:"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_OffsetStrings, 1, wxRA_SPECIFY_COLS );
m_Choice_Drill_Offset = new wxRadioBox( itemDialog1, ID_SEL_DRILL_SHEET,
_("Drill Origin:"), wxDefaultPosition, wxDefaultSize,
m_Choice_Drill_OffsetStrings, 1, wxRA_SPECIFY_COLS );
m_Choice_Drill_Offset->SetSelection(0);
if (WinEDA_DrillFrame::ShowToolTips())
m_Choice_Drill_Offset->SetToolTip(_("Choose the coordinate origin: absolute or relative to the auxiliray axis"));
m_Choice_Drill_Offset->SetToolTip(_("Choose the coordinate origin: absolute or relative to the auxiliary axis"));
m_LeftBoxSizer->Add(m_Choice_Drill_Offset, 0, wxGROW|wxALL, 5);
wxBoxSizer* itemBoxSizer8 = new wxBoxSizer(wxVERTICAL);
......@@ -202,9 +204,12 @@ void WinEDA_DrillFrame::CreateControls()
wxArrayString m_Choice_Drill_MapStrings;
m_Choice_Drill_MapStrings.Add(_("None"));
m_Choice_Drill_MapStrings.Add(_("drill sheet (HPGL)"));
m_Choice_Drill_MapStrings.Add(_("drill sheet (PostScript)"));
m_Choice_Drill_Map = new wxRadioBox( itemDialog1, ID_SEL_DRILL_SHEET, _("Drill Sheet:"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_MapStrings, 1, wxRA_SPECIFY_COLS );
m_Choice_Drill_MapStrings.Add(_("Drill sheet (HPGL)"));
m_Choice_Drill_MapStrings.Add(_("Drill sheet (PostScript)"));
m_Choice_Drill_MapStrings.Add(_("Drill sheet (Gerber)"));
m_Choice_Drill_Map = new wxRadioBox( itemDialog1, ID_SEL_DRILL_SHEET,
_("Drill Sheet:"), wxDefaultPosition, wxDefaultSize,
m_Choice_Drill_MapStrings, 1, wxRA_SPECIFY_COLS );
m_Choice_Drill_Map->SetSelection(0);
if (WinEDA_DrillFrame::ShowToolTips())
m_Choice_Drill_Map->SetToolTip(_("Creates a drill map in PS or HPGL format"));
......
......@@ -156,7 +156,8 @@ private:
void UpdateConfig();
void Write_Excellon_Header( FILE * aFile);
void GenDrillReport( const wxString aFileName );
int Create_Drill_File_EXCELLON( std::vector<HOLE_INFO> & aHoleListBuffer,
int Create_Drill_File_EXCELLON(FILE *excellon_dest,
std::vector<HOLE_INFO> & aHoleListBuffer,
std::vector<DRILL_TOOL> & aToolListBuffer );
int Gen_Liste_Tools( std::vector<DRILL_TOOL> & buffer, bool print_header );
};
......
......@@ -318,13 +318,13 @@ void DIALOG_PRINT_USING_PRINTER::SetScale( wxCommandEvent& event )
/******************************************************************/
{
s_Scale_Select = m_ScaleOption->GetSelection();
Scale_X = Scale_Y = s_ScaleList[s_Scale_Select];
g_pcb_plot_options.Scale = s_ScaleList[s_Scale_Select];
if( m_FineAdjustXscaleOpt )
m_FineAdjustXscaleOpt->GetValue().ToDouble( &m_XScaleAdjust );
if( m_FineAdjustYscaleOpt )
m_FineAdjustYscaleOpt->GetValue().ToDouble( &m_YScaleAdjust );
Scale_X *= m_XScaleAdjust;
Scale_Y *= m_YScaleAdjust;
g_pcb_plot_options.ScaleAdjX = m_XScaleAdjust;
g_pcb_plot_options.ScaleAdjX = m_YScaleAdjust;
}
......
......@@ -20,43 +20,33 @@ using namespace std;
#include "macros.h"
#include "gendrill.h"
static void PlotDrillSymbol( const wxPoint& position, int diametre, int aShapeId, int format );
static void PlotOvalDrillSymbol( const wxPoint& position,
const wxSize& size,
int orient,
int format );
/**********************************************************************************/
void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, wxSize aSheetSize,
void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName,
Ki_PageDescr* aSheet,
std::vector<HOLE_INFO> aHoleListBuffer,
std::vector<DRILL_TOOL> aToolListBuffer,
bool aUnit_Drill_is_Inch, int format )
bool aUnit_Drill_is_Inch, int format,
const wxPoint &auxoffset)
/**********************************************************************************/
/* Genere le plan de percage (Drill map) format HPGL ou POSTSCRIPT
/* Genere le plan de percage (Drill map)
*/
{
unsigned ii;
int x, y;
int plotX, plotY, TextWidth, LineWidth;
int plotX, plotY, TextWidth;
double scale = 1.0;
int intervalle = 0, CharSize = 0;
EDA_BaseStruct* PtStruct;
int old_g_PlotOrient = g_PlotOrient;
char line[1024];
int dX, dY;
wxPoint BoardCentre;
int PlotMarge_in_mils = 400; // Margin in 1/1000 inch
int marge = PlotMarge_in_mils * U_PCB;
wxPoint offset;
wxSize SheetSize;
float fTextScale = 1.0;
double scale_x = 1.0, scale_y = 1.0;
Ki_PageDescr* SheetPS = NULL;
wxString msg;
Plotter *plotter = NULL;
SetLocaleTo_C_standard( ); // Use the standard notation for float numbers
g_PlotOrient = 0;
/* calcul des dimensions et centre du PCB */
aPcb->ComputeBoundaryBox();
......@@ -68,88 +58,82 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, w
// Echelle 1 en HPGL, dessin sur feuille A4 en PS, + texte description des symboles
switch( format )
{
case PLOT_FORMAT_GERBER:
scale = 1;
offset = auxoffset;
plotter = new Gerber_Plotter();
plotter->set_viewport(offset, scale, 0);
break;
case PLOT_FORMAT_HPGL: /* Calcul des echelles de conversion format HPGL */
Scale_X = Scale_Y = 1.0;
scale_x = Scale_X * SCALE_HPGL;
scale_y = Scale_Y * SCALE_HPGL;
fTextScale = (float)SCALE_HPGL;
SheetSize = aSheetSize;
{
SheetSize = aSheet->m_Size;
SheetSize.x *= U_PCB;
SheetSize.y *= U_PCB;
g_PlotOffset.x = 0;
g_PlotOffset.y = (int) (SheetSize.y * scale_y);
offset.x = 0;
offset.y = 0;
scale = 1;
HPGL_Plotter *hpgl_plotter = new HPGL_Plotter;
plotter = hpgl_plotter;
hpgl_plotter->set_pen_number(g_pcb_plot_options.HPGL_Pen_Num );
hpgl_plotter->set_pen_speed(g_pcb_plot_options.HPGL_Pen_Speed);
hpgl_plotter->set_pen_overlap(0);
plotter->set_paper_size(aSheet);
plotter->set_viewport(offset, scale, 0);
}
break;
case PLOT_FORMAT_POST:
{
// calcul en unites internes des dimensions de la feuille ( connues en 1/1000 pouce )
SheetPS = &g_Sheet_A4;
Ki_PageDescr* SheetPS = &g_Sheet_A4;
SheetSize.x = SheetPS->m_Size.x * U_PCB;
SheetSize.y = SheetPS->m_Size.y * U_PCB;
float Xscale = (float) ( SheetSize.x - (marge * 2) ) / dX;
float Yscale = (float) ( SheetSize.y * 0.6 - (marge * 2) ) / dY;
scale_x = scale_y = MIN( Xscale, Yscale );
g_PlotOffset.x = -(SheetSize.x / 2) +
(int) (BoardCentre.x * scale_x) + marge;
g_PlotOffset.y = SheetSize.y / 2 +
(int) (BoardCentre.y * scale_y) - marge;
g_PlotOffset.y += SheetSize.y / 8; /* decalage pour legende */
/* Keep size for drill legend */
double Xscale = (double) ( SheetSize.x * 0.8 ) / dX;
double Yscale = (double) ( SheetSize.y * 0.6 ) / dY;
scale = MIN( Xscale, Yscale );
offset.x = BoardCentre.x-(SheetSize.x/2)/scale;
offset.y = BoardCentre.y-(SheetSize.y/2)/scale;
offset.y += SheetSize.y / 8; /* decalage pour legende */
PS_Plotter *ps_plotter = new PS_Plotter;
plotter=ps_plotter;
ps_plotter->set_paper_size(SheetPS);
plotter->set_viewport(offset, scale, 0);
break;
}
default:
break;
wxASSERT(false);
}
switch( format )
{
case PLOT_FORMAT_HPGL:
InitPlotParametresHPGL( g_PlotOffset, scale_x, scale_y );
PrintHeaderHPGL( aFile, g_HPGL_Pen_Speed, g_HPGL_Pen_Num );
break;
case PLOT_FORMAT_POST:
{
int BBox[4];
BBox[0] = BBox[1] = PlotMarge_in_mils;
BBox[2] = SheetPS->m_Size.x - PlotMarge_in_mils;
BBox[3] = SheetPS->m_Size.y - PlotMarge_in_mils;
InitPlotParametresPS( g_PlotOffset,
SheetPS,
(double) 1.0 / PCB_INTERNAL_UNIT,
(double) 1.0 / PCB_INTERNAL_UNIT );
SetDefaultLineWidthPS( 10 ); // Set line with to 10/1000 inch
PrintHeaderPS( aFile, wxT( "PCBNEW-PS" ), aFullFileName, 1, BBox, wxLANDSCAPE );
InitPlotParametresPS( g_PlotOffset, SheetPS, scale_x, scale_y );
}
break;
default:
break;
}
plotter->set_creator(wxT("PCBNEW"));
plotter->set_filename(aFullFileName);
plotter->set_default_line_width(10);
plotter->start_plot(aFile);
/* Draw items on edge layer */
PtStruct = aPcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
for (PtStruct = aPcb->m_Drawings;
PtStruct != NULL;
PtStruct = PtStruct->Next() )
{
switch( PtStruct->Type() )
{
case TYPE_DRAWSEGMENT:
PlotDrawSegment( (DRAWSEGMENT*) PtStruct, format, EDGE_LAYER );
PlotDrawSegment(plotter, (DRAWSEGMENT*) PtStruct, EDGE_LAYER, FILLED );
break;
case TYPE_TEXTE:
PlotTextePcb( (TEXTE_PCB*) PtStruct, format, EDGE_LAYER );
PlotTextePcb(plotter, (TEXTE_PCB*) PtStruct, EDGE_LAYER, FILLED );
break;
case TYPE_COTATION:
PlotCotation( (COTATION*) PtStruct, format, EDGE_LAYER );
PlotCotation(plotter, (COTATION*) PtStruct, EDGE_LAYER, FILLED );
break;
case TYPE_MIRE:
PlotMirePcb( (MIREPCB*) PtStruct, format, EDGE_LAYER );
PlotMirePcb(plotter, (MIREPCB*) PtStruct, EDGE_LAYER, FILLED );
break;
case TYPE_MARKER: // do not draw
......@@ -162,134 +146,54 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, w
}
// Set Drill Symbols width in 1/10000 mils
LineWidth = wxRound( 50.0 / scale_x ); // real scale will be CharScale * scale_x
int tmpPlotLineWidth = g_PlotLine_Width;
plotter->set_default_line_width(10);
plotter->set_current_line_width(-1);
// Plot board outlines and drill map
if ( format == PLOT_FORMAT_POST)
{
SetDefaultLineWidthPS( LineWidth );
SetCurrentLineWidthPS( LineWidth );
g_PlotLine_Width = LineWidth; // Default line width in FILAIRE mode, used to plot drill symbols
}
Gen_Drill_PcbMap( aPcb, aFile, aHoleListBuffer, aToolListBuffer, format );
Gen_Drill_PcbMap( aPcb, plotter, aHoleListBuffer, aToolListBuffer);
/* Impression de la liste des symboles utilises */
CharSize = 800; /* text size in 1/10000 mils */
float CharScale = 1.0 / scale_x; /* real scale will be CharScale * scale_x,
double CharScale = 1.0 / scale; /* real scale will be CharScale * scale_x,
* because the global plot scale is scale_x */
TextWidth = (int) ((CharSize * CharScale) / 10); // Set text width (thickness)
intervalle = (int) (CharSize * CharScale) + TextWidth;
switch( format )
{
default:
case PLOT_FORMAT_POST:
g_PlotOffset.x = 0;
g_PlotOffset.y = 0;
InitPlotParametresPS( g_PlotOffset, SheetPS, scale_x, scale_x );
SetDefaultLineWidthPS( LineWidth );
SetCurrentLineWidthPS( LineWidth );
break;
case PLOT_FORMAT_HPGL:
{
InitPlotParametresHPGL( g_PlotOffset, scale_x, scale_x );
/* generation des dim: commande SI x,y; x et y = dim en cm */
char csize[256];
sprintf( csize, "%2.3f", (float) CharSize * CharScale * 0.000254 );
sprintf( line, "SI %s, %s;\n", csize, csize );
fputs( line, aFile );
break;
}
}
/* Trace des informations */
plotX = marge + 1000;
plotY = CharSize + 1000;
plotX = aPcb->m_BoundaryBox.GetX() + 200 * CharScale;
plotY = aPcb->m_BoundaryBox.GetBottom() + intervalle;
for( ii = 0; ii < aToolListBuffer.size(); ii++ )
/* Plot title "Info" */
wxString Text = wxT( "Drill Map:" );
plotter->text( wxPoint(plotX,plotY), BLACK,
Text,
0, wxSize((int)(CharSize * CharScale), (int)(CharSize * CharScale)),
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
TextWidth, false, false );
for(unsigned ii = 0; ii < aToolListBuffer.size(); ii++ )
{
int plot_diam;
if( aToolListBuffer[ii].m_TotalCount == 0 )
continue;
plot_diam = (int) (aToolListBuffer[ii].m_Diameter);
x = plotX; y = plotY;
x = -g_PlotOffset.x + (int) (x * fTextScale);
y = g_PlotOffset.y - (int) (y * fTextScale);
sprintf( line, "%d setlinewidth\n", LineWidth );
SetDefaultLineWidthPS( LineWidth );
SetCurrentLineWidthPS( LineWidth );
PlotDrillSymbol( wxPoint( x, y ), plot_diam, ii, format );
intervalle = (int) (CharSize * CharScale) + TextWidth;
intervalle = (int) ( intervalle * 1.2);
if( intervalle < (plot_diam + 200 + TextWidth) )
intervalle = plot_diam + 200 + TextWidth;
plotY += intervalle;
int rayon = plot_diam / 2;
x = plotX + rayon + (int) (CharSize * CharScale);
y = plotY;
x = -g_PlotOffset.x + (int) (x * fTextScale);
y = g_PlotOffset.y - (int) (y * fTextScale);
plot_diam = (int) (aToolListBuffer[ii].m_Diameter);
x = plotX - 200 * CharScale - plot_diam / 2;
y = plotY + CharSize*CharScale;
plotter->marker( wxPoint( x, y ), plot_diam, ii );
/* Trace de la legende associee */
switch( format )
{
case PLOT_FORMAT_HPGL:
// List the diameter of each drill in the selected Drill Unit,
// and then its diameter in the other Drill Unit.
if( aUnit_Drill_is_Inch )
sprintf( line, "PU %d, %d; LB%2.3f\" / %2.2fmm ",
x + (int) (intervalle * CharScale * fTextScale),
y - (int) (CharSize / 2 * CharScale * fTextScale),
float (aToolListBuffer[ii].m_Diameter) * 0.0001,
float (aToolListBuffer[ii].m_Diameter) * 0.00254 );
else
sprintf( line, "PU %d, %d; LB%2.2fmm / %2.3f\" ",
x + (int) (intervalle * CharScale * fTextScale),
y - (int) (CharSize / 2 * CharScale * fTextScale),
float (aToolListBuffer[ii].m_Diameter) * 0.00254,
float (aToolListBuffer[ii].m_Diameter) * 0.0001 );
fputs( line, aFile );
// Now list how many holes and ovals are associated with each drill.
if( ( aToolListBuffer[ii].m_TotalCount == 1 )
&& ( aToolListBuffer[ii].m_OvalCount == 0 ) )
sprintf( line, "(1 hole)\n" );
else if( aToolListBuffer[ii].m_TotalCount == 1 ) // && ( buffer[ii]m_OvalCount == 1 )
sprintf( line, "(1 hole) (with 1 oblong)\n" );
else if( aToolListBuffer[ii].m_OvalCount == 0 )
sprintf( line, "(%d holes)\n",
aToolListBuffer[ii].m_TotalCount );
else if( aToolListBuffer[ii].m_OvalCount == 1 )
sprintf( line, "(%d holes) (with 1 oblong)\n",
aToolListBuffer[ii].m_TotalCount );
else // if ( aToolListBuffer[ii]m_OvalCount > 1 )
sprintf( line, "(%d holes) (with %d oblongs)\n",
aToolListBuffer[ii].m_TotalCount,
aToolListBuffer[ii].m_OvalCount );
fputs( line, aFile );
fputs( "\03;\n", aFile );
break;
case PLOT_FORMAT_POST:
// List the diameter of each drill in the selected Drill Unit,
// and then its diameter in the other Drill Unit.
if( aUnit_Drill_is_Inch )
sprintf( line, "%2.3f\" / %2.2fmm ",
float (aToolListBuffer[ii].m_Diameter) * 0.0001,
float (aToolListBuffer[ii].m_Diameter) * 0.00254 );
double (aToolListBuffer[ii].m_Diameter) * 0.0001,
double (aToolListBuffer[ii].m_Diameter) * 0.00254 );
else
sprintf( line, "%2.2fmm / %2.3f\" ",
float (aToolListBuffer[ii].m_Diameter) * 0.00254,
float (aToolListBuffer[ii].m_Diameter) * 0.0001 );
double (aToolListBuffer[ii].m_Diameter) * 0.00254,
double (aToolListBuffer[ii].m_Diameter) * 0.0001 );
msg = CONV_FROM_UTF8( line );
// Now list how many holes and ovals are associated with each drill.
......@@ -297,89 +201,48 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, w
&& ( aToolListBuffer[ii].m_OvalCount == 0 ) )
sprintf( line, "(1 hole)" );
else if( aToolListBuffer[ii].m_TotalCount == 1 ) // && ( aToolListBuffer[ii]m_OvalCount == 1 )
sprintf( line, "(1 hole) (with 1 oblong)" );
sprintf( line, "(1 slot)" );
else if( aToolListBuffer[ii].m_OvalCount == 0 )
sprintf( line, "(%d holes)",
aToolListBuffer[ii].m_TotalCount );
else if( aToolListBuffer[ii].m_OvalCount == 1 )
sprintf( line, "(%d holes) (with 1 oblong)",
aToolListBuffer[ii].m_TotalCount );
sprintf( line, "(%d holes + 1 slot)",
aToolListBuffer[ii].m_TotalCount - 1 );
else // if ( aToolListBuffer[ii]m_OvalCount > 1 )
sprintf( line, "(%d holes) (with %d oblongs)",
aToolListBuffer[ii].m_TotalCount,
sprintf( line, "(%d holes + %d slots)",
aToolListBuffer[ii].m_TotalCount -
aToolListBuffer[ii].m_OvalCount,
aToolListBuffer[ii].m_OvalCount );
msg += CONV_FROM_UTF8( line );
SetDefaultLineWidthPS( TextWidth );
SetCurrentLineWidthPS( TextWidth );
PlotGraphicText( format, wxPoint(x,y), BLACK,
plotter->text( wxPoint(plotX,y), BLACK,
msg,
0, wxSize((int)(CharSize * CharScale), (int)(CharSize * CharScale)),
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
TextWidth, false, false );
break;
}
plotY += intervalle;
}
/* Plot title "Info" */
plotY += (int) ( intervalle * 0.2); // Add exta line separation
x = plotX; y = plotY;
x = +g_PlotOffset.x + (int) (x * fTextScale);
y = g_PlotOffset.y - (int) (y * fTextScale);
switch( format )
{
case PLOT_FORMAT_HPGL:
sprintf( line, "PU %d, %d; LBInfo:\03;\n",
x + (int) (intervalle * CharScale * fTextScale),
y - (int) (CharSize / 2 * CharScale * fTextScale) );
fputs( line, aFile );
break;
case PLOT_FORMAT_POST:
SetDefaultLineWidthPS( TextWidth );
SetCurrentLineWidthPS( TextWidth );
wxString Text = wxT( "Info:" );
PlotGraphicText( format, wxPoint(x,y), BLACK,
Text,
0, wxSize((int)(CharSize * CharScale), (int)(CharSize * CharScale)),
GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
TextWidth, false, false );
break;
}
switch( format )
{
case PLOT_FORMAT_HPGL:
CloseFileHPGL( aFile );
break;
intervalle = (int) (CharSize * CharScale) + TextWidth;
intervalle = (int) ( intervalle * 1.2);
case PLOT_FORMAT_POST:
CloseFilePS( aFile );
break;
if( intervalle < (plot_diam + 200 + TextWidth) )
intervalle = plot_diam + 200 + TextWidth;
}
plotter->end_plot();
delete plotter;
SetLocaleTo_Default( ); // Revert to local notation for float numbers
// Retrieve setup values, changed for plotting drill map
g_PlotOrient = old_g_PlotOrient;
g_PlotLine_Width = tmpPlotLineWidth;
}
/****************************************************************************************/
void Gen_Drill_PcbMap( BOARD* aPcb, FILE* aFile,
void Gen_Drill_PcbMap( BOARD* aPcb, Plotter *plotter,
std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer,
int format )
std::vector<DRILL_TOOL>& aToolListBuffer)
/****************************************************************************************/
/** Creates the drill map aFile in HPGL or POSTSCRIPT format
* @param aPcb BOARD
* @param aFile = output aFile
* @param aHoleListBuffer = std::vector<HOLE_INFO> list of holes descriptors
* @param aToolListBuffer = std::vector<DRILL_TOOL> drill list buffer
* @param format = ouput format (hpgl / ps)
*/
{
wxPoint pos;
......@@ -399,216 +262,18 @@ void Gen_Drill_PcbMap( BOARD* aPcb, FILE* aFile,
pos.x = aHoleListBuffer[ii].m_Hole_Pos_X;
pos.y = aHoleListBuffer[ii].m_Hole_Pos_Y;
if( aHoleListBuffer[ii].m_Hole_Shape == 0 )
{
PlotDrillSymbol( pos, aHoleListBuffer[ii].m_Hole_Diameter,
aHoleListBuffer[ii].m_Tool_Reference - 1,
format );
}
else
/* Always plot the drill symbol (for slots identifies the needed
* cutter!) */
plotter->marker( pos, aHoleListBuffer[ii].m_Hole_Diameter,
aHoleListBuffer[ii].m_Tool_Reference - 1);
if( aHoleListBuffer[ii].m_Hole_Shape != 0 )
{
wxSize oblong_size;
oblong_size.x = aHoleListBuffer[ii].m_Hole_SizeX;
oblong_size.y = aHoleListBuffer[ii].m_Hole_SizeY;
PlotOvalDrillSymbol( pos, oblong_size, aHoleListBuffer[ii].m_Hole_Orient, format );
}
plotter->flash_pad_oval( pos, oblong_size,
aHoleListBuffer[ii].m_Hole_Orient, FILAIRE);
}
}
/************************************************************************************/
void PlotDrillSymbol( const wxPoint& position, int diametre, int aShapeId, int format )
/************************************************************************************/
/* Trace un motif de numero de forme aShapeId, aux coord x0, y0.
* x0, y0 = coordonnees tables
* diametre = diametre (coord table) du trou
* aShapeId = index ( permet de generer des formes caract )
*/
{
int rayon = diametre / 2;
void (*FctPlume)( wxPoint pos, int state );
int x0, y0;
x0 = position.x; y0 = position.y;
FctPlume = Move_Plume_HPGL;
if( IsPostScript( format ) )
FctPlume = LineTo_PS;
switch( aShapeId )
{
case 0: /* vias : forme en X */
FctPlume( wxPoint( x0 - rayon, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0 + rayon, y0 + rayon ), 'D' );
FctPlume( wxPoint( x0 + rayon, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0 - rayon, y0 + rayon ), 'D' );
break;
case 1: /* Cercle */
if( format == PLOT_FORMAT_HPGL )
trace_1_pastille_RONDE_HPGL( wxPoint( x0, y0 ), diametre, FILAIRE );
if( IsPostScript( format ) )
trace_1_pastille_RONDE_POST( wxPoint( x0, y0 ), diametre, FILAIRE );
break;
case 2: /* forme en + */
FctPlume( wxPoint( x0, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0, y0 + rayon ), 'D' );
FctPlume( wxPoint( x0 + rayon, y0 ), 'U' );
FctPlume( wxPoint( x0 - rayon, y0 ), 'D' );
break;
case 3: /* forme en X cercle */
FctPlume( wxPoint( x0 - rayon, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0 + rayon, y0 + rayon ), 'D' );
FctPlume( wxPoint( x0 + rayon, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0 - rayon, y0 + rayon ), 'D' );
if( format == PLOT_FORMAT_HPGL )
trace_1_pastille_RONDE_HPGL( wxPoint( x0, y0 ), diametre, FILAIRE );
if( IsPostScript( format ) )
trace_1_pastille_RONDE_POST( wxPoint( x0, y0 ), diametre, FILAIRE );
break;
case 4: /* forme en cercle barre de - */
FctPlume( wxPoint( x0 - rayon, y0 ), 'U' );
FctPlume( wxPoint( x0 + rayon, y0 ), 'D' );
if( format == PLOT_FORMAT_HPGL )
trace_1_pastille_RONDE_HPGL( wxPoint( x0, y0 ), diametre, FILAIRE );
if( IsPostScript( format ) )
trace_1_pastille_RONDE_POST( wxPoint( x0, y0 ), diametre, FILAIRE );
break;
case 5: /* forme en cercle barre de | */
FctPlume( wxPoint( x0, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0, y0 + rayon ), 'D' );
if( format == PLOT_FORMAT_HPGL )
trace_1_pastille_RONDE_HPGL( wxPoint( x0, y0 ), diametre, FILAIRE );
if( IsPostScript( format ) )
trace_1_pastille_RONDE_POST( wxPoint( x0, y0 ), diametre, FILAIRE );
break;
case 6: /* forme en carre */
if( format == PLOT_FORMAT_HPGL )
trace_1_pad_TRAPEZE_HPGL( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 0,
FILAIRE );
if( IsPostScript( format ) )
trace_1_pad_TRAPEZE_POST( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 0,
FILAIRE );
break;
case 7: /* forme en losange */
if( format == PLOT_FORMAT_HPGL )
trace_1_pad_TRAPEZE_HPGL( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 450,
FILAIRE );
if( IsPostScript( format ) )
trace_1_pad_TRAPEZE_POST( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 450,
FILAIRE );
break;
case 8: /* forme en carre barre par un X*/
FctPlume( wxPoint( x0 - rayon, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0 + rayon, y0 + rayon ), 'D' );
FctPlume( wxPoint( x0 + rayon, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0 - rayon, y0 + rayon ), 'D' );
if( format == PLOT_FORMAT_HPGL )
trace_1_pad_TRAPEZE_HPGL( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 0,
FILAIRE );
if( IsPostScript( format ) )
trace_1_pad_TRAPEZE_POST( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 0,
FILAIRE );
break;
case 9: /* forme en losange barre par un +*/
FctPlume( wxPoint( x0, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0, y0 + rayon ), 'D' );
FctPlume( wxPoint( x0 + rayon, y0 ), 'U' );
FctPlume( wxPoint( x0 - rayon, y0 ), 'D' );
if( format == PLOT_FORMAT_HPGL )
trace_1_pad_TRAPEZE_HPGL( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 450,
FILAIRE );
if( IsPostScript( format ) )
trace_1_pad_TRAPEZE_POST( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 450,
FILAIRE );
break;
case 10: /* forme en carre barre par un '/' */
FctPlume( wxPoint( x0 - rayon, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0 + rayon, y0 + rayon ), 'D' );
if( format == PLOT_FORMAT_HPGL )
trace_1_pad_TRAPEZE_HPGL( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 0,
FILAIRE );
if( IsPostScript( format ) )
trace_1_pad_TRAPEZE_POST( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 0,
FILAIRE );
break;
case 11: /* forme en losange barre par un |*/
FctPlume( wxPoint( x0, y0 - rayon ), 'U' );
FctPlume( wxPoint( x0, y0 + rayon ), 'D' );
if( format == PLOT_FORMAT_HPGL )
trace_1_pad_TRAPEZE_HPGL( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 450,
FILAIRE );
if( IsPostScript( format ) )
trace_1_pad_TRAPEZE_POST( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 450,
FILAIRE );
break;
case 12: /* forme en losange barre par un -*/
FctPlume( wxPoint( x0 - rayon, y0 ), 'U' );
FctPlume( wxPoint( x0 + rayon, y0 ), 'D' );
if( format == PLOT_FORMAT_HPGL )
trace_1_pad_TRAPEZE_HPGL( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 450,
FILAIRE );
if( IsPostScript( format ) )
trace_1_pad_TRAPEZE_POST( wxPoint( x0, y0 ), wxSize( rayon, rayon ), wxSize( 0,
0 ), 450,
FILAIRE );
break;
default:
if( format == PLOT_FORMAT_HPGL )
trace_1_pastille_RONDE_HPGL( wxPoint( x0, y0 ), diametre, FILAIRE );
if( IsPostScript( format ) )
trace_1_pastille_RONDE_POST( wxPoint( x0, y0 ), diametre, FILAIRE );
break;
}
if( format == PLOT_FORMAT_HPGL )
Plume_HPGL( 'U' );
}
/*********************************************************************************************/
void PlotOvalDrillSymbol( const wxPoint& position, const wxSize& size, int orient, int format )
/*********************************************************************************************/
/* Draws an oblong hole.
* because functions to draw oblong shapes exist to draw oblong pads, Use they.
*/
{
switch( format )
{
case PLOT_FORMAT_HPGL:
trace_1_pastille_OVALE_HPGL( position, size, orient, FILAIRE );
break;
case PLOT_FORMAT_POST:
trace_1_pastille_OVALE_POST( position, size, orient, FILAIRE );
break;
}
}
......@@ -684,13 +349,13 @@ void GenDrillReportFile( FILE* aFile, BOARD* aPcb, const wxString& aBoardFilenam
if( aUnit_Drill_is_Inch )
sprintf( line, "T%d %2.3f\" %2.2fmm ",
ii + 1,
float (aToolListBuffer[ii].m_Diameter) * 0.0001,
float (aToolListBuffer[ii].m_Diameter) * 0.00254 );
double (aToolListBuffer[ii].m_Diameter) * 0.0001,
double (aToolListBuffer[ii].m_Diameter) * 0.00254 );
else
sprintf( line, "T%d %2.2fmm %2.3f\" ",
ii + 1,
float (aToolListBuffer[ii].m_Diameter) * 0.00254,
float (aToolListBuffer[ii].m_Diameter) * 0.0001 );
double (aToolListBuffer[ii].m_Diameter) * 0.00254,
double (aToolListBuffer[ii].m_Diameter) * 0.0001 );
fputs( line, aFile );
// Now list how many holes and ovals are associated with each drill.
......
......@@ -104,11 +104,11 @@ void WinEDA_DrillFrame::InitDisplayParams( void )
m_MicroViaDrillValue->SetLabel( msg );
msg.Empty();
msg << g_HPGL_Pen_Num;
msg << g_pcb_plot_options.HPGL_Pen_Num;
m_PenNum->SetValue( msg );
msg.Empty();
msg << g_HPGL_Pen_Speed;
msg << g_pcb_plot_options.HPGL_Pen_Speed;
m_PenSpeed->SetValue( msg );
// See if we have some buried vias or/and microvias, and display microvias drill value if so
......@@ -180,11 +180,11 @@ void WinEDA_DrillFrame::SetParams( void )
msg = m_PenSpeed->GetValue();
if( msg.ToLong( &ltmp ) )
g_HPGL_Pen_Speed = ltmp;
g_pcb_plot_options.HPGL_Pen_Speed = ltmp;
msg = m_PenNum->GetValue();
if( msg.ToLong( &ltmp ) )
g_HPGL_Pen_Num = ltmp;
g_pcb_plot_options.HPGL_Pen_Num = ltmp;
if( m_Choice_Drill_Offset->GetSelection() == 0 )
File_Drill_Offset = wxPoint( 0, 0 );
else
......@@ -323,9 +323,9 @@ void WinEDA_DrillFrame::GenDrillFiles( wxCommandEvent& event )
if( dlg.ShowModal() == wxID_CANCEL )
continue;
dest = wxFopen( dlg.GetPath(), wxT( "w" ) );
FILE *excellon_dest = wxFopen( dlg.GetPath(), wxT( "w" ) );
if( dest == 0 )
if( excellon_dest == 0 )
{
msg = _( "Unable to create file " ) + dlg.GetPath();
DisplayError( this, msg );
......@@ -333,7 +333,7 @@ void WinEDA_DrillFrame::GenDrillFiles( wxCommandEvent& event )
return;
}
Create_Drill_File_EXCELLON( s_HoleListBuffer, s_ToolListBuffer );
Create_Drill_File_EXCELLON(excellon_dest, s_HoleListBuffer, s_ToolListBuffer );
switch( m_Choice_Drill_Map->GetSelection() )
{
......@@ -349,6 +349,11 @@ void WinEDA_DrillFrame::GenDrillFiles( wxCommandEvent& event )
GenDrillMap( dlg.GetPath(), s_HoleListBuffer, s_ToolListBuffer,
PLOT_FORMAT_POST );
break;
case 3:
GenDrillMap( dlg.GetPath(), s_HoleListBuffer, s_ToolListBuffer,
PLOT_FORMAT_GERBER );
break;
}
if( !ExistsBuriedVias )
......@@ -403,7 +408,8 @@ void WinEDA_DrillFrame::UpdatePrecisionOptions( wxCommandEvent& event )
/**********************************************************************************/
int WinEDA_DrillFrame::Create_Drill_File_EXCELLON( std::vector<HOLE_INFO>& aHoleListBuffer,
int WinEDA_DrillFrame::Create_Drill_File_EXCELLON(FILE *excellon_dest,
std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer )
/**********************************************************************************/
......@@ -421,7 +427,7 @@ int WinEDA_DrillFrame::Create_Drill_File_EXCELLON( std::vector<HOLE_INFO>& aHol
SetLocaleTo_C_standard(); // Use the standard notation for float numbers
Write_Excellon_Header( dest );
Write_Excellon_Header( excellon_dest );
holes_count = 0;
int tool_reference = -2;
......@@ -430,25 +436,23 @@ int WinEDA_DrillFrame::Create_Drill_File_EXCELLON( std::vector<HOLE_INFO>& aHol
for( unsigned ii = 0; ii < aToolListBuffer.size(); ii++ )
{
if( s_Unit_Drill_is_Inch ) /* does it need T01, T02 or is T1,T2 ok?*/
sprintf( line, "T%dC%.3f\n", ii + 1,
fprintf( excellon_dest, "T%dC%.3f\n", ii + 1,
float (aToolListBuffer[ii].m_Diameter) * s_ConversionUnits );
else
sprintf( line, "T%dC%.3f\n", ii + 1,
fprintf( excellon_dest, "T%dC%.3f\n", ii + 1,
float (aToolListBuffer[ii].m_Diameter) * s_ConversionUnits * 10.0 );
fputs( line, dest );
}
fputs( "%\n", dest );
fputs( "%\n", excellon_dest );
if( !Minimal )
fputs( "M47\n", dest ); /* Operator message */
fputs( "G05\n", dest ); /* Drill mode */
fputs( "M47\n", excellon_dest ); /* Operator message */
fputs( "G05\n", excellon_dest ); /* Drill mode */
/* Units : */
if( s_Unit_Drill_is_Inch && !Minimal )
fputs( "M72\n", dest ); /* M72 = inch mode */
fputs( "M72\n", excellon_dest ); /* M72 = inch mode */
else if( !Minimal )
fputs( "M71\n", dest ); /* M71 = metric mode */
fputs( "M71\n", excellon_dest ); /* M71 = metric mode */
/* Read the hole file and generate lines for normal holes (oblong holes will be created later) */
for( unsigned ii = 0; ii < aHoleListBuffer.size(); ii++ )
......@@ -458,8 +462,7 @@ int WinEDA_DrillFrame::Create_Drill_File_EXCELLON( std::vector<HOLE_INFO>& aHol
if( tool_reference != aHoleListBuffer[ii].m_Tool_Reference )
{
tool_reference = aHoleListBuffer[ii].m_Tool_Reference;
sprintf( line, "T%d\n", tool_reference );
fputs( line, dest );
fprintf( excellon_dest, "T%d\n", tool_reference );
}
x0 = aHoleListBuffer[ii].m_Hole_Pos_X - File_Drill_Offset.x;
......@@ -479,7 +482,7 @@ int WinEDA_DrillFrame::Create_Drill_File_EXCELLON( std::vector<HOLE_INFO>& aHol
Gen_Line_EXCELLON( line, xt * 10, yt * 10 );
}
fputs( line, dest );
fputs( line, excellon_dest );
holes_count++;
}
......@@ -492,8 +495,7 @@ int WinEDA_DrillFrame::Create_Drill_File_EXCELLON( std::vector<HOLE_INFO>& aHol
if( tool_reference != aHoleListBuffer[ii].m_Tool_Reference )
{
tool_reference = aHoleListBuffer[ii].m_Tool_Reference;
sprintf( line, "T%d\n", tool_reference );
fputs( line, dest );
fprintf( excellon_dest, "T%d\n", tool_reference );
}
diam = MIN( aHoleListBuffer[ii].m_Hole_SizeX, aHoleListBuffer[ii].m_Hole_SizeY );
......@@ -534,21 +536,21 @@ int WinEDA_DrillFrame::Create_Drill_File_EXCELLON( std::vector<HOLE_INFO>& aHol
if( line[kk] == '\n' || line[kk] =='\r' )
line[kk] = 0;
fputs( line, dest );
fputs( line, excellon_dest );
fputs( "G85", dest ); // add the "G85" command
fputs( "G85",excellon_dest ); // add the "G85" command
xt = float (xf) * s_ConversionUnits; yt = float (yf) * s_ConversionUnits;
if( s_Unit_Drill_is_Inch )
Gen_Line_EXCELLON( line, xt, yt );
else
Gen_Line_EXCELLON( line, xt * 10, yt * 10 );
fputs( line, dest );
fputs( "G05\n", dest );
fputs( line, excellon_dest );
fputs( "G05\n", excellon_dest );
holes_count++;
}
Write_End_Of_File_Drill( dest );
Write_End_Of_File_Drill( excellon_dest );
SetLocaleTo_Default(); // Revert to locale float notation
......@@ -750,6 +752,12 @@ void WinEDA_DrillFrame::GenDrillMap( const wxString aFileName,
wildcard = _( "PostScript files (.ps)|*.ps" );
break;
case PLOT_FORMAT_GERBER:
ext = wxT( "pho" );
wildcard = _( "Gerber files (.pho)|*.pho" );
break;
default:
DisplayError( this, wxT( "WinEDA_DrillFrame::GenDrillMap() error" ) );
return;
......@@ -767,9 +775,9 @@ void WinEDA_DrillFrame::GenDrillMap( const wxString aFileName,
if( dlg.ShowModal() == wxID_CANCEL )
return;
dest = wxFopen( dlg.GetPath(), wxT( "wt" ) );
FILE *drillplot_dest = wxFopen( dlg.GetPath(), wxT( "wt" ) );
if( dest == 0 )
if( drillplot_dest == 0 )
{
msg = _( "Unable to create file" );
msg << wxT( " <" ) << dlg.GetPath() << wxT( ">" );
......@@ -778,13 +786,13 @@ void WinEDA_DrillFrame::GenDrillMap( const wxString aFileName,
}
GenDrillMapFile( m_Parent->GetBoard(),
dest,
drillplot_dest,
dlg.GetPath(),
m_Parent->GetScreen()->m_CurrentSheetDesc->m_Size,
m_Parent->GetScreen()->m_CurrentSheetDesc,
s_HoleListBuffer,
s_ToolListBuffer,
s_Unit_Drill_is_Inch,
format );
format, File_Drill_Offset );
}
......@@ -811,16 +819,16 @@ void WinEDA_DrillFrame::GenDrillReport( const wxString aFileName )
if( dlg.ShowModal() == wxID_CANCEL )
return;
dest = wxFopen( dlg.GetPath(), wxT( "w" ) );
FILE *report_dest = wxFopen( dlg.GetPath(), wxT( "w" ) );
if( dest == 0 )
if( report_dest == 0 )
{
msg = _( "Unable to create file " ) + dlg.GetPath();
DisplayError( this, msg );
return;
}
GenDrillReportFile( dest, m_Parent->GetBoard(),
GenDrillReportFile( report_dest, m_Parent->GetBoard(),
m_Parent->GetScreen()->m_FileName,
s_Unit_Drill_is_Inch,
s_HoleListBuffer,
......
......@@ -79,16 +79,15 @@ void Build_Holes_List( BOARD* Pcb, std::vector<HOLE_INFO>& aHoleListBuffer,
void GenDrillMapFile( BOARD* aPcb,
FILE* aFile,
const wxString& aFullFileName,
wxSize aSheetSize,
Ki_PageDescr *aSheet,
std::vector<HOLE_INFO> aHoleListBuffer,
std::vector<DRILL_TOOL> aToolListBuffer,
bool aUnit_Drill_is_Inch,
int format );
int format, const wxPoint& auxoffset );
void Gen_Drill_PcbMap( BOARD* aPcb, FILE* aFile,
void Gen_Drill_PcbMap( BOARD* aPcb, Plotter* plotter,
std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer,
int format );
std::vector<DRILL_TOOL>& aToolListBuffer);
/*
* Create a list of drill values and drill count
......
......@@ -24,8 +24,6 @@ void TraceArc( int ux0, int uy0, int ux1, int uy1, int ArcAngle, int lg, int
/* Local functions */
static void DrawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, int layer,
int color, int op_logique );
static void DrawHVSegment( int ux0, int uy0, int ux1, int uy1, int demi_largeur, int layer,
int color, int op_logique );
static void TraceFilledCercle( BOARD* Pcb, int cx, int cy, int rayon, int masque_layer,
int color, int op_logique );
......@@ -763,94 +761,6 @@ void DrawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, int layer,
}
}
/********************************************************************/
void DrawHVSegment( int ux0, int uy0, int ux1, int uy1, int demi_largeur, int layer,
int color, int op_logique )
/********************************************************************/
/* Draw a horizontal or vertical segment.
* same as DrawSegmentQcq, but faster
*/
{
int row, col;
int row_max, col_max, row_min, col_min;
void (*WriteCell)( int, int, int, BoardCell );
switch( op_logique )
{
default:
case WRITE_CELL:
WriteCell = SetCell; break;
case WRITE_OR_CELL:
WriteCell = OrCell; break;
case WRITE_XOR_CELL:
WriteCell = XorCell; break;
case WRITE_AND_CELL:
WriteCell = AndCell; break;
case WRITE_ADD_CELL:
WriteCell = AddCell; break;
}
// Modif des coord pour que les coord de fin soient > coord de debut
if( uy1 < uy0 )
EXCHG( uy0, uy1 ); // ceci n'est vrai que parce que
if( ux1 < ux0 )
EXCHG( ux0, ux1 ); // dx ou dy ou les 2 sonts nuls
// Le segment est assimile a un rectangle.
// TODO: traiter correctement les extremites arrondies
// if ( ux0 == ux1 ) // Vertical Segment
{
ux0 -= demi_largeur; ux1 += demi_largeur;
}
// else // Horizontal segment
{
uy0 -= demi_largeur; uy1 += demi_largeur;
}
// Calcul des coord limites des cellules appartenant au rectangle
row_max = uy1 / g_GridRoutingSize;
col_max = ux1 / g_GridRoutingSize;
row_min = uy0 / g_GridRoutingSize;
if( uy0 > row_min * g_GridRoutingSize )
row_min++; // Traitement de l'arrondi par defaut
col_min = ux0 / g_GridRoutingSize;
if( ux0 > col_min * g_GridRoutingSize )
col_min++;
if( row_min < 0 )
row_min = 0;
if( row_max >= (Nrows - 1) )
row_max = Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= (Ncols - 1) )
col_max = Ncols - 1;
if( row_min > row_max )
row_max = row_min;
if( col_min > col_max )
col_max = col_min;
for( row = row_min; row <= row_max; row++ )
{
for( col = col_min; col <= col_max; col++ )
{
OP_CELL( layer, row, col );
}
}
}
/*****************************************************************/
void TraceCercle( int ux0, int uy0, int ux1, int uy1, int lg, int layer,
int color, int op_logique )
......
......@@ -655,7 +655,7 @@ static PARAM_CFG_SETCOLOR ColorCheveluCfg
static PARAM_CFG_INT HPGLpenNumCfg
(
wxT( "HPGLnum" ), /* Keyword */
&g_HPGL_Pen_Num, /* Parameter address */
&g_pcb_plot_options.HPGL_Pen_Num, /* Parameter address */
1, /* Default value */
1, 16 /* Min and max values*/
);
......@@ -663,7 +663,7 @@ static PARAM_CFG_INT HPGLpenNumCfg
static PARAM_CFG_INT HPGLdiamCfg // HPGL pen size (mils)
(
wxT( "HPGdiam" ), /* Keyword */
&g_HPGL_Pen_Diam, /* Parameter address */
&g_pcb_plot_options.HPGL_Pen_Diam, /* Parameter address */
15, /* Default value */
0, 100 /* Min and max values*/
);
......@@ -671,7 +671,7 @@ static PARAM_CFG_INT HPGLdiamCfg // HPGL pen size (mils)
static PARAM_CFG_INT HPGLspeedCfg //HPGL pen speed (cm/s)
(
wxT( "HPGLSpd" ), /* Keyword */
&g_HPGL_Pen_Speed, /* Parameter address */
&g_pcb_plot_options.HPGL_Pen_Speed, /* Parameter address */
20, /* Default value */
0, 1000 /* Min and max values*/
);
......@@ -679,18 +679,11 @@ static PARAM_CFG_INT HPGLspeedCfg //HPGL pen speed (cm/s)
static PARAM_CFG_INT HPGLrecouvrementCfg
(
wxT( "HPGLrec" ), /* Keyword */
&g_HPGL_Pen_Recouvrement, /* Parameter address */
&g_pcb_plot_options.HPGL_Pen_Recouvrement, /* Parameter address */
2, /* Default value */
0, 0x100 /* Min and max values*/
);
static PARAM_CFG_BOOL HPGLcenterCfg //HPGL Org Coord ( 0 normal, 1 Centre)
(
wxT( "HPGLorg" ), /* Keyword */
&HPGL_Org_Centre, /* Parameter address */
FALSE /* Default value */
);
static PARAM_CFG_INT VernisEpargneGardeCfg
(
wxT( "VEgarde" ), /* Keyword */
......@@ -734,7 +727,7 @@ static PARAM_CFG_INT ModuleSegmWidthCfg
static PARAM_CFG_INT WTraitSerigraphiePlotCfg
(
wxT( "WpenSer" ), /* Keyword */
&g_PlotLine_Width, /* Parameter address */
&g_pcb_plot_options.PlotLine_Width, /* Parameter address */
10, /* Default value */
1, 10000 /* Min and max values*/
);
......@@ -877,7 +870,6 @@ PARAM_CFG_BASE* ParamCfgList[] =
&HPGLdiamCfg,
&HPGLspeedCfg,
&HPGLrecouvrementCfg,
&HPGLcenterCfg,
&VernisEpargneGardeCfg,
&DrawSegmLargeurCfg,
&EdgeSegmLargeurCfg,
......
......@@ -55,32 +55,6 @@ wxString g_Current_PadName; // Last used pad name (pad num)
PCB_SCREEN* ScreenModule = NULL;
/* Options : */
// True to exclude contents of Edges Pcb layer
bool g_Exclude_Edges_Pcb = FALSE;
bool g_Plot_Frame_Ref; // True to plot/print frame references
bool g_DrawViaOnMaskLayer; // True if vias are drawn on Mask layer (ie protected by mask)
// = FILAIRE, FILL or SKETCH
int g_Plot_Mode = FILLED;
bool Plot_Set_MIROIR;
bool Sel_Rotate_Window;
bool HPGL_Org_Centre; // TRUE si en HPGL, l'origine le centre de la feuille
int g_PlotPSColorOpt; // True for color Postscript output
bool g_Plot_PS_Negative; // True to create a negative board ps plot
/* Autorisation de trace des divers items en serigraphie */
bool Sel_Texte_Reference = TRUE;
bool Sel_Texte_Valeur = TRUE;
bool Sel_Texte_Divers = TRUE;
bool Sel_Texte_Invisible;
/* Plot pads sur couche serigraphie */
bool PlotPadsOnSilkLayer = TRUE;
bool Plot_Pads_All_Layers; /* Plot pads meme n'appartenant pas a la
couche ( utile pour serigraphie) */
// Wildcard for footprint libraries filesnames
const wxString g_FootprintLibFileWildcard( wxT( "Kicad footprint library file (*.mod)|*.mod" ) );
......
......@@ -59,6 +59,9 @@ enum id_plotps {
};
/* The group of plot options - sadly global XXX */
PCB_Plot_Options g_pcb_plot_options;
/*******************************/
/* Dialog box for plot control */
/*******************************/
......@@ -76,7 +79,6 @@ public:
wxRadioBox* m_PlotModeOpt;
wxCheckBox* m_PlotMirorOpt;
wxCheckBox* m_PlotNoViaOnMaskOpt;
wxCheckBox* m_HPGL_PlotCenter_Opt;
wxCheckBox* m_Exclude_Edges_Pcb;
wxCheckBox* m_Plot_Sheet_Ref;
wxCheckBox* m_Plot_Invisible_Text;
......@@ -129,6 +131,7 @@ private:
void OnQuit( wxCommandEvent& event );
void OnClose( wxCloseEvent& event );
void SetCommands( wxCommandEvent& event );
void OnSetScaleOpt( wxCommandEvent& event );
void SaveOptPlot( wxCommandEvent& event );
void CreateDrillFile( wxCommandEvent& event );
......@@ -143,6 +146,7 @@ BEGIN_EVENT_TABLE( WinEDA_PlotFrame, wxDialog )
EVT_BUTTON( ID_SAVE_OPT_PLOT, WinEDA_PlotFrame::SaveOptPlot )
EVT_BUTTON( ID_CREATE_DRILL_FILE, WinEDA_PlotFrame::CreateDrillFile )
EVT_RADIOBOX( ID_SEL_PLOT_FORMAT, WinEDA_PlotFrame::SetCommands )
EVT_RADIOBOX( ID_SCALE_OPT, WinEDA_PlotFrame::OnSetScaleOpt )
END_EVENT_TABLE()
......@@ -204,11 +208,11 @@ void WinEDA_PlotFrame::OnInitDialog( wxInitDialogEvent& event )
if( config )
{
config->Read( OPTKEY_OUTPUT_FORMAT, &g_PlotFormat );
config->Read( OPTKEY_PLOT_LINEWIDTH_VALUE, &g_PlotLine_Width );
config->Read( OPTKEY_OUTPUT_FORMAT, &g_pcb_plot_options.PlotFormat );
config->Read( OPTKEY_PLOT_LINEWIDTH_VALUE, &g_pcb_plot_options.PlotLine_Width );
}
m_PlotFormatOpt->SetSelection( g_PlotFormat );
m_PlotFormatOpt->SetSelection( g_pcb_plot_options.PlotFormat );
// Creation des menus d'option du format HPGL
......@@ -218,20 +222,20 @@ void WinEDA_PlotFrame::OnInitDialog( wxInitDialogEvent& event )
MidRightBoxSizer->Add( HPGL_OptionsBoxSizer, 0, wxGROW | wxALL, 5 );
m_HPGLPenSizeOpt = new WinEDA_ValueCtrl( this, _( "Pen Size" ),
g_HPGL_Pen_Diam,
g_pcb_plot_options.HPGL_Pen_Diam,
g_UnitMetric,
HPGL_OptionsBoxSizer,
UNITS_MILS );
// unites standards = cm pour vitesse plume en HPGL
m_HPGLPenSpeedOpt = new WinEDA_ValueCtrl( this, _( "Pen Speed (cm/s)" ),
g_HPGL_Pen_Speed, CENTIMETRE,
g_pcb_plot_options.HPGL_Pen_Speed, CENTIMETRE,
HPGL_OptionsBoxSizer, 1 );
m_HPGLPenSpeedOpt->SetToolTip( _( "Set pen speed in cm/s" ) );
m_HPGLPenOverlayOpt = new WinEDA_ValueCtrl( this, _( "Pen ovr" ),
g_HPGL_Pen_Recouvrement,
g_pcb_plot_options.HPGL_Pen_Recouvrement,
g_UnitMetric,
HPGL_OptionsBoxSizer,
UNITS_MILS );
......@@ -239,7 +243,7 @@ void WinEDA_PlotFrame::OnInitDialog( wxInitDialogEvent& event )
m_HPGLPenOverlayOpt->SetToolTip( _( "Set plot overlay for filling" ) );
m_LinesWidth = new WinEDA_ValueCtrl( this, _( "Lines Width" ),
g_PlotLine_Width,
g_pcb_plot_options.PlotLine_Width,
g_UnitMetric,
MidRightBoxSizer,
PCB_INTERNAL_UNIT );
......@@ -269,7 +273,7 @@ mode and plot pads outlines on silk screen layers" ) );
if( config )
{
config->Read( OPTKEY_EDGELAYER_GERBER, &g_Exclude_Edges_Pcb );
config->Read( OPTKEY_EDGELAYER_GERBER, &g_pcb_plot_options.Exclude_Edges_Pcb );
config->Read( OPTKEY_XFINESCALE_ADJ, &m_XScaleAdjust );
config->Read( OPTKEY_YFINESCALE_ADJ, &m_YScaleAdjust );
}
......@@ -294,7 +298,7 @@ scale plotting" ) );
scale plotting" ) );
m_Plot_PS_Negative = new wxCheckBox( this, -1, _( "Plot negative" ) );
m_Plot_PS_Negative->SetValue( g_Plot_PS_Negative );
m_Plot_PS_Negative->SetValue( g_pcb_plot_options.Plot_PS_Negative );
RightBoxSizer->Add( m_Plot_PS_Negative, 0, wxGROW | wxALL, 5 );
......@@ -357,7 +361,7 @@ scale plotting" ) );
ID_EXCLUDE_EDGES_PCB,
_( "Exclude Edges_Pcb layer" ) );
m_Exclude_Edges_Pcb->SetValue( g_Exclude_Edges_Pcb );
m_Exclude_Edges_Pcb->SetValue( g_pcb_plot_options.Exclude_Edges_Pcb );
m_Exclude_Edges_Pcb->SetToolTip(
_( "Exclude contents of Edges_Pcb layer from all other layers" ) );
LeftBoxSizer->Add( m_Exclude_Edges_Pcb, 0, wxGROW | wxALL, 1 );
......@@ -368,11 +372,11 @@ scale plotting" ) );
m_Plot_Sheet_Ref = new wxCheckBox( this, ID_PRINT_REF,
_( "Print sheet ref" ) );
m_Plot_Sheet_Ref->SetValue( g_Plot_Frame_Ref );
m_Plot_Sheet_Ref->SetValue( g_pcb_plot_options.Plot_Frame_Ref );
LeftBoxSizer->Add( m_Plot_Sheet_Ref, 0, wxGROW | wxALL, 1 );
}
else
g_Plot_Frame_Ref = false;
g_pcb_plot_options.Plot_Frame_Ref = false;
// Option to plot pads on silkscreen layers or all layers
m_Plot_Pads_on_Silkscreen = new wxCheckBox( this,
......@@ -380,9 +384,9 @@ scale plotting" ) );
_( "Print pads on silkscreen" ) );
if( config )
config->Read( OPTKEY_PADS_ON_SILKSCREEN, &PlotPadsOnSilkLayer );
config->Read( OPTKEY_PADS_ON_SILKSCREEN, &g_pcb_plot_options.PlotPadsOnSilkLayer );
m_Plot_Pads_on_Silkscreen->SetValue( PlotPadsOnSilkLayer );
m_Plot_Pads_on_Silkscreen->SetValue( &g_pcb_plot_options.PlotPadsOnSilkLayer );
m_Plot_Pads_on_Silkscreen->SetToolTip(
_( "Enable/disable print/plot pads on silkscreen layers" ) );
LeftBoxSizer->Add( m_Plot_Pads_on_Silkscreen, 0, wxGROW | wxALL, 1 );
......@@ -390,9 +394,9 @@ scale plotting" ) );
m_Force_Plot_Pads = new wxCheckBox( this, ID_FORCE_PRINT_PAD,
_( "Always print pads" ) );
if( config )
config->Read( OPTKEY_ALWAYS_PRINT_PADS, &Plot_Pads_All_Layers );
config->Read( OPTKEY_ALWAYS_PRINT_PADS, &g_pcb_plot_options.Plot_Pads_All_Layers );
m_Force_Plot_Pads->SetValue( Plot_Pads_All_Layers );
m_Force_Plot_Pads->SetValue( g_pcb_plot_options.Plot_Pads_All_Layers );
m_Force_Plot_Pads->SetToolTip( _( "Force print/plot pads on ALL layers" ) );
LeftBoxSizer->Add( m_Force_Plot_Pads, 0, wxGROW | wxALL, 1 );
......@@ -400,7 +404,7 @@ scale plotting" ) );
m_Plot_Text_Value = new wxCheckBox( this, ID_PRINT_VALUE,
_( "Print module value" ) );
m_Plot_Text_Value->SetValue( Sel_Texte_Valeur );
m_Plot_Text_Value->SetValue( g_pcb_plot_options.Sel_Texte_Valeur );
m_Plot_Text_Value->SetToolTip(
_( "Enable/disable print/plot module value on silkscreen layers" ) );
LeftBoxSizer->Add( m_Plot_Text_Value, 0, wxGROW | wxALL, 1 );
......@@ -408,7 +412,7 @@ scale plotting" ) );
m_Plot_Text_Ref = new wxCheckBox( this, ID_PRINT_REF,
_( "Print module reference" ) );
m_Plot_Text_Ref->SetValue( Sel_Texte_Reference );
m_Plot_Text_Ref->SetValue( g_pcb_plot_options.Sel_Texte_Reference );
m_Plot_Text_Ref->SetToolTip(
_( "Enable/disable print/plot module reference on silkscreen layers" ) );
LeftBoxSizer->Add( m_Plot_Text_Ref, 0, wxGROW | wxALL, 1 );
......@@ -416,7 +420,7 @@ scale plotting" ) );
m_Plot_Text_Div = new wxCheckBox( this, ID_PRINT_MODULE_TEXTS,
_( "Print other module texts" ) );
m_Plot_Text_Div->SetValue( Sel_Texte_Divers );
m_Plot_Text_Div->SetValue( g_pcb_plot_options.Sel_Texte_Divers );
m_Plot_Text_Div->SetToolTip(
_( "Enable/disable print/plot module field texts on silkscreen layers" ) );
LeftBoxSizer->Add( m_Plot_Text_Div, 0, wxGROW | wxALL, 1 );
......@@ -425,7 +429,7 @@ scale plotting" ) );
ID_FORCE_PRINT_INVISIBLE_TEXT,
_( "Force print invisible texts" ) );
m_Plot_Invisible_Text->SetValue( Sel_Texte_Invisible );
m_Plot_Invisible_Text->SetValue( g_pcb_plot_options.Sel_Texte_Invisible );
m_Plot_Invisible_Text->SetToolTip(
_( "Force print/plot module invisible texts on silkscreen layers" ) );
LeftBoxSizer->Add( m_Plot_Invisible_Text, 0, wxGROW | wxALL, 1 );
......@@ -442,7 +446,7 @@ scale plotting" ) );
wxDefaultPosition, wxSize( -1, -1 ),
3, drillmsg, 1, wxRA_SPECIFY_COLS );
m_Drill_Shape_Opt->SetSelection( g_DrillShapeOpt );
m_Drill_Shape_Opt->SetSelection( g_pcb_plot_options.DrillShapeOpt );
MidLeftBoxSizer->Add( m_Drill_Shape_Opt, 0, wxGROW | wxALL, 5 );
static const wxString scalemsg[5] =
......@@ -459,7 +463,7 @@ scale plotting" ) );
wxSize( -1, -1 ),
5, scalemsg, 1, wxRA_SPECIFY_COLS );
m_Scale_Opt->SetSelection( g_PlotScaleOpt );
m_Scale_Opt->SetSelection( g_pcb_plot_options.PlotScaleOpt );
MidLeftBoxSizer->Add( m_Scale_Opt, 0, wxGROW | wxALL, 5 );
static const wxString list_opt3[3] = { _( "Line" ), _( "Filled" ), _(
......@@ -469,33 +473,27 @@ scale plotting" ) );
wxDefaultPosition, wxDefaultSize,
3, list_opt3, 1 );
m_PlotModeOpt->SetSelection( g_Plot_Mode );
m_PlotModeOpt->SetSelection( g_pcb_plot_options.Trace_Mode );
MidLeftBoxSizer->Add( m_PlotModeOpt, 0, wxGROW | wxALL, 5 );
m_PlotMirorOpt = new wxCheckBox( this, ID_MIROR_OPT,
_( "Plot mirror" ) );
m_PlotMirorOpt->SetValue( Plot_Set_MIROIR );
m_PlotMirorOpt->SetValue( g_pcb_plot_options.Plot_Set_MIROIR );
MidLeftBoxSizer->Add( m_PlotMirorOpt, 0, wxGROW | wxALL, 5 );
m_PlotNoViaOnMaskOpt = new wxCheckBox( this, ID_MASKVIA_OPT,
_( "Vias on mask" ) );
m_PlotNoViaOnMaskOpt->SetValue( g_DrawViaOnMaskLayer );
m_PlotNoViaOnMaskOpt->SetValue( g_pcb_plot_options.DrawViaOnMaskLayer );
m_PlotNoViaOnMaskOpt->SetToolTip(
_( "Print/plot vias on mask layers. They are in this case not protected" ) );
MidLeftBoxSizer->Add( m_PlotNoViaOnMaskOpt, 0, wxGROW | wxALL, 5 );
m_HPGL_PlotCenter_Opt = new wxCheckBox( this, ID_PLOT_CENTRE_OPT,
_( "Org = Centre" ) );
m_HPGL_PlotCenter_Opt->SetValue( HPGL_Org_Centre );
m_HPGL_PlotCenter_Opt->SetToolTip( _( "Draw origin ( 0,0 ) in sheet center" ) );
MidLeftBoxSizer->Add( m_HPGL_PlotCenter_Opt, 0, wxGROW | wxALL, 5 );
// Update options values:
wxCommandEvent cmd_event;
SetCommands( cmd_event );
OnSetScaleOpt( cmd_event );
GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this );
......@@ -522,6 +520,14 @@ void WinEDA_PlotFrame::CreateDrillFile( wxCommandEvent& event )
( (WinEDA_PcbFrame*) m_Parent )->InstallDrillFrame( event );
}
void WinEDA_PlotFrame::OnSetScaleOpt( wxCommandEvent& event )
{
/* Disable sheet reference for scale != 1:1 */
bool scale1 = (m_Scale_Opt->GetSelection() == 1);
m_Plot_Sheet_Ref->Enable( scale1 );
if (!scale1)
m_Plot_Sheet_Ref->SetValue(false);
}
void WinEDA_PlotFrame::SetCommands( wxCommandEvent& event )
{
......@@ -540,9 +546,8 @@ void WinEDA_PlotFrame::SetCommands( wxCommandEvent& event )
m_HPGLPenSizeOpt->Enable( false );
m_HPGLPenSpeedOpt->Enable( false );
m_HPGLPenOverlayOpt->Enable( false );
m_HPGL_PlotCenter_Opt->Enable( false );
m_Exclude_Edges_Pcb->SetValue( false );
m_Exclude_Edges_Pcb->Enable( false );
m_Plot_Sheet_Ref->Enable( true );
m_Scale_Opt->Enable( true );
m_FineAdjustXscaleOpt->Enable( true );
m_FineAdjustYscaleOpt->Enable( true );
......@@ -550,8 +555,11 @@ void WinEDA_PlotFrame::SetCommands( wxCommandEvent& event )
break;
case PLOT_FORMAT_GERBER:
m_Drill_Shape_Opt->SetSelection( 0 );
m_Drill_Shape_Opt->Enable( false );
m_PlotModeOpt->SetSelection( 1 );
m_PlotModeOpt->Enable( false );
m_PlotMirorOpt->SetValue( false );
m_PlotMirorOpt->Enable( false );
m_Choice_Plot_Offset->Enable( true );
m_LinesWidth->Enable( true );
......@@ -559,17 +567,18 @@ void WinEDA_PlotFrame::SetCommands( wxCommandEvent& event )
m_HPGLPenSizeOpt->Enable( false );
m_HPGLPenSpeedOpt->Enable( false );
m_HPGLPenOverlayOpt->Enable( false );
m_HPGL_PlotCenter_Opt->Enable( false );
m_Exclude_Edges_Pcb->Enable( true );
m_Plot_Sheet_Ref->Enable( false );
m_Scale_Opt->SetSelection( 1 );
m_Scale_Opt->Enable( false );
m_FineAdjustXscaleOpt->Enable( false );
m_FineAdjustYscaleOpt->Enable( false );
m_Plot_PS_Negative->SetValue( false );
m_Plot_PS_Negative->Enable( false );
break;
case PLOT_FORMAT_HPGL:
m_PlotMirorOpt->Enable( true );
m_Drill_Shape_Opt->SetSelection( 0 );
m_Drill_Shape_Opt->Enable( false );
m_PlotModeOpt->Enable( true );
m_Choice_Plot_Offset->Enable( false );
......@@ -578,53 +587,52 @@ void WinEDA_PlotFrame::SetCommands( wxCommandEvent& event )
m_HPGLPenSizeOpt->Enable( true );
m_HPGLPenSpeedOpt->Enable( true );
m_HPGLPenOverlayOpt->Enable( true );
m_HPGL_PlotCenter_Opt->Enable( true );
m_Exclude_Edges_Pcb->SetValue( false );
m_Exclude_Edges_Pcb->Enable( false );
m_Plot_Sheet_Ref->Enable( true );
m_Scale_Opt->Enable( true );
m_FineAdjustXscaleOpt->Enable( false );
m_FineAdjustYscaleOpt->Enable( false );
m_Plot_PS_Negative->SetValue( false );
m_Plot_PS_Negative->Enable( false );
break;
}
g_PlotFormat = format;
g_pcb_plot_options.PlotFormat = format;
}
void WinEDA_PlotFrame::SaveOptPlot( wxCommandEvent& event )
{
g_Exclude_Edges_Pcb = m_Exclude_Edges_Pcb->GetValue();
g_pcb_plot_options.Exclude_Edges_Pcb = m_Exclude_Edges_Pcb->GetValue();
if( m_Plot_Sheet_Ref )
g_Plot_Frame_Ref = m_Plot_Sheet_Ref->GetValue();
g_pcb_plot_options.Plot_Frame_Ref = m_Plot_Sheet_Ref->GetValue();
PlotPadsOnSilkLayer = m_Plot_Pads_on_Silkscreen->GetValue();
Plot_Pads_All_Layers = m_Force_Plot_Pads->GetValue();
g_pcb_plot_options.PlotPadsOnSilkLayer = m_Plot_Pads_on_Silkscreen->GetValue();
g_pcb_plot_options.Plot_Pads_All_Layers = m_Force_Plot_Pads->GetValue();
s_PlotOriginIsAuxAxis =
(m_Choice_Plot_Offset->GetSelection() == 0) ? FALSE : TRUE;
Sel_Texte_Valeur = m_Plot_Text_Value->GetValue();
Sel_Texte_Reference = m_Plot_Text_Ref->GetValue();
Sel_Texte_Divers = m_Plot_Text_Div->GetValue();
Sel_Texte_Invisible = m_Plot_Invisible_Text->GetValue();
g_pcb_plot_options.Sel_Texte_Valeur = m_Plot_Text_Value->GetValue();
g_pcb_plot_options.Sel_Texte_Reference = m_Plot_Text_Ref->GetValue();
g_pcb_plot_options.Sel_Texte_Divers = m_Plot_Text_Div->GetValue();
g_pcb_plot_options.Sel_Texte_Invisible = m_Plot_Invisible_Text->GetValue();
g_PlotScaleOpt = m_Scale_Opt->GetSelection();
g_DrillShapeOpt = m_Drill_Shape_Opt->GetSelection();
Plot_Set_MIROIR = m_PlotMirorOpt->GetValue();
if( Plot_Set_MIROIR )
g_PlotOrient = PLOT_MIROIR;
g_pcb_plot_options.PlotScaleOpt = m_Scale_Opt->GetSelection();
g_pcb_plot_options.DrillShapeOpt = (PCB_Plot_Options::DrillShapeOptT) m_Drill_Shape_Opt->GetSelection();
g_pcb_plot_options.Plot_Set_MIROIR = m_PlotMirorOpt->GetValue();
if( g_pcb_plot_options.Plot_Set_MIROIR )
g_pcb_plot_options.PlotOrient = PLOT_MIROIR;
else
g_PlotOrient = 0;
g_Plot_Mode = m_PlotModeOpt->GetSelection();
g_DrawViaOnMaskLayer = m_PlotNoViaOnMaskOpt->GetValue();
g_pcb_plot_options.PlotOrient = 0;
g_pcb_plot_options.Trace_Mode = (GRTraceMode)m_PlotModeOpt->GetSelection();
g_pcb_plot_options.DrawViaOnMaskLayer = m_PlotNoViaOnMaskOpt->GetValue();
g_HPGL_Pen_Diam = m_HPGLPenSizeOpt->GetValue();
g_HPGL_Pen_Speed = m_HPGLPenSpeedOpt->GetValue();
g_HPGL_Pen_Recouvrement = m_HPGLPenOverlayOpt->GetValue();
HPGL_Org_Centre = m_HPGL_PlotCenter_Opt->GetValue();
g_PlotLine_Width = m_LinesWidth->GetValue();
g_pcb_plot_options.HPGL_Pen_Diam = m_HPGLPenSizeOpt->GetValue();
g_pcb_plot_options.HPGL_Pen_Speed = m_HPGLPenSpeedOpt->GetValue();
g_pcb_plot_options.HPGL_Pen_Recouvrement = m_HPGLPenOverlayOpt->GetValue();
g_pcb_plot_options.PlotLine_Width = m_LinesWidth->GetValue();
m_XScaleAdjust = m_FineAdjustXscaleOpt->GetValue();
m_YScaleAdjust = m_FineAdjustYscaleOpt->GetValue();
......@@ -633,16 +641,16 @@ void WinEDA_PlotFrame::SaveOptPlot( wxCommandEvent& event )
if( config )
{
config->Write( OPTKEY_EDGELAYER_GERBER, g_Exclude_Edges_Pcb );
config->Write( OPTKEY_EDGELAYER_GERBER, g_pcb_plot_options.Exclude_Edges_Pcb );
config->Write( OPTKEY_XFINESCALE_ADJ, m_XScaleAdjust );
config->Write( OPTKEY_YFINESCALE_ADJ, m_YScaleAdjust );
config->Write( OPTKEY_PADS_ON_SILKSCREEN, PlotPadsOnSilkLayer );
config->Write( OPTKEY_ALWAYS_PRINT_PADS, Plot_Pads_All_Layers );
config->Write( OPTKEY_PADS_ON_SILKSCREEN, g_pcb_plot_options.PlotPadsOnSilkLayer );
config->Write( OPTKEY_ALWAYS_PRINT_PADS, g_pcb_plot_options.Plot_Pads_All_Layers );
int formatNdx = m_PlotFormatOpt->GetSelection();
config->Write( OPTKEY_OUTPUT_FORMAT, formatNdx );
config->Write( OPTKEY_PLOT_LINEWIDTH_VALUE, g_PlotLine_Width );
config->Write( OPTKEY_PLOT_LINEWIDTH_VALUE, g_pcb_plot_options.PlotLine_Width );
wxString layerKey;
for( int layer = 0; layer<NB_LAYERS; ++layer )
......@@ -652,7 +660,7 @@ void WinEDA_PlotFrame::SaveOptPlot( wxCommandEvent& event )
}
}
g_Plot_PS_Negative = m_Plot_PS_Negative->GetValue();
g_pcb_plot_options.Plot_PS_Negative = m_Plot_PS_Negative->GetValue();
}
......@@ -667,22 +675,22 @@ void WinEDA_PlotFrame::Plot( wxCommandEvent& event )
SaveOptPlot( event );
switch( g_PlotScaleOpt )
switch( g_pcb_plot_options.PlotScaleOpt )
{
default:
Scale_X = Scale_Y = 1;
g_pcb_plot_options.Scale = 1;
break;
case 2:
Scale_X = Scale_Y = 1.5;
g_pcb_plot_options.Scale = 1.5;
break;
case 3:
Scale_X = Scale_Y = 2;
g_pcb_plot_options.Scale = 2;
break;
case 4:
Scale_X = Scale_Y = 3;
g_pcb_plot_options.Scale = 3;
break;
}
......@@ -693,10 +701,10 @@ void WinEDA_PlotFrame::Plot( wxCommandEvent& event )
*/
if( m_FineAdjustXscaleOpt->m_ValueCtrl->IsEnabled()
&& m_XScaleAdjust != 0.0 )
Scale_X *= m_XScaleAdjust;
g_pcb_plot_options.ScaleAdjX = m_XScaleAdjust;
if( m_FineAdjustYscaleOpt->m_ValueCtrl->IsEnabled()
&& m_YScaleAdjust != 0.0 )
Scale_Y *= m_YScaleAdjust;
g_pcb_plot_options.ScaleAdjY = m_YScaleAdjust;
int format = getFormat();
......@@ -709,7 +717,7 @@ void WinEDA_PlotFrame::Plot( wxCommandEvent& event )
default:
case PLOT_FORMAT_GERBER:
Scale_X = Scale_Y = 1.0; // No scale option allowed in gerber format
g_pcb_plot_options.Scale = 1.0; // No scale option allowed in gerber format
ext = wxT( "pho" );
wildcard = _( "GERBER photo plot files (.pho)|*.pho" );
break;
......@@ -721,10 +729,10 @@ void WinEDA_PlotFrame::Plot( wxCommandEvent& event )
}
// Test for a reasonnable scale value
if( Scale_X < MIN_SCALE || Scale_Y < MIN_SCALE )
if( g_pcb_plot_options.Scale < MIN_SCALE )
DisplayInfoMessage( this,
_( "Warning: Scale option set to a very small value" ) );
if( Scale_X > MAX_SCALE || Scale_Y > MAX_SCALE )
if( g_pcb_plot_options.Scale > MAX_SCALE )
DisplayInfoMessage( this,
_( "Warning: Scale option set to a very large value" ) );
......@@ -749,17 +757,20 @@ void WinEDA_PlotFrame::Plot( wxCommandEvent& event )
switch( format )
{
case PLOT_FORMAT_POST:
m_Parent->Genere_PS( fn.GetFullPath(), layer_to_plot, useA4() );
m_Parent->Genere_PS( fn.GetFullPath(), layer_to_plot, useA4(),
g_pcb_plot_options.Trace_Mode );
break;
default:
case PLOT_FORMAT_GERBER:
m_Parent->Genere_GERBER( fn.GetFullPath(), layer_to_plot,
s_PlotOriginIsAuxAxis );
s_PlotOriginIsAuxAxis,
g_pcb_plot_options.Trace_Mode );
break;
case PLOT_FORMAT_HPGL:
m_Parent->Genere_HPGL( fn.GetFullPath(), layer_to_plot );
m_Parent->Genere_HPGL( fn.GetFullPath(), layer_to_plot,
g_pcb_plot_options.Trace_Mode );
break;
}
}
......
......@@ -19,105 +19,75 @@
/* coeff de conversion dim en 0,1 mil -> dim en unite HPGL: */
#define SCALE_HPGL 0.102041
/* Options : */
extern bool g_Exclude_Edges_Pcb;
extern bool g_Plot_Frame_Ref; // True to plot/print frame references
extern bool g_DrawViaOnMaskLayer; // True if vias are drawn on Mask layer (ie protected by mask)
extern int g_Plot_Mode;
extern bool Plot_Set_MIROIR;
extern bool Sel_Rotate_Window;
extern bool HPGL_Org_Centre; // TRUE si en HPGL, l'origine le centre de la feuille
extern int g_PlotPSColorOpt; // True for color Postscript output
extern bool g_Plot_PS_Negative; // True to create a negative board ps plot
/* Autorisation de trace des divers items en serigraphie */
extern bool Sel_Texte_Reference;
extern bool Sel_Texte_Valeur;
extern bool Sel_Texte_Divers;
extern bool Sel_Texte_Invisible;
extern bool PlotPadsOnSilkLayer;
extern bool Plot_Pads_All_Layers; /* Plot pads meme n'appartenant pas a la
/* Plot Options : */
struct PCB_Plot_Options {
bool Exclude_Edges_Pcb;
int PlotLine_Width;
bool Plot_Frame_Ref; // True to plot/print frame references
bool DrawViaOnMaskLayer; // True if vias are drawn on Mask layer (ie protected by mask)
GRTraceMode Trace_Mode;
bool Plot_Set_MIROIR;
int HPGL_Pen_Num;
int HPGL_Pen_Speed;
int HPGL_Pen_Diam;
int HPGL_Pen_Recouvrement;
int PlotPSColorOpt; // True for color Postscript output
bool Plot_PS_Negative; // True to create a negative board ps plot
/* Autorisation de trace des divers items en serigraphie */
bool Sel_Texte_Reference;
bool Sel_Texte_Valeur;
bool Sel_Texte_Divers;
bool Sel_Texte_Invisible;
bool PlotPadsOnSilkLayer;
bool Plot_Pads_All_Layers; /* Plot pads meme n'appartenant pas a la
couche ( utile pour serigraphie) */
/* Variables utiles */
extern FILE * dest;
/* id for plot format (see enum PlotFormat in plot_common.h) */
extern int g_PlotScaleOpt;
extern int g_DrillShapeOpt;
/* id for plot format (see enum PlotFormat in plot_common.h) */
int PlotFormat;
int PlotOrient;
int PlotScaleOpt;
enum DrillShapeOptT {
NO_DRILL_SHAPE = 0,
SMALL_DRILL_SHAPE = 1,
FULL_DRILL_SHAPE = 2
};
DrillShapeOptT DrillShapeOpt;
double Scale;
double ScaleAdjX;
double ScaleAdjY;
};
extern PCB_Plot_Options g_pcb_plot_options;
/*************************************/
/* Constantes utiles en trace GERBER */
/*************************************/
/* codes de type de forme d'outils */
#define GERB_CIRCLE 1
#define GERB_RECT 2
#define GERB_LINE 3
#define GERB_OVALE 4
#define GERB_DONUT 5
/* PLOT_RTN.CC */
void PlotTextePcb( TEXTE_PCB* pt_texte, int format_plot, int masque_layer );
void PlotTextePcb(Plotter *plotter, TEXTE_PCB* pt_texte, int masque_layer,
GRTraceMode trace_mode);
/* Trace 1 Texte type PCB , c.a.d autre que les textes sur modules,
* prepare les parametres de trace de texte */
void PlotArc( int format_plot, wxPoint centre, int start_angle, int end_angle,
int rayon, int width );
void PlotCircle( int format_plot, int width, wxPoint centre, int rayon );
void PlotFilledPolygon( int format_plot, int nbpoints, int* coord );
void PlotPolygon( int format_plot, int nbpoints, int* coord, int width );
void PlotDrawSegment( DRAWSEGMENT* PtSegm, int format_plot, int masque_layer );
void PlotDrawSegment(Plotter *plotter, DRAWSEGMENT* PtSegm, int masque_layer,
GRTraceMode trace_mode);
void PlotCotation( COTATION* Cotation, int format_plot, int masque_layer );
void PlotCotation(Plotter *plotter, COTATION* Cotation, int masque_layer ,
GRTraceMode trace_mode);
void PlotMirePcb( MIREPCB* PtMire, int format_plot, int masque_layer );
void PlotMirePcb(Plotter *plotter, MIREPCB* PtMire, int masque_layer ,
GRTraceMode trace_mode);
void Plot_1_EdgeModule( int format_plot, EDGE_MODULE* PtEdge );
void Plot_1_EdgeModule(Plotter *plotter, EDGE_MODULE* PtEdge ,
GRTraceMode trace_mode);
void PlotFilledAreas( ZONE_CONTAINER* aZone, int aFormat );
void PlotFilledAreas(Plotter *plotter, ZONE_CONTAINER* aZone,
GRTraceMode trace_mode);
/* PLOTGERB.CPP */
void SelectD_CODE_For_LineDraw( int aSize );
void trace_1_contour_GERBER( wxPoint pos, wxSize size, wxSize delta,
int penwidth, int orient );
/* Trace 1 contour rectangulaire ou trapezoidal d'orientation quelconque
* donne par son centre, ses dimensions,
* ses variations, l'epaisseur du trait et son orientation orient */
/* PLOTHPGL.CPP */
/** Function Plot a filled segment (track)
* @param aStart = starting point
* @param aEnd = ending point
* @param aWidth = segment width (thickness)
* @param aPlotMode = FILLED, SKETCH ..
* @return true if Ok, false if aWidth > pen size (the segment is always plotted)
*/
bool Plot_Filled_Segment_HPGL( wxPoint aStart, wxPoint aEnd, int aWidth, GRFillMode aPlotMode );
void trace_1_pad_TRAPEZE_HPGL( wxPoint padpos, wxSize size, wxSize delta,
int orient, int modetrace );
void trace_1_pastille_RONDE_HPGL( wxPoint padpos, int diametre, int modetrace );
void trace_1_pastille_OVALE_HPGL( wxPoint padpos, wxSize size, int orient, int modetrace );
void PlotRectangularPad_HPGL( wxPoint padpos, wxSize padsize, int orient, int modetrace );
/**************/
/* PLOTPS.CPP */
/**************/
void trace_1_pastille_OVALE_POST( wxPoint centre, wxSize size, int orient, int modetrace );
void trace_1_pastille_RONDE_POST( wxPoint centre, int diametre, int modetrace );
void trace_1_pad_rectangulaire_POST( wxPoint centre, wxSize size, int orient,
int modetrace );
void trace_1_contour_POST( wxPoint centre, wxSize size, wxSize delta,
int dim_trait, int orient );
void trace_1_pad_TRAPEZE_POST( wxPoint centre, wxSize size, wxSize delta,
int orient, int modetrace );
void SelectD_CODE_For_LineDraw(Plotter *plotter, int aSize );
#endif /* #define PCBPLOT_H */
......@@ -16,13 +16,14 @@
/* Fonctions locales */
static void Plot_Edges_Modules( BOARD* pcb, int format_plot, int masque_layer );
static void PlotTextModule( TEXTE_MODULE* pt_texte, int format_plot );
static void Plot_Edges_Modules(Plotter *plotter, BOARD* pcb, int masque_layer,
GRTraceMode trace_mode );
static void PlotTextModule(Plotter *plotter, TEXTE_MODULE* pt_texte,
GRTraceMode trace_mode );
/**********************************************************/
void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
FILE* File, int masque_layer )
void WinEDA_BasePcbFrame::Plot_Serigraphie( Plotter *plotter,
int masque_layer, GRTraceMode trace_mode )
/***********************************************************/
/* Genere le trace des couches type serigraphie, en format HPGL ou GERBER*/
......@@ -33,28 +34,29 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
D_PAD* pt_pad;
TEXTE_MODULE* pt_texte;
EDA_BaseStruct* PtStruct;
wxString msg;
/* Trace du contour du PCB et des Elements du type Drawings Pcb */
PtStruct = m_Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
for( PtStruct = m_Pcb->m_Drawings;
PtStruct != NULL;
PtStruct = PtStruct->Next() )
{
switch( PtStruct->Type() )
{
case TYPE_DRAWSEGMENT:
PlotDrawSegment( (DRAWSEGMENT*) PtStruct, format_plot, masque_layer );
PlotDrawSegment(plotter, (DRAWSEGMENT*) PtStruct, masque_layer, trace_mode );
break;
case TYPE_TEXTE:
PlotTextePcb( (TEXTE_PCB*) PtStruct, format_plot, masque_layer );
PlotTextePcb(plotter, (TEXTE_PCB*) PtStruct, masque_layer, trace_mode );
break;
case TYPE_COTATION:
PlotCotation( (COTATION*) PtStruct, format_plot, masque_layer );
PlotCotation(plotter, (COTATION*) PtStruct, masque_layer, trace_mode );
break;
case TYPE_MIRE:
PlotMirePcb( (MIREPCB*) PtStruct, format_plot, masque_layer );
PlotMirePcb(plotter, (MIREPCB*) PtStruct, masque_layer, trace_mode );
break;
case TYPE_MARKER:
......@@ -67,20 +69,30 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
}
/* trace des contours des MODULES : */
Plot_Edges_Modules( m_Pcb, format_plot, masque_layer );
Plot_Edges_Modules(plotter, m_Pcb, masque_layer, trace_mode );
/* Trace des MODULES : PADS */
if( PlotPadsOnSilkLayer || Plot_Pads_All_Layers )
if( g_pcb_plot_options.PlotPadsOnSilkLayer
|| g_pcb_plot_options.Plot_Pads_All_Layers )
{
for( MODULE* Module = m_Pcb->m_Modules; Module; Module = Module->Next() )
for( MODULE* Module = m_Pcb->m_Modules;
Module;
Module = Module->Next() )
{
pt_pad = (D_PAD*) Module->m_Pads;
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
for(pt_pad = (D_PAD*) Module->m_Pads;
pt_pad != NULL;
pt_pad = pt_pad->Next() )
{
/* Tst si layer OK */
if( (pt_pad->m_Masque_Layer & masque_layer) == 0 )
if( (pt_pad->m_Masque_Layer & masque_layer) == 0
/* Copper pads go on copper silk, component
* pads go on component silk */
&& (((pt_pad->m_Masque_Layer & CUIVRE_LAYER) == 0)
|| ((masque_layer & SILKSCREEN_LAYER_CU) == 0 ))
&& (((pt_pad->m_Masque_Layer & CMP_LAYER) == 0)
|| ((masque_layer & SILKSCREEN_LAYER_CMP) == 0 )))
{
if( !Plot_Pads_All_Layers )
if( !g_pcb_plot_options.Plot_Pads_All_Layers )
continue;
}
......@@ -91,98 +103,27 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
switch( pt_pad->m_PadShape & 0x7F )
{
case PAD_CIRCLE:
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
PlotCircle( PLOT_FORMAT_GERBER,
g_PlotLine_Width, pos, size.x / 2 );
break;
case PLOT_FORMAT_HPGL:
trace_1_pastille_RONDE_HPGL( pos, size.x, FILAIRE );
break;
case PLOT_FORMAT_POST:
trace_1_pastille_RONDE_POST( pos, size.x, FILAIRE );
break;
}
plotter->flash_pad_circle(pos, size.x, FILAIRE);
break;
case PAD_OVAL:
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
trace_1_contour_GERBER( pos, size, wxSize( 0, 0 ),
g_PlotLine_Width,
pt_pad->m_Orient );
break;
case PLOT_FORMAT_HPGL:
trace_1_pastille_OVALE_HPGL( pos, size,
plotter->flash_pad_oval(pos, size,
pt_pad->m_Orient, FILAIRE );
break;
case PLOT_FORMAT_POST:
trace_1_pastille_OVALE_POST( pos, size,
pt_pad->m_Orient, FILAIRE );
break;
}
break;
case PAD_TRAPEZOID:
{
case PAD_TRAPEZOID: {
wxSize delta;
delta = pt_pad->m_DeltaSize;
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
trace_1_contour_GERBER( pos, size, delta,
g_PlotLine_Width,
(int) pt_pad->m_Orient );
break;
case PLOT_FORMAT_HPGL:
trace_1_pad_TRAPEZE_HPGL( pos, size,
delta, (int) pt_pad->m_Orient,
FILAIRE );
break;
case PLOT_FORMAT_POST:
trace_1_pad_TRAPEZE_POST( pos, size,
delta, (int) pt_pad->m_Orient,
plotter->flash_pad_trapez( pos, size,
delta, pt_pad->m_Orient,
FILAIRE );
break;
}
break;
}
case PAD_RECT:
default:
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
trace_1_contour_GERBER( pos, size, wxSize( 0, 0 ),
g_PlotLine_Width,
(int) pt_pad->m_Orient );
break;
case PLOT_FORMAT_HPGL:
PlotRectangularPad_HPGL( pos, size, pt_pad->m_Orient, FILAIRE );
break;
case PLOT_FORMAT_POST:
trace_1_pad_rectangulaire_POST( pos, size,
(int) pt_pad->m_Orient, FILAIRE );
break;
}
plotter->flash_pad_rect( pos, size, pt_pad->m_Orient,
FILAIRE);
break;
}
}
......@@ -190,11 +131,13 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
} /* Fin Sequence de trace des Pads */
/* Trace Textes MODULES */
for( MODULE* Module = m_Pcb->m_Modules; Module; Module = Module->Next() )
for( MODULE* Module = m_Pcb->m_Modules;
Module;
Module = Module->Next() )
{
/* Analyse des autorisations de trace pour les textes VALEUR et REF */
trace_val = Sel_Texte_Valeur;
trace_ref = Sel_Texte_Reference; // les 2 autorisations de tracer sont donnees
trace_val = g_pcb_plot_options.Sel_Texte_Valeur;
trace_ref = g_pcb_plot_options.Sel_Texte_Reference; // les 2 autorisations de tracer sont donnees
TEXTE_MODULE* text = Module->m_Reference;
unsigned textLayer = text->GetLayer();
......@@ -207,13 +150,13 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
_( "Your BOARD has a bad layer number of %u for module\n %s's \"reference\" text." ),
textLayer, Module->GetReference().GetData() );
DisplayError( this, errMsg );
goto exit;
return;
}
if( ( (1 << textLayer) & masque_layer ) == 0 )
trace_ref = FALSE;
if( text->m_NoShow && !Sel_Texte_Invisible )
if( text->m_NoShow && !g_pcb_plot_options.Sel_Texte_Invisible )
trace_ref = FALSE;
text = Module->m_Value;
......@@ -227,35 +170,32 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
_( "Your BOARD has a bad layer number of %u for module\n %s's \"value\" text." ),
textLayer, Module->GetReference().GetData() );
DisplayError( this, errMsg );
goto exit;
return;
}
if( ( (1 << textLayer) & masque_layer ) == 0 )
trace_val = FALSE;
if( text->m_NoShow && !Sel_Texte_Invisible )
if( text->m_NoShow && !g_pcb_plot_options.Sel_Texte_Invisible )
trace_val = FALSE;
/* Trace effectif des textes */
if( trace_ref )
{
PlotTextModule( Module->m_Reference, format_plot );
}
PlotTextModule(plotter, Module->m_Reference, trace_mode );
if( trace_val )
{
PlotTextModule( Module->m_Value, format_plot );
}
PlotTextModule(plotter, Module->m_Value, trace_mode );
pt_texte = (TEXTE_MODULE*) Module->m_Drawings.GetFirst();
for( ; pt_texte != NULL; pt_texte = pt_texte->Next() )
for(pt_texte = (TEXTE_MODULE*) Module->m_Drawings.GetFirst() ;
pt_texte != NULL;
pt_texte = pt_texte->Next() )
{
if( pt_texte->Type() != TYPE_TEXTE_MODULE )
continue;
if( !Sel_Texte_Divers )
if( !g_pcb_plot_options.Sel_Texte_Divers )
continue;
if( (pt_texte->m_NoShow) && !Sel_Texte_Invisible )
if( (pt_texte->m_NoShow) && !g_pcb_plot_options.Sel_Texte_Invisible )
continue;
textLayer = pt_texte->GetLayer();
......@@ -264,17 +204,16 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
wxString errMsg;
errMsg.Printf(
_(
"Your BOARD has a bad layer number of %u for module\n %s's \"module text\" text of %s." ),
_( "Your BOARD has a bad layer number of %u for module\n %s's \"module text\" text of %s." ),
textLayer, Module->GetReference().GetData(), pt_texte->m_Text.GetData() );
DisplayError( this, errMsg );
goto exit;
return;
}
if( !( (1 << textLayer) & masque_layer ) )
continue;
PlotTextModule( pt_texte, format_plot );
PlotTextModule(plotter, pt_texte, trace_mode);
}
}
......@@ -284,7 +223,7 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
ZONE_CONTAINER* edge_zone = m_Pcb->GetArea( ii );
if( ( ( 1 << edge_zone->GetLayer() ) & masque_layer ) == 0 )
continue;
PlotFilledAreas( edge_zone, format_plot );
PlotFilledAreas(plotter, edge_zone, trace_mode );
}
// Plot segments used to fill zone areas:
......@@ -292,30 +231,15 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
{
if( ( ( 1 << seg->GetLayer() ) & masque_layer ) == 0 )
continue;
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
SelectD_CODE_For_LineDraw( seg->m_Width );
PlotGERBERLine( seg->m_Start, seg->m_End, seg->m_Width );
break;
case PLOT_FORMAT_HPGL:
Plot_Filled_Segment_HPGL( seg->m_Start, seg->m_End, seg->m_Width, FILLED );
break;
case PLOT_FORMAT_POST:
PlotFilledSegmentPS( seg->m_Start, seg->m_End, seg->m_Width );
break;
}
plotter->thick_segment(seg->m_Start, seg->m_End, seg->m_Width,
trace_mode);
}
exit:
;
}
/********************************************************************/
static void PlotTextModule( TEXTE_MODULE* pt_texte, int format_plot )
static void PlotTextModule(Plotter *plotter, TEXTE_MODULE* pt_texte,
GRTraceMode trace_mode)
/********************************************************************/
{
wxSize size;
......@@ -329,27 +253,13 @@ static void PlotTextModule( TEXTE_MODULE* pt_texte, int format_plot )
orient = pt_texte->GetDrawRotation();
thickness = pt_texte->m_Width;
if( g_Plot_Mode == FILAIRE )
thickness = g_PlotLine_Width;
if( trace_mode == FILAIRE )
thickness = -1;
if( pt_texte->m_Mirror )
size.x = -size.x; // Text is mirrored
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
SelectD_CODE_For_LineDraw( thickness );
break;
case PLOT_FORMAT_HPGL:
break;
case PLOT_FORMAT_POST:
SetCurrentLineWidthPS( thickness );
break;
}
PlotGraphicText( format_plot, pos, g_Plot_PS_Negative ? WHITE : BLACK,
plotter->text( pos, BLACK,
pt_texte->m_Text,
orient, size,
pt_texte->m_HJustify, pt_texte->m_VJustify,
......@@ -358,7 +268,8 @@ static void PlotTextModule( TEXTE_MODULE* pt_texte, int format_plot )
/*******************************************************************************/
void PlotCotation( COTATION* Cotation, int format_plot, int masque_layer )
void PlotCotation(Plotter *plotter, COTATION* Cotation, int masque_layer,
GRTraceMode trace_mode)
/*******************************************************************************/
{
DRAWSEGMENT* DrawTmp;
......@@ -368,45 +279,46 @@ void PlotCotation( COTATION* Cotation, int format_plot, int masque_layer )
DrawTmp = new DRAWSEGMENT( NULL );
DrawTmp->m_Width = Cotation->m_Width;
DrawTmp->m_Width = (trace_mode==FILAIRE)?-1:Cotation->m_Width;
DrawTmp->SetLayer( Cotation->GetLayer() );
PlotTextePcb( Cotation->m_Text, format_plot, masque_layer );
PlotTextePcb(plotter, Cotation->m_Text, masque_layer, trace_mode );
DrawTmp->m_Start.x = Cotation->Barre_ox; DrawTmp->m_Start.y = Cotation->Barre_oy;
DrawTmp->m_End.x = Cotation->Barre_fx; DrawTmp->m_End.y = Cotation->Barre_fy;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
DrawTmp->m_Start.x = Cotation->TraitG_ox; DrawTmp->m_Start.y = Cotation->TraitG_oy;
DrawTmp->m_End.x = Cotation->TraitG_fx; DrawTmp->m_End.y = Cotation->TraitG_fy;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
DrawTmp->m_Start.x = Cotation->TraitD_ox; DrawTmp->m_Start.y = Cotation->TraitD_oy;
DrawTmp->m_End.x = Cotation->TraitD_fx; DrawTmp->m_End.y = Cotation->TraitD_fy;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
DrawTmp->m_Start.x = Cotation->FlecheD1_ox; DrawTmp->m_Start.y = Cotation->FlecheD1_oy;
DrawTmp->m_End.x = Cotation->FlecheD1_fx; DrawTmp->m_End.y = Cotation->FlecheD1_fy;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
DrawTmp->m_Start.x = Cotation->FlecheD2_ox; DrawTmp->m_Start.y = Cotation->FlecheD2_oy;
DrawTmp->m_End.x = Cotation->FlecheD2_fx; DrawTmp->m_End.y = Cotation->FlecheD2_fy;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
DrawTmp->m_Start.x = Cotation->FlecheG1_ox; DrawTmp->m_Start.y = Cotation->FlecheG1_oy;
DrawTmp->m_End.x = Cotation->FlecheG1_fx; DrawTmp->m_End.y = Cotation->FlecheG1_fy;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
DrawTmp->m_Start.x = Cotation->FlecheG2_ox; DrawTmp->m_Start.y = Cotation->FlecheG2_oy;
DrawTmp->m_End.x = Cotation->FlecheG2_fx; DrawTmp->m_End.y = Cotation->FlecheG2_fy;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
delete DrawTmp;
}
/*****************************************************************/
void PlotMirePcb( MIREPCB* Mire, int format_plot, int masque_layer )
void PlotMirePcb(Plotter *plotter, MIREPCB* Mire, int masque_layer,
GRTraceMode trace_mode )
/*****************************************************************/
{
DRAWSEGMENT* DrawTmp;
......@@ -417,14 +329,14 @@ void PlotMirePcb( MIREPCB* Mire, int format_plot, int masque_layer )
DrawTmp = new DRAWSEGMENT( NULL );
DrawTmp->m_Width = Mire->m_Width;
DrawTmp->m_Width = (trace_mode==FILAIRE)?-1:Mire->m_Width;
DrawTmp->SetLayer( Mire->GetLayer() );
DrawTmp->m_Start.x = Mire->m_Pos.x; DrawTmp->m_Start.y = Mire->m_Pos.y;
DrawTmp->m_End.x = DrawTmp->m_Start.x + (Mire->m_Size / 4);
DrawTmp->m_End.y = DrawTmp->m_Start.y;
DrawTmp->m_Shape = S_CIRCLE;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
DrawTmp->m_Shape = S_SEGMENT;
/* Trace des 2 traits */
......@@ -440,29 +352,26 @@ void PlotMirePcb( MIREPCB* Mire, int format_plot, int masque_layer )
DrawTmp->m_Start.x = Mire->m_Pos.x - dx1; DrawTmp->m_Start.y = Mire->m_Pos.y - dy1;
DrawTmp->m_End.x = Mire->m_Pos.x + dx1; DrawTmp->m_End.y = Mire->m_Pos.y + dy1;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
DrawTmp->m_Start.x = Mire->m_Pos.x - dx2; DrawTmp->m_Start.y = Mire->m_Pos.y - dy2;
DrawTmp->m_End.x = Mire->m_Pos.x + dx2; DrawTmp->m_End.y = Mire->m_Pos.y + dy2;
PlotDrawSegment( DrawTmp, format_plot, masque_layer );
PlotDrawSegment(plotter, DrawTmp, masque_layer, trace_mode );
delete DrawTmp;
}
/**********************************************************************/
void Plot_Edges_Modules( BOARD* pcb, int format_plot, int masque_layer )
void Plot_Edges_Modules(Plotter *plotter, BOARD* pcb, int masque_layer,
GRTraceMode trace_mode )
/**********************************************************************/
/* Trace les contours des modules */
{
int nb_items; /* Pour affichage activite: nbr modules traites */
wxString msg;
nb_items = 0;
for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
{
EDGE_MODULE* edge = (EDGE_MODULE*) module->m_Drawings.GetFirst();
for( ; edge; edge = edge->Next() )
for(EDGE_MODULE* edge = (EDGE_MODULE*) module->m_Drawings.GetFirst();
edge;
edge = edge->Next() )
{
if( edge->Type() != TYPE_EDGE_MODULE )
continue;
......@@ -470,18 +379,15 @@ void Plot_Edges_Modules( BOARD* pcb, int format_plot, int masque_layer )
if( (g_TabOneLayerMask[edge->GetLayer()] & masque_layer) == 0 )
continue;
Plot_1_EdgeModule( format_plot, edge );
Plot_1_EdgeModule( plotter, edge, trace_mode );
}
/* Affichage du nombre de modules traites */
nb_items++;
msg.Printf( wxT( "%d" ), nb_items );
}
}
/**************************************************************/
void Plot_1_EdgeModule( int format_plot, EDGE_MODULE* PtEdge )
void Plot_1_EdgeModule( Plotter *plotter, EDGE_MODULE* PtEdge,
GRTraceMode trace_mode)
/**************************************************************/
/* Trace les contours des modules */
{
......@@ -497,50 +403,25 @@ void Plot_1_EdgeModule( int format_plot, EDGE_MODULE* PtEdge )
type_trace = PtEdge->m_Shape;
thickness = PtEdge->m_Width;
if( g_Plot_Mode == FILAIRE )
{
thickness = g_PlotLine_Width;
wxLogDebug( wxT( "changing edgemodule thickness to g_PlotLine_Width" ) );
}
pos = PtEdge->m_Start;
end = PtEdge->m_End;
switch( type_trace )
{
case S_SEGMENT:
/* segment simple */
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
SelectD_CODE_For_LineDraw( thickness );
PlotGERBERLine( pos, end, thickness );
plotter->thick_segment(pos, end, thickness, trace_mode);
break;
case PLOT_FORMAT_HPGL:
Plot_Filled_Segment_HPGL( pos, end, thickness, (GRFillMode) g_Plot_Mode );
break;
case PLOT_FORMAT_POST:
PlotFilledSegmentPS( pos, end, thickness );
break;
}
break; /* Fin trace segment simple */
case S_CIRCLE:
radius = (int) hypot( (double) ( end.x - pos.x ), (double) ( end.y - pos.y ) );
PlotCircle( format_plot, thickness, pos, radius );
plotter->thick_circle( pos, radius*2, thickness, trace_mode);
break;
case S_ARC:
radius = (int) hypot( (double) ( end.x - pos.x ), (double) ( end.y - pos.y ) );
StAngle = ArcTangente( end.y - pos.y, end.x - pos.x );
EndAngle = StAngle + PtEdge->m_Angle;
if( StAngle > EndAngle )
EXCHG( StAngle, EndAngle );
PlotArc( format_plot, pos, StAngle, EndAngle, radius, thickness );
plotter->thick_arc( pos, -EndAngle, -StAngle, radius, thickness, trace_mode );
break;
case S_POLYGON:
......@@ -575,7 +456,7 @@ void Plot_1_EdgeModule( int format_plot, EDGE_MODULE* PtEdge )
*ptr++ = y;
}
PlotFilledPolygon( format_plot, PtEdge->m_PolyPoints.size(), ptr_base );
plotter->poly(PtEdge->m_PolyPoints.size(), ptr_base, NO_FILL, thickness );
free( ptr_base );
}
break;
......@@ -584,7 +465,8 @@ void Plot_1_EdgeModule( int format_plot, EDGE_MODULE* PtEdge )
/****************************************************************************/
void PlotTextePcb( TEXTE_PCB* pt_texte, int format_plot, int masque_layer )
void PlotTextePcb(Plotter *plotter, TEXTE_PCB* pt_texte, int masque_layer,
GRTraceMode trace_mode)
/****************************************************************************/
/* Trace 1 Texte type PCB , c.a.d autre que les textes sur modules */
{
......@@ -601,25 +483,11 @@ void PlotTextePcb( TEXTE_PCB* pt_texte, int format_plot, int masque_layer )
size = pt_texte->m_Size;
pos = pt_texte->m_Pos;
orient = pt_texte->m_Orient;
thickness = pt_texte->m_Width;
thickness = (trace_mode==FILAIRE)?-1:pt_texte->m_Width;
if( pt_texte->m_Mirror )
size.x = -size.x;
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
SelectD_CODE_For_LineDraw( thickness );
break;
case PLOT_FORMAT_HPGL:
break;
case PLOT_FORMAT_POST:
SetCurrentLineWidthPS( thickness );
break;
}
if( pt_texte->m_MultilineAllowed )
{
wxArrayString* list = wxStringSplit( pt_texte->m_Text, '\n' );
......@@ -631,7 +499,7 @@ void PlotTextePcb( TEXTE_PCB* pt_texte, int format_plot, int masque_layer )
for( unsigned i = 0; i<list->Count(); i++ )
{
wxString txt = list->Item( i );
PlotGraphicText( format_plot, pos, g_Plot_PS_Negative ? WHITE : BLACK,
plotter->text( pos, BLACK,
txt,
orient, size,
pt_texte->m_HJustify, pt_texte->m_VJustify,
......@@ -643,7 +511,7 @@ void PlotTextePcb( TEXTE_PCB* pt_texte, int format_plot, int masque_layer )
}
else
PlotGraphicText( format_plot, pos, g_Plot_PS_Negative ? WHITE : BLACK,
plotter->text( pos, BLACK,
pt_texte->m_Text,
orient, size,
pt_texte->m_HJustify, pt_texte->m_VJustify,
......@@ -652,7 +520,8 @@ void PlotTextePcb( TEXTE_PCB* pt_texte, int format_plot, int masque_layer )
/*********************************************************/
void PlotFilledAreas( ZONE_CONTAINER* aZone, int aFormat )
void PlotFilledAreas(Plotter *plotter, ZONE_CONTAINER* aZone,
GRTraceMode trace_mode)
/*********************************************************/
/* Plot areas (given by .m_FilledPolysList member) in a zone
......@@ -670,13 +539,13 @@ void PlotFilledAreas( ZONE_CONTAINER* aZone, int aFormat )
imax++; // provide room to sore an extra coordinte to close the ploygon
if( CornersBuffer == NULL )
{
CornersBufferSize = imax * 4;
CornersBufferSize = imax * 2;
CornersBuffer = (int*) MyMalloc( CornersBufferSize * sizeof(int) );
}
if( (imax * 4) > CornersBufferSize )
{
CornersBufferSize = imax * 4;
CornersBufferSize = imax * 2;
CornersBuffer = (int*) realloc( CornersBuffer, CornersBufferSize * sizeof(int) );
}
......@@ -693,8 +562,8 @@ void PlotFilledAreas( ZONE_CONTAINER* aZone, int aFormat )
if( corner->end_contour ) // Plot the current filled area outline
{
// First, close the outline
if( CornersBuffer[0] != CornersBuffer[ii - 2] || CornersBuffer[1] !=
CornersBuffer[ii - 1] )
if( CornersBuffer[0] != CornersBuffer[ii - 2]
|| CornersBuffer[1] != CornersBuffer[ii - 1] )
{
CornersBuffer[ii++] = CornersBuffer[0];
CornersBuffer[ii] = CornersBuffer[1];
......@@ -702,19 +571,38 @@ void PlotFilledAreas( ZONE_CONTAINER* aZone, int aFormat )
}
// Plot the current filled area outline
if (trace_mode == FILLED)
{
if( aZone->m_FillMode == 0 ) // We are using solid polygons (if != 0: using segments in m_Zone)
PlotFilledPolygon( aFormat, corners_count, CornersBuffer );
plotter->poly( corners_count, CornersBuffer, FILLED_SHAPE );
if( aZone->m_ZoneMinThickness > 0 )
PlotPolygon( aFormat, corners_count, CornersBuffer, aZone->m_ZoneMinThickness );
plotter->poly( corners_count, CornersBuffer, NO_FILL,
aZone->m_ZoneMinThickness );
}
else
{
if( aZone->m_ZoneMinThickness > 0 )
{
for (int ii=1; ii<corners_count; ii++)
plotter->thick_segment(
wxPoint(CornersBuffer[ii*2-2],
CornersBuffer[ii*2-1]),
wxPoint(CornersBuffer[ii*2],
CornersBuffer[ii*2+1]),
(trace_mode == FILAIRE)?-1:aZone->m_ZoneMinThickness,
trace_mode);
}
plotter->set_current_line_width(-1);
}
corners_count = 0;
ii = 0;
}
}
}
/******************************************************************************/
void PlotDrawSegment( DRAWSEGMENT* pt_segm, int Format, int masque_layer )
void PlotDrawSegment(Plotter *plotter, DRAWSEGMENT* pt_segm, int masque_layer,
GRTraceMode trace_mode)
/******************************************************************************/
/* Trace un element du type DRAWSEGMENT draw appartenant
......@@ -728,282 +616,356 @@ void PlotDrawSegment( DRAWSEGMENT* pt_segm, int Format, int masque_layer )
if( (g_TabOneLayerMask[pt_segm->GetLayer()] & masque_layer) == 0 )
return;
if( trace_mode == FILAIRE )
thickness = g_pcb_plot_options.PlotLine_Width;
else
thickness = pt_segm->m_Width;
if( g_Plot_Mode == FILAIRE )
thickness = g_PlotLine_Width;
start = pt_segm->m_Start;
end = pt_segm->m_End;
if( pt_segm->m_Shape == S_CIRCLE )
plotter->set_current_line_width(thickness);
switch (pt_segm->m_Shape)
{
case S_CIRCLE:
radius = (int) hypot( (double) ( end.x - start.x ), (double) ( end.y - start.y ) );
}
plotter->thick_circle(start,radius*2,thickness,trace_mode);
break;
if( pt_segm->m_Shape == S_ARC )
{
case S_ARC:
radius = (int) hypot( (double) ( end.x - start.x ), (double) ( end.y - start.y ) );
StAngle = ArcTangente( end.y - start.y, end.x - start.x );
EndAngle = StAngle + pt_segm->m_Angle;
if( StAngle > EndAngle )
EXCHG( StAngle, EndAngle );
}
switch( Format )
{
case PLOT_FORMAT_GERBER:
SelectD_CODE_For_LineDraw( thickness );
switch(pt_segm->m_Shape)
{
case S_CIRCLE:
PlotCircle( PLOT_FORMAT_GERBER, thickness, start, radius );
plotter->thick_arc(start, -EndAngle, -StAngle, radius, thickness, trace_mode);
break;
case S_ARC:
PlotArc( PLOT_FORMAT_GERBER, start,
StAngle, EndAngle, radius, thickness );
break;
case S_CURVE:
for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
PlotGERBERLine( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness);
}
for (unsigned i=1; i < pt_segm->m_BezierPoints.size(); i++)
plotter->thick_segment( pt_segm->m_BezierPoints[i-1],
pt_segm->m_BezierPoints[i], thickness, trace_mode);
break;
default:
PlotGERBERLine( start, end, thickness );
plotter->thick_segment(start, end, thickness, trace_mode);
}
break;
}
case PLOT_FORMAT_HPGL:
/*********************************************************************/
void WinEDA_BasePcbFrame::Plot_Layer(Plotter *plotter, int Layer,
GRTraceMode trace_mode )
/*********************************************************************/
{
// Specify that the contents of the "Edges Pcb" layer are to be plotted
// in addition to the contents of the currently specified layer.
int layer_mask = g_TabOneLayerMask[Layer];
if( !g_pcb_plot_options.Exclude_Edges_Pcb )
layer_mask |= EDGE_LAYER;
switch(pt_segm->m_Shape)
switch( Layer )
{
case S_CIRCLE:
PlotCircle( PLOT_FORMAT_HPGL, thickness, start, radius );
case FIRST_COPPER_LAYER:
case LAYER_N_2:
case LAYER_N_3:
case LAYER_N_4:
case LAYER_N_5:
case LAYER_N_6:
case LAYER_N_7:
case LAYER_N_8:
case LAYER_N_9:
case LAYER_N_10:
case LAYER_N_11:
case LAYER_N_12:
case LAYER_N_13:
case LAYER_N_14:
case LAYER_N_15:
case LAST_COPPER_LAYER:
Plot_Standard_Layer( plotter, layer_mask, 0, true, trace_mode );
break;
case S_ARC:
PlotArc( PLOT_FORMAT_HPGL, start, StAngle, EndAngle, radius, thickness );
case SOLDERMASK_N_CU:
case SOLDERMASK_N_CMP:
Plot_Standard_Layer( plotter, layer_mask,
g_DesignSettings.m_MaskMargin,
g_pcb_plot_options.DrawViaOnMaskLayer, trace_mode);
break;
case S_CURVE:
for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
Plot_Filled_Segment_HPGL( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness,(GRFillMode) g_Plot_Mode);
}
break;
default:
Plot_Filled_Segment_HPGL( start, end, thickness, (GRFillMode) g_Plot_Mode );
}
break;
case PLOT_FORMAT_POST:
switch(pt_segm->m_Shape)
{
case S_CIRCLE:
PlotCircle( PLOT_FORMAT_POST, thickness, start, radius );
break;
case S_ARC:
PlotArc( PLOT_FORMAT_POST, start,
StAngle, EndAngle, radius, thickness );
break;
case S_CURVE:
for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
PlotFilledSegmentPS( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness);
}
case SOLDERPASTE_N_CU:
case SOLDERPASTE_N_CMP:
Plot_Standard_Layer( plotter, layer_mask, 0, false, trace_mode);
break;
default:
PlotFilledSegmentPS( start, end, thickness );
}
Plot_Serigraphie( plotter, layer_mask, trace_mode );
break;
}
PlotDrillMark(plotter, trace_mode );
}
/*********************************************************************/
void WinEDA_BasePcbFrame::Plot_Standard_Layer( Plotter* plotter,
int masque_layer, int garde, bool trace_via, GRTraceMode trace_mode )
/*********************************************************************/
/*****************************************************************************/
void PlotCircle( int format_plot, int thickness, wxPoint centre, int radius )
/*****************************************************************************/
/* routine de trace de 1 cercle de centre cx, cy */
/* Trace en format HPGL. d'une couche cuivre ou masque
* 1 unite HPGL = 0.98 mils ( 1 mil = 1.02041 unite HPGL ) .
*/
{
switch( format_plot )
wxPoint pos;
wxSize size;
wxString msg;
// trace des elements type Drawings Pcb :
for (BOARD_ITEM* item = m_Pcb->m_Drawings;
item;
item = item->Next() )
{
case PLOT_FORMAT_GERBER:
SelectD_CODE_For_LineDraw( thickness );
PlotCircle_GERBER( centre, radius, thickness );
switch( item->Type() )
{
case TYPE_DRAWSEGMENT:
PlotDrawSegment(plotter, (DRAWSEGMENT*) item, masque_layer, trace_mode );
break;
case PLOT_FORMAT_HPGL:
trace_1_pastille_RONDE_HPGL( centre, radius * 2, FILAIRE );
case TYPE_TEXTE:
PlotTextePcb(plotter, (TEXTE_PCB*) item, masque_layer, trace_mode );
break;
case PLOT_FORMAT_POST:
PlotCirclePS( centre, radius * 2, false, thickness );
case TYPE_COTATION:
PlotCotation(plotter, (COTATION*) item, masque_layer, trace_mode );
break;
}
}
case TYPE_MIRE:
PlotMirePcb(plotter, (MIREPCB*) item, masque_layer, trace_mode );
break;
/**********************************************************************/
void PlotFilledPolygon( int format_plot, int nbpoints, int* coord )
/**********************************************************************/
/* plot a polygon */
{
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
PlotFilledPolygon_GERBER( nbpoints, coord );
case TYPE_MARKER:
break;
case PLOT_FORMAT_HPGL:
PlotPolyHPGL( nbpoints, coord, true );
default:
DisplayError( this,
wxT( "Plot_Layer : Unexpected Draw Type" ) );
break;
}
}
/* Draw footprint shapes without pads (pads will plotted later) */
for( MODULE* module = m_Pcb->m_Modules;
module;
module = module->Next() )
{
for( BOARD_ITEM* item = module->m_Drawings;
item;
item = item->Next() )
{
switch( item->Type() )
{
case TYPE_EDGE_MODULE:
if( masque_layer & g_TabOneLayerMask[ item->GetLayer() ] )
Plot_1_EdgeModule( plotter, (EDGE_MODULE*) item, trace_mode );
break;
case PLOT_FORMAT_POST:
PlotPolyPS( nbpoints, coord, true );
default:
break;
}
}
}
}
/* Plot footprint pads */
for( MODULE* module = m_Pcb->m_Modules;
module;
module = module->Next() )
{
for( D_PAD* pad = module->m_Pads; pad; pad = pad->Next() )
{
wxPoint shape_pos;
if( (pad->m_Masque_Layer & masque_layer) == 0 )
continue;
/**********************************************************************/
void PlotPolygon( int format_plot, int nbpoints, int* coord, int width )
/**********************************************************************/
shape_pos = pad->ReturnShapePos();
pos = shape_pos;
/* plot a non filled polygon
*/
{
switch( format_plot )
size.x = pad->m_Size.x + 2 * garde;
size.y = pad->m_Size.y + 2 * garde;
/* Don't draw a null size item : */
if( size.x <= 0 || size.y <= 0 )
continue;
switch( pad->m_PadShape )
{
case PLOT_FORMAT_GERBER:
SelectD_CODE_For_LineDraw( width );
PlotPolygon_GERBER( nbpoints, coord, width );
case PAD_CIRCLE:
plotter->flash_pad_circle(pos, size.x, trace_mode);
break;
case PLOT_FORMAT_HPGL:
{
// Compute pen_dim (from g_HPGL_Pen_Diam in mils) in pcb units,
// with plot scale (if Scale is 2, pen diametre is always g_HPGL_Pen_Diam
// so apparent pen diam is real pen diam / Scale
int pen_diam = wxRound( (g_HPGL_Pen_Diam * U_PCB) / Scale_X ); // Assume Scale_X # Scale_Y
wxString msg;
if( pen_diam >= width )
PlotPolyHPGL( nbpoints, coord, false, width ); // PlotPolyHPGL does not handle width
else
{
wxPoint start, end;
start.x = *coord++;
start.y = *coord++;
for( int ii = 1; ii < nbpoints; ii++ )
case PAD_OVAL:
plotter->flash_pad_oval(pos, size, pad->m_Orient,
trace_mode);
break;
case PAD_TRAPEZOID:
{
end.x = *coord++;
end.y = *coord++;
Plot_Filled_Segment_HPGL( start, end, width, (GRFillMode) g_Plot_Mode );
start = end;
}
}
wxSize delta = pad->m_DeltaSize;
plotter->flash_pad_trapez(pos, size,
delta, pad->m_Orient, trace_mode);
}
break;
case PLOT_FORMAT_POST:
PlotPolyPS( nbpoints, coord, false, width );
case PAD_RECT:
default:
plotter->flash_pad_rect(pos, size, pad->m_Orient,
trace_mode);
break;
}
}
}
}
/* Plot vias : */
if( trace_via )
{
for( TRACK* track = m_Pcb->m_Track;
track;
track = track->Next() )
{
if( track->Type() != TYPE_VIA )
continue;
/************************************************************************/
void PlotArc( int format_plot, wxPoint centre, int start_angle, int end_angle,
int radius, int thickness )
/************************************************************************/
SEGVIA* Via = (SEGVIA*) track;
// vias not plotted if not on selected layer, but if layer
// == SOLDERMASK_LAYER_CU or SOLDERMASK_LAYER_CMP, vias are drawn,
// if they are on a external copper layer
int via_mask_layer = Via->ReturnMaskLayer();
if( via_mask_layer & CUIVRE_LAYER )
via_mask_layer |= SOLDERMASK_LAYER_CU;
if( via_mask_layer & CMP_LAYER )
via_mask_layer |= SOLDERMASK_LAYER_CMP;
if( ( via_mask_layer & masque_layer) == 0 )
continue;
/* Polt 1 arc
* start, end = angles in 1/10 degree for start and stop point
*/
{
int ii;
int ox, oy, fx, fy;
int delta; /* increment (en 0.1 degres) angulaire pour trace de cercles */
pos = Via->m_Start;
size.x = size.y = Via->m_Width + 2 * garde;
if( g_Plot_Mode == FILAIRE )
thickness = g_PlotLine_Width;
/* Don't draw a null size item : */
if( size.x <= 0 )
continue;
if( IsPostScript( format_plot ) )
{
PlotArcPS( centre, start_angle, end_angle, radius, false, thickness );
return;
plotter->flash_pad_circle(pos, size.x, trace_mode );
}
}
// change due to Y axis is negative orientation on screen
start_angle = -start_angle;
end_angle = -end_angle;
EXCHG( start_angle, end_angle );
/* Correction pour petits cercles par rapport a l'thickness du trait */
if( radius < (thickness * 10) )
delta = 225; /* 16 segm pour 360 deg */
if( radius < (thickness * 5) )
delta = 300; /* 12 segm pour 360 deg */
/* Plot tracks (not vias) : */
for( TRACK* track = m_Pcb->m_Track;
track;
track = track->Next() )
{
wxPoint end;
if( start_angle > end_angle )
end_angle += 3600;
if( track->Type() == TYPE_VIA )
continue;
ox = radius;
oy = 0;
if( (g_TabOneLayerMask[track->GetLayer()] & masque_layer) == 0 )
continue;
RotatePoint( &ox, &oy, start_angle );
size.x = size.y = track->m_Width;
pos = track->m_Start;
end = track->m_End;
if( format_plot == PLOT_FORMAT_GERBER )
SelectD_CODE_For_LineDraw( thickness );
plotter->thick_segment( pos, end, size.x, trace_mode );
}
delta = 120; /* un cercle sera trace en 3600/delta = 30 segments / cercle*/
for( ii = start_angle + delta; ii < end_angle; ii += delta )
/* Plot zones: */
for( TRACK* track = m_Pcb->m_Zone;
track;
track = track->Next() )
{
fx = radius;
fy = 0;
wxPoint end;
RotatePoint( &fx, &fy, ii );
if( (g_TabOneLayerMask[track->GetLayer()] & masque_layer) == 0 )
continue;
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
PlotGERBERLine( wxPoint( centre.x + ox, centre.y + oy ),
wxPoint( centre.x + fx, centre.y + fy ), thickness );
break;
size.x = size.y = track->m_Width;
pos = track->m_Start;
end = track->m_End;
case PLOT_FORMAT_HPGL:
Plot_Filled_Segment_HPGL( wxPoint( centre.x + ox, centre.y + oy ),
wxPoint( centre.x + fx, centre.y + fy ),
thickness, (GRFillMode) g_Plot_Mode );
break;
plotter->thick_segment( pos, end, size.x, trace_mode );
}
case PLOT_FORMAT_POST:
break;
/* Plot filled ares */
for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = m_Pcb->GetArea( ii );
if( ( ( 1 << edge_zone->GetLayer() ) & masque_layer ) == 0 )
continue;
PlotFilledAreas(plotter, edge_zone, trace_mode );
}
}
ox = fx;
oy = fy;
/*************************************/
void WinEDA_BasePcbFrame::PlotDrillMark(Plotter *plotter, GRTraceMode trace_mode )
/*************************************/
/* Draw a drill mark for pads and vias.
* Must be called after all drawings, because it
* redraw the drill mark on a pad or via, as a negative (i.e. white) shape
*/
{
const int SMALL_DRILL = 150;
wxPoint pos;
wxSize diam;
MODULE* Module;
D_PAD* PtPad;
TRACK* pts;
if( g_pcb_plot_options.DrillShapeOpt == PCB_Plot_Options::NO_DRILL_SHAPE )
return;
if (trace_mode == FILLED) {
plotter->set_color(WHITE);
}
fx = radius;
fy = 0;
for( pts = m_Pcb->m_Track; pts != NULL; pts = pts->Next() )
{
if( pts->Type() != TYPE_VIA )
continue;
pos = pts->m_Start;
if( g_pcb_plot_options.DrillShapeOpt == PCB_Plot_Options::SMALL_DRILL_SHAPE )
diam.x = diam.y = SMALL_DRILL;
else
diam.x = diam.y = pts->GetDrillValue();
RotatePoint( &fx, &fy, end_angle );
plotter->flash_pad_circle( pos, diam.x, trace_mode );
}
switch( format_plot )
for( Module = m_Pcb->m_Modules;
Module != NULL;
Module = Module->Next() )
{
case PLOT_FORMAT_GERBER:
PlotGERBERLine( wxPoint( centre.x + ox, centre.y + oy ),
wxPoint( centre.x + fx, centre.y + fy ), thickness );
break;
case PLOT_FORMAT_HPGL:
Plot_Filled_Segment_HPGL( wxPoint( centre.x + ox, centre.y + oy ),
wxPoint( centre.x + fx, centre.y + fy ),
thickness, (GRFillMode) g_Plot_Mode );
break;
for(PtPad = Module->m_Pads;
PtPad != NULL;
PtPad = PtPad->Next() )
{
if( PtPad->m_Drill.x == 0 )
continue;
case PLOT_FORMAT_POST:
break;
// Output hole shapes:
pos = PtPad->m_Pos;
if( PtPad->m_DrillShape == PAD_OVAL )
{
diam = PtPad->m_Drill;
plotter->flash_pad_oval(pos, diam, PtPad->m_Orient, trace_mode);
}
else
{
diam.x = (g_pcb_plot_options.DrillShapeOpt == PCB_Plot_Options::SMALL_DRILL_SHAPE)
? SMALL_DRILL : PtPad->m_Drill.x;
plotter->flash_pad_circle(pos, diam.x, trace_mode);
}
}
}
if (trace_mode == FILLED) {
plotter->set_color(BLACK);
}
}
......@@ -17,55 +17,13 @@
#include "pcbnew.h"
#include "pcbplot.h"
#include "trigo.h"
#include "appl_wxstruct.h"
/* Class to handle a D_CODE when plotting a board : */
#define FIRST_DCODE_VALUE 10 // D_CODE < 10 is a command, D_CODE >= 10 is a tool
class D_CODE
{
public:
D_CODE* m_Pnext, * m_Pback; /* for a linked list */
wxSize m_Size; /* horiz and Vert size*/
int m_Type; /* Type ( Line, rect , circulaire , ovale .. ); -1 = not used (free) descr */
int m_NumDcode; /* code number ( >= 10 ); 0 = not in use */
D_CODE()
{
m_Pnext = m_Pback = NULL;
m_Type = -1;
m_NumDcode = 0;
}
};
/* Variables locales : */
static int s_Last_D_code;
static float Gerb_scale_plot; // Coeff de conversion d'unites des traces
static D_CODE* s_DCodeList; // Pointeur sur la zone de stockage des D_CODES
wxString GerberFullFileName;
static double scale_x, scale_y; // echelles de convertion en X et Y (compte tenu
// des unites relatives du PCB et des traceurs
static bool ShowDcodeError = TRUE;
static void CloseFileGERBER( void );
static int Gen_D_CODE_File( FILE* penfile );
/* Routines Locales */
static void Init_ApertureList();
static void CloseFileGERBER();
static void Plot_1_CIRCLE_pad_GERBER( wxPoint pos, int diametre );
static void trace_1_pastille_OVALE_GERBER( wxPoint pos, wxSize size, int orient );
static void PlotRectangularPad_GERBER( wxPoint pos, wxSize size, int orient );
static D_CODE* get_D_code( int dx, int dy, int type, int drill );
static void trace_1_pad_TRAPEZE_GERBER( wxPoint pos, wxSize size, wxSize delta,
int orient, int modetrace );
#include "protos.h"
/********************************************************************************/
void WinEDA_BasePcbFrame::Genere_GERBER( const wxString& FullFileName, int Layer,
bool PlotOriginIsAuxAxis )
bool PlotOriginIsAuxAxis,
GRTraceMode trace_mode )
/********************************************************************************/
/* Creates the output files, one per board layer:
......@@ -75,29 +33,24 @@ void WinEDA_BasePcbFrame::Genere_GERBER( const wxString& FullFileName, int Layer
* format 3.4 uses the native pcbnew units (1/10000 inch).
*/
{
int tracevia = 1;
wxPoint offset;
EraseMsgBox();
GerberFullFileName = FullFileName;
g_PlotOrient = 0;
if( Plot_Set_MIROIR )
g_PlotOrient |= PLOT_MIROIR;
/* Calculate scaling from pcbnew units (in 0.1 mil or 0.0001 inch) to gerber units */
Gerb_scale_plot = 1.0; /* for format 3.4 (4 digits for decimal format means 0.1 mil per gerber unit */
scale_x = Scale_X * Gerb_scale_plot;
scale_y = Scale_Y * Gerb_scale_plot;
g_PlotOffset.x = 0;
g_PlotOffset.y = 0;
double scale = g_pcb_plot_options.Scale;
if( PlotOriginIsAuxAxis )
g_PlotOffset = m_Auxiliary_Axis_Position;
offset = m_Auxiliary_Axis_Position;
else
{
offset.x = 0;
offset.y = 0;
}
g_Plot_PlotOutputFile = wxFopen( FullFileName, wxT( "wt" ) );
if( g_Plot_PlotOutputFile == NULL )
FILE *output_file = wxFopen( FullFileName, wxT( "wt" ) );
if( output_file == NULL )
{
wxString msg = _( "unable to create file " ) + FullFileName;
DisplayError( this, msg );
......@@ -105,727 +58,23 @@ void WinEDA_BasePcbFrame::Genere_GERBER( const wxString& FullFileName, int Layer
}
SetLocaleTo_C_standard();
InitPlotParametresGERBER( g_PlotOffset, scale_x, scale_y );
/* Clear the memory used for handle the D_CODE (aperture) list */
Init_ApertureList();
Plotter *plotter = new Gerber_Plotter();
/* No mirror and scaling for gerbers! */
plotter->set_viewport(offset, scale, 0);
plotter->set_default_line_width( g_pcb_plot_options.PlotLine_Width );
plotter->set_creator(wxT("PCBNEW-RS274X"));
plotter->set_filename(FullFileName);
Affiche_1_Parametre( this, 0, _( "File" ), FullFileName, CYAN );
s_Last_D_code = 0;
Write_Header_GERBER( wxGetApp().GetAppName(), g_Plot_PlotOutputFile );
int layer_mask = g_TabOneLayerMask[Layer];
// Specify that the contents of the "Edges Pcb" layer are also to be
// plotted, unless the option of excluding that layer has been selected.
if( !g_Exclude_Edges_Pcb )
layer_mask |= EDGE_LAYER;
switch( Layer )
{
case FIRST_COPPER_LAYER:
case LAYER_N_2:
case LAYER_N_3:
case LAYER_N_4:
case LAYER_N_5:
case LAYER_N_6:
case LAYER_N_7:
case LAYER_N_8:
case LAYER_N_9:
case LAYER_N_10:
case LAYER_N_11:
case LAYER_N_12:
case LAYER_N_13:
case LAYER_N_14:
case LAYER_N_15:
case LAST_COPPER_LAYER:
Plot_Layer_GERBER( g_Plot_PlotOutputFile, layer_mask, 0, 1 );
break;
case SOLDERMASK_N_CU:
case SOLDERMASK_N_CMP: /* Trace du vernis epargne */
if( g_DrawViaOnMaskLayer )
tracevia = 1;
else
tracevia = 0;
Plot_Layer_GERBER( g_Plot_PlotOutputFile, layer_mask, g_DesignSettings.m_MaskMargin, tracevia );
break;
plotter->start_plot(output_file);
// Sheet refs on gerber CAN be useful... and they're always 1:1
if( g_pcb_plot_options.Plot_Frame_Ref )
PlotWorkSheet( plotter, GetScreen() );
Plot_Layer(plotter, Layer, trace_mode);
case SOLDERPASTE_N_CU:
case SOLDERPASTE_N_CMP: /* Trace du masque de pate de soudure */
Plot_Layer_GERBER( g_Plot_PlotOutputFile, layer_mask, 0, 0 );
break;
default:
Plot_Serigraphie( PLOT_FORMAT_GERBER, g_Plot_PlotOutputFile, layer_mask );
break;
}
CloseFileGERBER();
plotter->end_plot();
delete plotter;
SetLocaleTo_Default();
}
/***********************************************************************/
void WinEDA_BasePcbFrame::Plot_Layer_GERBER( FILE* File, int masque_layer,
int garde, int tracevia )
/***********************************************************************/
/* Creates one GERBER file for a copper layer or a technical layer
* the silkscreen layers are plotted by Plot_Serigraphie() because they have special features
*/
{
wxPoint pos;
wxSize size;
wxString msg;
/* Draw items type Drawings Pcb matching with masque_layer: */
for( BOARD_ITEM* item = m_Pcb->m_Drawings; item; item = item->Next() )
{
switch( item->Type() )
{
case TYPE_DRAWSEGMENT:
PlotDrawSegment( (DRAWSEGMENT*) item, PLOT_FORMAT_GERBER,
masque_layer );
break;
case TYPE_TEXTE:
PlotTextePcb( (TEXTE_PCB*) item, PLOT_FORMAT_GERBER,
masque_layer );
break;
case TYPE_COTATION:
PlotCotation( (COTATION*) item, PLOT_FORMAT_GERBER,
masque_layer );
break;
case TYPE_MIRE:
PlotMirePcb( (MIREPCB*) item, PLOT_FORMAT_GERBER,
masque_layer );
break;
case TYPE_MARKER:
break;
default:
DisplayError( this, wxT( "Type Draw non gere" ) );
break;
}
}
/* Draw footprint shapes without pads (pads will plotted later) */
for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() )
{
for( BOARD_ITEM* item = module->m_Drawings; item; item = item->Next() )
{
switch( item->Type() )
{
case TYPE_EDGE_MODULE:
if( masque_layer & g_TabOneLayerMask[( (EDGE_MODULE*) item)->GetLayer()] )
Plot_1_EdgeModule( PLOT_FORMAT_GERBER, (EDGE_MODULE*) item );
break;
default:
break;
}
}
}
/* Plot footprint pads */
for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() )
{
for( D_PAD* pad = module->m_Pads; pad; pad = pad->Next() )
{
wxPoint shape_pos;
if( (pad->m_Masque_Layer & masque_layer) == 0 )
continue;
shape_pos = pad->ReturnShapePos();
pos = shape_pos;
size.x = pad->m_Size.x + 2 * garde;
size.y = pad->m_Size.y + 2 * garde;
/* Don't draw a null size item : */
if( size.x <= 0 || size.y <= 0 )
continue;
switch( pad->m_PadShape )
{
case PAD_CIRCLE:
Plot_1_CIRCLE_pad_GERBER( pos, size.x );
break;
case PAD_OVAL:
// Check whether the pad really has a circular shape instead
if( size.x == size.y )
Plot_1_CIRCLE_pad_GERBER( pos, size.x );
else
trace_1_pastille_OVALE_GERBER( pos, size, pad->m_Orient );
break;
case PAD_TRAPEZOID:
{
wxSize delta = pad->m_DeltaSize;
trace_1_pad_TRAPEZE_GERBER( pos, size,
delta, pad->m_Orient, FILLED );
}
break;
case PAD_RECT:
default:
PlotRectangularPad_GERBER( pos, size, pad->m_Orient );
break;
}
}
}
/* Plot vias : */
if( tracevia )
{
for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
{
if( track->Type() != TYPE_VIA )
continue;
SEGVIA* Via = (SEGVIA*) track;
// vias not plotted if not on selected layer, but if layer
// == SOLDERMASK_LAYER_CU or SOLDERMASK_LAYER_CMP, vias are drawn,
// if they are on a external copper layer
int via_mask_layer = Via->ReturnMaskLayer();
if( via_mask_layer & CUIVRE_LAYER )
via_mask_layer |= SOLDERMASK_LAYER_CU;
if( via_mask_layer & CMP_LAYER )
via_mask_layer |= SOLDERMASK_LAYER_CMP;
if( ( via_mask_layer & masque_layer) == 0 )
continue;
pos = Via->m_Start;
size.x = size.y = Via->m_Width + 2 * garde;
/* Don't draw a null size item : */
if( size.x <= 0 )
continue;
Plot_1_CIRCLE_pad_GERBER( pos, size.x );
}
}
/* Plot tracks (not vias) : */
for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
{
wxPoint end;
if( track->Type() == TYPE_VIA )
continue;
if( (g_TabOneLayerMask[track->GetLayer()] & masque_layer) == 0 )
continue;
size.x = size.y = track->m_Width;
pos = track->m_Start;
end = track->m_End;
SelectD_CODE_For_LineDraw( size.x );
PlotGERBERLine( pos, end, size.x );
}
/* Plot zones: */
for( TRACK* track = m_Pcb->m_Zone; track; track = track->Next() )
{
wxPoint end;
if( (g_TabOneLayerMask[track->GetLayer()] & masque_layer) == 0 )
continue;
size.x = size.y = track->m_Width;
pos = track->m_Start;
end = track->m_End;
SelectD_CODE_For_LineDraw( size.x );
PlotGERBERLine( pos, end, size.x );
}
/* Plot filled ares */
for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = m_Pcb->GetArea( ii );
if( ( ( 1 << edge_zone->GetLayer() ) & masque_layer ) == 0 )
continue;
PlotFilledAreas( edge_zone, PLOT_FORMAT_GERBER );
}
}
/**********************************************************************/
void trace_1_pastille_OVALE_GERBER( wxPoint pos, wxSize size, int orient )
/**********************************************************************/
/* Trace 1 pastille PAD_OVAL en position pos_X,Y:
* dimensions dx, dy,
* orientation orient
* Pour une orientation verticale ou horizontale, la forme est flashee
* Pour une orientation quelconque la forme est tracee comme un segment
*/
{
D_CODE* dcode_ptr;
char cbuf[256];
int x0, y0, x1, y1, delta;
if( orient == 900 || orient == 2700 ) /* orient tournee de 90 deg */
EXCHG( size.x, size.y );
/* Trace de la forme flashee */
if( orient == 0 || orient == 900 || orient == 1800 || orient == 2700 )
{
UserToDeviceCoordinate( pos );
UserToDeviceSize( size );
dcode_ptr = get_D_code( size.x, size.y, GERB_OVALE, 0 );
if( dcode_ptr->m_NumDcode != s_Last_D_code )
{
sprintf( cbuf, "G54D%d*\n", dcode_ptr->m_NumDcode );
fputs( cbuf, g_Plot_PlotOutputFile );
s_Last_D_code = dcode_ptr->m_NumDcode;
}
sprintf( cbuf, "X%5.5dY%5.5dD03*\n", pos.x, pos.y );
fputs( cbuf, g_Plot_PlotOutputFile );
}
else /* Forme tracee comme un segment */
{
if( size.x > size.y )
{
EXCHG( size.x, size.y );
if( orient < 2700 )
orient += 900;
else
orient -= 2700;
}
/* la pastille est ramenee a une pastille ovale avec dy > dx */
delta = size.y - size.x;
x0 = 0;
y0 = -delta / 2;
x1 = 0;
y1 = delta / 2;
RotatePoint( &x0, &y0, orient );
RotatePoint( &x1, &y1, orient );
SelectD_CODE_For_LineDraw( size.x );
PlotGERBERLine( wxPoint( pos.x + x0, pos.y + y0 ),
wxPoint( pos.x + x1, pos.y + y1 ), size.x );
}
}
/******************************************************************/
void Plot_1_CIRCLE_pad_GERBER( wxPoint pos, int diametre )
/******************************************************************/
/* Plot a circular pad or via at the user position pos
*/
{
D_CODE* dcode_ptr;
char cbuf[256];
wxSize size( diametre, diametre );
UserToDeviceCoordinate( pos );
UserToDeviceSize( size );
dcode_ptr = get_D_code( size.x, size.x, GERB_CIRCLE, 0 );
if( dcode_ptr->m_NumDcode != s_Last_D_code )
{
sprintf( cbuf, "G54D%d*\n", dcode_ptr->m_NumDcode );
fputs( cbuf, g_Plot_PlotOutputFile );
s_Last_D_code = dcode_ptr->m_NumDcode;
}
sprintf( cbuf, "X%5.5dY%5.5dD03*\n", pos.x, pos.y );
fputs( cbuf, g_Plot_PlotOutputFile );
}
/**************************************************************************/
void PlotRectangularPad_GERBER( wxPoint pos, wxSize size, int orient )
/**************************************************************************/
/* Plot 1 rectangular pad
* donne par son centre, ses dimensions, et son orientation
* For a vertical or horizontal shape, the shape is an aperture (Dcode) and it is flashed
* For others orientations the shape is plotted as a polygon
*/
{
D_CODE* dcode_ptr;
char cbuf[256];
/* Trace de la forme flashee */
switch( orient )
{
case 900:
case 2700: /* la rotation de 90 ou 270 degres revient a permutter des dimensions */
EXCHG( size.x, size.y );
// Pass through
case 0:
case 1800:
UserToDeviceCoordinate( pos );
UserToDeviceSize( size );
dcode_ptr = get_D_code( size.x, size.y, GERB_RECT, 0 );
if( dcode_ptr->m_NumDcode != s_Last_D_code )
{
sprintf( cbuf, "G54D%d*\n", dcode_ptr->m_NumDcode );
fputs( cbuf, g_Plot_PlotOutputFile );
s_Last_D_code = dcode_ptr->m_NumDcode;
}
sprintf( cbuf, "X%5.5dY%5.5dD03*\n", pos.x, pos.y );
fputs( cbuf, g_Plot_PlotOutputFile );
break;
default: /* plot pad shape as polygon */
trace_1_pad_TRAPEZE_GERBER( pos, size, wxSize( 0, 0 ), orient, FILLED );
break;
}
}
/*****************************************************************/
void trace_1_contour_GERBER( wxPoint pos, wxSize size, wxSize delta,
int penwidth, int orient )
/*****************************************************************/
/* Trace 1 contour rectangulaire ou trapezoidal d'orientation quelconque
* donne par son centre,
* ses dimensions ,
* ses variations ,
* l'epaisseur du trait,
* et son orientation orient
*/
{
int ii;
wxPoint coord[4];
size.x /= 2;
size.y /= 2;
delta.x /= 2;
delta.y /= 2; /* demi dim dx et dy */
coord[0].x = pos.x - size.x - delta.y;
coord[0].y = pos.y + size.y + delta.x;
coord[1].x = pos.x - size.x + delta.y;
coord[1].y = pos.y - size.y - delta.x;
coord[2].x = pos.x + size.x - delta.y;
coord[2].y = pos.y - size.y + delta.x;
coord[3].x = pos.x + size.x + delta.y;
coord[3].y = pos.y + size.y - delta.x;
for( ii = 0; ii < 4; ii++ )
{
RotatePoint( &coord[ii].x, &coord[ii].y, pos.x, pos.y, orient );
}
SelectD_CODE_For_LineDraw( penwidth );
PlotGERBERLine( coord[0], coord[1], penwidth );
PlotGERBERLine( coord[1], coord[2], penwidth );
PlotGERBERLine( coord[2], coord[3], penwidth );
PlotGERBERLine( coord[3], coord[0], penwidth );
}
/*******************************************************************/
void trace_1_pad_TRAPEZE_GERBER( wxPoint pos, wxSize size, wxSize delta,
int orient, int modetrace )
/*******************************************************************/
/* Trace 1 pad trapezoidal donne par :
* son centre pos.x,pos.y
* ses dimensions size.x et size.y
* les variations delta.x et delta.y ( 1 des deux au moins doit etre nulle)
* son orientation orient en 0.1 degres
* le mode de trace (FILLED, SKETCH, FILAIRE)
*
* Le trace n'est fait que pour un trapeze, c.a.d que delta.x ou delta.y
* = 0.
*
* les notation des sommets sont ( vis a vis de la table tracante )
*
* " 0 ------------- 3 "
* " . . "
* " . O . "
* " . . "
* " 1 ---- 2 "
*
*
* exemple de Disposition pour delta.y > 0, delta.x = 0
* " 1 ---- 2 "
* " . . "
* " . O . "
* " . . "
* " 0 ------------- 3 "
*
*
* exemple de Disposition pour delta.y = 0, delta.x > 0
* " 0 "
* " . . "
* " . . "
* " . 3 "
* " . . "
* " . O . "
* " . . "
* " . 2 "
* " . . "
* " . . "
* " 1 "
*/
{
int ii, jj;
int dx, dy;
wxPoint polygon[4]; /* polygon corners */
int coord[8];
int ddx, ddy;
/* calcul des dimensions optimales du spot choisi = 1/4 plus petite dim */
dx = size.x - abs( delta.y );
dy = size.y - abs( delta.x );
dx = size.x / 2;
dy = size.y / 2;
ddx = delta.x / 2;
ddy = delta.y / 2;
polygon[0].x = -dx - ddy;
polygon[0].y = +dy + ddx;
polygon[1].x = -dx + ddy;
polygon[1].y = -dy - ddx;
polygon[2].x = +dx - ddy;
polygon[2].y = -dy + ddx;
polygon[3].x = +dx + ddy;
polygon[3].y = +dy - ddx;
/* Dessin du polygone et Remplissage eventuel de l'interieur */
for( ii = 0, jj = 0; ii < 4; ii++ )
{
RotatePoint( &polygon[ii].x, &polygon[ii].y, orient );
coord[jj] = polygon[ii].x += pos.x;
jj++;
coord[jj] = polygon[ii].y += pos.y;
jj++;
}
if( modetrace != FILLED )
{
int plotLine_width = (int) ( 10 * g_PlotLine_Width * Gerb_scale_plot );
SelectD_CODE_For_LineDraw( plotLine_width );
PlotGERBERLine( polygon[0], polygon[1], plotLine_width );
PlotGERBERLine( polygon[1], polygon[2], plotLine_width );
PlotGERBERLine( polygon[2], polygon[3], plotLine_width );
PlotGERBERLine( polygon[3], polygon[0], plotLine_width );
}
else
PlotFilledPolygon_GERBER( 4, coord );
}
/**********************************************************/
void SelectD_CODE_For_LineDraw( int aSize )
/**********************************************************/
/** Selects a D_Code nn to draw lines and writes G54Dnn to output file
* @param aSize = D_CODE diameter
*/
{
D_CODE* dcode_ptr;
dcode_ptr = get_D_code( aSize, aSize, GERB_LINE, 0 );
if( dcode_ptr->m_NumDcode != s_Last_D_code )
{
fprintf( g_Plot_PlotOutputFile, "G54D%d*\n", dcode_ptr->m_NumDcode );
s_Last_D_code = dcode_ptr->m_NumDcode;
}
}
/*******************************************************/
D_CODE* get_D_code( int dx, int dy, int type, int drill )
/*******************************************************/
/* Fonction Recherchant et Creant eventuellement la description
* du D_CODE du type et dimensions demandees
*/
{
D_CODE* ptr_tool, * last_dcode_ptr;
int num_new_D_code = FIRST_DCODE_VALUE;
ptr_tool = last_dcode_ptr = s_DCodeList;
while( ptr_tool && ptr_tool->m_Type >= 0 )
{
if( ( ptr_tool->m_Size.x == dx )
&& ( ptr_tool->m_Size.y == dy )
&& ( ptr_tool->m_Type == type ) )
return ptr_tool; /* D_code deja existant */
last_dcode_ptr = ptr_tool;
ptr_tool = ptr_tool->m_Pnext;
num_new_D_code++;
}
/* At this point, the requested D_CODE does not exist: It will be created */
if( ptr_tool == NULL ) /* We must create a new data */
{
ptr_tool = new D_CODE();
ptr_tool->m_NumDcode = num_new_D_code;
if( last_dcode_ptr )
{
ptr_tool->m_Pback = last_dcode_ptr;
last_dcode_ptr->m_Pnext = ptr_tool;
}
else
s_DCodeList = ptr_tool;
}
ptr_tool->m_Size.x = dx;
ptr_tool->m_Size.y = dy;
ptr_tool->m_Type = type;
return ptr_tool;
}
/***********************************/
static void Init_ApertureList()
/***********************************/
/* Init the memory to handle the aperture list:
* the member .m_Type is used by get_D_code() to handle the end of list:
* .m_Type < 0 is the first free aperture descr
*/
{
D_CODE* ptr_tool;
ptr_tool = s_DCodeList;
while( ptr_tool )
{
s_DCodeList->m_Type = -1;
ptr_tool = ptr_tool->m_Pnext;
}
ShowDcodeError = TRUE;
}
/******************************************************/
int Gen_D_CODE_File( FILE* penfile )
/******************************************************/
/* Genere la liste courante des D_CODES
* Retourne le nombre de D_Codes utilises
* Genere une sequence RS274X
*/
{
D_CODE* ptr_tool;
char cbuf[1024];
int nb_dcodes = 0;
/* Init : */
ptr_tool = s_DCodeList;
while( ptr_tool && ( ptr_tool->m_Type >= 0 ) )
{
float fscale = 0.0001f; // For 3.4 format
char* text;
sprintf( cbuf, "%%ADD%d", ptr_tool->m_NumDcode );
text = cbuf + strlen( cbuf );
switch( ptr_tool->m_Type )
{
case 1: // Circle (flash )
sprintf( text, "C,%f*%%\n", ptr_tool->m_Size.x * fscale );
break;
case 2: // PAD_RECT
sprintf( text, "R,%fX%f*%%\n", ptr_tool->m_Size.x * fscale,
ptr_tool->m_Size.y * fscale );
break;
case 3: // Circle ( lines )
sprintf( text, "C,%f*%%\n", ptr_tool->m_Size.x * fscale );
break;
case 4: // PAD_OVAL
sprintf( text, "O,%fX%f*%%\n", ptr_tool->m_Size.x * fscale,
ptr_tool->m_Size.y * fscale );
break;
default:
DisplayError( NULL, wxT( "Gen_D_CODE_File(): Dcode Type err" ) );
break;
}
fputs( cbuf, penfile );
ptr_tool = ptr_tool->m_Pnext;
nb_dcodes++;
}
return nb_dcodes;
}
/*****************************/
void CloseFileGERBER( void )
/****************************/
{
char line[1024];
wxString TmpFileName, msg;
FILE* tmpfile;
fputs( "M02*\n", g_Plot_PlotOutputFile );
fclose( g_Plot_PlotOutputFile );
// Reouverture g_Plot_PlotOutputFile pour ajout des Apertures
g_Plot_PlotOutputFile = wxFopen( GerberFullFileName, wxT( "rt" ) );
if( g_Plot_PlotOutputFile == NULL )
{
msg.Printf( _( "unable to reopen file <%s>" ), GerberFullFileName.GetData() );
DisplayError( NULL, msg );
return;
}
// Ouverture tmpfile
TmpFileName = GerberFullFileName + wxT( ".$$$" );
tmpfile = wxFopen( TmpFileName, wxT( "wt" ) );
if( tmpfile == NULL )
{
fclose( g_Plot_PlotOutputFile );
DisplayError( NULL, wxT( "CloseFileGERBER(): Can't Open tmp file" ) );
return;
}
// Placement des Apertures en RS274X
rewind( g_Plot_PlotOutputFile );
while( fgets( line, 1024, g_Plot_PlotOutputFile ) )
{
fputs( line, tmpfile );
if( strcmp( strtok( line, "\n\r" ), "G04 APERTURE LIST*" ) == 0 )
{
Gen_D_CODE_File( tmpfile );
fputs( "G04 APERTURE END LIST*\n", tmpfile );
}
}
fclose( tmpfile );
fclose( g_Plot_PlotOutputFile );
wxRemoveFile( GerberFullFileName );
wxRenameFile( TmpFileName, GerberFullFileName );
}
......@@ -12,760 +12,101 @@
#include "protos.h"
/* Variables locales : */
static int pen_rayon; /* Rayon de la plume en unites pcb */
static int pen_diam; /* Diametre de la plume en unites pcb */
static int pen_recouvrement; /* recouvrement en remplissage en unites pcb */
static int s_Nb_Plot_Errors; // Error count (errors when a line thichness is less than pen width
/* Routines Locales */
/*****************************************************************************/
void WinEDA_BasePcbFrame::Genere_HPGL( const wxString& FullFileName, int Layer )
void WinEDA_BasePcbFrame::Genere_HPGL( const wxString& FullFileName, int Layer,
GRTraceMode trace_mode)
/*****************************************************************************/
{
int modetrace;
wxSize SheetSize;
wxSize BoardSize;
wxPoint BoardCenter;
double scale_x, scale_y;
int marge = 0 * U_PCB; // Extra margin (set to 0)
bool Center = FALSE;
Ki_PageDescr* currentsheet = GetScreen()->m_CurrentSheetDesc;
double scale;
wxPoint offset;
modetrace = g_Plot_Mode;
/* Calcul des echelles de conversion */
scale_x = Scale_X * SCALE_HPGL;
scale_y = Scale_Y * SCALE_HPGL;
// calcul en unites internes des dimensions de la feuille ( connues en 1/1000 pouce )
SheetSize.x = GetScreen()->m_CurrentSheetDesc->m_Size.x * U_PCB;
SheetSize.y = GetScreen()->m_CurrentSheetDesc->m_Size.y * U_PCB;
g_PlotOffset.x = 0;
g_PlotOffset.y = (int) (SheetSize.y * scale_y);
MsgPanel->EraseMsgBox();
// Compute pen_dim (from g_HPGL_Pen_Diam in mils) in pcb units,
// with plot scale (if Scale is 2, pen diametre is always g_HPGL_Pen_Diam
// so apparent pen diam is real pen diam / Scale
pen_diam = wxRound( (g_HPGL_Pen_Diam * U_PCB) / Scale_X ); // Assume Scale_X # Scale_Y
pen_rayon = pen_diam / 2;
s_Nb_Plot_Errors = 0;
int pen_diam = wxRound( (g_pcb_plot_options.HPGL_Pen_Diam * U_PCB) / g_pcb_plot_options.Scale );
// compute pen_recouvrement (from g_HPGL_Pen_Recouvrement in mils)
// with plot scale
if( g_HPGL_Pen_Recouvrement < 0 )
g_HPGL_Pen_Recouvrement = 0;
if( g_HPGL_Pen_Recouvrement >= g_HPGL_Pen_Diam )
g_HPGL_Pen_Recouvrement = g_HPGL_Pen_Diam - 1;
pen_recouvrement = wxRound( g_HPGL_Pen_Recouvrement * 10.0 / Scale_X );
if( g_pcb_plot_options.HPGL_Pen_Recouvrement < 0 )
g_pcb_plot_options.HPGL_Pen_Recouvrement = 0;
if( g_pcb_plot_options.HPGL_Pen_Recouvrement >= g_pcb_plot_options.HPGL_Pen_Diam )
g_pcb_plot_options.HPGL_Pen_Recouvrement = g_pcb_plot_options.HPGL_Pen_Diam - 1;
int pen_recouvrement = wxRound( g_pcb_plot_options.HPGL_Pen_Recouvrement * 10.0 / g_pcb_plot_options.Scale );
dest = wxFopen( FullFileName, wxT( "wt" ) );
if( dest == NULL )
FILE *output_file = wxFopen( FullFileName, wxT( "wt" ) );
if( output_file == NULL )
{
wxString msg = _( "Unable to create " ) + FullFileName;
wxString msg = _( "Unable to create file " ) + FullFileName;
DisplayError( this, msg );
return;
}
SetLocaleTo_C_standard();
Affiche_1_Parametre( this, 0, _( "File" ), FullFileName, CYAN );
PrintHeaderHPGL( dest, g_HPGL_Pen_Speed, g_HPGL_Pen_Num );
if( g_pcb_plot_options.PlotScaleOpt != 1 )
Center = TRUE; // Echelle != 1 donc trace centree du PCB
if( g_Plot_Frame_Ref && (g_PlotScaleOpt == 1) )
{
int tmp = g_PlotOrient; g_PlotOrient = 0;
InitPlotParametresHPGL( g_PlotOffset, scale_x, scale_y, g_PlotOrient );
PlotWorkSheet( PLOT_FORMAT_HPGL, GetScreen() );
g_PlotOrient = tmp;
}
// calcul en unites internes des dimensions des feuilles ( connues en 1/1000 pouce )
SheetSize.x = currentsheet->m_Size.x * U_PCB;
SheetSize.y = currentsheet->m_Size.y * U_PCB;
/* calcul des dimensions et centre du PCB */
m_Pcb->ComputeBoundaryBox();
BoardSize = m_Pcb->m_BoundaryBox.GetSize();
BoardCenter = m_Pcb->m_BoundaryBox.Centre();
if( g_PlotScaleOpt == 0 ) // Optimum scale
if( g_pcb_plot_options.PlotScaleOpt == 0 ) // Optimum scale
{
float Xscale, Yscale;
Xscale = (float) ( SheetSize.x - ( 2 * marge) ) / BoardSize.x;
Yscale = (float) ( SheetSize.y - ( 2 * marge) ) / BoardSize.y;
scale_x = scale_y = MIN( Xscale, Yscale ) * SCALE_HPGL;
double Xscale, Yscale;
// Fit to 80% of the page
Xscale = ( (SheetSize.x*0.8) / BoardSize.x);
Yscale = ( (SheetSize.y*0.8) / BoardSize.y);
scale = MIN( Xscale, Yscale );
}
else
scale = g_pcb_plot_options.Scale;
BoardCenter.x = (int) (BoardCenter.x * scale_x);
BoardCenter.y = (int) (BoardCenter.y * scale_y);
if( g_PlotScaleOpt != 1 )
Center = TRUE; // Echelle != 1
/* Calcul du cadrage */
marge = (int) (marge * SCALE_HPGL);
if( Center )
g_PlotOffset.x = (int) (-SheetSize.x / 2 * SCALE_HPGL) +
BoardCenter.x + marge;
switch( g_PlotOrient )
{
default:
// Calcul du cadrage (echelle != 1 donc recadrage du trace)
if( Center )
{
g_PlotOffset.y = (int) (SheetSize.y / 2 * SCALE_HPGL) +
BoardCenter.y + marge;
offset.x = BoardCenter.x-(SheetSize.x/2)/scale;
offset.y = BoardCenter.y-(SheetSize.y/2)/scale;
}
break;
case PLOT_MIROIR:
if( Center )
g_PlotOffset.y = (int) (-SheetSize.y / 2 * SCALE_HPGL) + BoardCenter.y;
else
g_PlotOffset.y = (int) ( ( -SheetSize.y +
m_Pcb->m_BoundaryBox.GetBottom() +
m_Pcb->m_BoundaryBox.GetY() ) * SCALE_HPGL );
break;
}
InitPlotParametresHPGL( g_PlotOffset, scale_x, scale_y, g_PlotOrient );
// Specify that the contents of the "Edges Pcb" layer are to be plotted
// in addition to the contents of the currently specified layer.
int layer_mask = g_TabOneLayerMask[Layer] | EDGE_LAYER;
switch( Layer )
{
case FIRST_COPPER_LAYER:
case LAYER_N_2:
case LAYER_N_3:
case LAYER_N_4:
case LAYER_N_5:
case LAYER_N_6:
case LAYER_N_7:
case LAYER_N_8:
case LAYER_N_9:
case LAYER_N_10:
case LAYER_N_11:
case LAYER_N_12:
case LAYER_N_13:
case LAYER_N_14:
case LAYER_N_15:
case LAST_COPPER_LAYER:
Plot_Layer_HPGL( dest, layer_mask, 0, 1, modetrace );
break;
case SILKSCREEN_N_CU:
case SILKSCREEN_N_CMP:
Plot_Serigraphie( PLOT_FORMAT_HPGL, dest, layer_mask );
break;
case SOLDERMASK_N_CU:
case SOLDERMASK_N_CMP: /* Trace du vernis epargne */
{
int tracevia;
if( g_DrawViaOnMaskLayer )
tracevia = 1;
else
tracevia = 0;
Plot_Layer_HPGL( dest, layer_mask,
g_DesignSettings.m_MaskMargin, tracevia, modetrace );
}
break;
case SOLDERPASTE_N_CU:
case SOLDERPASTE_N_CMP: /* Trace du masque de pate de soudure */
Plot_Layer_HPGL( dest, layer_mask, 0, 0, modetrace );
break;
default: /* Trace des autres couches (dessin, adhesives,eco,comment) */
Plot_Serigraphie( PLOT_FORMAT_HPGL, dest, layer_mask );
break;
}
/* fin */
CloseFileHPGL( dest );
offset.x = 0;
offset.y = 0;
}
HPGL_Plotter *plotter = new HPGL_Plotter();
plotter->set_paper_size(currentsheet);
plotter->set_viewport(offset, scale,
g_pcb_plot_options.PlotOrient);
plotter->set_default_line_width( g_pcb_plot_options.PlotLine_Width );
plotter->set_creator(wxT("PCBNEW-HPGL"));
plotter->set_filename(FullFileName);
plotter->set_pen_speed(g_pcb_plot_options.HPGL_Pen_Speed);
plotter->set_pen_number(g_pcb_plot_options.HPGL_Pen_Num);
plotter->set_pen_overlap(pen_recouvrement);
plotter->set_pen_diameter(pen_diam);
plotter->start_plot(output_file);
/* The worksheet is not significant with scale!=1... It is with
* paperscale!=1, anyway */
if( g_pcb_plot_options.Plot_Frame_Ref && !Center)
PlotWorkSheet( plotter, GetScreen() );
Plot_Layer(plotter, Layer, trace_mode);
plotter->end_plot();
delete plotter;
SetLocaleTo_Default();
}
/*********************************************************************/
void WinEDA_BasePcbFrame::Plot_Layer_HPGL( FILE* File, int masque_layer,
int garde, int tracevia, int modetrace )
/*********************************************************************/
/* Trace en format HPGL. d'une couche cuivre ou masque
* 1 unite HPGL = 0.98 mils ( 1 mil = 1.02041 unite HPGL ) .
*/
{
wxSize size;
wxPoint start, end;
MODULE* Module;
D_PAD* PtPad;
TRACK* pts;
BOARD_ITEM* PtStruct;
wxString msg;
/* trace des elements type Drawings Pcb : */
PtStruct = m_Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
{
switch( PtStruct->Type() )
{
case TYPE_DRAWSEGMENT:
PlotDrawSegment( (DRAWSEGMENT*) PtStruct, PLOT_FORMAT_HPGL,
masque_layer );
break;
case TYPE_TEXTE:
PlotTextePcb( (TEXTE_PCB*) PtStruct, PLOT_FORMAT_HPGL,
masque_layer );
break;
case TYPE_COTATION:
PlotCotation( (COTATION*) PtStruct, PLOT_FORMAT_HPGL,
masque_layer );
break;
case TYPE_MIRE:
PlotMirePcb( (MIREPCB*) PtStruct, PLOT_FORMAT_HPGL,
masque_layer );
break;
case TYPE_MARKER:
break;
default:
DisplayError( this, wxT( "Type Draw non gere" ) );
break;
}
}
/* Trace des Elements des modules autres que pads */
Module = m_Pcb->m_Modules;
for( ; Module != NULL; Module = Module->Next() )
{
PtStruct = Module->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
{
switch( PtStruct->Type() )
{
case TYPE_EDGE_MODULE:
if( masque_layer &
g_TabOneLayerMask[ PtStruct->GetLayer() ] )
Plot_1_EdgeModule( PLOT_FORMAT_HPGL, (EDGE_MODULE*) PtStruct );
break;
default:
break;
}
}
}
/* Trace des Elements des modules : Pastilles */
Module = m_Pcb->m_Modules;
for( ; Module != NULL; Module = Module->Next() )
{
PtPad = (D_PAD*) Module->m_Pads;
for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Next() )
{
wxPoint shape_pos;
if( (PtPad->m_Masque_Layer & masque_layer) == 0 )
continue;
shape_pos = PtPad->ReturnShapePos();
start = shape_pos;
size = PtPad->m_Size;
size.x += garde * 2; size.y += garde * 2;
switch( PtPad->m_PadShape & 0x7F )
{
case PAD_CIRCLE:
trace_1_pastille_RONDE_HPGL( start, size.x, modetrace );
break;
case PAD_OVAL:
{
trace_1_pastille_OVALE_HPGL( start, size, PtPad->m_Orient, modetrace );
break;
}
case PAD_TRAPEZOID:
{
wxSize delta;
delta = PtPad->m_DeltaSize;
trace_1_pad_TRAPEZE_HPGL( start, size, delta,
PtPad->m_Orient, modetrace );
break;
}
case PAD_RECT:
default:
PlotRectangularPad_HPGL( start, size,
PtPad->m_Orient, modetrace );
break;
}
}
}
/* trace des VIAS : */
if( tracevia )
{
TRACK* pts;
for( pts = m_Pcb->m_Track; pts != NULL; pts = pts->Next() )
{
if( pts->Type() != TYPE_VIA )
continue;
SEGVIA* Via = (SEGVIA*) pts;
/* vias not plotted if not on selected layer, but if layer
* == SOLDERMASK_LAYER_CU or SOLDERMASK_LAYER_CMP, vias are drawn ,
* if they are on a external copper layer
*/
int via_mask_layer = Via->ReturnMaskLayer();
if( (via_mask_layer & CUIVRE_LAYER ) )
via_mask_layer |= SOLDERMASK_LAYER_CU;
if( (via_mask_layer & CMP_LAYER ) )
via_mask_layer |= SOLDERMASK_LAYER_CMP;
if( (via_mask_layer & masque_layer) == 0 )
continue;
start = Via->m_Start;
size.x = Via->m_Width + (garde * 2);
trace_1_pastille_RONDE_HPGL( start, size.x, modetrace );
}
fputs( "PU;\n", dest );
}
/* trace des segments pistes */
for( pts = m_Pcb->m_Track; pts != NULL; pts = pts->Next() )
{
if( pts->Type() == TYPE_VIA )
continue;
if( (g_TabOneLayerMask[pts->GetLayer()] & masque_layer) )
Plot_Filled_Segment_HPGL( pts->m_Start, pts->m_End, pts->m_Width, (GRFillMode)g_Plot_Mode );
}
/* trace des segments pistes et zones */
for( pts = m_Pcb->m_Zone; pts != NULL; pts = pts->Next() )
{
if( (g_TabOneLayerMask[pts->GetLayer()] & masque_layer) )
Plot_Filled_Segment_HPGL( pts->m_Start, pts->m_End, pts->m_Width, (GRFillMode)g_Plot_Mode );
}
/* Plot filled ares */
for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* zone = m_Pcb->GetArea( ii );
if( ( ( 1 << zone->GetLayer() ) & masque_layer ) == 0 )
continue;
PlotFilledAreas( zone, PLOT_FORMAT_HPGL );
}
}
/*********************************************************************************************/
bool Plot_Filled_Segment_HPGL( wxPoint aStart, wxPoint aEnd, int aWidth, GRFillMode aPlotMode )
/*********************************************************************************************/
/** Function Plot a filled segment (track)
* @param aStart = starting point
* @param aEnd = ending point
* @param aWidth = segment width (thickness)
* @param aPlotMode = FILLED, SKETCH ..
* @return true if Ok, false if aWidth > pen size (the segment is always plotted)
*/
{
wxPoint center;
wxSize size;
int orient;
if( (pen_diam >= aWidth) || (g_Plot_Mode == FILAIRE) ) /* just a line is Ok */
{
Move_Plume_HPGL( aStart, 'U' );
Move_Plume_HPGL( aEnd, 'D' );
Plume_HPGL( 'U' );
return pen_diam <= aWidth;;
}
// A segment is like an oval pal, so use trace_1_pastille_OVALE_HPGL to do the work.
center.x = (aStart.x + aEnd.x) / 2;
center.y = (aStart.y + aEnd.y) / 2;
size.x = aEnd.x - aStart.x;
size.y = aEnd.y - aStart.y;
if ( size.y == 0 )
orient = 0;
else if ( size.x == 0 )
orient = 900;
else orient = - (int) (atan2( (double)size.y, (double)size.x ) * 1800.0 / M_PI);
size.x = (int) sqrt( ((double)size.x * size.x) + ((double)size.y * size.y) ) + aWidth; // module.
size.y = aWidth;
trace_1_pastille_OVALE_HPGL( center, size, orient, aPlotMode );
return pen_diam <= aWidth;
}
/************************************************************************************/
void trace_1_pastille_OVALE_HPGL( wxPoint pos, wxSize size, int aOrient, int modetrace )
/************************************************************************************/
/* Trace 1 pastille PAD_OVAL en position pos_X,Y , de dim size.x, size.y */
{
int rayon, deltaxy, cx, cy;
/* la pastille est ramenee a une pastille ovale avec size.y > size.x
* ( ovale vertical en orientation 0 ) */
if( size.x > size.y )
{
EXCHG( size.x, size.y ); aOrient += 900;
if( aOrient >= 3600 )
aOrient -= 3600;
}
deltaxy = size.y - size.x; /* = distance entre centres de l'ovale */
rayon = size.x / 2;
if( modetrace == FILLED )
{
PlotRectangularPad_HPGL( pos, wxSize( size.x, deltaxy+pen_diam ),
aOrient, modetrace );
cx = 0; cy = deltaxy / 2;
RotatePoint( &cx, &cy, aOrient );
trace_1_pastille_RONDE_HPGL( wxPoint( cx + pos.x, cy + pos.y ), size.x, modetrace );
Plume_HPGL( 'U' );
cx = 0; cy = -deltaxy / 2;
RotatePoint( &cx, &cy, aOrient );
trace_1_pastille_RONDE_HPGL( wxPoint( cx + pos.x, cy + pos.y ), size.x, modetrace );
}
else /* Trace en mode SKETCH */
{
cx = -rayon; cy = -deltaxy / 2;
RotatePoint( &cx, &cy, aOrient );
Move_Plume_HPGL( wxPoint( cx + pos.x, cy + pos.y ), 'U' );
cx = -rayon; cy = deltaxy / 2;
RotatePoint( &cx, &cy, aOrient );
Move_Plume_HPGL( wxPoint( cx + pos.x, cy + pos.y ), 'D' );
cx = rayon; cy = -deltaxy / 2;
RotatePoint( &cx, &cy, aOrient );
Move_Plume_HPGL( wxPoint( cx + pos.x, cy + pos.y ), 'U' );
cx = rayon; cy = deltaxy / 2;
RotatePoint( &cx, &cy, aOrient );
Move_Plume_HPGL( wxPoint( cx + pos.x, cy + pos.y ), 'D' );
Plume_HPGL( 'U' );
cx = 0; cy = deltaxy / 2;
RotatePoint( &cx, &cy, aOrient );
PlotArc( PLOT_FORMAT_HPGL, wxPoint( cx + pos.x, cy + pos.y ),
-aOrient, -aOrient - 1800,
size.x / 2, pen_diam );
cx = 0; cy = -deltaxy / 2;
RotatePoint( &cx, &cy, aOrient );
PlotArc( PLOT_FORMAT_HPGL, wxPoint( cx + pos.x, cy + pos.y ),
-aOrient - 1800, -aOrient,
size.x / 2, pen_diam );
}
Plume_HPGL( 'U' );
}
/**************************************************************************/
void trace_1_pastille_RONDE_HPGL( wxPoint pos, int diametre, int modetrace )
/**************************************************************************/
/* Trace 1 pastille RONDE (via,pad rond) en position pos */
{
char cbuf[1024];
int rayon, delta;
UserToDeviceCoordinate( pos );
delta = pen_diam - pen_recouvrement;
rayon = diametre / 2;
if( modetrace != FILAIRE )
{
rayon = (diametre - pen_diam ) / 2;
}
if( rayon < 0 )
{
rayon = 0; s_Nb_Plot_Errors++;
}
wxSize rsize( rayon, rayon );
UserToDeviceSize( rsize );
Plume_HPGL( 'U' );
sprintf( cbuf, "PA %d,%d;CI %d;\n", pos.x, pos.y, rsize.x );
fputs( cbuf, dest );
if( modetrace == FILLED ) /* Trace en mode Remplissage */
{
if( delta > 0 )
{
while( (rayon -= delta ) >= 0 )
{
rsize.x = rsize.y = rayon;
UserToDeviceSize( rsize );
sprintf( cbuf, "PA %d,%d; CI %d;\n", pos.x, pos.y, rsize.x );
fputs( cbuf, dest );
}
}
}
Plume_HPGL( 'U' ); return;
}
/***************************************************************/
void PlotRectangularPad_HPGL( wxPoint padpos, wxSize padsize,
int orient, int modetrace )
/****************************************************************/
/*
* Trace 1 pad rectangulaire vertical ou horizontal ( Pad rectangulaire )
* donne par son centre et ses dimensions X et Y
* Units are user units
*/
{
wxSize size;
int delta;
int ox, oy, fx, fy;
size.x = padsize.x / 2; size.y = padsize.y / 2;
if( modetrace != FILAIRE )
{
size.x = (padsize.x - (int) pen_diam) / 2;
size.y = (padsize.y - (int) pen_diam) / 2;
}
if( (size.x < 0 ) || (size.y < 0) )
{
s_Nb_Plot_Errors++;
}
if( size.x < 0 )
size.x = 0;if( size.y < 0 )
size.y = 0;
/* Si une des dimensions est nulle, le trace se reduit a 1 trait */
if( size.x == 0 )
{
ox = padpos.x; oy = padpos.y - size.y;
RotatePoint( &ox, &oy, padpos.x, padpos.y, orient );
fx = padpos.x; fy = padpos.y + size.y;
RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( ox, oy ), 'U' );
Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
Plume_HPGL( 'U' ); return;
}
if( size.y == 0 )
{
ox = padpos.x - size.x; oy = padpos.y;
RotatePoint( &ox, &oy, padpos.x, padpos.y, orient );
fx = padpos.x + size.x; fy = padpos.y;
RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( ox, oy ), 'U' );
Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
Plume_HPGL( 'U' ); return;
}
ox = padpos.x - size.x; oy = padpos.y - size.y;
RotatePoint( &ox, &oy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( ox, oy ), 'U' );
fx = padpos.x - size.x; fy = padpos.y + size.y;
RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
fx = padpos.x + size.x; fy = padpos.y + size.y;
RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
fx = padpos.x + size.x; fy = padpos.y - size.y;
RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
Move_Plume_HPGL( wxPoint( ox, oy ), 'D' );
if( modetrace != FILLED )
{
Plume_HPGL( 'U' ); return;
}
/* Trace en mode Remplissage */
delta = (int) (pen_diam - pen_recouvrement);
if( delta > 0 )
while( (size.x > 0) && (size.y > 0) )
{
size.x -= delta; size.y -= delta;
if( size.x < 0 )
size.x = 0;if( size.y < 0 )
size.y = 0;
ox = padpos.x - size.x; oy = padpos.y - size.y;
RotatePoint( &ox, &oy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( ox, oy ), 'D' );
fx = padpos.x - size.x; fy = padpos.y + size.y;
RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
fx = padpos.x + size.x; fy = padpos.y + size.y;
RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
fx = padpos.x + size.x; fy = padpos.y - size.y;
RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
Move_Plume_HPGL( wxPoint( ox, oy ), 'D' );
}
Plume_HPGL( 'U' );
}
/********************************************************************/
void trace_1_pad_TRAPEZE_HPGL( wxPoint padpos, wxSize size, wxSize delta,
int orient, int modetrace )
/********************************************************************/
/*
* Trace 1 pad trapezoidal donne par :
* son centre padpos.x,padpos.y
* ses dimensions dimX et dimY
* les variations deltaX et deltaY
* son orientation orient et 0.1 degres
* le mode de trace (FILLED, SKETCH, FILAIRE)
* Le trace n'est fait que pour un trapeze, c.a.d que deltaX ou deltaY
* = 0.
*
* les notation des sommets sont ( vis a vis de la table tracante )
* 0 ------------- 3
* . .
* . .
* . .
* 1 --- 2
*/
{
int ii, jj;
wxPoint polygone[4]; /* coord des sommets / centre du pad */
wxPoint coord[4]; /* coord reelles des sommets du trapeze a tracer */
float fangle; /* angle d'inclinaison des cotes du trapeze */
int rayon; /* rayon de la plume */
int moveX, moveY; /* variation de position plume selon axe X et Y , lors
* du remplissage du trapeze */
rayon = (int) pen_rayon; if( modetrace == FILAIRE )
rayon = 0;
moveX = moveY = rayon;
size.x /= 2; size.y /= 2;
delta.x /= 2; delta.y /= 2;
polygone[0].x = -size.x - delta.y; polygone[0].y = +size.y + delta.x;
polygone[1].x = -size.x + delta.y; polygone[1].y = -size.y - delta.x;
polygone[2].x = +size.x - delta.y; polygone[2].y = -size.y + delta.x;
polygone[3].x = +size.x + delta.y; polygone[3].y = +size.y - delta.x;
/* Calcul du demi angle d'inclinaison des cotes du trapeze */
if( delta.y ) /* Trapeze horizontal */
{
fangle = atan2( (double) (polygone[1].y - polygone[0].y),
(double) (polygone[1].x - polygone[0].x) ) / 2;
}
else
{
fangle = atan2( (double) (polygone[3].y - polygone[0].y),
(double) (polygone[3].x - polygone[0].x) ) / 2;
}
/* Trace du contour */
polygone[0].x += moveX; polygone[0].y -= moveY;
polygone[1].x += moveX; polygone[1].y += moveY;
polygone[2].x -= moveX; polygone[2].y += moveY;
polygone[3].x -= moveX; polygone[3].y -= moveY;
for( ii = 0; ii < 4; ii++ )
{
coord[ii].x = polygone[ii].x + padpos.x;
coord[ii].y = polygone[ii].y + padpos.y;
RotatePoint( &coord[ii], padpos, orient );
}
// Plot edge:
Move_Plume_HPGL( coord[0], 'U' );
Move_Plume_HPGL( coord[1], 'D' );
Move_Plume_HPGL( coord[2], 'D' );
Move_Plume_HPGL( coord[3], 'D' );
Move_Plume_HPGL( coord[0], 'D' );
if( modetrace != FILLED )
{
Plume_HPGL( 'U' ); return;
}
/* Fill the shape */
moveX = moveY = pen_diam - pen_recouvrement;
/* calcul de jj = hauteur du remplissage */
if( delta.y ) /* Trapeze horizontal */
{
jj = size.y - (int) ( pen_diam + (2 * pen_recouvrement) );
}
else
{
jj = size.x - (int) ( pen_diam + (2 * pen_recouvrement) );
}
/* Calcul de jj = nombre de segments a tracer pour le remplissage */
jj = jj / (int) (pen_diam - pen_recouvrement);
/* Trace du contour */
for( ; jj > 0; jj-- )
{
polygone[0].x += moveX; polygone[0].y -= moveY;
polygone[1].x += moveX; polygone[1].y += moveY;
polygone[2].x -= moveX; polygone[2].y += moveY;
polygone[3].x -= moveX; polygone[3].y -= moveY;
/* Test de limitation de variation des dimensions :
* si les sommets se "croisent", il ne faut plus modifier les
* coordonnees correspondantes */
if( polygone[0].x > polygone[3].x )
{ /* croisement sur axe X des 2 sommets 0 et 3 */
polygone[0].x = polygone[3].x = 0;
}
if( polygone[1].x > polygone[2].x )
{ /* croisement sur axe X des 2 sommets 1 et 2 */
polygone[1].x = polygone[2].x = 0;
}
if( polygone[1].y > polygone[0].y )
{ /* croisement sur axe Y des 2 sommets 0 et 1 */
polygone[0].y = polygone[1].y = 0;
}
if( polygone[2].y > polygone[3].y )
{ /* croisement sur axe Y des 2 sommets 2 et 3 */
polygone[2].y = polygone[3].y = 0;
}
for( ii = 0; ii < 4; ii++ )
{
coord[ii].x = polygone[ii].x + padpos.x;
coord[ii].y = polygone[ii].y + padpos.y;
RotatePoint( &coord[ii], padpos, orient );
}
Move_Plume_HPGL( coord[0], 'U' );
Move_Plume_HPGL( coord[1], 'D' );
Move_Plume_HPGL( coord[2], 'D' );
Move_Plume_HPGL( coord[3], 'D' );
Move_Plume_HPGL( coord[0], 'D' );
}
Plume_HPGL( 'U' );
}
......@@ -10,767 +10,128 @@
#include "pcbplot.h"
#include "trigo.h"
// Routines Locales
static void PrintDrillMark( BOARD* Pcb );
static Ki_PageDescr* SheetPS;
// variables locales:
const int DRILL_MARK = 1;
#include "protos.h"
/****************************************************************************/
void WinEDA_BasePcbFrame::Genere_PS( const wxString& FullFileName, int Layer, bool useA4 )
void WinEDA_BasePcbFrame::Genere_PS( const wxString& FullFileName, int Layer,
bool useA4, GRTraceMode trace_mode)
/****************************************************************************/
/* Genere un fichier POSTSCRIPT (*.ps) de trace du circuit, couche layer
* if layer < 0: all layers
*/
{
int modetrace, tracevia;
wxSize PcbSheetSize;
wxSize SheetSize;
wxSize PaperSize;
wxSize BoardSize;
wxPoint BoardCenter;
bool Center = FALSE;
Ki_PageDescr* currentsheet = GetScreen()->m_CurrentSheetDesc;
double scale_format; // Facteur correctif pour conversion forlat Ax->A4
double scale_x, scale_y;
int PlotMarge_in_mils = 0;
double scale, paperscale;
Ki_PageDescr* SheetPS;
wxPoint offset;
MsgPanel->EraseMsgBox();
dest = wxFopen( FullFileName, wxT( "wt" ) );
if( dest == NULL )
FILE *output_file = wxFopen( FullFileName, wxT( "wt" ) );
if( output_file == NULL )
{
wxString msg = _( "Unable to create file " ) + FullFileName;
DisplayError( this, msg );
return;
}
SetLocaleTo_C_standard( );
SetLocaleTo_C_standard();
Affiche_1_Parametre( this, 0, _( "File" ), FullFileName, CYAN );
if( g_PlotScaleOpt != 1 )
if( g_pcb_plot_options.PlotScaleOpt != 1 )
Center = TRUE; // Echelle != 1 donc trace centree du PCB
modetrace = g_Plot_Mode;
scale_format = 1.0;
// Set default line width
if( g_PlotLine_Width < 1 )
g_PlotLine_Width = 1;
if( g_pcb_plot_options.PlotLine_Width < 1 )
g_pcb_plot_options.PlotLine_Width = 1;
// calcul en unites internes des dimensions des feuilles ( connues en 1/1000 pouce )
PcbSheetSize.x = currentsheet->m_Size.x * U_PCB;
PcbSheetSize.y = currentsheet->m_Size.y * U_PCB;
SheetSize.x = currentsheet->m_Size.x * U_PCB;
SheetSize.y = currentsheet->m_Size.y * U_PCB;
if( useA4 )
{
SheetPS = &g_Sheet_A4;
PaperSize.x = g_Sheet_A4.m_Size.x * U_PCB;
PaperSize.y = g_Sheet_A4.m_Size.y * U_PCB;
scale_format = (float) PaperSize.x / PcbSheetSize.x;
paperscale = (float) PaperSize.x / SheetSize.x;
}
else
{
SheetPS = currentsheet;
PaperSize = PcbSheetSize;
}
// calcul de l'offset de trace:
// calcul du cadrage horizontal du mode paysage ( val algebr. plus grande = decalage a gauche )
g_PlotOffset.x = PlotMarge_in_mils * U_PCB;
// cadrage vertical du mode paysage ( val algebr. plus grande = decalage vers le haut )
g_PlotOffset.y = PaperSize.y - PlotMarge_in_mils * U_PCB;
int BBox[4];
BBox[0] = BBox[1] = PlotMarge_in_mils;
BBox[2] = SheetPS->m_Size.x - PlotMarge_in_mils;
BBox[3] = SheetPS->m_Size.y - PlotMarge_in_mils;
scale_x = scale_y = 1.0;
InitPlotParametresPS( g_PlotOffset, SheetPS, 1.0 / m_InternalUnits, 1.0 / m_InternalUnits );
SetDefaultLineWidthPS( g_PlotLine_Width );
PrintHeaderPS( dest, wxT( "PCBNEW-PS" ), FullFileName, 1, BBox, wxLANDSCAPE );
if( g_Plot_Frame_Ref )
{
int tmp = g_PlotOrient;
g_PlotOrient = 0;
SetPlotScale( 1.0, 1.0 );
PlotWorkSheet( PLOT_FORMAT_POST, GetScreen() );
g_PlotOrient = tmp;
PaperSize = SheetSize;
paperscale = 1;
}
// calcul des dimensions et centre du PCB
/* calcul des dimensions et centre du PCB */
m_Pcb->ComputeBoundaryBox();
BoardSize = m_Pcb->m_BoundaryBox.GetSize();
BoardCenter = m_Pcb->m_BoundaryBox.Centre();
scale_x = Scale_X;
scale_y = Scale_Y;
if( g_PlotScaleOpt == 0 ) // Optimum scale
if( g_pcb_plot_options.PlotScaleOpt == 0 ) // Optimum scale
{
float Xscale, Yscale;
int noprint_size = 2 * PlotMarge_in_mils * U_PCB;
if( g_Plot_Frame_Ref )
noprint_size += 500 * U_PCB;
Xscale = (float) ( PaperSize.x - noprint_size ) / BoardSize.x;
Yscale = (float) ( PaperSize.y - noprint_size ) / BoardSize.y;
scale_x = scale_y = MIN( Xscale, Yscale );
double Xscale, Yscale;
// Fit to 80% of the page
Xscale = (PaperSize.x*0.8) / BoardSize.x;
Yscale = (PaperSize.y*0.8) / BoardSize.y;
scale = MIN( Xscale, Yscale );
}
BoardCenter.x = (int) (BoardCenter.x * scale_x);
BoardCenter.y = (int) (BoardCenter.y * scale_y);
else
scale = g_pcb_plot_options.Scale * paperscale;
// Calcul du cadrage (echelle != 1 donc recadrage du trace)
if( Center )
{
g_PlotOffset.x -= PaperSize.x / 2 - BoardCenter.x + PlotMarge_in_mils * U_PCB;
g_PlotOffset.y = PaperSize.y / 2 + BoardCenter.y; // cadrage horizontal du mode paysage
offset.x = BoardCenter.x-(PaperSize.x/2)/scale;
offset.y = BoardCenter.y-(PaperSize.y/2)/scale;
}
if( g_PlotOrient == PLOT_MIROIR )
{
if( Center )
g_PlotOffset.y = -PaperSize.y / 2 + BoardCenter.y;
else
g_PlotOffset.y = -PaperSize.y + m_Pcb->m_BoundaryBox.GetBottom()
+ m_Pcb->m_BoundaryBox.GetY() + PlotMarge_in_mils * U_PCB;
{
offset.x = 0;
offset.y = 0;
}
InitPlotParametresPS( g_PlotOffset, SheetPS, scale_x, scale_y, g_PlotOrient );
PS_Plotter *plotter = new PS_Plotter();
plotter->set_paper_size(SheetPS);
plotter->set_scale_adjust(g_pcb_plot_options.ScaleAdjX,
g_pcb_plot_options.ScaleAdjY);
plotter->set_viewport(offset, scale,
g_pcb_plot_options.PlotOrient);
plotter->set_default_line_width( g_pcb_plot_options.PlotLine_Width );
plotter->set_creator(wxT("PCBNEW-PS"));
plotter->set_filename(FullFileName);
plotter->start_plot(output_file);
/* The worksheet is not significant with scale!=1... It is with
* paperscale!=1, anyway */
if( g_pcb_plot_options.Plot_Frame_Ref && !Center)
PlotWorkSheet( plotter, GetScreen() );
// If plot a negative board:
// Draw a black rectangle (background for plot board in white)
// and switch the current color to WHITE
if( g_Plot_PS_Negative )
{
int Rectangle[10]; // Put here the board corners
int margin = 500; // Add a 0.1 inch margin around the board
Rectangle[0] = m_Pcb->m_BoundaryBox.GetX() - margin;
Rectangle[1] = m_Pcb->m_BoundaryBox.GetY() - margin;
Rectangle[2] = m_Pcb->m_BoundaryBox.GetRight() + margin;
Rectangle[3] = Rectangle[1];
Rectangle[4] = Rectangle[2];
Rectangle[5] = m_Pcb->m_BoundaryBox.GetBottom() + margin;
Rectangle[6] = Rectangle[0];
Rectangle[7] = Rectangle[5];
Rectangle[8] = Rectangle[0];
Rectangle[9] = Rectangle[1];
SetColorMapPS( BLACK );
PlotPolyPS( 5, Rectangle, TRUE );
SetColorMapPS( WHITE );
}
// Specify that the contents of the "Edges Pcb" layer are to be plotted
// in addition to the contents of the currently specified layer.
int layer_mask = g_TabOneLayerMask[Layer] | EDGE_LAYER;
switch( Layer )
{
case - 1:
Plot_Layer_PS( dest, layer_mask, 0, 1, modetrace );
break;
case FIRST_COPPER_LAYER:
case LAYER_N_2:
case LAYER_N_3:
case LAYER_N_4:
case LAYER_N_5:
case LAYER_N_6:
case LAYER_N_7:
case LAYER_N_8:
case LAYER_N_9:
case LAYER_N_10:
case LAYER_N_11:
case LAYER_N_12:
case LAYER_N_13:
case LAYER_N_14:
case LAYER_N_15:
case LAST_COPPER_LAYER:
Plot_Layer_PS( dest, layer_mask, 0, 1, modetrace );
break;
case SILKSCREEN_N_CU:
case SILKSCREEN_N_CMP:
Plot_Serigraphie( PLOT_FORMAT_POST, dest, layer_mask );
break;
case SOLDERMASK_N_CU:
case SOLDERMASK_N_CMP: // Trace du vernis epargne
if( g_DrawViaOnMaskLayer )
tracevia = 1;
else
tracevia = 0;
Plot_Layer_PS( dest, layer_mask, g_DesignSettings.m_MaskMargin,
tracevia, modetrace );
break;
case SOLDERPASTE_N_CU:
case SOLDERPASTE_N_CMP: // Trace du masque de pate de soudure
Plot_Layer_PS( dest, layer_mask, 0, 0, modetrace );
break;
default:
Plot_Serigraphie( PLOT_FORMAT_POST, dest, layer_mask );
break;
}
// fin
CloseFilePS( dest );
SetLocaleTo_Default( );
}
/********************************************************************/
void WinEDA_BasePcbFrame::Plot_Layer_PS( FILE* File, int masque_layer,
int garde, int tracevia, int modetrace )
/********************************************************************/
/* Trace en format POSTSCRIPT d'une couche cuivre ou masque
*/
{
wxPoint pos, end;
wxSize size;
MODULE* Module;
D_PAD* PtPad;
TRACK* pts;
BOARD_ITEM* PtStruct;
wxString msg;
// (Following command has been superceded by new command on line 173.)
// masque_layer |= EDGE_LAYER; // Les elements de la couche EDGE sont tj traces
// trace des elements type Drawings Pcb :
PtStruct = m_Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
{
switch( PtStruct->Type() )
{
case TYPE_DRAWSEGMENT:
PlotDrawSegment( (DRAWSEGMENT*) PtStruct, PLOT_FORMAT_POST,
masque_layer );
break;
case TYPE_TEXTE:
PlotTextePcb( (TEXTE_PCB*) PtStruct, PLOT_FORMAT_POST,
masque_layer );
break;
case TYPE_COTATION:
PlotCotation( (COTATION*) PtStruct, PLOT_FORMAT_POST,
masque_layer );
break;
case TYPE_MIRE:
PlotMirePcb( (MIREPCB*) PtStruct, PLOT_FORMAT_POST,
masque_layer );
break;
case TYPE_MARKER:
break;
default:
DisplayError( this,
wxT( "WinEDA_BasePcbFrame::Plot_Layer_PS() : Unexpected Draw Type" ) );
break;
}
}
// Trace des Elements des modules autres que pads
Module = m_Pcb->m_Modules;
for( ; Module != NULL; Module = Module->Next() )
{
PtStruct = Module->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
{
switch( PtStruct->Type() )
{
case TYPE_EDGE_MODULE:
if( masque_layer & g_TabOneLayerMask[ PtStruct->GetLayer() ] )
Plot_1_EdgeModule( PLOT_FORMAT_POST, (EDGE_MODULE*) PtStruct );
break;
default:
break;
}
}
}
// Trace des Elements des modules : Pastilles
Module = m_Pcb->m_Modules;
for( ; Module != NULL; Module = Module->Next() )
{
PtPad = (D_PAD*) Module->m_Pads;
for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Next() )
{
if( (PtPad->m_Masque_Layer & masque_layer) == 0 )
continue;
wxPoint shape_pos = PtPad->ReturnShapePos();
pos = shape_pos;
size.x = PtPad->m_Size.x + garde * 2;
size.y = PtPad->m_Size.y + garde * 2;
switch( PtPad->m_PadShape )
{
case PAD_CIRCLE:
trace_1_pastille_RONDE_POST( pos, size.x, modetrace );
break;
case PAD_OVAL:
trace_1_pastille_OVALE_POST( pos, size, PtPad->m_Orient, modetrace );
break;
case PAD_TRAPEZOID:
{
wxSize delta;
delta = PtPad->m_DeltaSize;
trace_1_pad_TRAPEZE_POST( pos, size, delta,
PtPad->m_Orient, modetrace );
break;
}
case PAD_RECT:
default:
trace_1_pad_rectangulaire_POST( pos, size, PtPad->m_Orient, modetrace );
break;
}
}
}
// trace des VIAS :
if( tracevia )
{
for( pts = m_Pcb->m_Track; pts != NULL; pts = pts->Next() )
{
if( pts->Type() != TYPE_VIA )
continue;
SEGVIA* Via = (SEGVIA*) pts;
// vias not plotted if not on selected layer, but if layer
// == SOLDERMASK_LAYER_CU or SOLDERMASK_LAYER_CMP, vias are drawn,
// if they are on a external copper layer
int via_mask_layer = Via->ReturnMaskLayer();
if( via_mask_layer & CUIVRE_LAYER )
via_mask_layer |= SOLDERMASK_LAYER_CU;
if( via_mask_layer & CMP_LAYER )
via_mask_layer |= SOLDERMASK_LAYER_CMP;
if( (via_mask_layer & masque_layer) == 0 )
continue;
pos = Via->m_Start;
size.x = size.y = Via->m_Width + garde * 2;
trace_1_pastille_RONDE_POST( pos, size.x, modetrace );
}
}
// trace des pistes et zones:
for( pts = m_Pcb->m_Track; pts != NULL; pts = pts->Next() )
{
if( pts->Type() == TYPE_VIA )
continue;
if( (g_TabOneLayerMask[pts->GetLayer()] & masque_layer) == 0 )
continue;
size.x = size.y = pts->m_Width;
pos = pts->m_Start;
end = pts->m_End;
PlotFilledSegmentPS( pos, end, size.x );
}
for( pts = m_Pcb->m_Zone; pts != NULL; pts = pts->Next() )
{
if( (g_TabOneLayerMask[pts->GetLayer()] & masque_layer) == 0 )
continue;
size.x = size.y = pts->m_Width;
pos = pts->m_Start;
end = pts->m_End;
PlotFilledSegmentPS( pos, end, size.x );
}
/* Plot filled ares */
for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = m_Pcb->GetArea(ii);
if( ( (1 << edge_zone->GetLayer()) & masque_layer ) == 0 )
continue;
PlotFilledAreas(edge_zone, PLOT_FORMAT_POST);
}
// Trace des trous de percage
if( modetrace == FILLED )
PrintDrillMark( m_Pcb );
}
/*************************************/
static void PrintDrillMark( BOARD* Pcb )
/*************************************/
/* Draw a drill mark for pads and vias.
* Must be called after all drawings, because it
* redraw the drill mark on a pad or via, as a negative (i.e. white) shape
*/
{
const int SMALL_DRILL = 150;
wxPoint pos;
wxSize diam;
MODULE* Module;
D_PAD* PtPad;
TRACK* pts;
if( g_DrillShapeOpt == 0 )
return;
if( g_Plot_PS_Negative )
fprintf( dest, " 0 setgray\n" );
else
fprintf( dest, " 1 setgray\n" );
diam.x = diam.y = (g_DrillShapeOpt == DRILL_MARK) ? SMALL_DRILL :
g_DesignSettings.m_ViaDrill;
for( pts = Pcb->m_Track; pts != NULL; pts = pts->Next() )
{
if( pts->Type() != TYPE_VIA )
continue;
pos = pts->m_Start;
if( g_DrillShapeOpt == DRILL_MARK )
diam.x = diam.y = SMALL_DRILL;
else
diam.x = diam.y = pts->GetDrillValue();
trace_1_pastille_RONDE_POST( pos, diam.x, FILLED );
}
Module = Pcb->m_Modules;
for( ; Module != NULL; Module = Module->Next() )
{
PtPad = Module->m_Pads;
for( ; PtPad != NULL; PtPad = PtPad->Next() )
{
if( PtPad->m_Drill.x == 0 )
continue;
// Output hole shapes:
pos = PtPad->m_Pos;
if( PtPad->m_DrillShape == PAD_OVAL )
{
diam = PtPad->m_Drill;
trace_1_pastille_OVALE_POST( pos, diam, PtPad->m_Orient, FILLED );
}
else
{
diam.x = (g_DrillShapeOpt == DRILL_MARK) ? SMALL_DRILL :
PtPad->m_Drill.x;
trace_1_pastille_RONDE_POST( pos, diam.x, FILLED );
}
}
}
fprintf( dest, " 0 setgray\n" );
}
/***********************************************************************************/
void trace_1_pastille_OVALE_POST( wxPoint pos, wxSize size, int orient, int modetrace )
/************************************************************************************/
/* Trace 1 pastille PAD_OVAL en position pos_X,Y:
* dimensions dx,dy,
* orientation orient
* La forme est tracee comme un segment
*/
{
int x0, y0, x1, y1, delta;
int thickness, rayon;
// la pastille est ramenee a une pastille ovale avec dy > dx
if( size.x > size.y )
{
EXCHG( size.x, size.y );
orient += 900;
if( orient >= 3600 )
orient -= 3600;
}
delta = size.y - size.x;
x0 = 0;
y0 = -delta / 2;
x1 = 0;
y1 = delta / 2;
RotatePoint( &x0, &y0, orient );
RotatePoint( &x1, &y1, orient );
if( modetrace == FILLED )
{
PlotFilledSegmentPS( wxPoint( pos.x + x0, pos.y + y0 ),
wxPoint( pos.x + x1, pos.y + y1 ), size.x );
}
else
{
thickness = g_PlotLine_Width;
rayon = (size.x - thickness) / 2;
if( rayon < 1 )
rayon = 1;
if( rayon < thickness )
thickness = rayon;
PlotArcPS( wxPoint( pos.x + x1, pos.y + y1 ), -orient, -orient + 1800, rayon, false, thickness);
PlotArcPS( wxPoint( pos.x + x0, pos.y + y0 ), -orient + 1800, -orient, rayon, false, thickness );
x0 = -rayon;
y0 = -delta / 2;
x1 = -rayon;
y1 = delta / 2;
RotatePoint( &x0, &y0, orient );
RotatePoint( &x1, &y1, orient );
PlotFilledSegmentPS( wxPoint( pos.x + x0, pos.y + y0 ),
wxPoint( pos.x + x1, pos.y + y1 ), thickness );
x0 = rayon;
y0 = -delta / 2;
x1 = rayon;
y1 = delta / 2;
RotatePoint( &x0, &y0, orient );
RotatePoint( &x1, &y1, orient );
PlotFilledSegmentPS( wxPoint( pos.x + x0, pos.y + y0 ),
wxPoint( pos.x + x1, pos.y + y1 ), thickness );
}
}
/*******************************************************************************/
void trace_1_pastille_RONDE_POST( wxPoint centre, int diametre, int modetrace )
/*******************************************************************************/
/* Trace 1 pastille RONDE (via,pad rond) en position pos_X,Y
*/
{
int rayon, w;
wxSize diam( diametre, diametre );
UserToDeviceCoordinate( centre );
UserToDeviceSize( diam );
if( modetrace == FILLED )
{
SetCurrentLineWidthPS( 0 );
rayon = diam.x / 2;
if( rayon < 1 )
rayon = 1;
fprintf( dest, "%d %d %d cir1\n",
centre.x, centre.y, rayon );
}
else
{
w = g_PlotLine_Width;
rayon = (diam.x - w) / 2;
if( rayon < 1 )
rayon = 1;
if( rayon < w )
w = rayon;
SetCurrentLineWidthPS( w );
fprintf( dest, "%d %d %d cir0\n",
centre.x, centre.y, rayon );
}
}
/**************************************************************************/
void trace_1_pad_rectangulaire_POST( wxPoint centre,
wxSize size, int orient, int modetrace )
/**************************************************************************/
/*
* Trace 1 pad rectangulaire d'orientation quelconque
* donne par son centre, ses dimensions,
* et son orientation orient
*/
{
int x0, y0, x1, y1, w;
if( modetrace == FILLED )
{
x0 = centre.x - size.x / 2;
x1 = centre.x + size.x / 2;
y0 = y1 = centre.y;
w = size.y;
RotatePoint( &x0, &y0, centre.x, centre.y, orient );
RotatePoint( &x1, &y1, centre.x, centre.y, orient );
fprintf( dest, "linemode0 " );
ForcePenReinit(); // Force init line width for PlotFilledSegmentPS
PlotFilledSegmentPS( wxPoint( x0, y0 ), wxPoint( x1, y1 ), w );
ForcePenReinit();
fprintf( dest, "linemode1 " );
SetCurrentLineWidthPS( 0 ); // Force init line width to default
}
else
{
w = g_PlotLine_Width;
size.x -= w;
if( size.x < 1 )
size.x = 1;
size.y -= w;
if( size.y < 1 )
size.y = 1;
trace_1_contour_POST( centre, size, wxSize( 0, 0 ), w, orient );
}
if( g_pcb_plot_options.Plot_PS_Negative )
{
int margin = 500; // Add a 0.5 inch margin around the board
plotter->set_negative(true);
plotter->set_color( WHITE ); // Which will be plotted as black
plotter->rect(wxPoint(m_Pcb->m_BoundaryBox.GetX() - margin,
m_Pcb->m_BoundaryBox.GetY() - margin),
wxPoint(m_Pcb->m_BoundaryBox.GetRight() + margin,
m_Pcb->m_BoundaryBox.GetBottom() + margin),
FILLED_SHAPE);
plotter->set_color( BLACK );
}
Plot_Layer(plotter, Layer, trace_mode);
plotter->end_plot();
delete plotter;
SetLocaleTo_Default();
}
/**************************************************************/
void trace_1_contour_POST( wxPoint centre, wxSize size, wxSize delta,
int dim_trait, int orient )
/**************************************************************/
/*
* Trace 1 contour rectangulaire ou trapezoidal d'orientation quelconque
* donne par son centre centre,
* ses dimensions size,
* ses variations delta
* epaisseur de trait dim_trait
* et son orientation orient (en 0.1 degres)
*/
{
int ii;
int dx, dy, lpen;
int ddx, ddy;
wxPoint coord[4];
lpen = dim_trait;
dx = size.x / 2;
dy = size.y / 2;
ddx = delta.x >> 1;
ddy = delta.y >> 1; // demi dim dx et dy
coord[0].x = centre.x - dx - ddy;
coord[0].y = centre.y + dy + ddx;
coord[1].x = centre.x - dx + ddy;
coord[1].y = centre.y - dy - ddx;
coord[2].x = centre.x + dx - ddy;
coord[2].y = centre.y - dy + ddx;
coord[3].x = centre.x + dx + ddy;
coord[3].y = centre.y + dy - ddx;
for( ii = 0; ii < 4; ii++ )
{
RotatePoint( &coord[ii], centre, orient );
}
PlotFilledSegmentPS( coord[0], coord[1], lpen );
PlotFilledSegmentPS( coord[1], coord[2], lpen );
PlotFilledSegmentPS( coord[2], coord[3], lpen );
PlotFilledSegmentPS( coord[3], coord[0], lpen );
}
/*******************************************************************/
void trace_1_pad_TRAPEZE_POST( wxPoint centre, wxSize size, wxSize delta,
int orient, int modetrace )
/*******************************************************************/
/*
* Trace 1 pad trapezoidal donne par :
* son centre centre
* ses dimensions size
* les variations delta ( 1 des deux au moins doit etre nulle)
* son orientation orient en 0.1 degres
* le mode de trace (FILLED, SKETCH, FILAIRE)
*
* Le trace n'est fait que pour un trapeze, c.a.d que deltaX ou deltaY
* = 0.
*
* les notation des sommets sont ( vis a vis de la table tracante )
*
* " 0 ------------- 3 "
* " . . "
* " . O . "
* " . . "
* " 1 ---- 2 "
*
*
* exemple de Disposition pour deltaY > 0, deltaX = 0
* " 1 ---- 2 "
* " . . "
* " . O . "
* " . . "
* " 0 ------------- 3 "
*
*
* exemple de Disposition pour deltaY = 0, deltaX > 0
* " 0 "
* " . . "
* " . . "
* " . 3 "
* " . . "
* " . O . "
* " . . "
* " . 2 "
* " . . "
* " . . "
* " 1 "
*/
{
int ii;
int dx, dy;
wxPoint polygone[4]; // coord des sommets / centre du pad
int ddx, ddy;
int l_pen; // diam spot (plume)
l_pen = 1;
if( modetrace == FILAIRE || g_Plot_Mode == FILAIRE )
{
wxSize lsize( g_PlotLine_Width, g_PlotLine_Width );
UserToDeviceSize( lsize );
l_pen = lsize.x;
}
dx = size.x / 2;
dy = size.y / 2;
ddx = delta.x / 2;
ddy = delta.y / 2;
polygone[0].x = -dx - ddy;
polygone[0].y = +dy + ddx;
polygone[1].x = -dx + ddy;
polygone[1].y = -dy - ddx;
polygone[2].x = +dx - ddy;
polygone[2].y = -dy + ddx;
polygone[3].x = +dx + ddy;
polygone[3].y = +dy - ddx;
for( ii = 0; ii < 4; ii++ )
{
RotatePoint( &polygone[ii].x, &polygone[ii].y, orient );
polygone[ii].x += centre.x;
polygone[ii].y += centre.y;
}
SetCurrentLineWidthPS( l_pen );
UserToDeviceCoordinate( polygone[0] );
fprintf( dest, "newpath %d %d moveto\n", polygone[0].x, polygone[0].y );
for( ii = 1; ii < 4; ii++ )
{
UserToDeviceCoordinate( polygone[ii] );
fprintf( dest, "%d %d lineto\n", polygone[ii].x, polygone[ii].y );
}
fprintf( dest, "%d %d lineto ", polygone[0].x, polygone[0].y );
fprintf( dest, "poly%d\n", (modetrace == FILLED?1:0) );
}
......@@ -147,7 +147,7 @@ void WinEDA_DrawPanel::PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintMa
GRForceBlackPen( blackpenstate );
if( aPrint_Sheet_Ref )
m_Parent->TraceWorkSheet( aDC, GetScreen(), g_PlotLine_Width );
m_Parent->TraceWorkSheet( aDC, GetScreen(), 10 );
m_PrintIsMirrored = false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment