void SEGZONE::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
                    const wxPoint& aOffset )
{
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();

    if( displ_opts->m_DisplayZonesMode != 0 )
        return;

    BOARD * brd = GetBoard( );
    EDA_COLOR_T color = brd->GetLayerColor(m_Layer);

    if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
        return;

#ifdef USE_WX_OVERLAY
    // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay
    if( (m_Flags & IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC)))
      return;
#endif

    if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && displ_opts->m_ContrastModeDisplay )
    {
        LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;

        if( !IsOnLayer( curr_layer ) )
            ColorTurnToDarkDarkGray( &color );
    }

    if( aDrawMode & GR_HIGHLIGHT )
        ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) );

    ColorApplyHighlightFlag( &color );

    SetAlpha( &color, 150 );

    GRSetDrawMode( aDC, aDrawMode );

    int l_trace = m_Width / 2;

    if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH )
    {
        GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color );
        return;
    }

    if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
    {
        GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
    }
    else
    {
        GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
                     m_Start.y + aOffset.y,
                     m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color );
    }

    // No clearance or netnames for zones
}
void SEGZONE::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
                    const wxPoint& aOffset )
{
    auto displ_opts = (PCB_DISPLAY_OPTIONS*)( panel->GetDisplayOptions() );

    if( displ_opts->m_DisplayZonesMode != 0 )
        return;

    BOARD* brd = GetBoard();

    auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
    auto color = frame->Settings().Colors().GetLayerColor( m_Layer );

    if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
        return;

#ifdef USE_WX_OVERLAY
    // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay
    if( (m_Flags & IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC)))
      return;
#endif

    if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && displ_opts->m_ContrastModeDisplay )
    {
        PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;

        if( !IsOnLayer( curr_layer ) )
            color = COLOR4D( DARKDARKGRAY );
    }

    if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
        color.SetToLegacyHighlightColor();

    color.a = 0.588;

    GRSetDrawMode( aDC, aDrawMode );

    // Draw track as line if width <= 1pixel:
    if( aDC->LogicalToDeviceXRel( m_Width ) <= 1 )
    {
        GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
        return;
    }

    if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
    {
        GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
    }
    else
    {
        GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
                     m_Start.y + aOffset.y,
                     m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color );
    }

    // No clearance or netnames for zones
}
void D_CODE::DrawFlashedShape(  GERBER_DRAW_ITEM* aParent,
                                EDA_RECT* aClipBox, wxDC* aDC, COLOR4D aColor,
                                wxPoint aShapePos, bool aFilledShape )
{
    int radius;

    switch( m_Shape )
    {
    case APT_MACRO:
        GetMacro()->DrawApertureMacroShape( aParent, aClipBox, aDC, aColor,
                                            aShapePos, aFilledShape);
        break;

    case APT_CIRCLE:
        radius = m_Size.x >> 1;
        if( !aFilledShape )
            GRCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos), radius, 0, aColor );
        else
            if( m_DrillShape == APT_DEF_NO_HOLE )
            {
                GRFilledCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos),
                                radius, aColor );
            }
            else if( m_DrillShape == APT_DEF_ROUND_HOLE )    // round hole in shape
            {
                int width = (m_Size.x - m_Drill.x ) / 2;
                GRCircle( aClipBox, aDC,  aParent->GetABPosition(aShapePos),
                          radius - (width / 2), width, aColor );
            }
            else                            // rectangular hole
            {
                if( m_Polygon.OutlineCount() == 0 )
                    ConvertShapeToPolygon();

                DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
            }
        break;

    case APT_RECT:
    {
        wxPoint start;
        start.x = aShapePos.x - m_Size.x / 2;
        start.y = aShapePos.y - m_Size.y / 2;
        wxPoint end = start + m_Size;
        start = aParent->GetABPosition( start );
        end = aParent->GetABPosition( end );

        if( !aFilledShape )
        {
            GRRect( aClipBox, aDC, start.x, start.y, end.x, end.y, 0, aColor );
        }
        else if( m_DrillShape == APT_DEF_NO_HOLE )
        {
            GRFilledRect( aClipBox, aDC, start.x, start.y, end.x, end.y, 0, aColor, aColor );
        }
        else
        {
            if( m_Polygon.OutlineCount() == 0 )
                ConvertShapeToPolygon();

            DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
        }
    }
    break;

    case APT_OVAL:
    {
        wxPoint start = aShapePos;
        wxPoint end   = aShapePos;

        if( m_Size.x > m_Size.y )   // horizontal oval
        {
            int delta = (m_Size.x - m_Size.y) / 2;
            start.x -= delta;
            end.x   += delta;
            radius   = m_Size.y;
        }
        else   // horizontal oval
        {
            int delta = (m_Size.y - m_Size.x) / 2;
            start.y -= delta;
            end.y   += delta;
            radius   = m_Size.x;
        }

        start = aParent->GetABPosition( start );
        end = aParent->GetABPosition( end );

        if( !aFilledShape )
        {
            GRCSegm( aClipBox, aDC, start.x, start.y, end.x, end.y, radius, aColor );
        }
        else if( m_DrillShape == APT_DEF_NO_HOLE )
        {
            GRFillCSegm( aClipBox, aDC, start.x, start.y, end.x, end.y, radius, aColor );
        }
        else
        {
            if( m_Polygon.OutlineCount() == 0 )
                ConvertShapeToPolygon();

            DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
        }
    }
    break;

    case APT_POLYGON:
        if( m_Polygon.OutlineCount() == 0 )
            ConvertShapeToPolygon();

        DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
        break;
    }
}
void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
                                     wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset )
{
    static std::vector <char>    CornersTypeBuffer;
    static std::vector <wxPoint> CornersBuffer;

    // outline_mode is false to show filled polys,
    // and true to show polygons outlines only (test and debug purposes)
    bool outline_mode = DisplayOpt.DisplayZonesMode == 2 ? true : false;

    if( DC == NULL )
        return;

    if( DisplayOpt.DisplayZonesMode == 1 )     // Do not show filled areas
        return;

    if( m_FilledPolysList.GetCornersCount() == 0 )  // Nothing to draw
        return;

    BOARD* brd = GetBoard();
    LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
    EDA_COLOR_T color = brd->GetLayerColor( m_Layer );

    if( brd->IsLayerVisible( m_Layer ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG )
        return;

    GRSetDrawMode( DC, aDrawMode );

    if( DisplayOpt.ContrastModeDisplay )
    {
        if( !IsOnLayer( curr_layer ) )
            ColorTurnToDarkDarkGray( &color );
    }

    if( aDrawMode & GR_HIGHLIGHT )
        ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) );

    ColorApplyHighlightFlag( &color );

    SetAlpha( &color, 150 );

    CornersTypeBuffer.clear();
    CornersBuffer.clear();

    // Draw all filled areas
    int imax = m_FilledPolysList.GetCornersCount() - 1;

    for( int ic = 0; ic <= imax; ic++ )
    {
        const CPolyPt& corner = m_FilledPolysList.GetCorner( ic );
        wxPoint  coord( corner.x + offset.x, corner.y + offset.y );
        CornersBuffer.push_back( coord );
        CornersTypeBuffer.push_back( (char) corner.m_utility );

        // the last corner of a filled area is found: draw it
        if( (corner.end_contour) || (ic == imax) )
        {
            /* Draw the current filled area: draw segments outline first
             * Curiously, draw segments outline first and after draw filled polygons
             * with outlines thickness = 0 is a faster than
             * just draw filled polygons but with outlines thickness = m_ZoneMinThickness
             * So DO NOT use draw filled polygons with outlines having a thickness  > 0
             * Note: Extra segments ( added to joint holes with external outline) flagged by
             * m_utility != 0 are not drawn
             * Note not all polygon libraries provide a flag for these extra-segments, therefore
             * the m_utility member can be always 0
             */
            {
                // Draw outlines:
                if( (m_ZoneMinThickness > 1) || outline_mode )
                {
                    int ilim = CornersBuffer.size() - 1;

                    for(  int is = 0, ie = ilim; is <= ilim; ie = is, is++ )
                    {
                        int x0 = CornersBuffer[is].x;
                        int y0 = CornersBuffer[is].y;
                        int x1 = CornersBuffer[ie].x;
                        int y1 = CornersBuffer[ie].y;

                        // Draw only basic outlines, not extra segments.
                        if( CornersTypeBuffer[ie] == 0 )
                        {
                            if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
                                GRCSegm( panel->GetClipBox(), DC,
                                         x0, y0, x1, y1,
                                         m_ZoneMinThickness, color );
                            else
                                GRFillCSegm( panel->GetClipBox(), DC,
                                             x0, y0, x1, y1,
                                             m_ZoneMinThickness, color );
                        }
                    }
                }

                // Draw areas:
                if( m_FillMode==0  && !outline_mode )
                    GRPoly( panel->GetClipBox(), DC, CornersBuffer.size(), &CornersBuffer[0],
                            true, 0, color, color );
            }

            CornersTypeBuffer.clear();
            CornersBuffer.clear();
        }
    }

    if( m_FillMode == 1  && !outline_mode )     // filled with segments
    {
        for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
        {
            wxPoint start = m_FillSegmList[ic].m_Start + offset;
            wxPoint end   = m_FillSegmList[ic].m_End + offset;

            if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
                GRCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
                         m_ZoneMinThickness, color );
            else
                GRFillCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
                             m_ZoneMinThickness, color );
        }
    }
}
void MIREPCB::Draw(WinEDA_DrawPanel * panel, wxDC * DC,
	const wxPoint & offset, int mode_color)
/**********************************************************/
/* Affichage de 1 mire : 2 segments + 1 cercle
	le cercle a pour rayon le demi rayon de la mire
	les 2 traits ont pour longueur le diametre de la mire
*/
{
int rayon, ox, oy, gcolor, width;
int dx1,dx2, dy1, dy2;
int typeaff;
int zoom;

	ox = m_Pos.x + offset.x;
	oy = m_Pos.y + offset.y;

	gcolor = g_DesignSettings.m_LayerColor[m_Layer];
	if ( (gcolor & ITEM_NOT_SHOW) != 0 ) return;

	zoom = panel->GetZoom();

	GRSetDrawMode(DC, mode_color);
	typeaff = DisplayOpt.DisplayDrawItems;
	width = m_Width;
	if( width/zoom < 2 ) typeaff = FILAIRE;

	/* Trace du cercle: */
	rayon = m_Size / 4;
	switch( typeaff )
	{
		case FILAIRE:
			GRCircle(&panel->m_ClipBox, DC, ox, oy, rayon, gcolor) ;
			break;

		default:
		case FILLED:
			GRCircle(&panel->m_ClipBox, DC, ox, oy, rayon, width, gcolor);
			break;

		case SKETCH:
			GRCircle(&panel->m_ClipBox, DC, ox, oy, rayon + (width/2), gcolor) ;
			GRCircle(&panel->m_ClipBox, DC, ox, oy, rayon - (width/2), gcolor) ;
			break;
	}


	/* Trace des 2 traits */
	rayon = m_Size/2;
	dx1 = rayon, dy1 = 0;
	dx2 = 0, dy2 = rayon;

	if( m_Shape) /* Forme X */
	{
		dx1 = dy1 = (rayon * 7)/5;
		dx2 = dx1; dy2 = -dy1;
	}

	switch( typeaff )
	{
		case FILAIRE:
			GRLine(&panel->m_ClipBox, DC, ox - dx1, oy - dy1,
					 ox + dx1, oy + dy1, gcolor);
			GRLine(&panel->m_ClipBox, DC, ox - dx2, oy - dy2,
					 ox + dx2, oy + dy2, gcolor);
			break;

		case FILLED:
			GRFillCSegm(&panel->m_ClipBox, DC, ox - dx1, oy - dy1,
						ox + dx1, oy + dy1,
						width, gcolor);
			GRFillCSegm(&panel->m_ClipBox, DC, ox - dx2, oy - dy2,
						ox + dx2, oy + dy2,
						width, gcolor);
			break;

		case SKETCH:
			GRCSegm(&panel->m_ClipBox, DC, ox - dx1, oy - dy1,
						ox + dx1, oy + dy1,
						width, gcolor);
			GRCSegm(&panel->m_ClipBox, DC, ox - dx2, oy - dy2,
						ox + dx2, oy + dy2,
						width, gcolor);
			break;
	}
}
void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
                                     wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset )
{
    static std::vector <wxPoint> CornersBuffer;
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();

    // outline_mode is false to show filled polys,
    // and true to show polygons outlines only (test and debug purposes)
    bool outline_mode = displ_opts->m_DisplayZonesMode == 2 ? true : false;

    if( DC == NULL )
        return;

    if( displ_opts->m_DisplayZonesMode == 1 )     // Do not show filled areas
        return;

    if( m_FilledPolysList.IsEmpty() )  // Nothing to draw
        return;

    BOARD*      brd = GetBoard();
    LAYER_ID    curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
    COLOR4D     color = brd->GetLayerColor( m_Layer );

    if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
        return;

    GRSetDrawMode( DC, aDrawMode );

    if( displ_opts->m_ContrastModeDisplay )
    {
        if( !IsOnLayer( curr_layer ) )
            color = COLOR4D( DARKDARKGRAY );
    }

    if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
        color.SetToLegacyHighlightColor();

    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:
        if( ( m_ZoneMinThickness > 1 ) || outline_mode )
        {
            int ilim = CornersBuffer.size() - 1;

            for( int is = 0, ie = ilim; is <= ilim; ie = is, is++ )
            {
                int x0 = CornersBuffer[is].x;
                int y0 = CornersBuffer[is].y;
                int x1 = CornersBuffer[ie].x;
                int y1 = CornersBuffer[ie].y;

                // Draw only basic outlines, not extra segments.
                if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
                    GRCSegm( panel->GetClipBox(), DC,
                             x0, y0, x1, y1,
                             m_ZoneMinThickness, color );
                else
                    GRFillCSegm( panel->GetClipBox(), DC,
                                 x0, y0, x1, y1, m_ZoneMinThickness, color );
            }
        }

        // Draw areas:
        if( m_FillMode == 0 && !outline_mode )
            GRPoly( panel->GetClipBox(), DC, CornersBuffer.size(), &CornersBuffer[0],
                    true, 0, color, color );
    }

    if( m_FillMode == 1  && !outline_mode )     // filled with segments
    {
        for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
        {
            wxPoint start = m_FillSegmList[ic].m_Start + offset;
            wxPoint end   = m_FillSegmList[ic].m_End + offset;

            if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
                GRCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
                         m_ZoneMinThickness, color );
            else
                GRFillCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
                             m_ZoneMinThickness, color );
        }
    }
}
void Trace_Segment(WinEDA_DrawPanel * panel, wxDC * DC, TRACK* track, int draw_mode)
/***********************************************************************************/
/* routine de trace de 1 segment de piste.
Parametres :
	pt_piste = adresse de la description de la piste en buflib
	draw_mode = mode ( GR_XOR, GR_OR..)
*/
{
int l_piste;
int color;
int zoom;
int rayon;
int fillopt;
static bool show_err;

	color = g_DesignSettings.m_LayerColor[track->m_Layer];
	if(color & ITEM_NOT_SHOW ) return ;

	zoom = panel->GetZoom();

	GRSetDrawMode(DC, draw_mode);
	if( draw_mode & GR_SURBRILL)
		{
		if( draw_mode & GR_AND)	color &= ~HIGHT_LIGHT_FLAG;
		else color |= HIGHT_LIGHT_FLAG;
		}
	if ( color & HIGHT_LIGHT_FLAG)
		color = ColorRefs[color & MASKCOLOR].m_LightColor;

	rayon = l_piste = track->m_Width >> 1;

	fillopt = DisplayOpt.DisplayPcbTrackFill ? FILLED : SKETCH;

	switch (track->m_Shape)
		{
		case S_CIRCLE:
			rayon = (int)hypot((double)(track->m_End.x-track->m_Start.x),
						(double)(track->m_End.y-track->m_Start.y) );
			if ( (l_piste/zoom) < L_MIN_DESSIN)
				{
				GRCircle(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
					rayon , color) ;
				}

			if( fillopt == SKETCH)
				{
				GRCircle(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
						rayon-l_piste, color);
				GRCircle(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
						rayon+l_piste, color);
				}
			else
				{
				GRCircle(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
					rayon, track->m_Width,color);
				}
			break;

		case S_ARC:
			{
			if( fillopt == SKETCH)
				{
				GRArc1(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
						track->m_End.x, track->m_End.y,
						track->m_Param, track->m_Sous_Netcode, color);
				}
			else
				{
				GRArc1(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
						track->m_End.x, track->m_End.y,
						track->m_Param,track->m_Sous_Netcode,
						track->m_Width, color);
				}
			}
			break;

		case S_SPOT_CIRCLE:
			fillopt = DisplayOpt.DisplayPadFill ? FILLED : SKETCH;
			if ( (rayon/zoom) < L_MIN_DESSIN)
				{
				GRCircle(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
					rayon , color) ;
				}

			else if( fillopt == SKETCH )
				{
				GRCircle(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
									rayon, color);
				}
			else
				{
				GRFilledCircle(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
						rayon, color, color);
				}
			break;

		case  S_SPOT_RECT:
		case  S_RECT:
			fillopt = DisplayOpt.DisplayPadFill ? FILLED : SKETCH;
			if ( (l_piste/zoom) < L_MIN_DESSIN)
				{
				GRLine(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
						 track->m_End.x, track->m_End.y, color);
				}
			else if( fillopt == SKETCH )
				{
				GRRect(&panel->m_ClipBox, DC,
						track->m_Start.x - l_piste,
						track->m_Start.y - l_piste,
						track->m_End.x + l_piste,
						track->m_End.y + l_piste,
						color) ;
				}
			else
				{
				GRFilledRect(&panel->m_ClipBox, DC,
						track->m_Start.x - l_piste,
						track->m_Start.y - l_piste,
						track->m_End.x + l_piste,
						track->m_End.y + l_piste,
						color, color) ;
				}
			break;

		case  S_SPOT_OVALE:
			fillopt = DisplayOpt.DisplayPadFill ? FILLED : SKETCH;
		case  S_SEGMENT:
			if ( (l_piste/zoom) < L_MIN_DESSIN)
				{
				GRLine(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
					 track->m_End.x, track->m_End.y, color);
				break;
				}

			if( fillopt == SKETCH )
				{
				GRCSegm(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
						track->m_End.x, track->m_End.y,
				track->m_Width, color) ;
				}
			else
				{
				GRFillCSegm(&panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
						track->m_End.x, track->m_End.y,
						track->m_Width, color) ;
				}
			break;

		default:
			if ( ! show_err )
				{
				DisplayError(panel, wxT("Trace_Segment() type error"));
				show_err = TRUE;
				}
			break;
		}
}
void Trace_DrawSegmentPcb(WinEDA_DrawPanel * panel, wxDC * DC,
		DRAWSEGMENT * PtDrawSegment, int draw_mode)
/**************************************************************************/
/* Affichage d'un segment type drawing PCB:
	Entree : ox, oy = offset de trace
	draw_mode = mode de trace ( GR_OR, GR_XOR, GrAND)
		Les contours sont de differents type:
		segment
		cercle
		arc
*/
{
int ux0, uy0, dx, dy;
int l_piste;
int color, mode;
int zoom = panel->GetZoom();
int rayon;

	color = g_DesignSettings.m_LayerColor[PtDrawSegment->m_Layer];
	if(color & ITEM_NOT_SHOW ) return ;

	GRSetDrawMode(DC, draw_mode);
	l_piste = PtDrawSegment->m_Width >> 1;  /* l_piste = demi largeur piste */

	/* coord de depart */
	ux0 = PtDrawSegment->m_Start.x;
	uy0 = PtDrawSegment->m_Start.y;
	/* coord d'arrivee */
	dx = PtDrawSegment->m_End.x;
	dy = PtDrawSegment->m_End.y;


	mode = DisplayOpt.DisplayPcbTrackFill ? FILLED : SKETCH;
	if(PtDrawSegment->m_Flags & FORCE_SKETCH) mode = SKETCH;
	if ( l_piste < (L_MIN_DESSIN * zoom) ) mode = FILAIRE;

	switch (PtDrawSegment->m_Shape)
		{
		case S_CIRCLE:
			rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) );
			if ( mode == FILAIRE)
				{
				GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon, color) ;
				}
			else if( mode == SKETCH)
				{
				GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon-l_piste, color);
				GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon+l_piste, color);
				}
			else
				{
				GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon, PtDrawSegment->m_Width,color);
				}
			break;

		case S_ARC:
			{
			int StAngle, EndAngle;
			rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) );
			StAngle = (int) ArcTangente(dy-uy0, dx-ux0);
			EndAngle = StAngle + PtDrawSegment->m_Angle;
			if ( mode == FILAIRE)
				GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle, rayon, color);
			else if( mode == SKETCH)
				{
				GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle,
					rayon - l_piste, color);
				GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle,
					rayon + l_piste, color);
				}
			else
				{
				GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle,
						rayon, PtDrawSegment->m_Width,color);
				}
			}
			break;


		default:
			if( mode == FILAIRE)
				GRLine(&panel->m_ClipBox, DC, ux0, uy0, dx, dy, color) ;
			else if( mode == SKETCH)
				{
				GRCSegm(&panel->m_ClipBox, DC, ux0, uy0, dx, dy,
						PtDrawSegment->m_Width, color) ;
				}
			else
				{
				GRFillCSegm(&panel->m_ClipBox, DC, ux0, uy0, dx, dy,
						 PtDrawSegment->m_Width, color) ;
				}
			break;
		}
}
void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
                  const wxPoint& aOffset )
{
    BOARD * brd = GetBoard( );
    EDA_COLOR_T color = brd->GetLayerColor(m_Layer);

    if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
        return;

#ifdef USE_WX_OVERLAY
    // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay
    if( (m_Flags & IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC)))
      return;
#endif

    if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && DisplayOpt.ContrastModeDisplay )
    {
        LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;

        if( !IsOnLayer( curr_layer ) )
            ColorTurnToDarkDarkGray( &color );
    }

    if( aDrawMode & GR_HIGHLIGHT )
        ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) );

    ColorApplyHighlightFlag( &color );

    SetAlpha( &color, 150 );

    GRSetDrawMode( aDC, aDrawMode );

    int l_trace = m_Width / 2;

    if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH )
    {
        GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color );
        return;
    }

    if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
    {
        GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
    }
    else
    {
        GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
                     m_Start.y + aOffset.y,
                     m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color );
    }

    if( panel->GetScreen()->m_IsPrinting )
        return;

    // Show clearance for tracks, not for zone segments
    if( ShowClearance( this ) )
    {
        GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset,
                 m_Width + (GetClearance() * 2), color );
    }

    DrawShortNetname( panel, aDC, aDrawMode, color );
}
void EDA_TextStruct::Draw(WinEDA_DrawPanel * panel, wxDC * DC,
				const wxPoint & offset, int color, int draw_mode,
				int display_mode, int anchor_color)
/***************************************************************/
/*
 Trace de 1 texte type EDA_TextStruct.
	offset = Offset de trace (usuellement (0,0)
	color = couleur du texte
	draw_mode = GR_OR, GR_XOR.., -1 si mode courant.
	display_mose = FILAIRE, FILLED ou SKETCH
    anchor_color = couleur de l'ancre ( -1 si pas d'ancre ).
*/
{
int zoom;
int coord[100];
int ii, jj, kk, ll, nbpoints;
int width;

	if( m_TextDrawings == NULL)	/* pointeur sur la liste des segments de dessin */
		CreateDrawData();
	if( m_TextDrawings == NULL)	return;

	zoom = panel->GetZoom();
	width = m_Width / zoom;
	if ( display_mode == FILAIRE ) width = 0;
	/* choix de la couleur du texte : */
	if ( draw_mode != -1 ) GRSetDrawMode(DC, draw_mode);

	/* trace du texte */
	if ( zoom > m_ZoomLevelDrawable)
		{
		GRLine(&panel->m_ClipBox, DC,
			m_TextDrawings[1] + offset.x + m_Pos.x,
			m_TextDrawings[2] + offset.y + m_Pos.y,
			m_TextDrawings[3] + offset.x + m_Pos.x,
			m_TextDrawings[4] + offset.y + m_Pos.y,
			color);
		}

	else
		{
		/* trace ancre du texte ? */
		if( anchor_color != -1)
			{
			int anchor_size = 2 * zoom;
			anchor_color &= MASKCOLOR;
			/* calcul de la position du texte */
			int cX = m_Pos.x - offset.x;
			int cY = m_Pos.y - offset.y;
			/* trace ancre du texte */
			GRLine(&panel->m_ClipBox, DC, cX - anchor_size, cY,
				cX + anchor_size, cY, anchor_color);
			GRLine(&panel->m_ClipBox, DC, cX, cY - anchor_size ,
				cX, cY + anchor_size , anchor_color);
			}
		jj = 5; ii = jj+1;
		while (ii < m_TextDrawingsSize)
			{
			nbpoints = m_TextDrawings[jj];
			if (nbpoints > 50 ) nbpoints = 50;
			for ( kk = 0, ll = 0; (kk < nbpoints) && (ii < m_TextDrawingsSize) ; kk++)
				{
				coord[ll] = m_TextDrawings[ii] + offset.x + m_Pos.x;
				ll++; ii++;
				coord[ll] = m_TextDrawings[ii] + offset.y + m_Pos.y;
				ll++; ii++;
				}
			jj = ii; ii++;

			if( width > 2)
				{
				for ( kk = 0, ll = 0; kk < (nbpoints-1); kk ++, ll+= 2 )
					{
					if( display_mode == SKETCH)
						GRCSegm(&panel->m_ClipBox, DC,
						coord[ll],coord[ll+1],
						coord[ll+2],coord[ll+3],
						m_Width, color) ;

					else GRFillCSegm(&panel->m_ClipBox, DC,
						coord[ll],coord[ll+1],
						coord[ll+2],coord[ll+3],
						m_Width, color) ;
					}
				}
			else
				GRPoly(&panel->m_ClipBox, DC, nbpoints, coord, 0, color, color);

			}
		 }
}
void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
{
    wxPoint coord[4];
    double  angle = m_Orient;
    int     seg_width;

    GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );

    // 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_CIRCLE:
        if( aDrawInfo.m_ShowPadFilled )
            GRFilledCircle( aClipBox, aDC, shape_pos.x, shape_pos.y,
                            halfsize.x + aDrawInfo.m_Mask_margin.x, 0,
                            aDrawInfo.m_Color, aDrawInfo.m_Color );
        else
            GRCircle( aClipBox, aDC, shape_pos.x, shape_pos.y,
                      halfsize.x + aDrawInfo.m_Mask_margin.x,
                      m_PadSketchModePenSize, aDrawInfo.m_Color );

        if( aDrawInfo.m_PadClearance )
        {
            GRCircle( aClipBox,
                      aDC, shape_pos.x, shape_pos.y,
                      halfsize.x + aDrawInfo.m_PadClearance,
                      0, aDrawInfo.m_Color );
        }

        break;

    case PAD_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( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
                         seg_width, aDrawInfo.m_Color );
        }
        else
        {
            GRCSegm( aClipBox, 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( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
                     seg_width, aDrawInfo.m_Color );
        }
    }
        break;

    case PAD_RECT:
    case PAD_TRAPEZOID:
        BuildPadPolygon( coord, aDrawInfo.m_Mask_margin, angle );

        for( int ii = 0; ii < 4; ii++ )
            coord[ii] += shape_pos;

        GRClosedPoly( aClipBox, aDC, 4, coord, aDrawInfo.m_ShowPadFilled,
                      aDrawInfo.m_ShowPadFilled ? 0 : m_PadSketchModePenSize,
                      aDrawInfo.m_Color, aDrawInfo.m_Color );

        if( aDrawInfo.m_PadClearance )
        {
            BuildPadPolygon( coord, wxSize( aDrawInfo.m_PadClearance,
                                            aDrawInfo.m_PadClearance ), angle );
            for( int ii = 0; ii < 4; ii++ )
                coord[ii] += shape_pos;

            GRClosedPoly( aClipBox, aDC, 4, coord, 0, aDrawInfo.m_Color, aDrawInfo.m_Color );
        }
        break;

    default:
        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;

        if( aDrawInfo.m_IsPrinting )
        {
            blackpenstate = GetGRForceBlackPenState();
            GRForceBlackPen( false );
            aDrawInfo.m_HoleColor = WHITE;
        }

        if( aDrawInfo.m_DrawMode != GR_XOR )
            GRSetDrawMode( aDC, GR_COPY );
        else
            GRSetDrawMode( aDC, GR_XOR );

        EDA_COLOR_T hole_color = aDrawInfo.m_HoleColor;

        if( aDrawInfo. m_ShowNotPlatedHole )    // Draw a specific hole color
            hole_color = aDrawInfo.m_NPHoleColor;

        switch( GetDrillShape() )
        {
        case PAD_DRILL_CIRCLE:
            if( aDC->LogicalToDeviceXRel( hole ) > MIN_DRAW_WIDTH )
                GRFilledCircle( aClipBox, aDC, holepos.x, holepos.y, hole, 0,
                                hole_color, hole_color );
            break;

        case PAD_DRILL_OBLONG:
        {
            wxPoint drl_start, drl_end;
            GetOblongDrillGeometry( drl_start, drl_end, seg_width );
            GRFilledSegment( aClipBox, aDC, holepos + drl_start,
                             holepos + drl_end, seg_width, hole_color );
        }
            break;

        default:
            break;
        }

        if( aDrawInfo.m_IsPrinting )
            GRForceBlackPen( blackpenstate );
    }

    GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );

    // Draw "No connect" ( / or \ or cross X ) if necessary
    if( GetNetCode() == 0 && aDrawInfo.m_ShowNCMark )
    {
        int dx0 = std::min( halfsize.x, halfsize.y );
        EDA_COLOR_T nc_color = BLUE;

        if( m_layerMask[F_Cu] )    /* Draw \ */
            GRLine( aClipBox, aDC, holepos.x - dx0, holepos.y - dx0,
                    holepos.x + dx0, holepos.y + dx0, 0, nc_color );

        if( m_layerMask[B_Cu] )     // Draw /
            GRLine( aClipBox, aDC, holepos.x + dx0, holepos.y - dx0,
                    holepos.x - dx0, holepos.y + dx0, 0, nc_color );
    }

    if( aDrawInfo.m_DrawMode != GR_XOR )
        GRSetDrawMode( aDC, GR_COPY );
    else
        GRSetDrawMode( aDC, GR_XOR );

    // 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
    int     shortname_len = 0;

    if( aDrawInfo.m_Display_netname )
        shortname_len = GetShortNetname().Len();

    if( GetShape() == PAD_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
     */
    #define MIN_CHAR_COUNT 3
    wxString buffer;

    int      tsize;
    EDA_RECT* clipBox = aDrawInfo.m_DrawPanel?
                        aDrawInfo.m_DrawPanel->GetClipBox() : NULL;

    if( aDrawInfo.m_Display_padnum )
    {
        StringPadName( buffer );
        int numpad_len = buffer.Len();
        numpad_len = std::max( numpad_len, MIN_CHAR_COUNT );

        tsize = std::min( 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;
            DrawGraphicHaloText( clipBox, aDC, tpos,
                                 aDrawInfo.m_Color, BLACK, WHITE,
                                 buffer, 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;
        DrawGraphicHaloText( clipBox, aDC, tpos,
                             aDrawInfo.m_Color, BLACK, WHITE,
                             GetShortNetname(), t_angle,
                             wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER,
                             GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
    }
}
void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
                        const wxPoint& aOffset )
{
    int ux0, uy0, dx, dy;
    int l_trace;
    int mode;
    int radius;
    LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
    EDA_COLOR_T color;

    BOARD * brd =  GetBoard( );

    if( brd->IsLayerVisible( GetLayer() ) == false )
        return;

    color = brd->GetLayerColor( GetLayer() );

    if( ( draw_mode & GR_ALLOW_HIGHCONTRAST ) &&  DisplayOpt.ContrastModeDisplay )
    {
        if( !IsOnLayer( curr_layer ) && !IsOnLayer( EDGE_N ) )
            ColorTurnToDarkDarkGray( &color );
    }


    GRSetDrawMode( DC, draw_mode );
    l_trace = m_Width >> 1;  /* half trace width */

    // Line start point or Circle and Arc center
    ux0 = m_Start.x + aOffset.x;
    uy0 = m_Start.y + aOffset.y;

    // Line end point or circle and arc start point
    dx = m_End.x + aOffset.x;
    dy = m_End.y + aOffset.y;

    mode = DisplayOpt.DisplayDrawItems;

    if( m_Flags & FORCE_SKETCH )
        mode = SKETCH;

    if( DC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH )
        mode = LINE;

    switch( m_Shape )
    {
    case S_CIRCLE:
        radius = KiROUND( Distance( ux0, uy0, dx, dy ) );

        if( mode == LINE )
        {
            GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, color );
        }
        else if( mode == SKETCH )
        {
            GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - l_trace, color );
            GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + l_trace, color );
        }
        else
        {
            GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color );
        }

        break;

    case S_ARC:
        double StAngle, EndAngle;
        radius   = KiROUND( Distance( ux0, uy0, dx, dy ) );
        StAngle  = ArcTangente( dy - uy0, dx - ux0 );
        EndAngle = StAngle + m_Angle;

        if( !panel->GetPrintMirrored() )
        {
            if( StAngle > EndAngle )
                EXCHG( StAngle, EndAngle );
        }
        else    // Mirrored mode: arc orientation is reversed
        {
            if( StAngle < EndAngle )
                EXCHG( StAngle, EndAngle );
        }


        if( mode == LINE )
            GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius, color );

        else if( mode == SKETCH )
        {
            GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
                   radius - l_trace, color );
            GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
                   radius + l_trace, color );
        }
        else
        {
            GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
                   radius, m_Width, color );
        }
        break;

    case S_CURVE:
        m_BezierPoints = Bezier2Poly(m_Start, m_BezierC1, m_BezierC2, m_End);

        for (unsigned int i=1; i < m_BezierPoints.size(); i++) {
            if( mode == LINE )
                GRLine( panel->GetClipBox(), DC,
                        m_BezierPoints[i].x, m_BezierPoints[i].y,
                        m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, 0,
                        color );
            else if( mode == SKETCH )
            {
                GRCSegm( panel->GetClipBox(), DC,
                         m_BezierPoints[i].x, m_BezierPoints[i].y,
                         m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
                         m_Width, color );
            }
            else
            {
                GRFillCSegm( panel->GetClipBox(), DC,
                             m_BezierPoints[i].x, m_BezierPoints[i].y,
                             m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
                             m_Width, color );
            }
        }

        break;

    default:
        if( mode == LINE )
        {
            GRLine( panel->GetClipBox(), DC, ux0, uy0, dx, dy, 0, color );
        }
        else if( mode == SKETCH )
        {
            GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
        }
        else
        {
            GRFillCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
        }

        break;
    }
}
Exemple #13
0
void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
{
    wxPoint coord[4];
    int     delta_cx, delta_cy;
    int     angle = m_Orient;
    int     seg_width;

    GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );

    // calculate pad shape position :
    wxPoint shape_pos = ReturnShapePos() - aDrawInfo.m_Offset;

    wxSize  halfsize = m_Size;
    halfsize.x >>= 1;
    halfsize.y >>= 1;

    switch( GetShape() )
    {
    case PAD_CIRCLE:
        if( aDrawInfo.m_ShowPadFilled )
            GRFilledCircle( aClipBox, aDC, shape_pos.x, shape_pos.y,
                            halfsize.x + aDrawInfo.m_Mask_margin.x, 0,
                            aDrawInfo.m_Color, aDrawInfo.m_Color );
        else
            GRCircle( aClipBox, aDC, shape_pos.x, shape_pos.y,
                      halfsize.x + aDrawInfo.m_Mask_margin.x,
                      m_PadSketchModePenSize, aDrawInfo.m_Color );

        if( aDrawInfo.m_PadClearance )
        {
            GRCircle( aClipBox,
                      aDC, shape_pos.x, shape_pos.y,
                      halfsize.x + aDrawInfo.m_PadClearance,
                      0,
                      aDrawInfo.m_Color );
        }

        break;

    case PAD_OVAL:
    {
        wxPoint segStart, segEnd;
        seg_width = BuildSegmentFromOvalShape(segStart, segEnd, angle);
        segStart += shape_pos;
        segEnd += shape_pos;

        if( aDrawInfo.m_ShowPadFilled )
        {
            GRFillCSegm( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
                         seg_width, aDrawInfo.m_Color );
        }
        else
        {
            GRCSegm( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
                     seg_width, m_PadSketchModePenSize, aDrawInfo.m_Color );
        }

        /* Draw the isolation line. */
        if( aDrawInfo.m_PadClearance )
        {
            seg_width += 2 * aDrawInfo.m_PadClearance;
            GRCSegm( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
                     seg_width, aDrawInfo.m_Color );
        }
    }
        break;

    case PAD_RECT:
    case PAD_TRAPEZOID:
        BuildPadPolygon( coord, aDrawInfo.m_Mask_margin, angle );

        for( int ii = 0; ii < 4; ii++ )
            coord[ii] += shape_pos;

        GRClosedPoly( aClipBox, aDC, 4, coord, aDrawInfo.m_ShowPadFilled,
                      aDrawInfo.m_ShowPadFilled ? 0 : m_PadSketchModePenSize,
                      aDrawInfo.m_Color, aDrawInfo.m_Color );

        if( aDrawInfo.m_PadClearance )
        {
            BuildPadPolygon( coord, wxSize( aDrawInfo.m_PadClearance,
                                            aDrawInfo.m_PadClearance ), angle );
            for( int ii = 0; ii < 4; ii++ )
                coord[ii] += shape_pos;

            GRClosedPoly( aClipBox, aDC, 4, coord, 0, aDrawInfo.m_Color, aDrawInfo.m_Color );
        }
        break;


    default:
        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;

        if( aDrawInfo.m_IsPrinting )
        {
            blackpenstate = GetGRForceBlackPenState();
            GRForceBlackPen( false );
            aDrawInfo.m_HoleColor = g_DrawBgColor;
        }

        if( aDrawInfo.m_DrawMode != GR_XOR )
            GRSetDrawMode( aDC, GR_COPY );
        else
            GRSetDrawMode( aDC, GR_XOR );

        int hole_color = aDrawInfo.m_HoleColor;

        if( aDrawInfo. m_ShowNotPlatedHole )    // Draw a specific hole color
            hole_color = aDrawInfo.m_NPHoleColor;

        switch( m_DrillShape )
        {
        case PAD_CIRCLE:
            if( aDC->LogicalToDeviceXRel( hole ) > 1 )
                GRFilledCircle( aClipBox, aDC, holepos.x, holepos.y, hole, 0,
                                aDrawInfo.m_Color, hole_color );
            break;

        case PAD_OVAL:
            halfsize.x = m_Drill.x >> 1;
            halfsize.y = m_Drill.y >> 1;

            if( m_Drill.x > m_Drill.y )  /* horizontal */
            {
                delta_cx = halfsize.x - halfsize.y;
                delta_cy = 0;
                seg_width    = m_Drill.y;
            }
            else                         /* vertical */
            {
                delta_cx = 0;
                delta_cy = halfsize.y - halfsize.x;
                seg_width    = m_Drill.x;
            }

            RotatePoint( &delta_cx, &delta_cy, angle );

            GRFillCSegm( aClipBox, aDC, holepos.x + delta_cx, holepos.y + delta_cy,
                         holepos.x - delta_cx, holepos.y - delta_cy, seg_width,
                         hole_color );
            break;

        default:
            break;
        }

        if( aDrawInfo.m_IsPrinting )
            GRForceBlackPen( blackpenstate );
    }

    GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );

    /* Draw "No connect" ( / or \ or cross X ) if necessary. : */
    if( m_Netname.IsEmpty() && aDrawInfo.m_ShowNCMark )
    {
        int dx0 = MIN( halfsize.x, halfsize.y );
        int nc_color = BLUE;

        if( m_layerMask & LAYER_FRONT )    /* Draw \ */
            GRLine( aClipBox, aDC, holepos.x - dx0, holepos.y - dx0,
                    holepos.x + dx0, holepos.y + dx0, 0, nc_color );

        if( m_layerMask & LAYER_BACK ) /* Draw / */
            GRLine( aClipBox, aDC, holepos.x + dx0, holepos.y - dx0,
                    holepos.x - dx0, holepos.y + dx0, 0, nc_color );
    }

    /* 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
    int     shortname_len = m_ShortNetname.Len();

    if( !aDrawInfo.m_Display_netname )
        shortname_len = 0;

    if( GetShape() == PAD_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 */
    int 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
     */
    #define MIN_CHAR_COUNT 3
    wxString buffer;

    int      tsize;

    if( aDrawInfo.m_Display_padnum )
    {
        ReturnStringPadName( buffer );
        int numpad_len = buffer.Len();
        numpad_len = MAX( numpad_len, MIN_CHAR_COUNT );

        tsize = min( AreaSize.y, AreaSize.x / numpad_len );
        #define CHAR_SIZE_MIN 5

        if( aDC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN ) // Not drawable when size too small.
        {
            // tsize reserve room for marges and segments thickness
            tsize = (int) ( tsize * 0.8 );
            DrawGraphicText( aDrawInfo.m_DrawPanel, aDC, tpos, WHITE, buffer, 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 = MAX( shortname_len, MIN_CHAR_COUNT );
    tsize = min( AreaSize.y, AreaSize.x / shortname_len );

    if( aDC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN )  // 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 = (int) ( tsize * 0.8 );
        DrawGraphicText( aDrawInfo.m_DrawPanel, aDC, tpos, WHITE, m_ShortNetname, t_angle,
                         wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER,
                         GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
    }
}