diff --git a/common/base_struct.cpp b/common/base_struct.cpp index 59a8cca33f..f51da95579 100644 --- a/common/base_struct.cpp +++ b/common/base_struct.cpp @@ -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; diff --git a/common/common_plotGERBER_functions.cpp b/common/common_plotGERBER_functions.cpp index 5bc309ffe3..b3ff4b163a 100644 --- a/common/common_plotGERBER_functions.cpp +++ b/common/common_plotGERBER_functions.cpp @@ -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; -/**********************************************/ -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 ) + 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; + + + // 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 */ { - static wxPoint LastPoint; - switch ( aCommand ) + 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 + */ +{ + 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::iterator Gerber_Plotter::get_aperture(const wxSize &size, + Aperture::Aperture_Type type) +/******************************************************/ +{ + int last_D_code = 9; + // Search an existing aperture + vector::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::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 */ + wxASSERT(output_file); + wxPoint start,end; + double aRadius = diametre / 2; + const int delta = 3600/32; /* increment (in 0.1 degrees) to draw circles */ - delta = 3600/32; /* there are delta segments for draw a circle */ - - 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 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) -*/ +void Gerber_Plotter::flash_pad_circle(wxPoint pos, int diametre, + GRTraceMode trace_mode) +/* Plot a circular pad or via at the user position pos + */ { - wxPoint start, end, startpoint; - startpoint.x = *aCoord++; - startpoint.y = *aCoord++; - start = startpoint; - for( int ii = 0; ii < aCornersCount-1; ii++ ) + wxASSERT(output_file); + wxSize size( diametre, diametre ); + + switch (trace_mode) { - end.x = *aCoord; - aCoord++; - end.y = *aCoord; - aCoord++; - PlotGERBERLine(start, end, aWidth ); - start = end; + 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; } - - if ( startpoint != end ) // Close poly - PlotGERBERLine(end, startpoint, aWidth ); - } +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 + */ +{ + 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 */ + { + 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 ); + + // 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 ); +} diff --git a/common/common_plotHPGL_functions.cpp b/common/common_plotHPGL_functions.cpp index 2007c350b2..e088162ee7 100644 --- a/common/common_plotHPGL_functions.cpp +++ b/common/common_plotHPGL_functions.cpp @@ -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 PlotRectHPGL( wxPoint p1, wxPoint p2, bool fill, int width ) +void HPGL_Plotter::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width ) /************************************************************/ { - char Line[256]; - - UserToDeviceCoordinate( p1 ); - UserToDeviceCoordinate( p2 ); - - 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 ); - - Plume_HPGL( 'U' ); return; + 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 PlotCircleHPGL( wxPoint centre, int diameter, bool fill, int width ) +void HPGL_Plotter::circle( wxPoint centre, int diameter, FILL_T fill, int width ) /************************************************************/ { - int rayon; - char Line[256]; + wxASSERT(output_file); + double rayon = user_to_device_size(diameter / 2); - UserToDeviceCoordinate( centre ); - rayon = (int) (diameter / 2 * g_Plot_XScale); - - if( rayon < 0 ) - rayon = 0; - - Plume_HPGL( 'U' ); - sprintf( Line, "PA %d,%d;CI %d,%d;\n", centre.x, centre.y, rayon, CHORD_ANGLE ); - fputs( Line, g_Plot_PlotOutputFile ); - - Plume_HPGL( 'U' ); return; + if( rayon > 0 ) + { + move_to(centre); + fprintf( output_file, "CI %g;\n", rayon); + pen_finish(); + } } +/*****************************************************/ +void HPGL_Plotter::poly( int nb, int* coord, FILL_T fill, int width ) +/*****************************************************/ + +/* 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 ) +/***************************/ + +/* leve (plume = 'U') ou baisse (plume = 'D') la plume + */ +{ + 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; + } +} + +/**********************************************/ +void HPGL_Plotter::pen_to( wxPoint pos, char plume ) +/**********************************************/ + +/* + * 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 ); + + if (pen_lastpos != pos) + fprintf( output_file, "PA %d,%d;\n", pos.x, pos.y ); + pen_lastpos = pos; +} + +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 ); + cmap.y = (int) ( centre.y - ( rayon * sin( StAngle * M_PI / 1800 ) ) ); + user_to_device_coordinates( 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' ); + 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 PlotPolyHPGL( int nb, int* coord, bool fill, int width ) -/*****************************************************/ - -/* 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_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 */ { - int ii; + wxASSERT(output_file); + int rayon, deltaxy, cx, cy; - if( nb <= 1 ) - return; - - Move_Plume_HPGL( wxPoint( coord[0], coord[1] ), 'U' ); - for( ii = 1; ii < nb; ii++ ) + /* la pastille est ramenee a une pastille ovale avec size.y > size.x + * ( ovale vertical en orientation 0 ) */ + if( size.x > size.y ) { - Move_Plume_HPGL( wxPoint( coord[ii * 2], coord[(ii * 2) + 1] ), 'D' ); + EXCHG( size.x, size.y ); orient += 900; + if( orient >= 3600 ) + orient -= 3600; } - - /* Fermeture eventuelle du polygone */ - if( fill ) + deltaxy = size.y - size.x; /* = distance entre centres de l'ovale */ + rayon = size.x / 2; + if( trace_mode == FILLED ) { - ii = (nb - 1) * 2; - if( (coord[ii] != coord[0] ) || (coord[ii + 1] != coord[0]) ) - Move_Plume_HPGL( wxPoint( coord[0], coord[1] ), 'D' ); + 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); } - Plume_HPGL( 'U' ); } +/*******************************************************************************/ +void HPGL_Plotter::flash_pad_circle(wxPoint pos, int diametre, + GRTraceMode trace_mode) +/*******************************************************************************/ +/* Trace 1 pastille RONDE (via,pad rond) en position pos */ +{ + wxASSERT(output_file); + int rayon, delta; -/**********************************************/ -void Move_Plume_HPGL( wxPoint pos, int plume ) -/**********************************************/ + user_to_device_coordinates( pos ); + delta = pen_diameter - pen_overlap; + rayon = diametre / 2; + if( trace_mode != FILAIRE ) + { + rayon = (diametre - pen_diameter ) / 2; + } + + if( rayon < 0 ) + { + rayon = 0; + } + wxSize rsize( rayon, rayon ); + + user_to_device_size( rsize ); + + 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 ) ); + + 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 ) ); + + 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 Plume_HPGL( int plume ) -/***************************/ - -/* leve (plume = 'U') ou baisse (plume = 'D') la plume +/*******************************************************************/ +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] ); + } } } + diff --git a/common/common_plotPS_functions.cpp b/common/common_plotPS_functions.cpp index 3e8cfe8758..c3e76b3240 100644 --- a/common/common_plotPS_functions.cpp +++ b/common/common_plotPS_functions.cpp @@ -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", output_file ); // Print header - fputs( "%!PS-Adobe-3.0\n", g_Plot_PlotOutputFile ); // 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 ); + 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" ); - 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 ); - - // 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 ) ); + 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 ) ); - 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 ); + 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 ) ); - if( PaperOrientation == wxPORTRAIT ) - sprintf( Line, "%%%%Orientation: Portrait\n" ); - else - sprintf( Line, "%%%%Orientation: Landscape\n" ); + fprintf( output_file, "%%%%Orientation: Landscape\n" ); - fputs( Line, g_Plot_PlotOutputFile ); - - sprintf( Line, "%%%%EndComments\n" ); - fputs( Line, g_Plot_PlotOutputFile ); + 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 généré 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 ); - - fclose( plot_file ); - - return TRUE; + 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; + + // 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 + }; + + 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); } diff --git a/common/common_plot_functions.cpp b/common/common_plot_functions.cpp index 0b436445a1..574ae6468a 100644 --- a/common/common_plot_functions.cpp +++ b/common/common_plot_functions.cpp @@ -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 - - switch( format_plot ) - { - case PLOT_FORMAT_HPGL: - Plume_HPGL( 'U' ); - break; - - case PLOT_FORMAT_POST: - break; - } } - /******************************************/ -void UserToDeviceCoordinate( wxPoint& pos ) +void Plotter::user_to_device_coordinates( wxPoint& pos ) /******************************************/ /* 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 * g_Plot_XScale); - pos.y = (int) (pos.y * g_Plot_YScale); + 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); +} - switch( g_Plot_PlotOrientOptions ) /* Calcul du cadrage */ +/********************************************************************/ +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 ) { - default: - pos.x -= g_Plot_PlotOffset.x; pos.y = g_Plot_PlotOffset.y - pos.y; + 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); + } + + 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 Plotter::marker( const wxPoint& position, int diametre, int aShapeId) +/************************************************************************************/ + +/* 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; + + int x0, y0; + + 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 PLOT_MIROIR: - pos.x -= g_Plot_PlotOffset.x; pos.y = -g_Plot_PlotOffset.y + pos.y; + 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: + circle(position, diametre, NO_FILL); break; } } - -/************************************/ -void UserToDeviceSize( wxSize& size ) -/************************************/ -/* modifie les dimension size.x et size.y pour le trace selon l'echelle */ +/***************************************************************/ +void Plotter::segment_as_oval( wxPoint start, wxPoint end, int width, + GRTraceMode tracemode) +/***************************************************************/ { - size.x = (int) (size.x * g_Plot_XScale); - size.y = (int) (size.y * g_Plot_YScale); + /* 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 Plotter::thick_rect( wxPoint p1, wxPoint p2, int width, + GRTraceMode tracemode) +{ + 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; +} + diff --git a/common/drawtxt.cpp b/common/drawtxt.cpp index bdcc8eec88..91d99c0aec 100644 --- a/common/drawtxt.cpp +++ b/common/drawtxt.cpp @@ -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( ¤t_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; + set_current_line_width( aWidth ); - case PLOT_FORMAT_HPGL: - MovePenFct = Move_Plume_HPGL; - break; - case PLOT_FORMAT_GERBER: - MovePenFct = LineTo_GERBER; - /* Gerber tool has to be set outside... */ - break; + if( aColor >= 0 ) + set_color( aColor ); - default: - return; - } - - if( aColor >= 0 && IsPostScript( aFormat_plot ) ) - SetColorMapPS( 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 ); } diff --git a/eeschema/class_pin.cpp b/eeschema/class_pin.cpp index 6e639c5d16..bd0c70be66 100644 --- a/eeschema/class_pin.cpp +++ b/eeschema/class_pin.cpp @@ -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, diff --git a/eeschema/classes_body_items.h b/eeschema/classes_body_items.h index d34f07a7e7..e3a91bbf38 100644 --- a/eeschema/classes_body_items.h +++ b/eeschema/classes_body_items.h @@ -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, diff --git a/eeschema/eeconfig.cpp b/eeschema/eeconfig.cpp index 70a5b4cc9a..b9d078bd55 100644 --- a/eeschema/eeconfig.cpp +++ b/eeschema/eeconfig.cpp @@ -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; } diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index d21823e2f7..26d7f3bc99 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -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; diff --git a/eeschema/general.h b/eeschema/general.h index ee1f35d022..4956d9f942 100644 --- a/eeschema/general.h +++ b/eeschema/general.h @@ -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 { diff --git a/eeschema/plot.cpp b/eeschema/plot.cpp index 97295bcff4..4601b42523 100644 --- a/eeschema/plot.cpp +++ b/eeschema/plot.cpp @@ -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; iCount(); 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 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(); + } +} + diff --git a/eeschema/plothpgl.cpp b/eeschema/plothpgl.cpp index 0090570889..ed525850a5 100644 --- a/eeschema/plothpgl.cpp +++ b/eeschema/plothpgl.cpp @@ -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 ); + 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 ); - m_Parent->PlotWorkSheet( PLOT_FORMAT_HPGL, screen ); + plotter->set_color( BLACK ); + m_Parent->PlotWorkSheet( plotter, 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; - } - - 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; - - 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 diff --git a/eeschema/plothpgl.h b/eeschema/plothpgl.h index ff3ec85b98..0c51f31f07 100644 --- a/eeschema/plothpgl.h +++ b/eeschema/plothpgl.h @@ -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(); diff --git a/eeschema/plotps.cpp b/eeschema/plotps.cpp index 9ec47c1241..5fd76c15e0 100644 --- a/eeschema/plotps.cpp +++ b/eeschema/plotps.cpp @@ -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; - RealSheet = &g_Sheet_A4; - - if( pagesize == PAGE_SIZE_AUTO ) - RealSheet = PlotSheet; - else if( pagesize == PAGE_SIZE_A ) + switch (pagesize) + { + case PAGE_SIZE_A: RealSheet = &g_Sheet_A; + break; + case PAGE_SIZE_A4: + RealSheet = &g_Sheet_A4; + break; + case PAGE_SIZE_AUTO: + default: + RealSheet = PlotSheet; + 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; + wxString msg; - PlotOutput = wxFopen( FileName, wxT( "wt" ) ); - if( PlotOutput == NULL ) + 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 ); + plotter->set_creator(wxT("EESchema-PS")); + plotter->set_filename(FileName); + plotter->start_plot(output_file); - 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; - - 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" ) ); diff --git a/eeschema/plotps.h b/eeschema/plotps.h index ec933a0757..39e850d3fd 100644 --- a/eeschema/plotps.h +++ b/eeschema/plotps.h @@ -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 diff --git a/eeschema/protos.h b/eeschema/protos.h index de6134a493..1dae9e7bc7 100644 --- a/eeschema/protos.h +++ b/eeschema/protos.h @@ -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 */ diff --git a/gerbview/gerbview_config.h b/gerbview/gerbview_config.h index 3e8af5b95d..c3e676deb4 100644 --- a/gerbview/gerbview_config.h +++ b/gerbview/gerbview_config.h @@ -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 */ diff --git a/gerbview/pcbplot.cpp b/gerbview/pcbplot.cpp index d855207904..df3e330511 100644 --- a/gerbview/pcbplot.cpp +++ b/gerbview/pcbplot.cpp @@ -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) -{ -} - diff --git a/gerbview/pcbplot.h b/gerbview/pcbplot.h index ce4d727aa2..5979badb45 100644 --- a/gerbview/pcbplot.h +++ b/gerbview/pcbplot.h @@ -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 diff --git a/include/base_struct.h b/include/base_struct.h index d4ae10692c..23fd0dc46b 100644 --- a/include/base_struct.h +++ b/include/base_struct.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: diff --git a/include/drawtxt.h b/include/drawtxt.h index 30567e6988..22d5269e23 100644 --- a/include/drawtxt.h +++ b/include/drawtxt.h @@ -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__ */ diff --git a/include/pcbcommon.h b/include/pcbcommon.h index 7cd1a63e90..258f59ce70 100644 --- a/include/pcbcommon.h +++ b/include/pcbcommon.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__ */ diff --git a/include/plot_common.h b/include/plot_common.h index 260a9caf05..e5a339914d 100644 --- a/include/plot_common.h +++ b/include/plot_common.h @@ -1,193 +1,384 @@ /** * 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 +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 }; - -static inline bool IsPostScript( int aFormat ) -{ - return aFormat == PLOT_FORMAT_POST; -} - - const int PLOT_MIROIR = 1; -// 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; +class Plotter +{ +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; + } -/*******************************/ -/* 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 + virtual ~Plotter() + { + /* Emergency cleanup */ + if( output_file ) + { + fclose( output_file ); + } + } -/*******************************/ -/* 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 ); + virtual void start_plot( FILE* fout ) = 0; + virtual void end_plot() = 0; -// 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 ); + virtual void set_negative( bool _negative ) + { + negative_mode = _negative; + } -/*********************************/ -/* 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 ); + virtual void set_color_mode( bool _color_mode ) + { + color_mode = _color_mode; + } -void PlotPolyHPGL( int nb, - int* coord, - bool fill, - int width = -1 ); -void Move_Plume_HPGL( wxPoint pos, - int plume ); -void Plume_HPGL( int plume ); + bool get_color_mode() const + { + return color_mode; + } -/*********************************/ -/* 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 ); + 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; -/** 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 ); + virtual void set_creator( const wxString& _creator ) + { + creator = _creator; + } -/** 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 ); + virtual void set_filename( const wxString& _filename ) + { + filename = _filename; + } -/** 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 ); + 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::iterator get_aperture( const wxSize& size, + Aperture::Aperture_Type type ); + + FILE* work_file, * final_file; + void write_aperture_list(); + + vector apertures; + vector::iterator current_aperture; +}; #endif /* __INCLUDE__PLOT_COMMON_H__ */ - diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 10bf7e695a..54f912f870 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.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 ); diff --git a/include/wxstruct.h b/include/wxstruct.h index e8ba012956..85bca2267f 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -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 diff --git a/pcbnew/class_pcb_text.cpp b/pcbnew/class_pcb_text.cpp index 889427b00a..bd1c88a270 100644 --- a/pcbnew/class_pcb_text.cpp +++ b/pcbnew/class_pcb_text.cpp @@ -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; diff --git a/pcbnew/dialog_gendrill.cpp b/pcbnew/dialog_gendrill.cpp index 3f2df9519a..5e6b24be24 100644 --- a/pcbnew/dialog_gendrill.cpp +++ b/pcbnew/dialog_gendrill.cpp @@ -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")); diff --git a/pcbnew/dialog_gendrill.h b/pcbnew/dialog_gendrill.h index 6c0805e842..ecccd3d275 100644 --- a/pcbnew/dialog_gendrill.h +++ b/pcbnew/dialog_gendrill.h @@ -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 & aHoleListBuffer, + int Create_Drill_File_EXCELLON(FILE *excellon_dest, + std::vector & aHoleListBuffer, std::vector & aToolListBuffer ); int Gen_Liste_Tools( std::vector & buffer, bool print_header ); }; diff --git a/pcbnew/dialog_print_using_printer.cpp b/pcbnew/dialog_print_using_printer.cpp index acddfded79..b0d1cf093b 100644 --- a/pcbnew/dialog_print_using_printer.cpp +++ b/pcbnew/dialog_print_using_printer.cpp @@ -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; } diff --git a/pcbnew/gen_drill_report_files.cpp b/pcbnew/gen_drill_report_files.cpp index 4763959471..81468a02f1 100644 --- a/pcbnew/gen_drill_report_files.cpp +++ b/pcbnew/gen_drill_report_files.cpp @@ -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 aHoleListBuffer, std::vector 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; + /* Keep size for drill legend */ + double Xscale = (double) ( SheetSize.x * 0.8 ) / dX; + double Yscale = (double) ( SheetSize.y * 0.6 ) / dY; - scale_x = scale_y = MIN( Xscale, Yscale ); + scale = 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 */ + 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; + plotY += intervalle; + 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; - - 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); + 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; - - case PLOT_FORMAT_POST: - CloseFilePS( aFile ); - break; + intervalle = (int) (CharSize * CharScale) + TextWidth; + intervalle = (int) ( intervalle * 1.2); + + 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& aHoleListBuffer, - std::vector& aToolListBuffer, - int format ) + std::vector& aToolListBuffer) /****************************************************************************************/ /** Creates the drill map aFile in HPGL or POSTSCRIPT format * @param aPcb BOARD - * @param aFile = output aFile * @param aHoleListBuffer = std::vector list of holes descriptors * @param aToolListBuffer = std::vector 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. diff --git a/pcbnew/gendrill.cpp b/pcbnew/gendrill.cpp index 0770e73dcb..24f9c51814 100644 --- a/pcbnew/gendrill.cpp +++ b/pcbnew/gendrill.cpp @@ -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( <mp ) ) - g_HPGL_Pen_Speed = ltmp; + g_pcb_plot_options.HPGL_Pen_Speed = ltmp; msg = m_PenNum->GetValue(); if( msg.ToLong( <mp ) ) - 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& aHoleListBuffer, +int WinEDA_DrillFrame::Create_Drill_File_EXCELLON(FILE *excellon_dest, + std::vector& aHoleListBuffer, std::vector& aToolListBuffer ) /**********************************************************************************/ @@ -421,7 +427,7 @@ int WinEDA_DrillFrame::Create_Drill_File_EXCELLON( std::vector& 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& 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& 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& 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& 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& 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, diff --git a/pcbnew/gendrill.h b/pcbnew/gendrill.h index 669237045a..09177f213a 100644 --- a/pcbnew/gendrill.h +++ b/pcbnew/gendrill.h @@ -79,16 +79,15 @@ void Build_Holes_List( BOARD* Pcb, std::vector& aHoleListBuffer, void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, - wxSize aSheetSize, + Ki_PageDescr *aSheet, std::vector aHoleListBuffer, std::vector 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& aHoleListBuffer, - std::vector& aToolListBuffer, - int format ); + std::vector& aToolListBuffer); /* * Create a list of drill values and drill count diff --git a/pcbnew/graphpcb.cpp b/pcbnew/graphpcb.cpp index 325b56dc74..135a8470bd 100644 --- a/pcbnew/graphpcb.cpp +++ b/pcbnew/graphpcb.cpp @@ -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 ) diff --git a/pcbnew/pcbcfg.h b/pcbnew/pcbcfg.h index a83eda8df0..35e5fa9a7d 100644 --- a/pcbnew/pcbcfg.h +++ b/pcbnew/pcbcfg.h @@ -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, diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index c2575ade58..2d79dfa4ca 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -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" ) ); diff --git a/pcbnew/pcbplot.cpp b/pcbnew/pcbplot.cpp index a13a6e0401..c2c28d47d1 100644 --- a/pcbnew/pcbplot.cpp +++ b/pcbnew/pcbplot.cpp @@ -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; layerGetValue(); + 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; } } diff --git a/pcbnew/pcbplot.h b/pcbnew/pcbplot.h index fab4b4ccbc..0c9b5f10fb 100644 --- a/pcbnew/pcbplot.h +++ b/pcbnew/pcbplot.h @@ -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 +/* 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 */ -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 + /* 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 */ + /* 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 FILE * dest; - -/* id for plot format (see enum PlotFormat in plot_common.h) */ -extern int g_PlotScaleOpt; -extern int g_DrillShapeOpt; +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 */ diff --git a/pcbnew/plot_rtn.cpp b/pcbnew/plot_rtn.cpp index 8b3ce0c55a..8951311d15 100644 --- a/pcbnew/plot_rtn.cpp +++ b/pcbnew/plot_rtn.cpp @@ -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; iCount(); 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; iithick_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 */ -{ - switch( format_plot ) - { - case PLOT_FORMAT_GERBER: - SelectD_CODE_For_LineDraw( thickness ); - PlotCircle_GERBER( centre, radius, thickness ); - break; - - case PLOT_FORMAT_HPGL: - trace_1_pastille_RONDE_HPGL( centre, radius * 2, FILAIRE ); - break; - - case PLOT_FORMAT_POST: - PlotCirclePS( centre, radius * 2, false, thickness ); - break; - } -} - - -/**********************************************************************/ -void PlotFilledPolygon( int format_plot, int nbpoints, int* coord ) -/**********************************************************************/ -/* plot a polygon */ -{ - switch( format_plot ) - { - case PLOT_FORMAT_GERBER: - PlotFilledPolygon_GERBER( nbpoints, coord ); - break; - - case PLOT_FORMAT_HPGL: - PlotPolyHPGL( nbpoints, coord, true ); - break; - - case PLOT_FORMAT_POST: - PlotPolyPS( nbpoints, coord, true ); - break; - } -} - - -/**********************************************************************/ -void PlotPolygon( int format_plot, int nbpoints, int* coord, int width ) -/**********************************************************************/ - -/* plot a non filled polygon +/* 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( width ); - PlotPolygon_GERBER( nbpoints, coord, width ); + switch( item->Type() ) + { + case TYPE_DRAWSEGMENT: + PlotDrawSegment(plotter, (DRAWSEGMENT*) item, masque_layer, 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++ ) - { - end.x = *coord++; - end.y = *coord++; - Plot_Filled_Segment_HPGL( start, end, width, (GRFillMode) g_Plot_Mode ); - start = end; - } + case TYPE_TEXTE: + PlotTextePcb(plotter, (TEXTE_PCB*) item, masque_layer, trace_mode ); + break; + + case TYPE_COTATION: + PlotCotation(plotter, (COTATION*) item, masque_layer, trace_mode ); + break; + + case TYPE_MIRE: + PlotMirePcb(plotter, (MIREPCB*) item, masque_layer, trace_mode ); + break; + + case TYPE_MARKER: + break; + + 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; + + 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: + plotter->flash_pad_circle(pos, size.x, trace_mode); + break; + + case PAD_OVAL: + plotter->flash_pad_oval(pos, size, pad->m_Orient, + trace_mode); + break; + + case PAD_TRAPEZOID: + { + 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; + + 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; + + plotter->flash_pad_circle(pos, size.x, trace_mode ); + } + } + + /* 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; + + plotter->thick_segment( pos, end, size.x, trace_mode ); + } + + /* 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; + + plotter->thick_segment( pos, end, size.x, trace_mode ); + } + + /* 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 ); + } } -/************************************************************************/ -void PlotArc( int format_plot, wxPoint centre, int start_angle, int end_angle, - int radius, int thickness ) -/************************************************************************/ +/*************************************/ +void WinEDA_BasePcbFrame::PlotDrillMark(Plotter *plotter, GRTraceMode trace_mode ) +/*************************************/ -/* Polt 1 arc - * start, end = angles in 1/10 degree for start and stop point +/* 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 */ { - int ii; - int ox, oy, fx, fy; - int delta; /* increment (en 0.1 degres) angulaire pour trace de cercles */ + const int SMALL_DRILL = 150; + wxPoint pos; + wxSize diam; + MODULE* Module; + D_PAD* PtPad; + TRACK* pts; - if( g_Plot_Mode == FILAIRE ) - thickness = g_PlotLine_Width; - - if( IsPostScript( format_plot ) ) - { - PlotArcPS( centre, start_angle, end_angle, radius, false, thickness ); + if( g_pcb_plot_options.DrillShapeOpt == PCB_Plot_Options::NO_DRILL_SHAPE ) return; + + if (trace_mode == FILLED) { + plotter->set_color(WHITE); } - // 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 */ - - if( start_angle > end_angle ) - end_angle += 3600; - - ox = radius; - oy = 0; - - RotatePoint( &ox, &oy, start_angle ); - - if( format_plot == PLOT_FORMAT_GERBER ) - SelectD_CODE_For_LineDraw( thickness ); - - delta = 120; /* un cercle sera trace en 3600/delta = 30 segments / cercle*/ - for( ii = start_angle + delta; ii < end_angle; ii += delta ) + for( pts = m_Pcb->m_Track; pts != NULL; pts = pts->Next() ) { - fx = radius; - fy = 0; + 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, ii ); + plotter->flash_pad_circle( pos, diam.x, trace_mode ); + } - switch( format_plot ) + for( Module = m_Pcb->m_Modules; + Module != NULL; + Module = Module->Next() ) + { + + for(PtPad = Module->m_Pads; + PtPad != NULL; + PtPad = PtPad->Next() ) { - case PLOT_FORMAT_GERBER: - PlotGERBERLine( wxPoint( centre.x + ox, centre.y + oy ), - wxPoint( centre.x + fx, centre.y + fy ), thickness ); - break; + if( PtPad->m_Drill.x == 0 ) + continue; - 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; - - 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); + } } - - ox = fx; - oy = fy; } - - fx = radius; - fy = 0; - - RotatePoint( &fx, &fy, end_angle ); - - switch( format_plot ) - { - 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; - - case PLOT_FORMAT_POST: - break; + + if (trace_mode == FILLED) { + plotter->set_color(BLACK); } } diff --git a/pcbnew/plotgerb.cpp b/pcbnew/plotgerb.cpp index 6ceaa96b82..9eafbf29af 100644 --- a/pcbnew/plotgerb.cpp +++ b/pcbnew/plotgerb.cpp @@ -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; + 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); - 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; - - 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 ); -} diff --git a/pcbnew/plothpgl.cpp b/pcbnew/plothpgl.cpp index 3f56faccd1..d583a767d1 100644 --- a/pcbnew/plothpgl.cpp +++ b/pcbnew/plothpgl.cpp @@ -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; + offset.x = 0; + offset.y = 0; } - /* fin */ - CloseFileHPGL( dest ); + 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' ); -} diff --git a/pcbnew/plotps.cpp b/pcbnew/plotps.cpp index bb580cc6b1..d33ed7e180 100644 --- a/pcbnew/plotps.cpp +++ b/pcbnew/plotps.cpp @@ -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; + PaperSize = SheetSize; + paperscale = 1; } - // 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; - } - - // 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 ) + if( g_pcb_plot_options.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 ); + 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 ); } - // 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( ); + Plot_Layer(plotter, Layer, trace_mode); + plotter->end_plot(); + delete plotter; + 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 ); - } -} - - -/**************************************************************/ -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) ); -} diff --git a/pcbnew/print_board_functions.cpp b/pcbnew/print_board_functions.cpp index f31bb00eee..8e3482b2fd 100644 --- a/pcbnew/print_board_functions.cpp +++ b/pcbnew/print_board_functions.cpp @@ -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;