void PSLIKE_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, SHAPE_POLY_SET* aPolygons, EDA_DRAW_MODE_T aTraceMode, void* aData ) { wxSize size( aSize ); if( aTraceMode == FILLED ) SetCurrentLineWidth( 0 ); else { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); size.x -= GetCurrentLineWidth(); size.y -= GetCurrentLineWidth(); } std::vector< wxPoint > cornerList; for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt ) { SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt ); cornerList.clear(); for( int ii = 0; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); // Close polygon cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, GetCurrentLineWidth() ); } }
void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, SHAPE_POLY_SET* aPolygons, EDA_DRAW_MODE_T aTraceMode, void* aData ) { // A Pad custom is plotted as polygon. // A flashed circle @aPadPos is added (anchor pad) // However, because the anchor pad can be circle or rect, we use only // a circle not bigger than the rect. // the main purpose is to print a flashed DCode as pad anchor if( aTraceMode == FILLED ) FlashPadCircle( aPadPos, std::min( aSize.x, aSize.y ), aTraceMode, aData ); GBR_METADATA gbr_metadata; if( aData ) { gbr_metadata = *static_cast<GBR_METADATA*>( aData ); // If the pad is drawn on a copper layer, // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR if( gbr_metadata.IsCopper() ) gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR ); wxString attrname( ".P" ); gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers } SHAPE_POLY_SET polyshape = *aPolygons; if( aTraceMode != FILLED ) { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata ); polyshape.Inflate( -GetCurrentLineWidth()/2, 16 ); } std::vector< wxPoint > cornerList; for( int cnt = 0; cnt < polyshape.OutlineCount(); ++cnt ) { SHAPE_LINE_CHAIN& poly = polyshape.Outline( cnt ); cornerList.clear(); for( int ii = 0; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); // Close polygon cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL, aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata ); } }
void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, int aCornerRadius, double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) { GBR_METADATA gbr_metadata; if( aData ) { gbr_metadata = *static_cast<GBR_METADATA*>( aData ); // If the pad is drawn on a copper layer, // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR if( gbr_metadata.IsCopper() ) gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR ); wxString attrname( ".P" ); gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers } if( aTraceMode != FILLED ) SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata ); // Currently, a Pad RoundRect is plotted as polygon. // TODO: use Aperture macro and flash it SHAPE_POLY_SET outline; const int segmentToCircleCount = 64; TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient, aCornerRadius, segmentToCircleCount ); if( aTraceMode != FILLED ) outline.Inflate( -GetCurrentLineWidth()/2, 16 ); std::vector< wxPoint > cornerList; // TransformRoundRectToPolygon creates only one convex polygon SHAPE_LINE_CHAIN& poly = outline.Outline( 0 ); cornerList.reserve( poly.PointCount() + 1 ); for( int ii = 0; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); // Close polygon cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL, aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata ); // Now, flash a pad anchor, if a netlist attribute is set // (remove me when a Aperture macro will be used) if( aData && aTraceMode == FILLED ) { int diameter = std::min( aSize.x, aSize.y ); FlashPadCircle( aPadPos, diameter, aTraceMode , aData ); } }
void PSLIKE_PLOTTER::FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) { static std::vector< wxPoint > cornerList; wxSize size( aSize ); cornerList.clear(); if( aTraceMode == FILLED ) SetCurrentLineWidth( 0 ); else SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); size.x -= GetCurrentLineWidth(); size.y -= GetCurrentLineWidth(); if( size.x < 1 ) size.x = 1; if( size.y < 1 ) size.y = 1; int dx = size.x / 2; int dy = size.y / 2; wxPoint corner; corner.x = aPadPos.x - dx; corner.y = aPadPos.y + dy; cornerList.push_back( corner ); corner.x = aPadPos.x - dx; corner.y = aPadPos.y - dy; cornerList.push_back( corner ); corner.x = aPadPos.x + dx; corner.y = aPadPos.y - dy; cornerList.push_back( corner ); corner.x = aPadPos.x + dx; corner.y = aPadPos.y + dy, cornerList.push_back( corner ); for( unsigned ii = 0; ii < cornerList.size(); ii++ ) { RotatePoint( &cornerList[ii], aPadPos, aPadOrient ); } cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, GetCurrentLineWidth() ); }
void SVG_PLOTTER::setSVGPlotStyle() { fputs( "</g>\n<g style=\"", outputFile ); fputs( "fill:#", outputFile ); // output the background fill color fprintf( outputFile, "%6.6lX; ", m_brush_rgb_color ); switch( m_fillMode ) { case NO_FILL: fputs( "fill-opacity:0.0; ", outputFile ); break; case FILLED_SHAPE: fputs( "fill-opacity:1.0; ", outputFile ); break; case FILLED_WITH_BG_BODYCOLOR: fputs( "fill-opacity:0.6; ", outputFile ); break; } double pen_w = userToDeviceSize( GetCurrentLineWidth() ); fprintf( outputFile, "\nstroke:#%6.6lX; stroke-width:%g; stroke-opacity:1; \n", m_pen_rgb_color, pen_w ); fputs( "stroke-linecap:round; stroke-linejoin:round;\">\n", outputFile ); m_graphics_changed = false; }
void PSLIKE_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) { static std::vector< wxPoint > cornerList; cornerList.clear(); for( int ii = 0; ii < 4; ii++ ) cornerList.push_back( aCorners[ii] ); if( aTraceMode == FILLED ) { SetCurrentLineWidth( 0 ); } else { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); int w = GetCurrentLineWidth(); // offset polygon by w // coord[0] is assumed the lower left // coord[1] is assumed the upper left // coord[2] is assumed the upper right // coord[3] is assumed the lower right /* Trace the outline. */ cornerList[0].x += w; cornerList[0].y -= w; cornerList[1].x += w; cornerList[1].y += w; cornerList[2].x -= w; cornerList[2].y += w; cornerList[3].x -= w; cornerList[3].y -= w; } for( int ii = 0; ii < 4; ii++ ) { RotatePoint( &cornerList[ii], aPadOrient ); cornerList[ii] += aPadPos; } cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, GetCurrentLineWidth() ); }
/* Set the current line width (in IUs) for the next plot */ void PS_PLOTTER::SetCurrentLineWidth( int width, void* aData ) { wxASSERT( outputFile ); int pen_width; if( width >= 0 ) pen_width = width; else pen_width = defaultPenWidth; if( pen_width != GetCurrentLineWidth() ) fprintf( outputFile, "%g setlinewidth\n", userToDeviceSize( pen_width ) ); currentPenWidth = pen_width; }
void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, int aCornerRadius, double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) { wxSize size( aSize ); if( aTraceMode == FILLED ) SetCurrentLineWidth( 0 ); else { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); size.x -= GetCurrentLineWidth(); size.y -= GetCurrentLineWidth(); aCornerRadius -= GetCurrentLineWidth()/2; } SHAPE_POLY_SET outline; const int segmentToCircleCount = 64; TransformRoundRectToPolygon( outline, aPadPos, size, aOrient, aCornerRadius, segmentToCircleCount ); std::vector< wxPoint > cornerList; cornerList.reserve( segmentToCircleCount + 5 ); // TransformRoundRectToPolygon creates only one convex polygon SHAPE_LINE_CHAIN& poly = outline.Outline( 0 ); for( int ii = 0; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); // Close polygon cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, GetCurrentLineWidth() ); }
void PSLIKE_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_MODE_T modetrace ) { int current_line_width; wxASSERT( outputFile ); SetCurrentLineWidth( -1 ); current_line_width = GetCurrentLineWidth(); if( current_line_width > diametre ) current_line_width = diametre; if( modetrace == FILLED ) Circle( pos, diametre - currentPenWidth, FILLED_SHAPE, current_line_width ); else Circle( pos, diametre - currentPenWidth, NO_FILL, current_line_width ); SetCurrentLineWidth( -1 ); }
void PSLIKE_PLOTTER::FlashPadCircle( const wxPoint& aPadPos, int aDiameter, EDA_DRAW_MODE_T aTraceMode, void* aData ) { if( aTraceMode == FILLED ) Circle( aPadPos, aDiameter, FILLED_SHAPE, 0 ); else // Plot a ring: { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); int linewidth = GetCurrentLineWidth(); // avoid aDiameter <= 1 ) if( linewidth > aDiameter-2 ) linewidth = aDiameter-2; Circle( aPadPos, aDiameter - linewidth, NO_FILL, linewidth ); } SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); }
void PLOTTER::markerLozenge( const wxPoint& position, int radius ) { std::vector< wxPoint > corner_list; wxPoint corner; corner.x = position.x; corner.y = position.y + radius; corner_list.push_back( corner ); corner.x = position.x + radius; corner.y = position.y, corner_list.push_back( corner ); corner.x = position.x; corner.y = position.y - radius; corner_list.push_back( corner ); corner.x = position.x - radius; corner.y = position.y; corner_list.push_back( corner ); corner.x = position.x; corner.y = position.y + radius; corner_list.push_back( corner ); PlotPoly( corner_list, NO_FILL, GetCurrentLineWidth() ); }
void PLOTTER::markerSquare( const wxPoint& position, int radius ) { double r = KiROUND( radius / 1.4142 ); std::vector< wxPoint > corner_list; wxPoint corner; corner.x = position.x + r; corner.y = position.y + r; corner_list.push_back( corner ); corner.x = position.x + r; corner.y = position.y - r; corner_list.push_back( corner ); corner.x = position.x - r; corner.y = position.y - r; corner_list.push_back( corner ); corner.x = position.x - r; corner.y = position.y + r; corner_list.push_back( corner ); corner.x = position.x + r; corner.y = position.y + r; corner_list.push_back( corner ); PlotPoly( corner_list, NO_FILL, GetCurrentLineWidth() ); }
void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize, double orient, EDA_DRAW_MODE_T trace_mode, void* aData ) { wxASSERT( outputFile ); wxSize size( aSize ); GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData ); // Plot as an aperture flash switch( int( orient ) ) { case 900: case 2700: // rotation of 90 degrees or 270 swaps sizes std::swap( size.x, size.y ); // Pass through case 0: case 1800: if( trace_mode == SKETCH ) { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, gbr_metadata ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); Rect( wxPoint( pos.x - (size.x - currentPenWidth) / 2, pos.y - (size.y - currentPenWidth) / 2 ), wxPoint( pos.x + (size.x - currentPenWidth) / 2, pos.y + (size.y - currentPenWidth) / 2 ), NO_FILL, GetCurrentLineWidth() ); } else { DPOINT pos_dev = userToDeviceCoordinates( pos ); int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; selectAperture( size, APERTURE::Rect, aperture_attrib ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); emitDcode( pos_dev, 3 ); } break; default: // plot pad shape as polygon { // XXX to do: use an aperture macro to declare the rotated pad wxPoint coord[4]; // coord[0] is assumed the lower left // coord[1] is assumed the upper left // coord[2] is assumed the upper right // coord[3] is assumed the lower right /* Trace the outline. */ coord[0].x = -size.x/2; // lower left coord[0].y = size.y/2; coord[1].x = -size.x/2; // upper left coord[1].y = -size.y/2; coord[2].x = size.x/2; // upper right coord[2].y = -size.y/2; coord[3].x = size.x/2; // lower right coord[3].y = size.y/2; FlashPadTrapez( pos, coord, orient, trace_mode, aData ); } break; } }
void PLOTTER::markerCircle( const wxPoint& position, int radius ) { Circle( position, radius * 2, NO_FILL, GetCurrentLineWidth() ); }
double PLOTTER::GetDashGapLenIU() const { return userToDeviceSize( m_dashGapLength_mm*10000/25.4*m_IUsPerDecimil + GetCurrentLineWidth() ); }
void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners, double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData ) { // Currently, a Pad Trapezoid is plotted as polygon. // TODO: use Aperture macro and flash it // polygon corners list std::vector< wxPoint > cornerList; for( int ii = 0; ii < 4; ii++ ) cornerList.push_back( aCorners[ii] ); // Now, flash a pad anchor, if a netlist attribute is set // (remove me when a Aperture macro will be used) if( aData && ( aTrace_Mode == FILLED ) ) { // Calculate the radius of the circle inside the shape // It is the smaller dist from shape pos to edges int radius = INT_MAX; for( unsigned ii = 0, jj = cornerList.size()-1; ii < cornerList.size(); jj = ii, ii++ ) { SEG segment( aCorners[ii], aCorners[jj] ); int dist = segment.LineDistance( VECTOR2I( 0, 0) ); radius = std::min( radius, dist ); } FlashPadCircle( aPadPos, radius*2, aTrace_Mode, aData ); } // Draw the polygon and fill the interior as required for( unsigned ii = 0; ii < 4; ii++ ) { RotatePoint( &cornerList[ii], aPadOrient ); cornerList[ii] += aPadPos; } // Close the polygon cornerList.push_back( cornerList[0] ); GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData ); GBR_METADATA metadata; if( gbr_metadata ) { metadata = *gbr_metadata; // If the pad is drawn on a copper layer, // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR if( metadata.IsCopper() ) metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR ); wxString attrname( ".P" ); metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers } SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &metadata ); PlotPoly( cornerList, aTrace_Mode == FILLED ? FILLED_SHAPE : NO_FILL, aTrace_Mode == FILLED ? 0 : GetCurrentLineWidth(), &metadata ); }
double PLOTTER::GetDashMarkLenIU() const { double mark = userToDeviceSize( m_dashMarkLength_mm*10000/25.4*m_IUsPerDecimil - GetCurrentLineWidth() ); return ( mark < 0.0 ) ? 0.0 : mark; }