Remove dead code in pcbnew
* Remove dead zone printer * Remove old canvas in pad properties window
This commit is contained in:
parent
806e661ab3
commit
e4cbeeab4c
|
@ -472,7 +472,6 @@ set( PCB_COMMON_SRCS
|
|||
${CMAKE_SOURCE_DIR}/pcbnew/legacy_plugin.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/netlist_reader/netlist_reader.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pad_custom_shape_functions.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pad_print_functions.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_display_options.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_draw_panel_gal.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/netlist_reader/pcb_netlist.cpp
|
||||
|
|
|
@ -226,6 +226,47 @@ void D_PAD::SetRoundRectCornerRadius( double aRadius )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function BuildSegmentFromOvalShape
|
||||
* Has meaning only for OVAL (and ROUND) pads.
|
||||
* Build an equivalent segment having the same shape as the OVAL shape,
|
||||
* aSegStart and aSegEnd are the ending points of the equivalent segment of the shape
|
||||
* aRotation is the asked rotation of the segment (usually m_Orient)
|
||||
*/
|
||||
int D_PAD::BuildSegmentFromOvalShape( wxPoint& aSegStart, wxPoint& aSegEnd, double aRotation,
|
||||
const wxSize& aMargin ) const
|
||||
{
|
||||
int width;
|
||||
|
||||
if( m_Size.y < m_Size.x ) // Build an horizontal equiv segment
|
||||
{
|
||||
int delta = ( m_Size.x - m_Size.y ) / 2;
|
||||
aSegStart.x = -delta - aMargin.x;
|
||||
aSegStart.y = 0;
|
||||
aSegEnd.x = delta + aMargin.x;
|
||||
aSegEnd.y = 0;
|
||||
width = m_Size.y + ( aMargin.y * 2 );
|
||||
}
|
||||
else // Vertical oval: build a vertical equiv segment
|
||||
{
|
||||
int delta = ( m_Size.y -m_Size.x ) / 2;
|
||||
aSegStart.x = 0;
|
||||
aSegStart.y = -delta - aMargin.y;
|
||||
aSegEnd.x = 0;
|
||||
aSegEnd.y = delta + aMargin.y;
|
||||
width = m_Size.x + ( aMargin.x * 2 );
|
||||
}
|
||||
|
||||
if( aRotation )
|
||||
{
|
||||
RotatePoint( &aSegStart, aRotation);
|
||||
RotatePoint( &aSegEnd, aRotation);
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
const EDA_RECT D_PAD::GetBoundingBox() const
|
||||
{
|
||||
EDA_RECT area;
|
||||
|
@ -755,6 +796,150 @@ int D_PAD::GetThermalGap() const
|
|||
}
|
||||
|
||||
|
||||
void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue,
|
||||
double aRotation ) const
|
||||
{
|
||||
wxSize delta;
|
||||
wxSize halfsize;
|
||||
|
||||
halfsize.x = m_Size.x >> 1;
|
||||
halfsize.y = m_Size.y >> 1;
|
||||
|
||||
switch( GetShape() )
|
||||
{
|
||||
case PAD_SHAPE_RECT:
|
||||
// For rectangular shapes, inflate is easy
|
||||
halfsize += aInflateValue;
|
||||
|
||||
// Verify if do not deflate more than than size
|
||||
// Only possible for inflate negative values.
|
||||
if( halfsize.x < 0 )
|
||||
halfsize.x = 0;
|
||||
|
||||
if( halfsize.y < 0 )
|
||||
halfsize.y = 0;
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_TRAPEZOID:
|
||||
// Trapezoidal pad: verify delta values
|
||||
delta.x = ( m_DeltaSize.x >> 1 );
|
||||
delta.y = ( m_DeltaSize.y >> 1 );
|
||||
|
||||
// be sure delta values are not to large
|
||||
if( (delta.x < 0) && (delta.x <= -halfsize.y) )
|
||||
delta.x = -halfsize.y + 1;
|
||||
|
||||
if( (delta.x > 0) && (delta.x >= halfsize.y) )
|
||||
delta.x = halfsize.y - 1;
|
||||
|
||||
if( (delta.y < 0) && (delta.y <= -halfsize.x) )
|
||||
delta.y = -halfsize.x + 1;
|
||||
|
||||
if( (delta.y > 0) && (delta.y >= halfsize.x) )
|
||||
delta.y = halfsize.x - 1;
|
||||
break;
|
||||
|
||||
default: // is used only for rect and trap. pads
|
||||
return;
|
||||
}
|
||||
|
||||
// Build the basic rectangular or trapezoid shape
|
||||
// delta is null for rectangular shapes
|
||||
aCoord[0].x = -halfsize.x - delta.y; // lower left
|
||||
aCoord[0].y = +halfsize.y + delta.x;
|
||||
|
||||
aCoord[1].x = -halfsize.x + delta.y; // upper left
|
||||
aCoord[1].y = -halfsize.y - delta.x;
|
||||
|
||||
aCoord[2].x = +halfsize.x - delta.y; // upper right
|
||||
aCoord[2].y = -halfsize.y + delta.x;
|
||||
|
||||
aCoord[3].x = +halfsize.x + delta.y; // lower right
|
||||
aCoord[3].y = +halfsize.y - delta.x;
|
||||
|
||||
// Offsetting the trapezoid shape id needed
|
||||
// It is assumed delta.x or/and delta.y == 0
|
||||
if( GetShape() == PAD_SHAPE_TRAPEZOID && (aInflateValue.x != 0 || aInflateValue.y != 0) )
|
||||
{
|
||||
double angle;
|
||||
wxSize corr;
|
||||
|
||||
if( delta.y ) // lower and upper segment is horizontal
|
||||
{
|
||||
// Calculate angle of left (or right) segment with vertical axis
|
||||
angle = atan2( (double) m_DeltaSize.y, (double) m_Size.y );
|
||||
|
||||
// left and right sides are moved by aInflateValue.x in their perpendicular direction
|
||||
// We must calculate the corresponding displacement on the horizontal axis
|
||||
// that is delta.x +- corr.x depending on the corner
|
||||
corr.x = KiROUND( tan( angle ) * aInflateValue.x );
|
||||
delta.x = KiROUND( aInflateValue.x / cos( angle ) );
|
||||
|
||||
// Horizontal sides are moved up and down by aInflateValue.y
|
||||
delta.y = aInflateValue.y;
|
||||
|
||||
// corr.y = 0 by the constructor
|
||||
}
|
||||
else if( delta.x ) // left and right segment is vertical
|
||||
{
|
||||
// Calculate angle of lower (or upper) segment with horizontal axis
|
||||
angle = atan2( (double) m_DeltaSize.x, (double) m_Size.x );
|
||||
|
||||
// lower and upper sides are moved by aInflateValue.x in their perpendicular direction
|
||||
// We must calculate the corresponding displacement on the vertical axis
|
||||
// that is delta.y +- corr.y depending on the corner
|
||||
corr.y = KiROUND( tan( angle ) * aInflateValue.y );
|
||||
delta.y = KiROUND( aInflateValue.y / cos( angle ) );
|
||||
|
||||
// Vertical sides are moved left and right by aInflateValue.x
|
||||
delta.x = aInflateValue.x;
|
||||
|
||||
// corr.x = 0 by the constructor
|
||||
}
|
||||
else // the trapezoid is a rectangle
|
||||
{
|
||||
delta = aInflateValue; // this pad is rectangular (delta null).
|
||||
}
|
||||
|
||||
aCoord[0].x += -delta.x - corr.x; // lower left
|
||||
aCoord[0].y += delta.y + corr.y;
|
||||
|
||||
aCoord[1].x += -delta.x + corr.x; // upper left
|
||||
aCoord[1].y += -delta.y - corr.y;
|
||||
|
||||
aCoord[2].x += delta.x - corr.x; // upper right
|
||||
aCoord[2].y += -delta.y + corr.y;
|
||||
|
||||
aCoord[3].x += delta.x + corr.x; // lower right
|
||||
aCoord[3].y += delta.y - corr.y;
|
||||
|
||||
/* test coordinates and clamp them if the offset correction is too large:
|
||||
* Note: if a coordinate is bad, the other "symmetric" coordinate is bad
|
||||
* So when a bad coordinate is found, the 2 symmetric coordinates
|
||||
* are set to the minimun value (0)
|
||||
*/
|
||||
|
||||
if( aCoord[0].x > 0 ) // lower left x coordinate must be <= 0
|
||||
aCoord[0].x = aCoord[3].x = 0;
|
||||
|
||||
if( aCoord[1].x > 0 ) // upper left x coordinate must be <= 0
|
||||
aCoord[1].x = aCoord[2].x = 0;
|
||||
|
||||
if( aCoord[0].y < 0 ) // lower left y coordinate must be >= 0
|
||||
aCoord[0].y = aCoord[1].y = 0;
|
||||
|
||||
if( aCoord[3].y < 0 ) // lower right y coordinate must be >= 0
|
||||
aCoord[3].y = aCoord[2].y = 0;
|
||||
}
|
||||
|
||||
if( aRotation )
|
||||
{
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
RotatePoint( &aCoord[ii], aRotation );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void D_PAD::GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
MODULE* module;
|
||||
|
|
|
@ -59,30 +59,6 @@ namespace KIGFX
|
|||
class VIEW;
|
||||
}
|
||||
|
||||
// Helper class to store parameters used to draw a pad
|
||||
class PAD_DRAWINFO
|
||||
{
|
||||
public:
|
||||
COLOR4D m_Color; // color used to draw the pad shape , from pad layers and
|
||||
// visible layers
|
||||
COLOR4D m_HoleColor; // color used to draw the pad hole
|
||||
COLOR4D m_NPHoleColor; // color used to draw a pad Not Plated hole
|
||||
COLOR4D m_NoNetMarkColor; // color used to draw a mark on pads having no net
|
||||
int m_PadClearance; // clearance value, used to draw the pad area outlines
|
||||
wxSize m_Mask_margin; // margin, used to draw solder paste when only one layer is shown
|
||||
bool m_Display_padnum; // true to show pad number
|
||||
bool m_Display_netname; // true to show net name
|
||||
bool m_ShowPadFilled; // true to show pad as solid area, false to show pas in
|
||||
// sketch mode
|
||||
bool m_ShowNCMark; // true to show pad not connected mark
|
||||
bool m_ShowNotPlatedHole; // true when the pad hole in not plated, to draw a specific
|
||||
// pad shape
|
||||
bool m_IsPrinting; // true to print, false to display on screen.
|
||||
wxPoint m_Offset; // general draw offset
|
||||
|
||||
PAD_DRAWINFO();
|
||||
};
|
||||
|
||||
/** Helper class to handle a primitive (basic shape: polygon, segment, circle or arc)
|
||||
* to build a custom pad full shape from a set of primitives
|
||||
*/
|
||||
|
@ -545,16 +521,6 @@ public:
|
|||
void SetThermalGap( int aGap ) { m_ThermalGap = aGap; }
|
||||
int GetThermalGap() const;
|
||||
|
||||
/**
|
||||
* Function PrintShape
|
||||
* basic function to print a pad.
|
||||
* <p>
|
||||
* This function is used by Print after calculation of parameters (color, ) final
|
||||
* orientation transforms are set.
|
||||
* </p>
|
||||
*/
|
||||
void PrintShape( wxDC* aDC, PAD_DRAWINFO& aDrawInfo );
|
||||
|
||||
/**
|
||||
* Function BuildPadPolygon
|
||||
* Has meaning only for polygonal pads (trapezoid and rectangular)
|
||||
|
|
|
@ -318,81 +318,6 @@ bool ZONE_CONTAINER::IsOnLayer( PCB_LAYER_ID aLayer ) const
|
|||
}
|
||||
|
||||
|
||||
void ZONE_CONTAINER::PrintFilledArea( PCB_BASE_FRAME* aFrame, wxDC* DC, const wxPoint& offset )
|
||||
{
|
||||
static std::vector <wxPoint> CornersBuffer;
|
||||
|
||||
BOARD* brd = GetBoard();
|
||||
COLOR4D color = Pgm().GetSettingsManager().GetColorSettings()->GetColor( GetLayer() );
|
||||
auto& displ_opts = aFrame->GetDisplayOptions();
|
||||
bool outline_mode = displ_opts.m_DisplayZonesMode == 2;
|
||||
|
||||
if( DC == NULL )
|
||||
return;
|
||||
|
||||
if( displ_opts.m_DisplayZonesMode == 1 ) // Do not show filled areas
|
||||
return;
|
||||
|
||||
if( m_FilledPolysList.IsEmpty() ) // Nothing to draw
|
||||
return;
|
||||
|
||||
if( brd->IsLayerVisible( GetLayer() ) == false )
|
||||
return;
|
||||
|
||||
color.a = 0.588;
|
||||
|
||||
for( int ic = 0; ic < m_FilledPolysList.OutlineCount(); ic++ )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( ic );
|
||||
|
||||
CornersBuffer.clear();
|
||||
|
||||
wxPoint p0;
|
||||
|
||||
for( int j = 0; j < path.PointCount(); j++ )
|
||||
{
|
||||
const VECTOR2I& corner = path.CPoint( j );
|
||||
|
||||
wxPoint coord( corner.x + offset.x, corner.y + offset.y );
|
||||
|
||||
if( j == 0 )
|
||||
p0 = coord;
|
||||
|
||||
CornersBuffer.push_back( coord );
|
||||
}
|
||||
|
||||
CornersBuffer.push_back( p0 );
|
||||
|
||||
// Draw outlines:
|
||||
int outline_thickness = GetFilledPolysUseThickness() ? GetMinThickness() : 0;
|
||||
|
||||
if( ( outline_thickness > 1 ) || outline_mode )
|
||||
{
|
||||
int ilim = CornersBuffer.size() - 1;
|
||||
|
||||
for( int is = 0, ie = ilim; is <= ilim; ie = is, is++ )
|
||||
{
|
||||
// Draw only basic outlines, not extra segments.
|
||||
if( !displ_opts.m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
|
||||
{
|
||||
GRCSegm( nullptr, DC, CornersBuffer[is], CornersBuffer[ie],
|
||||
outline_thickness, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRFilledSegment( nullptr, DC, CornersBuffer[is], CornersBuffer[ie],
|
||||
outline_thickness, color );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw fill:
|
||||
if( !outline_mode )
|
||||
GRPoly( nullptr, DC, CornersBuffer.size(), &CornersBuffer[0], true, 0, color, color );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const EDA_RECT ZONE_CONTAINER::GetBoundingBox() const
|
||||
{
|
||||
auto bb = m_Poly->BBox();
|
||||
|
|
|
@ -105,16 +105,6 @@ public:
|
|||
|
||||
virtual LSET GetLayerSet() const override;
|
||||
|
||||
/**
|
||||
* Function PrintFilledArea
|
||||
* Draws the filled area for this zone (polygon list .m_FilledPolysList)
|
||||
* @param aFrame = current Frame
|
||||
* @param DC = current Device Context
|
||||
* @param offset = Draw offset (usually wxPoint(0,0))
|
||||
* @param aDrawMode = GR_OR, GR_XOR, GR_COPY ..
|
||||
*/
|
||||
void PrintFilledArea( PCB_BASE_FRAME* aFrame, wxDC* DC, const wxPoint& offset = ZeroOffset );
|
||||
|
||||
/** Function GetBoundingBox (virtual)
|
||||
* @return an EDA_RECT that is the bounding box of the zone outline
|
||||
*/
|
||||
|
|
|
@ -255,7 +255,6 @@ void DIALOG_PAD_PROPERTIES::prepareCanvas()
|
|||
m_panelShowPadGal->GetViewControls()->EnableMousewheelPan( mousewheelPan );
|
||||
|
||||
m_panelShowPadGal->Show();
|
||||
m_panelShowPad->Hide();
|
||||
|
||||
KIGFX::VIEW* view = m_panelShowPadGal->GetView();
|
||||
|
||||
|
@ -280,179 +279,6 @@ void DIALOG_PAD_PROPERTIES::prepareCanvas()
|
|||
}
|
||||
|
||||
|
||||
void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
|
||||
{
|
||||
wxPaintDC dc( m_panelShowPad );
|
||||
PAD_DRAWINFO drawInfo;
|
||||
|
||||
COLOR4D color = COLOR4D::BLACK;
|
||||
|
||||
if( m_dummyPad->GetLayerSet()[F_Cu] )
|
||||
color = m_parent->ColorSettings()->GetColor( LAYER_PAD_FR );
|
||||
|
||||
if( m_dummyPad->GetLayerSet()[B_Cu] )
|
||||
color = color.LegacyMix( m_parent->ColorSettings()->GetColor( LAYER_PAD_BK ) );
|
||||
|
||||
// What could happen: the pad color is *actually* black, or no copper was selected
|
||||
if( color == BLACK )
|
||||
color = LIGHTGRAY;
|
||||
|
||||
drawInfo.m_Color = color;
|
||||
drawInfo.m_HoleColor = DARKGRAY;
|
||||
drawInfo.m_Offset = m_dummyPad->GetPosition();
|
||||
drawInfo.m_Display_padnum = true;
|
||||
drawInfo.m_Display_netname = true;
|
||||
drawInfo.m_ShowPadFilled = !m_sketchPreview;
|
||||
|
||||
if( m_dummyPad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
|
||||
drawInfo.m_ShowNotPlatedHole = true;
|
||||
|
||||
// Shows the local pad clearance
|
||||
drawInfo.m_PadClearance = m_dummyPad->GetLocalClearance();
|
||||
|
||||
wxSize dc_size = dc.GetSize();
|
||||
dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
|
||||
|
||||
// Calculate a suitable scale to fit the available draw area
|
||||
int dim = m_dummyPad->GetBoundingRadius() *2;
|
||||
|
||||
// Invalid x size. User could enter zero, or have deleted all text prior to
|
||||
// entering a new value; this is also treated as zero. If dim is left at
|
||||
// zero, the drawing scale is zero and we get a crash.
|
||||
if( dim == 0 )
|
||||
{
|
||||
// If drill size has been set, use that. Otherwise default to 1mm.
|
||||
dim = m_dummyPad->GetDrillSize().x;
|
||||
|
||||
if( dim == 0 )
|
||||
dim = Millimeter2iu( 1.0 );
|
||||
}
|
||||
|
||||
if( m_dummyPad->GetLocalClearance() > 0 )
|
||||
dim += m_dummyPad->GetLocalClearance() * 2;
|
||||
|
||||
double scale = (double) dc_size.x / dim;
|
||||
|
||||
// If the pad is a circle, use the x size here instead.
|
||||
int ysize;
|
||||
|
||||
if( m_dummyPad->GetShape() == PAD_SHAPE_CIRCLE )
|
||||
ysize = m_dummyPad->GetSize().x;
|
||||
else
|
||||
ysize = m_dummyPad->GetSize().y;
|
||||
|
||||
dim = ysize + std::abs( m_dummyPad->GetDelta().x );
|
||||
|
||||
// Invalid y size. See note about x size above.
|
||||
if( dim == 0 )
|
||||
{
|
||||
dim = m_dummyPad->GetDrillSize().y;
|
||||
|
||||
if( dim == 0 )
|
||||
dim = Millimeter2iu( 0.1 );
|
||||
}
|
||||
|
||||
if( m_dummyPad->GetLocalClearance() > 0 )
|
||||
dim += m_dummyPad->GetLocalClearance() * 2;
|
||||
|
||||
double altscale = (double) dc_size.y / dim;
|
||||
scale = std::min( scale, altscale );
|
||||
|
||||
// Give a margin
|
||||
scale *= 0.7;
|
||||
dc.SetUserScale( scale, scale );
|
||||
|
||||
GRResetPenAndBrush( &dc );
|
||||
m_dummyPad->PrintShape( &dc, drawInfo );
|
||||
|
||||
// draw selected primitives:
|
||||
long select = m_listCtrlPrimitives->GetFirstSelected();
|
||||
|
||||
while( select >= 0 )
|
||||
{
|
||||
PAD_CS_PRIMITIVE& primitive = m_primitives[select];
|
||||
|
||||
// The best way to calculate parameters to draw a primitive is to
|
||||
// use a dummy DRAWSEGMENT and use its methods
|
||||
// Note: in legacy canvas, the pad has the 0,0 position
|
||||
DRAWSEGMENT dummySegment;
|
||||
primitive.ExportTo( &dummySegment );
|
||||
dummySegment.Rotate( wxPoint( 0, 0), m_dummyPad->GetOrientation() );
|
||||
|
||||
switch( primitive.m_Shape )
|
||||
{
|
||||
case S_SEGMENT: // usual segment : line with rounded ends
|
||||
if( !m_sketchPreview )
|
||||
GRFilledSegment( NULL, &dc, dummySegment.GetStart(), dummySegment.GetEnd(),
|
||||
primitive.m_Thickness, m_selectedColor );
|
||||
else
|
||||
GRCSegm( NULL, &dc, dummySegment.GetStart(), dummySegment.GetEnd(),
|
||||
primitive.m_Thickness, m_selectedColor );
|
||||
break;
|
||||
|
||||
case S_ARC: // Arc with rounded ends
|
||||
if( !m_sketchPreview )
|
||||
GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
|
||||
dummySegment.GetCenter(), primitive.m_Thickness, m_selectedColor );
|
||||
else
|
||||
{
|
||||
GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
|
||||
dummySegment.GetCenter(), 0, m_selectedColor );
|
||||
/* GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
|
||||
dummySegment.GetCenter() - primitive.m_Thickness, 0, m_selectedColor );*/
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CIRCLE: // ring or circle
|
||||
if( primitive.m_Thickness )
|
||||
{
|
||||
if( !m_sketchPreview )
|
||||
GRCircle( nullptr, &dc, dummySegment.GetCenter(), primitive.m_Radius,
|
||||
primitive.m_Thickness, m_selectedColor );
|
||||
else
|
||||
{
|
||||
GRCircle( nullptr, &dc, dummySegment.GetCenter(),
|
||||
primitive.m_Radius + primitive.m_Thickness/2, 0, m_selectedColor );
|
||||
GRCircle( nullptr, &dc, dummySegment.GetCenter(),
|
||||
primitive.m_Radius - primitive.m_Thickness/2, 0, m_selectedColor );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !m_sketchPreview )
|
||||
GRFilledCircle( nullptr, &dc, dummySegment.GetCenter(), primitive.m_Radius,
|
||||
m_selectedColor );
|
||||
else
|
||||
GRCircle( nullptr, &dc, dummySegment.GetCenter(), primitive.m_Radius, 0,
|
||||
m_selectedColor );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_POLYGON: // polygon
|
||||
{
|
||||
std::vector<wxPoint> poly = dummySegment.BuildPolyPointsList();
|
||||
GRClosedPoly( nullptr, &dc, poly.size(), &poly[0], !m_sketchPreview,
|
||||
primitive.m_Thickness, m_selectedColor, m_selectedColor );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
select = m_listCtrlPrimitives->GetNextSelected( select );
|
||||
}
|
||||
|
||||
// Draw X and Y axis. This is particularly useful to show the
|
||||
// reference position of pads with offset and no hole, or custom pad shapes
|
||||
const int t = 0; // line thickness
|
||||
GRLine( nullptr, &dc, -int( dc_size.x/scale ), 0, int( dc_size.x/scale ), 0, t, LIGHTBLUE );
|
||||
GRLine( nullptr, &dc, 0, -int( dc_size.y/scale ), 0, int( dc_size.y/scale ), t, LIGHTBLUE );
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_PAD_PROPERTIES::updateRoundRectCornerValues()
|
||||
{
|
||||
// Note: use m_tcCornerSizeRatio->ChangeValue() to avoid generating a wxEVT_TEXT event
|
||||
|
|
|
@ -125,7 +125,6 @@ private:
|
|||
void PadTypeSelected( wxCommandEvent& event ) override;
|
||||
|
||||
void OnSetLayers( wxCommandEvent& event ) override;
|
||||
void OnPaintShowPanel( wxPaintEvent& event ) override;
|
||||
|
||||
// Called when corner setup value is changed for rounded rect pads
|
||||
void onCornerSizePercentChange( wxCommandEvent& event ) override;
|
||||
|
|
|
@ -694,12 +694,6 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
|
|||
|
||||
bSizerDisplayPad->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_panelShowPad = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxFULL_REPAINT_ON_RESIZE|wxBORDER_SIMPLE );
|
||||
m_panelShowPad->SetBackgroundColour( wxColour( 0, 0, 0 ) );
|
||||
m_panelShowPad->SetMinSize( wxSize( 280,-1 ) );
|
||||
|
||||
bSizerDisplayPad->Add( m_panelShowPad, 12, wxEXPAND|wxALL, 5 );
|
||||
|
||||
m_panelShowPadGal = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), wxDefaultSize, m_galOptions, EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO);
|
||||
m_panelShowPadGal->SetMinSize( wxSize( 280,-1 ) );
|
||||
|
||||
|
@ -781,7 +775,6 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
|
|||
m_buttonAddShape->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onAddPrimitive ), NULL, this );
|
||||
m_buttonDup->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onDuplicatePrimitive ), NULL, this );
|
||||
m_buttonGeometry->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onGeometryTransform ), NULL, this );
|
||||
m_panelShowPad->Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPaintShowPanel ), NULL, this );
|
||||
m_cbShowPadOutline->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onChangePadMode ), NULL, this );
|
||||
m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnCancel ), NULL, this );
|
||||
}
|
||||
|
@ -834,7 +827,6 @@ DIALOG_PAD_PROPERTIES_BASE::~DIALOG_PAD_PROPERTIES_BASE()
|
|||
m_buttonAddShape->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onAddPrimitive ), NULL, this );
|
||||
m_buttonDup->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onDuplicatePrimitive ), NULL, this );
|
||||
m_buttonGeometry->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onGeometryTransform ), NULL, this );
|
||||
m_panelShowPad->Disconnect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPaintShowPanel ), NULL, this );
|
||||
m_cbShowPadOutline->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onChangePadMode ), NULL, this );
|
||||
m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnCancel ), NULL, this );
|
||||
|
||||
|
|
|
@ -8156,64 +8156,6 @@
|
|||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxALL</property>
|
||||
<property name="proportion">12</property>
|
||||
<object class="wxPanel" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg">0,0,0</property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">280,-1</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_panelShowPad</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size">-1,-1</property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxBORDER_SIMPLE</property>
|
||||
<event name="OnPaint">OnPaintShowPanel</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxALL</property>
|
||||
|
@ -8434,7 +8376,7 @@
|
|||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="Dialog" expanded="0">
|
||||
<object class="Dialog" expanded="1">
|
||||
<property name="aui_managed">0</property>
|
||||
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
|
||||
<property name="bg"></property>
|
||||
|
|
|
@ -185,7 +185,6 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
|
|||
wxButton* m_buttonGeometry;
|
||||
wxStaticText* m_parentInfoLine1;
|
||||
wxStaticText* m_parentInfoLine2;
|
||||
wxPanel* m_panelShowPad;
|
||||
PCB_DRAW_PANEL_GAL* m_panelShowPadGal;
|
||||
KIGFX::GAL_DISPLAY_OPTIONS m_galOptions;
|
||||
wxCheckBox* m_cbShowPadOutline;
|
||||
|
@ -213,7 +212,6 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
|
|||
virtual void onAddPrimitive( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onDuplicatePrimitive( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onGeometryTransform( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnPaintShowPanel( wxPaintEvent& event ) { event.Skip(); }
|
||||
virtual void onChangePadMode( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
|
|
@ -1,621 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <class_board.h>
|
||||
#include <common.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
#include <gr_text.h>
|
||||
#include <fctsys.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <gr_basic.h>
|
||||
#include <math/util.h> // for KiROUND
|
||||
#include <layers_id_colors_and_visibility.h>
|
||||
#include <settings/color_settings.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <pcb_screen.h>
|
||||
#include <pcbnew.h>
|
||||
#include <trigo.h>
|
||||
|
||||
|
||||
// Helper class to store parameters used to draw a pad
|
||||
PAD_DRAWINFO::PAD_DRAWINFO()
|
||||
{
|
||||
m_Color = BLACK;
|
||||
m_HoleColor = BLACK; // could be DARKGRAY;
|
||||
m_NPHoleColor = YELLOW;
|
||||
m_NoNetMarkColor = BLUE;
|
||||
m_PadClearance = 0;
|
||||
m_Display_padnum = true;
|
||||
m_Display_netname = true;
|
||||
m_ShowPadFilled = true;
|
||||
m_ShowNCMark = true;
|
||||
m_ShowNotPlatedHole = false;
|
||||
m_IsPrinting = false;
|
||||
}
|
||||
|
||||
|
||||
void D_PAD::PrintShape( wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
|
||||
{
|
||||
#define SEGCOUNT 32 // number of segments to approximate a circle
|
||||
wxPoint coord[12];
|
||||
double angle = m_Orient;
|
||||
int seg_width;
|
||||
|
||||
// calculate pad shape position :
|
||||
wxPoint shape_pos = ShapePos() - aDrawInfo.m_Offset;
|
||||
|
||||
wxSize halfsize = m_Size;
|
||||
halfsize.x >>= 1;
|
||||
halfsize.y >>= 1;
|
||||
|
||||
switch( GetShape() )
|
||||
{
|
||||
case PAD_SHAPE_CIRCLE:
|
||||
if( aDrawInfo.m_ShowPadFilled )
|
||||
GRFilledCircle( nullptr, aDC, shape_pos.x, shape_pos.y,
|
||||
halfsize.x + aDrawInfo.m_Mask_margin.x, 0,
|
||||
aDrawInfo.m_Color, aDrawInfo.m_Color );
|
||||
else
|
||||
GRCircle( nullptr, aDC, shape_pos.x, shape_pos.y,
|
||||
halfsize.x + aDrawInfo.m_Mask_margin.x,
|
||||
m_PadSketchModePenSize, aDrawInfo.m_Color );
|
||||
|
||||
if( aDrawInfo.m_PadClearance )
|
||||
{
|
||||
GRCircle( nullptr, aDC, shape_pos.x, shape_pos.y,
|
||||
halfsize.x + aDrawInfo.m_PadClearance, 0, aDrawInfo.m_Color );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_OVAL:
|
||||
{
|
||||
wxPoint segStart, segEnd;
|
||||
seg_width = BuildSegmentFromOvalShape( segStart, segEnd, angle, aDrawInfo.m_Mask_margin );
|
||||
segStart += shape_pos;
|
||||
segEnd += shape_pos;
|
||||
|
||||
if( aDrawInfo.m_ShowPadFilled )
|
||||
{
|
||||
GRFillCSegm( nullptr, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y, seg_width,
|
||||
aDrawInfo.m_Color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRCSegm( nullptr, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y, seg_width,
|
||||
m_PadSketchModePenSize, aDrawInfo.m_Color );
|
||||
}
|
||||
|
||||
// Draw the clearance line
|
||||
if( aDrawInfo.m_PadClearance )
|
||||
{
|
||||
seg_width += 2 * aDrawInfo.m_PadClearance;
|
||||
GRCSegm( nullptr, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y, seg_width,
|
||||
aDrawInfo.m_Color );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_RECT:
|
||||
case PAD_SHAPE_TRAPEZOID:
|
||||
BuildPadPolygon( coord, aDrawInfo.m_Mask_margin, angle );
|
||||
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
coord[ii] += shape_pos;
|
||||
|
||||
GRClosedPoly( nullptr, aDC, 4, coord, aDrawInfo.m_ShowPadFilled,
|
||||
aDrawInfo.m_ShowPadFilled ? 0 : m_PadSketchModePenSize,
|
||||
aDrawInfo.m_Color, aDrawInfo.m_Color );
|
||||
|
||||
if( aDrawInfo.m_PadClearance )
|
||||
{
|
||||
SHAPE_POLY_SET outline;
|
||||
TransformShapeWithClearanceToPolygon( outline, aDrawInfo.m_PadClearance );
|
||||
|
||||
// Draw the polygon: Inflate creates only one convex polygon
|
||||
if( outline.OutlineCount() > 0 )
|
||||
{
|
||||
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
||||
|
||||
if( poly.PointCount() > 0 )
|
||||
{
|
||||
GRClosedPoly( nullptr, aDC, poly.PointCount(),
|
||||
(const wxPoint*) &poly.CPoint( 0 ), false, 0, aDrawInfo.m_Color,
|
||||
aDrawInfo.m_Color );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
{
|
||||
// Use solder[Paste/Mask]size or pad size to build pad shape to draw
|
||||
wxSize size( GetSize() );
|
||||
size += aDrawInfo.m_Mask_margin * 2;
|
||||
int corner_radius = GetRoundRectCornerRadius( size );
|
||||
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
||||
|
||||
SHAPE_POLY_SET outline;
|
||||
TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
|
||||
corner_radius, GetChamferRectRatio(),
|
||||
doChamfer ? GetChamferPositions() : 0,
|
||||
ARC_HIGH_DEF );
|
||||
|
||||
// Draw the polygon: Inflate creates only one convex polygon
|
||||
bool filled = aDrawInfo.m_ShowPadFilled;
|
||||
|
||||
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
||||
|
||||
GRClosedPoly( nullptr, aDC, poly.PointCount(), (const wxPoint*) &poly.CPoint( 0 ), filled,
|
||||
0, aDrawInfo.m_Color, aDrawInfo.m_Color );
|
||||
|
||||
if( aDrawInfo.m_PadClearance )
|
||||
{
|
||||
outline.RemoveAllContours();
|
||||
size = GetSize();
|
||||
size.x += aDrawInfo.m_PadClearance * 2;
|
||||
size.y += aDrawInfo.m_PadClearance * 2;
|
||||
corner_radius = GetRoundRectCornerRadius() + aDrawInfo.m_PadClearance;
|
||||
|
||||
TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
|
||||
corner_radius, GetChamferRectRatio(),
|
||||
doChamfer ? GetChamferPositions() : 0,
|
||||
ARC_HIGH_DEF );
|
||||
|
||||
// Draw the polygon: Inflate creates only one convex polygon
|
||||
SHAPE_LINE_CHAIN& clearance_poly = outline.Outline( 0 );
|
||||
|
||||
GRClosedPoly( nullptr, aDC, clearance_poly.PointCount(),
|
||||
(const wxPoint*) &clearance_poly.CPoint( 0 ), false, 0, aDrawInfo.m_Color,
|
||||
aDrawInfo.m_Color );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
{
|
||||
// The full shape has 2 items
|
||||
// 1- The anchor pad: a round or rect pad located at pad position
|
||||
// 2- The custom complex shape
|
||||
// Note: The anchor pad shape is containing by the custom complex shape polygon
|
||||
// The anchor pad is shown to help user to see where is the anchor, only in sketch mode
|
||||
// (In filled mode, it is merged with the basic shapes)
|
||||
wxPoint pad_pos = GetPosition() - aDrawInfo.m_Offset;
|
||||
|
||||
// In sketch mode only: Draw the anchor pad: a round or rect pad
|
||||
if( !aDrawInfo.m_ShowPadFilled )
|
||||
{
|
||||
if( GetAnchorPadShape() == PAD_SHAPE_RECT )
|
||||
{
|
||||
wxPoint poly[4];
|
||||
poly[0] = wxPoint( - halfsize.x, - halfsize.y );
|
||||
poly[1] = wxPoint( - halfsize.x, + halfsize.y );
|
||||
poly[2] = wxPoint( + halfsize.x, + halfsize.y );
|
||||
poly[3] = wxPoint( + halfsize.x, - halfsize.y );
|
||||
|
||||
for( int ii = 0; ii < 4; ++ii )
|
||||
{
|
||||
RotatePoint( &poly[ii], m_Orient );
|
||||
poly[ii] += pad_pos;
|
||||
}
|
||||
|
||||
GRClosedPoly( nullptr, aDC, 4, poly, false, 0, aDrawInfo.m_Color,
|
||||
aDrawInfo.m_Color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRCircle( nullptr, aDC, pad_pos.x, pad_pos.y, halfsize.x,
|
||||
m_PadSketchModePenSize, aDrawInfo.m_Color );
|
||||
}
|
||||
}
|
||||
|
||||
SHAPE_POLY_SET outline; // Will contain the corners in board coordinates
|
||||
outline.Append( m_customShapeAsPolygon );
|
||||
CustomShapeAsPolygonToBoardPosition( &outline, pad_pos, GetOrientation() );
|
||||
|
||||
if( aDrawInfo.m_Mask_margin.x )
|
||||
{
|
||||
int numSegs = GetArcToSegmentCount( aDrawInfo.m_Mask_margin.x, ARC_HIGH_DEF, 360.0 );
|
||||
outline.InflateWithLinkedHoles(
|
||||
aDrawInfo.m_Mask_margin.x, numSegs, SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
|
||||
// Draw the polygon: only one polygon is expected
|
||||
// However we provide a multi polygon shape drawing
|
||||
// ( can happen with CUSTOM pads and negative margins )
|
||||
for( int jj = 0; jj < outline.OutlineCount(); ++jj )
|
||||
{
|
||||
auto& poly = outline.Outline( jj );
|
||||
|
||||
GRClosedPoly( nullptr, aDC, poly.PointCount(), (const wxPoint*) &poly.CPoint( 0 ),
|
||||
aDrawInfo.m_ShowPadFilled, 0, aDrawInfo.m_Color, aDrawInfo.m_Color );
|
||||
}
|
||||
|
||||
if( aDrawInfo.m_PadClearance )
|
||||
{
|
||||
SHAPE_POLY_SET clearance_outline;
|
||||
clearance_outline.Append( outline );
|
||||
|
||||
int numSegs = GetArcToSegmentCount( aDrawInfo.m_PadClearance, ARC_HIGH_DEF, 360.0 );
|
||||
clearance_outline.InflateWithLinkedHoles(
|
||||
aDrawInfo.m_PadClearance, numSegs, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
for( int jj = 0; jj < clearance_outline.OutlineCount(); ++jj )
|
||||
{
|
||||
auto& poly = clearance_outline.Outline( jj );
|
||||
|
||||
if( poly.PointCount() > 0 )
|
||||
{
|
||||
GRClosedPoly( nullptr, aDC, poly.PointCount(),
|
||||
(const wxPoint*) &poly.CPoint( 0 ), false, 0, aDrawInfo.m_Color,
|
||||
aDrawInfo.m_Color );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the pad hole
|
||||
wxPoint holepos = m_Pos - aDrawInfo.m_Offset;
|
||||
int hole = m_Drill.x >> 1;
|
||||
|
||||
bool drawhole = hole > 0;
|
||||
|
||||
if( !aDrawInfo.m_ShowPadFilled && !aDrawInfo.m_ShowNotPlatedHole )
|
||||
drawhole = false;
|
||||
|
||||
if( drawhole )
|
||||
{
|
||||
bool blackpenstate = false;
|
||||
COLOR4D fillcolor = aDrawInfo.m_ShowNotPlatedHole? aDrawInfo.m_NPHoleColor :
|
||||
aDrawInfo.m_HoleColor;
|
||||
COLOR4D hole_color = fillcolor;
|
||||
|
||||
fillcolor = COLOR4D::WHITE;
|
||||
blackpenstate = GetGRForceBlackPenState();
|
||||
GRForceBlackPen( false );
|
||||
|
||||
if( blackpenstate )
|
||||
hole_color = COLOR4D::BLACK;
|
||||
|
||||
switch( GetDrillShape() )
|
||||
{
|
||||
case PAD_DRILL_SHAPE_CIRCLE:
|
||||
if( aDC->LogicalToDeviceXRel( hole ) > 1 ) // hole is drawn if hole > 1pixel
|
||||
GRFilledCircle( nullptr, aDC, holepos.x, holepos.y, hole, 0, hole_color, fillcolor );
|
||||
break;
|
||||
|
||||
case PAD_DRILL_SHAPE_OBLONG:
|
||||
{
|
||||
wxPoint drl_start, drl_end;
|
||||
GetOblongDrillGeometry( drl_start, drl_end, seg_width );
|
||||
drl_start += holepos;
|
||||
drl_end += holepos;
|
||||
GRFilledSegment( nullptr, aDC, drl_start, drl_end, seg_width, fillcolor );
|
||||
GRCSegm( nullptr, aDC, drl_start, drl_end, seg_width, hole_color );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( aDrawInfo.m_IsPrinting )
|
||||
GRForceBlackPen( blackpenstate );
|
||||
}
|
||||
|
||||
// Draw "No connect" ( / or \ or cross X ) if necessary
|
||||
if( GetNetCode() == 0 && aDrawInfo.m_ShowNCMark )
|
||||
{
|
||||
int dx0 = std::min( halfsize.x, halfsize.y );
|
||||
|
||||
if( m_layerMask[F_Cu] ) /* Draw \ */
|
||||
GRLine( nullptr, aDC, holepos.x - dx0, holepos.y - dx0,
|
||||
holepos.x + dx0, holepos.y + dx0, 0, aDrawInfo.m_NoNetMarkColor );
|
||||
|
||||
if( m_layerMask[B_Cu] ) // Draw /
|
||||
GRLine( nullptr, aDC, holepos.x + dx0, holepos.y - dx0,
|
||||
holepos.x - dx0, holepos.y + dx0, 0, aDrawInfo.m_NoNetMarkColor );
|
||||
}
|
||||
|
||||
// Draw the pad number
|
||||
if( !aDrawInfo.m_Display_padnum && !aDrawInfo.m_Display_netname )
|
||||
return;
|
||||
|
||||
wxPoint tpos0 = shape_pos; // Position of the centre of text
|
||||
wxPoint tpos = tpos0;
|
||||
wxSize AreaSize; // size of text area, normalized to AreaSize.y < AreaSize.x
|
||||
wxString shortname;
|
||||
int shortname_len = 0;
|
||||
|
||||
if( aDrawInfo.m_Display_netname )
|
||||
{
|
||||
shortname = UnescapeString( GetShortNetname() );
|
||||
shortname_len = shortname.Len();
|
||||
}
|
||||
|
||||
if( GetShape() == PAD_SHAPE_CIRCLE )
|
||||
angle = 0;
|
||||
|
||||
AreaSize = m_Size;
|
||||
|
||||
if( m_Size.y > m_Size.x )
|
||||
{
|
||||
angle += 900;
|
||||
AreaSize.x = m_Size.y;
|
||||
AreaSize.y = m_Size.x;
|
||||
}
|
||||
|
||||
if( shortname_len > 0 ) // if there is a netname, provides room to display this netname
|
||||
{
|
||||
AreaSize.y /= 2; // Text used only the upper area of the
|
||||
// pad. The lower area displays the net name
|
||||
tpos.y -= AreaSize.y / 2;
|
||||
}
|
||||
|
||||
// Calculate the position of text, that is the middle point of the upper
|
||||
// area of the pad
|
||||
RotatePoint( &tpos, shape_pos, angle );
|
||||
|
||||
// Draw text with an angle between -90 deg and + 90 deg
|
||||
double t_angle = angle;
|
||||
NORMALIZE_ANGLE_90( t_angle );
|
||||
|
||||
/* Note: in next calculations, texte size is calculated for 3 or more
|
||||
* chars. Of course, pads numbers and nets names can have less than 3
|
||||
* chars. but after some tries, i found this is gives the best look
|
||||
*/
|
||||
constexpr int MIN_CHAR_COUNT = 3;
|
||||
|
||||
unsigned int tsize;
|
||||
|
||||
if( aDrawInfo.m_Display_padnum )
|
||||
{
|
||||
int numpad_len = std::max( (int) m_name.Length(), MIN_CHAR_COUNT );
|
||||
tsize = std::min( (int) AreaSize.y, AreaSize.x / numpad_len );
|
||||
|
||||
if( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE ) // Not drawable when size too small.
|
||||
{
|
||||
// tsize reserve room for marges and segments thickness
|
||||
tsize = ( tsize * 7 ) / 10;
|
||||
GRHaloText( aDC, tpos, aDrawInfo.m_Color, BLACK, WHITE, m_name, t_angle,
|
||||
wxSize( tsize , tsize ), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
|
||||
tsize / 7, false, false );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// display the short netname, if exists
|
||||
if( shortname_len == 0 )
|
||||
return;
|
||||
|
||||
shortname_len = std::max( shortname_len, MIN_CHAR_COUNT );
|
||||
tsize = std::min( AreaSize.y, AreaSize.x / shortname_len );
|
||||
|
||||
if( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE ) // Not drawable in size too small.
|
||||
{
|
||||
tpos = tpos0;
|
||||
|
||||
if( aDrawInfo.m_Display_padnum )
|
||||
tpos.y += AreaSize.y / 2;
|
||||
|
||||
RotatePoint( &tpos, shape_pos, angle );
|
||||
|
||||
// tsize reserve room for marges and segments thickness
|
||||
tsize = ( tsize * 7 ) / 10;
|
||||
GRHaloText( aDC, tpos, aDrawInfo.m_Color, BLACK, WHITE, shortname, t_angle,
|
||||
wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
|
||||
tsize / 7, false, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function BuildSegmentFromOvalShape
|
||||
* Has meaning only for OVAL (and ROUND) pads.
|
||||
* Build an equivalent segment having the same shape as the OVAL shape,
|
||||
* aSegStart and aSegEnd are the ending points of the equivalent segment of the shape
|
||||
* aRotation is the asked rotation of the segment (usually m_Orient)
|
||||
*/
|
||||
int D_PAD::BuildSegmentFromOvalShape( wxPoint& aSegStart, wxPoint& aSegEnd, double aRotation,
|
||||
const wxSize& aMargin ) const
|
||||
{
|
||||
int width;
|
||||
|
||||
if( m_Size.y < m_Size.x ) // Build an horizontal equiv segment
|
||||
{
|
||||
int delta = ( m_Size.x - m_Size.y ) / 2;
|
||||
aSegStart.x = -delta - aMargin.x;
|
||||
aSegStart.y = 0;
|
||||
aSegEnd.x = delta + aMargin.x;
|
||||
aSegEnd.y = 0;
|
||||
width = m_Size.y + ( aMargin.y * 2 );
|
||||
}
|
||||
else // Vertical oval: build a vertical equiv segment
|
||||
{
|
||||
int delta = ( m_Size.y -m_Size.x ) / 2;
|
||||
aSegStart.x = 0;
|
||||
aSegStart.y = -delta - aMargin.y;
|
||||
aSegEnd.x = 0;
|
||||
aSegEnd.y = delta + aMargin.y;
|
||||
width = m_Size.x + ( aMargin.x * 2 );
|
||||
}
|
||||
|
||||
if( aRotation )
|
||||
{
|
||||
RotatePoint( &aSegStart, aRotation);
|
||||
RotatePoint( &aSegEnd, aRotation);
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue,
|
||||
double aRotation ) const
|
||||
{
|
||||
wxSize delta;
|
||||
wxSize halfsize;
|
||||
|
||||
halfsize.x = m_Size.x >> 1;
|
||||
halfsize.y = m_Size.y >> 1;
|
||||
|
||||
switch( GetShape() )
|
||||
{
|
||||
case PAD_SHAPE_RECT:
|
||||
// For rectangular shapes, inflate is easy
|
||||
halfsize += aInflateValue;
|
||||
|
||||
// Verify if do not deflate more than than size
|
||||
// Only possible for inflate negative values.
|
||||
if( halfsize.x < 0 )
|
||||
halfsize.x = 0;
|
||||
|
||||
if( halfsize.y < 0 )
|
||||
halfsize.y = 0;
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_TRAPEZOID:
|
||||
// Trapezoidal pad: verify delta values
|
||||
delta.x = ( m_DeltaSize.x >> 1 );
|
||||
delta.y = ( m_DeltaSize.y >> 1 );
|
||||
|
||||
// be sure delta values are not to large
|
||||
if( (delta.x < 0) && (delta.x <= -halfsize.y) )
|
||||
delta.x = -halfsize.y + 1;
|
||||
|
||||
if( (delta.x > 0) && (delta.x >= halfsize.y) )
|
||||
delta.x = halfsize.y - 1;
|
||||
|
||||
if( (delta.y < 0) && (delta.y <= -halfsize.x) )
|
||||
delta.y = -halfsize.x + 1;
|
||||
|
||||
if( (delta.y > 0) && (delta.y >= halfsize.x) )
|
||||
delta.y = halfsize.x - 1;
|
||||
break;
|
||||
|
||||
default: // is used only for rect and trap. pads
|
||||
return;
|
||||
}
|
||||
|
||||
// Build the basic rectangular or trapezoid shape
|
||||
// delta is null for rectangular shapes
|
||||
aCoord[0].x = -halfsize.x - delta.y; // lower left
|
||||
aCoord[0].y = +halfsize.y + delta.x;
|
||||
|
||||
aCoord[1].x = -halfsize.x + delta.y; // upper left
|
||||
aCoord[1].y = -halfsize.y - delta.x;
|
||||
|
||||
aCoord[2].x = +halfsize.x - delta.y; // upper right
|
||||
aCoord[2].y = -halfsize.y + delta.x;
|
||||
|
||||
aCoord[3].x = +halfsize.x + delta.y; // lower right
|
||||
aCoord[3].y = +halfsize.y - delta.x;
|
||||
|
||||
// Offsetting the trapezoid shape id needed
|
||||
// It is assumed delta.x or/and delta.y == 0
|
||||
if( GetShape() == PAD_SHAPE_TRAPEZOID && (aInflateValue.x != 0 || aInflateValue.y != 0) )
|
||||
{
|
||||
double angle;
|
||||
wxSize corr;
|
||||
|
||||
if( delta.y ) // lower and upper segment is horizontal
|
||||
{
|
||||
// Calculate angle of left (or right) segment with vertical axis
|
||||
angle = atan2( (double) m_DeltaSize.y, (double) m_Size.y );
|
||||
|
||||
// left and right sides are moved by aInflateValue.x in their perpendicular direction
|
||||
// We must calculate the corresponding displacement on the horizontal axis
|
||||
// that is delta.x +- corr.x depending on the corner
|
||||
corr.x = KiROUND( tan( angle ) * aInflateValue.x );
|
||||
delta.x = KiROUND( aInflateValue.x / cos( angle ) );
|
||||
|
||||
// Horizontal sides are moved up and down by aInflateValue.y
|
||||
delta.y = aInflateValue.y;
|
||||
|
||||
// corr.y = 0 by the constructor
|
||||
}
|
||||
else if( delta.x ) // left and right segment is vertical
|
||||
{
|
||||
// Calculate angle of lower (or upper) segment with horizontal axis
|
||||
angle = atan2( (double) m_DeltaSize.x, (double) m_Size.x );
|
||||
|
||||
// lower and upper sides are moved by aInflateValue.x in their perpendicular direction
|
||||
// We must calculate the corresponding displacement on the vertical axis
|
||||
// that is delta.y +- corr.y depending on the corner
|
||||
corr.y = KiROUND( tan( angle ) * aInflateValue.y );
|
||||
delta.y = KiROUND( aInflateValue.y / cos( angle ) );
|
||||
|
||||
// Vertical sides are moved left and right by aInflateValue.x
|
||||
delta.x = aInflateValue.x;
|
||||
|
||||
// corr.x = 0 by the constructor
|
||||
}
|
||||
else // the trapezoid is a rectangle
|
||||
{
|
||||
delta = aInflateValue; // this pad is rectangular (delta null).
|
||||
}
|
||||
|
||||
aCoord[0].x += -delta.x - corr.x; // lower left
|
||||
aCoord[0].y += delta.y + corr.y;
|
||||
|
||||
aCoord[1].x += -delta.x + corr.x; // upper left
|
||||
aCoord[1].y += -delta.y - corr.y;
|
||||
|
||||
aCoord[2].x += delta.x - corr.x; // upper right
|
||||
aCoord[2].y += -delta.y + corr.y;
|
||||
|
||||
aCoord[3].x += delta.x + corr.x; // lower right
|
||||
aCoord[3].y += delta.y - corr.y;
|
||||
|
||||
/* test coordinates and clamp them if the offset correction is too large:
|
||||
* Note: if a coordinate is bad, the other "symmetric" coordinate is bad
|
||||
* So when a bad coordinate is found, the 2 symmetric coordinates
|
||||
* are set to the minimun value (0)
|
||||
*/
|
||||
|
||||
if( aCoord[0].x > 0 ) // lower left x coordinate must be <= 0
|
||||
aCoord[0].x = aCoord[3].x = 0;
|
||||
|
||||
if( aCoord[1].x > 0 ) // upper left x coordinate must be <= 0
|
||||
aCoord[1].x = aCoord[2].x = 0;
|
||||
|
||||
if( aCoord[0].y < 0 ) // lower left y coordinate must be >= 0
|
||||
aCoord[0].y = aCoord[1].y = 0;
|
||||
|
||||
if( aCoord[3].y < 0 ) // lower right y coordinate must be >= 0
|
||||
aCoord[3].y = aCoord[2].y = 0;
|
||||
}
|
||||
|
||||
if( aRotation )
|
||||
{
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
RotatePoint( &aCoord[ii], aRotation );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue