Commit cffe0cfc authored by charras's avatar charras

support for bezier curves

parent ed50bac8
...@@ -10,6 +10,7 @@ set(COMMON_SRCS ...@@ -10,6 +10,7 @@ set(COMMON_SRCS
base_screen.cpp base_screen.cpp
base_struct.cpp base_struct.cpp
basicframe.cpp basicframe.cpp
bezier_curves.cpp
block_commande.cpp block_commande.cpp
class_drawpickedstruct.cpp class_drawpickedstruct.cpp
common.cpp common.cpp
......
...@@ -9,29 +9,25 @@ ...@@ -9,29 +9,25 @@
#define BUILD_VERSION "(20090621-unstable)" #define BUILD_VERSION "(20090621-unstable)"
#ifndef KICAD_ABOUT_VERSION
#define KICAD_ABOUT_VERSION BUILD_VERSION
#endif
wxString g_BuildVersion
#ifdef HAVE_SVN_VERSION #ifdef HAVE_SVN_VERSION
#include "version.h" #include "version.h"
( wxT( KICAD_SVN_VERSION ) ) wxString g_BuildVersion( wxT( KICAD_SVN_VERSION ) );
#else #else
( wxT( BUILD_VERSION ) ) wxString g_BuildVersion( wxT( BUILD_VERSION ) );
#endif #endif
;
wxString g_BuildAboutVersion
#if defined(HAVE_SVN_VERSION) || defined(HAVE_SVN_REVISION) #if defined(HAVE_SVN_VERSION) || defined(HAVE_SVN_REVISION)
# include "version.h" # include "version.h"
( wxT( KICAD_ABOUT_VERSION ) ) #ifndef KICAD_ABOUT_VERSION
#define KICAD_ABOUT_VERSION BUILD_VERSION
#endif
wxString g_BuildAboutVersion( wxT( KICAD_ABOUT_VERSION ) );
#else #else
( wxT( BUILD_VERSION ) ) wxString g_BuildAboutVersion( wxT( BUILD_VERSION ) );
#endif #endif
;
/**********************************/ /**********************************/
...@@ -137,6 +133,7 @@ void InitKiCadAbout( wxAboutDialogInfo& info ) ...@@ -137,6 +133,7 @@ void InitKiCadAbout( wxAboutDialogInfo& info )
info.AddDeveloper( SetMsg( wxT( "Jerry Jacobs <jerkejacobs@gmail.com>" ) ) ); info.AddDeveloper( SetMsg( wxT( "Jerry Jacobs <jerkejacobs@gmail.com>" ) ) );
info.AddDeveloper( SetMsg( wxT( "Jonas Diemer <diemer@gmx.de>" ) ) ); info.AddDeveloper( SetMsg( wxT( "Jonas Diemer <diemer@gmx.de>" ) ) );
info.AddDeveloper( SetMsg( wxT( "KBool Library <http://boolean.klaasholwerda.nl/bool.html>" ) ) ); info.AddDeveloper( SetMsg( wxT( "KBool Library <http://boolean.klaasholwerda.nl/bool.html>" ) ) );
info.AddDeveloper( SetMsg( wxT( "Marco Serantoni <marco.serantoni@gmail.com>" ) ) );
info.AddDeveloper( SetMsg( wxT( "Rok Markovic <rok@kanardia.eu>" ) ) ); info.AddDeveloper( SetMsg( wxT( "Rok Markovic <rok@kanardia.eu>" ) ) );
info.AddDeveloper( SetMsg( wxT( "Tim Hanson <sideskate@gmail.com>" ) ) ); info.AddDeveloper( SetMsg( wxT( "Tim Hanson <sideskate@gmail.com>" ) ) );
info.AddDeveloper( SetMsg( wxT( "Vesa Solonen <vesa.solonen@hut.fi>" ) ) ); info.AddDeveloper( SetMsg( wxT( "Vesa Solonen <vesa.solonen@hut.fi>" ) ) );
......
This diff is collapsed.
...@@ -289,8 +289,8 @@ void WinEDA_DrawPanel::PostDirtyRect( EDA_Rect aRect ) ...@@ -289,8 +289,8 @@ void WinEDA_DrawPanel::PostDirtyRect( EDA_Rect aRect )
// The pcb units have finer granularity than the pixels, so it can happen // The pcb units have finer granularity than the pixels, so it can happen
// that the rectangle is not large enough for the erase portion. // that the rectangle is not large enough for the erase portion.
aRect.m_Size.x += 2; // += 1 is not enough! aRect.m_Size.x += 4; // += 1 is not enough!
aRect.m_Size.y += 2; aRect.m_Size.y += 4;
// D( printf( "2) PostDirtyRect( x=%d, y=%d, width=%d, height=%d)\n", aRect.m_Pos.x, aRect.m_Pos.y, aRect.m_Size.x, aRect.m_Size.y ); ) // D( printf( "2) PostDirtyRect( x=%d, y=%d, width=%d, height=%d)\n", aRect.m_Pos.x, aRect.m_Pos.y, aRect.m_Size.x, aRect.m_Size.y ); )
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include "macros.h" #include "macros.h"
#include "base_struct.h" #include "base_struct.h"
#include "class_base_screen.h" #include "class_base_screen.h"
#include "bezier_curves.h"
#ifndef FILLED #ifndef FILLED
#define FILLED 1 #define FILLED 1
...@@ -33,7 +35,7 @@ ...@@ -33,7 +35,7 @@
/* variables generales */ /* variables generales */
// pour les tracs en mode XOR = GR_XOR ou GR_NXOR selon couleur de fond // pour les tracÈs en mode XOR = GR_XOR ou GR_NXOR selon couleur de fond
int g_XorMode = GR_NXOR; int g_XorMode = GR_NXOR;
// couleur de fond de la frame de dessin // couleur de fond de la frame de dessin
int g_DrawBgColor = WHITE; int g_DrawBgColor = WHITE;
...@@ -364,7 +366,7 @@ bool GetGRForceBlackPenState( void ) ...@@ -364,7 +366,7 @@ bool GetGRForceBlackPenState( void )
void GRSetDrawMode( wxDC* DC, int draw_mode ) void GRSetDrawMode( wxDC* DC, int draw_mode )
{ {
if( draw_mode & GR_OR ) if( draw_mode & GR_OR )
#if defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS #if defined(__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION(2,9,0) )
DC->SetLogicalFunction( wxCOPY ); DC->SetLogicalFunction( wxCOPY );
#else #else
DC->SetLogicalFunction( wxOR ); DC->SetLogicalFunction( wxOR );
...@@ -372,7 +374,7 @@ void GRSetDrawMode( wxDC* DC, int draw_mode ) ...@@ -372,7 +374,7 @@ void GRSetDrawMode( wxDC* DC, int draw_mode )
else if( draw_mode & GR_XOR ) else if( draw_mode & GR_XOR )
DC->SetLogicalFunction( wxXOR ); DC->SetLogicalFunction( wxXOR );
else if( draw_mode & GR_NXOR ) else if( draw_mode & GR_NXOR )
#if defined (__WXMAC__) && wxMAC_USE_CORE_GRAPHICS #if defined (__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION(2,9,0) )
DC->SetLogicalFunction( wxXOR ); DC->SetLogicalFunction( wxXOR );
#else #else
DC->SetLogicalFunction( wxEQUIV ); DC->SetLogicalFunction( wxEQUIV );
...@@ -1497,3 +1499,36 @@ void ClipAndDrawFilledPoly( EDA_Rect* aClipBox, wxDC* aDC, wxPoint aPoints[], in ...@@ -1497,3 +1499,36 @@ void ClipAndDrawFilledPoly( EDA_Rect* aClipBox, wxDC* aDC, wxPoint aPoints[], in
aDC->DrawPolygon( clippedPolygon.size(), &clippedPolygon[0] ); aDC->DrawPolygon( clippedPolygon.size(), &clippedPolygon[0] );
} }
#endif #endif
void GRBezier( EDA_Rect* ClipBox,
wxDC* DC,
int x1,
int y1,
int x2,
int y2,
int x3,
int y3,
int width,
int Color )
{
std::vector<wxPoint> Points = Bezier2Poly( x1, y1, x2, y2, x3, y3 );
GRPoly( ClipBox, DC, Points.size(), &Points[0], false, width, Color, 0 );
}
void GRBezier( EDA_Rect* ClipBox,
wxDC* DC,
int x1,
int y1,
int x2,
int y2,
int x3,
int y3,
int x4,
int y4,
int width,
int Color )
{
std::vector<wxPoint> Points = Bezier2Poly( x1, y1, x2, y2, x3, y3, x4, y4 );
GRPoly( ClipBox, DC, Points.size(), &Points[0], false, width, Color, 0 );
}
...@@ -515,7 +515,7 @@ void DIALOG_BUILD_BOM::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem, ...@@ -515,7 +515,7 @@ void DIALOG_BUILD_BOM::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem,
/*******************************************************************************************/ /*******************************************************************************************/
{ {
// @todo make this variable length // @todo make this variable length
static const wxCheckBox* FieldListCtrl[] = { const wxCheckBox* FieldListCtrl[] = {
m_AddField1, m_AddField1,
m_AddField2, m_AddField2,
m_AddField3, m_AddField3,
...@@ -586,7 +586,7 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef( ...@@ -586,7 +586,7 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef(
if( CompactForm ) if( CompactForm )
{ {
// @todo make this variable length // @todo make this variable length
static const wxCheckBox* FieldListCtrl[FIELD8 - FIELD1 + 1] = { const wxCheckBox* FieldListCtrl[FIELD8 - FIELD1 + 1] = {
m_AddField1, m_AddField1,
m_AddField2, m_AddField2,
m_AddField3, m_AddField3,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "class_drawpanel.h" #include "class_drawpanel.h"
#include "drawtxt.h" #include "drawtxt.h"
#include "trigo.h" #include "trigo.h"
#include "bezier_curves.h"
#include "program.h" #include "program.h"
#include "libcmp.h" #include "libcmp.h"
...@@ -1104,3 +1105,234 @@ void LibDrawPolyline::DisplayInfo( WinEDA_DrawFrame* frame ) ...@@ -1104,3 +1105,234 @@ void LibDrawPolyline::DisplayInfo( WinEDA_DrawFrame* frame )
frame->MsgPanel->Affiche_1_Parametre( 40, _( "Bounding box" ), msg, BROWN ); frame->MsgPanel->Affiche_1_Parametre( 40, _( "Bounding box" ), msg, BROWN );
} }
/***************************/
/** class LibDrawBezier **/
/***************************/
LibDrawBezier::LibDrawBezier( EDA_LibComponentStruct* aParent ) :
LibEDA_BaseStruct( COMPONENT_BEZIER_DRAW_TYPE, aParent )
{
m_Fill = NO_FILL;
m_Width = 0;
m_typeName = _( "Bezier" );
}
bool LibDrawBezier::Save( FILE* ExportFile ) const
{
int ccount = GetCornerCount();
fprintf( ExportFile, "B %d %d %d %d", ccount, m_Unit, m_Convert, m_Width );
for( unsigned i = 0; i < GetCornerCount(); i++ )
{
fprintf( ExportFile, " %d %d", m_BezierPoints[i].x, m_BezierPoints[i].y );
}
fprintf( ExportFile, " %c\n", fill_tab[m_Fill] );
return true;
}
bool LibDrawBezier::Load( char* line, wxString& errorMsg )
{
char* p;
int i, ccount = 0;
wxPoint pt;
i = sscanf( &line[2], "%d %d %d %d", &ccount, &m_Unit, &m_Convert,
&m_Width );
if( i !=4 )
{
errorMsg.Printf( _( "Bezier only had %d parameters of the required 4" ), i );
return false;
}
if( ccount <= 0 )
{
errorMsg.Printf( _( "Bezier count parameter %d is invalid" ),
ccount );
return false;
}
p = strtok( &line[2], " \t\n" );
p = strtok( NULL, " \t\n" );
p = strtok( NULL, " \t\n" );
p = strtok( NULL, " \t\n" );
for( i = 0; i < ccount; i++ )
{
wxPoint point;
p = strtok( NULL, " \t\n" );
if( sscanf( p, "%d", &pt.x ) != 1 )
{
errorMsg.Printf( _( "Bezier point %d X position not defined" ),
i );
return false;
}
p = strtok( NULL, " \t\n" );
if( sscanf( p, "%d", &pt.y ) != 1 )
{
errorMsg.Printf( _( "Bezier point %d Y position not defined" ),
i );
return false;
}
m_BezierPoints.push_back( pt );
}
m_Fill = NO_FILL;
if( ( p = strtok( NULL, " \t\n" ) ) != NULL )
{
if( p[0] == 'F' )
m_Fill = FILLED_SHAPE;
if( p[0] == 'f' )
m_Fill = FILLED_WITH_BG_BODYCOLOR;
}
return true;
}
LibDrawBezier* LibDrawBezier::GenCopy()
{
LibDrawBezier* newitem = new LibDrawBezier(GetParent());
newitem->m_BezierPoints = m_BezierPoints; // Vector copy
newitem->m_Width = m_Width;
newitem->m_Unit = m_Unit;
newitem->m_Convert = m_Convert;
newitem->m_Flags = m_Flags;
newitem->m_Fill = m_Fill;
return newitem;
}
void LibDrawBezier::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] )
{
wxPoint pos1;
std::vector<wxPoint> PolyPointsTraslated;
int color = ReturnLayerColor( LAYER_DEVICE );
int linewidth = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
m_PolyPoints = Bezier2Poly( m_BezierPoints[0] ,
m_BezierPoints[1] ,
m_BezierPoints[2] ,
m_BezierPoints[3]);
PolyPointsTraslated.clear();
for( unsigned int i = 0; i < m_PolyPoints.size() ; i++)
PolyPointsTraslated.push_back( TransformCoordinate( aTransformMatrix, m_PolyPoints[i] ) + aOffset);
if( aColor < 0 ) // Used normal color or selected color
{
if( m_Selected & IS_SELECTED )
color = g_ItemSelectetColor;
}
else
color = aColor;
FILL_T fill = aData ? NO_FILL : m_Fill;
if( aColor >= 0 )
fill = NO_FILL;
if( fill == FILLED_WITH_BG_BODYCOLOR )
GRPoly( &aPanel->m_ClipBox, aDC, m_PolyPoints.size(),
&PolyPointsTraslated[0], 1, linewidth, color,
ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
else if( fill == FILLED_SHAPE )
GRPoly( &aPanel->m_ClipBox, aDC, m_PolyPoints.size(),
&PolyPointsTraslated[0], 1, linewidth, color, color );
else
GRPoly( &aPanel->m_ClipBox, aDC, m_PolyPoints.size(),
&PolyPointsTraslated[0], 0, linewidth, color, color );
}
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param aRefPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool LibDrawBezier::HitTest( const wxPoint& aRefPos )
{
int mindist = m_Width ? m_Width /2 : g_DrawDefaultLineThickness / 2;
// Have a minimal tolerance for hit test
if ( mindist < 3 )
mindist = 3; // = 3 mils
return HitTest( aRefPos, mindist, DefaultTransformMatrix );
}
/** Function HitTest
* @return true if the point aPosRef is near a segment
* @param aPosRef = a wxPoint to test
* @param aThreshold = max distance to a segment
* @param aTransMat = the transform matrix
*/
bool LibDrawBezier::HitTest( wxPoint aPosRef, int aThreshold,
const int aTransMat[2][2] )
{
wxPoint ref, start, end;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{
start = TransformCoordinate( aTransMat, m_PolyPoints[ii - 1] );
end = TransformCoordinate( aTransMat, m_PolyPoints[ii] );
if ( TestSegmentHit( aPosRef, start, end, aThreshold ) )
return true;
}
return false;
}
/** Function GetBoundingBox
* @return the boundary box for this, in library coordinates
*/
EDA_Rect LibDrawBezier::GetBoundingBox()
{
EDA_Rect rect;
int xmin, xmax, ymin, ymax;
if(!GetCornerCount())
return rect;
xmin = xmax = m_PolyPoints[0].x;
ymin = ymax = m_PolyPoints[0].y;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{
xmin = MIN( xmin, m_PolyPoints[ii].x );
xmax = MAX( xmax, m_PolyPoints[ii].x );
ymin = MIN( ymin, m_PolyPoints[ii].y );
ymax = MAX( ymax, m_PolyPoints[ii].y );
}
rect.SetOrigin( xmin, ymin * -1 );
rect.SetEnd( xmax, ymax * -1 );
rect.Inflate( m_Width / 2, m_Width / 2 );
return rect;
}
void LibDrawBezier::DisplayInfo( WinEDA_DrawFrame* frame )
{
wxString msg;
EDA_Rect bBox = GetBoundingBox();
LibEDA_BaseStruct::DisplayInfo( frame );
msg = ReturnStringFromValue( g_UnitMetric, m_Width,
EESCHEMA_INTERNAL_UNIT, true );
frame->MsgPanel->Affiche_1_Parametre( 20, _( "Line width" ), msg, BLUE );
msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y );
frame->MsgPanel->Affiche_1_Parametre( 40, _( "Bounding box" ), msg, BROWN );
}
...@@ -658,4 +658,70 @@ public: ...@@ -658,4 +658,70 @@ public:
virtual void DisplayInfo( WinEDA_DrawFrame* frame ); virtual void DisplayInfo( WinEDA_DrawFrame* frame );
}; };
/**********************************************************/
/* Graphic Body Item: Bezier Curve (set of lines) */
/**********************************************************/
class LibDrawBezier : public LibEDA_BaseStruct
{
public:
int m_Width; /* Line width */
std::vector<wxPoint> m_BezierPoints; // list of parameter (3|4)
std::vector<wxPoint> m_PolyPoints; // list of points (>= 2)
public:
LibDrawBezier(EDA_LibComponentStruct * aParent);
~LibDrawBezier() { }
virtual wxString GetClass() const
{
return wxT( "LibDrawBezier" );
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd"
* format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
virtual bool Save( FILE* aFile ) const;
virtual bool Load( char* line, wxString& errorMsg );
LibDrawBezier* GenCopy();
void AddPoint( const wxPoint& point );
/** Function GetCornerCount
* @return the number of corners
*/
unsigned GetCornerCount() const { return m_PolyPoints.size(); }
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param aRefPos A wxPoint to test
* @return bool - true if a hit, else false
*/
virtual bool HitTest( const wxPoint& aRefPos );
/** Function HitTest
* @return true if the point aPosRef is near a segment
* @param aPosRef = a wxPoint to test
* @param aThreshold = max distance to a segment
* @param aTransMat = the transform matrix
*/
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] );
/** Function GetBoundingBox
* @return the boundary box for this, in library coordinates
*/
virtual EDA_Rect GetBoundingBox();
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData,
const int aTransformMatrix[2][2] );
virtual void DisplayInfo( WinEDA_DrawFrame* frame );
};
#endif // CLASSES_BODY_ITEMS_H #endif // CLASSES_BODY_ITEMS_H
...@@ -594,6 +594,11 @@ static LibEDA_BaseStruct* ReadDrawEntryItemDescription (EDA_LibComponentStruct* ...@@ -594,6 +594,11 @@ static LibEDA_BaseStruct* ReadDrawEntryItemDescription (EDA_LibComponentStruct*
entryLoaded = New->Load( Line, errorMsg ); entryLoaded = New->Load( Line, errorMsg );
break; break;
case 'B': /* Bezier */
New = ( LibEDA_BaseStruct* ) new LibDrawBezier(aParent);
entryLoaded = New->Load( Line, errorMsg );
break;
default: default:
MsgLine.Printf( wxT( "Undefined DRAW command in line %d\n%s, aborted." ), MsgLine.Printf( wxT( "Undefined DRAW command in line %d\n%s, aborted." ),
*LineNum, Line ); *LineNum, Line );
......
...@@ -717,6 +717,13 @@ LibEDA_BaseStruct* LocateDrawItem( SCH_SCREEN* Screen, ...@@ -717,6 +717,13 @@ LibEDA_BaseStruct* LocateDrawItem( SCH_SCREEN* Screen,
return DrawItem; return DrawItem;
break; break;
case COMPONENT_BEZIER_DRAW_TYPE:
if( (masque & LOCATE_COMPONENT_POLYLINE_DRAW_TYPE) == 0 )
break;
if( DrawItem->HitTest( aRefPoint ) )
return DrawItem;
break;
case COMPONENT_LINE_DRAW_TYPE: case COMPONENT_LINE_DRAW_TYPE:
if( (masque & LOCATE_COMPONENT_LINE_DRAW_TYPE) == 0 ) if( (masque & LOCATE_COMPONENT_LINE_DRAW_TYPE) == 0 )
break; break;
......
...@@ -347,6 +347,29 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem ) ...@@ -347,6 +347,29 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
} }
break; break;
case COMPONENT_BEZIER_DRAW_TYPE:
{
LibDrawBezier* polyline = (LibDrawBezier*) DEntry;
Poly = (int*) MyMalloc( sizeof(int) * 2 * polyline->GetCornerCount() );
for( ii = 0; ii < (int) polyline->GetCornerCount(); ii++ )
{
pos = polyline->m_PolyPoints[ii];
pos = TransformCoordinate( TransMat, pos ) + DrawLibItem->m_Pos;
Poly[ii * 2] = pos.x;
Poly[ii * 2 + 1] = pos.y;
}
if( draw_bgfill && polyline->m_Fill == FILLED_WITH_BG_BODYCOLOR )
{
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
PlotPoly( ii, Poly, true, 0 );
}
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE ) );
PlotPoly( ii, Poly, polyline->m_Fill == FILLED_SHAPE ? true : false, polyline->m_Width );
MyFree( Poly );
}
default: default:
D( printf( "Drawing Type=%d\n", DEntry->Type() ) ); D( printf( "Drawing Type=%d\n", DEntry->Type() ) );
} }
......
...@@ -60,6 +60,10 @@ LibEDA_BaseStruct* CopyDrawEntryStruct( wxWindow* frame, ...@@ -60,6 +60,10 @@ LibEDA_BaseStruct* CopyDrawEntryStruct( wxWindow* frame,
NewDrawItem = ( (LibDrawPolyline*) DrawItem )->GenCopy(); NewDrawItem = ( (LibDrawPolyline*) DrawItem )->GenCopy();
break; break;
case COMPONENT_BEZIER_DRAW_TYPE:
NewDrawItem = ( (LibDrawBezier*) DrawItem )->GenCopy();
break;
default: default:
msg.Printf( wxT( "CopyDrawLibEntryStruct: unknown Draw Type %d" ), msg.Printf( wxT( "CopyDrawLibEntryStruct: unknown Draw Type %d" ),
DrawItem->Type() ); DrawItem->Type() );
......
...@@ -77,6 +77,7 @@ enum KICAD_T { ...@@ -77,6 +77,7 @@ enum KICAD_T {
COMPONENT_LINE_DRAW_TYPE, COMPONENT_LINE_DRAW_TYPE,
COMPONENT_PIN_DRAW_TYPE, COMPONENT_PIN_DRAW_TYPE,
COMPONENT_FIELD_DRAW_TYPE, COMPONENT_FIELD_DRAW_TYPE,
COMPONENT_BEZIER_DRAW_TYPE,
// End value // End value
MAX_STRUCT_TYPE_ID MAX_STRUCT_TYPE_ID
......
#ifndef BEZIER_CURVES_H
#define BEZIER_CURVES_H
#include <vector>
std::vector<wxPoint> Bezier2Poly(wxPoint c1, wxPoint c2, wxPoint c3);
std::vector<wxPoint> Bezier2Poly(wxPoint c1, wxPoint c2, wxPoint c3,wxPoint c4);
std::vector<wxPoint> Bezier2Poly(int x1, int y1, int x2, int y2, int x3, int y3);
std::vector<wxPoint> Bezier2Poly(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
#endif // BEZIER_CURVES_H
...@@ -19,7 +19,8 @@ enum Track_Shapes { ...@@ -19,7 +19,8 @@ enum Track_Shapes {
S_SPOT_OVALE, /* Oblong spot (for GERBER)*/ S_SPOT_OVALE, /* Oblong spot (for GERBER)*/
S_SPOT_CIRCLE, /* rounded spot (for GERBER)*/ S_SPOT_CIRCLE, /* rounded spot (for GERBER)*/
S_SPOT_RECT, /* Rectangular spott (for GERBER)*/ S_SPOT_RECT, /* Rectangular spott (for GERBER)*/
S_POLYGON /* polygonal shape */ S_POLYGON, /* polygonal shape */
S_CURVE /* Bezier Curve*/
}; };
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
#define GR_BASIC #define GR_BASIC
#include "colors.h" #include "colors.h"
#include <vector>
class EDA_Rect; class EDA_Rect;
...@@ -86,6 +85,8 @@ void GRSLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Colo ...@@ -86,6 +85,8 @@ void GRSLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Colo
void GRPoly(EDA_Rect * ClipBox, wxDC * DC, int n, wxPoint Points[], bool Fill, int width, int Color, int BgColor); void GRPoly(EDA_Rect * ClipBox, wxDC * DC, int n, wxPoint Points[], bool Fill, int width, int Color, int BgColor);
void GRBezier(EDA_Rect* ClipBox, wxDC* DC,int x1, int y1, int x2, int y2, int x3, int y3,int width, int Color);
void GRBezier(EDA_Rect* ClipBox, wxDC* DC,int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4,int width, int Color);
/** /**
* Function GRClosedPoly * Function GRClosedPoly
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <vector> #include <vector>
#include <wx/socket.h> #include <wx/socket.h>
#include "wx/log.h" #include "wx/log.h"
#include "wx/config.h" #include "wx/config.h"
......
...@@ -24,6 +24,7 @@ wxString BOARD_ITEM::ShowShape( Track_Shapes aShape ) ...@@ -24,6 +24,7 @@ wxString BOARD_ITEM::ShowShape( Track_Shapes aShape )
case S_RECT: return _( "Rect" ); case S_RECT: return _( "Rect" );
case S_ARC: return _( "Arc" ); case S_ARC: return _( "Arc" );
case S_CIRCLE: return _( "Circle" ); case S_CIRCLE: return _( "Circle" );
case S_CURVE: return _( "Bezier Curve" );
// used in Gerbview: // used in Gerbview:
case S_ARC_RECT: return wxT( "arc_rect" ); case S_ARC_RECT: return wxT( "arc_rect" );
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "fctsys.h" #include "fctsys.h"
#include "wxstruct.h" #include "wxstruct.h"
#include "gr_basic.h" #include "gr_basic.h"
#include "bezier_curves.h"
#include "common.h" #include "common.h"
#include "class_drawpanel.h" #include "class_drawpanel.h"
#include "kicad_string.h" #include "kicad_string.h"
...@@ -39,6 +40,8 @@ void DRAWSEGMENT::Copy( DRAWSEGMENT* source ) ...@@ -39,6 +40,8 @@ void DRAWSEGMENT::Copy( DRAWSEGMENT* source )
m_Shape = source->m_Shape; m_Shape = source->m_Shape;
m_Angle = source->m_Angle; m_Angle = source->m_Angle;
m_TimeStamp = source->m_TimeStamp; m_TimeStamp = source->m_TimeStamp;
m_BezierC1 = source->m_BezierC1;
m_BezierC2 = source->m_BezierC1;
} }
...@@ -56,10 +59,17 @@ bool DRAWSEGMENT::Save( FILE* aFile ) const ...@@ -56,10 +59,17 @@ bool DRAWSEGMENT::Save( FILE* aFile ) const
m_Shape, m_Shape,
m_Start.x, m_Start.y, m_Start.x, m_Start.y,
m_End.x, m_End.y, m_Width ); m_End.x, m_End.y, m_Width );
if( m_Type != S_CURVE) {
fprintf( aFile, "De %d %d %d %lX %X\n", fprintf( aFile, "De %d %d %d %lX %X\n",
m_Layer, m_Type, m_Angle, m_Layer, m_Type, m_Angle,
m_TimeStamp, ReturnStatus() ); m_TimeStamp, ReturnStatus() );
} else {
fprintf( aFile, "De %d %d %d %lX %X %d %d %d %d\n",
m_Layer, m_Type, m_Angle,
m_TimeStamp, ReturnStatus(),
m_BezierC1.x,m_BezierC1.y,
m_BezierC2.x,m_BezierC2.y);
}
if( fprintf( aFile, "$EndDRAWSEGMENT\n" ) != sizeof("$EndDRAWSEGMENT\n") - 1 ) if( fprintf( aFile, "$EndDRAWSEGMENT\n" ) != sizeof("$EndDRAWSEGMENT\n") - 1 )
goto out; goto out;
...@@ -96,9 +106,44 @@ bool DRAWSEGMENT::ReadDrawSegmentDescr( FILE* File, int* LineNum ) ...@@ -96,9 +106,44 @@ bool DRAWSEGMENT::ReadDrawSegmentDescr( FILE* File, int* LineNum )
if( Line[0] == 'D' ) if( Line[0] == 'D' )
{ {
int status; int status;
sscanf( Line + 2, " %d %d %d %lX %X", char* token=0;
&m_Layer, &m_Type, &m_Angle,
&m_TimeStamp, &status ); token = strtok(Line," ");
for(int i=0; (token = strtok(NULL," ")) != NULL; i++){
switch(i){
case 0:
sscanf(token,"%d",&m_Layer);
break;
case 1:
sscanf(token,"%d",&m_Type);
break;
case 2:
sscanf(token,"%d",&m_Angle);
break;
case 3:
sscanf(token,"%lX",&m_TimeStamp);
break;
case 4:
sscanf(token,"%X",&status);
break;
/* Bezier Control Points*/
case 5:
sscanf(token,"%d",&m_BezierC1.x);
break;
case 6:
sscanf(token,"%d",&m_BezierC1.y);
break;
case 7:
sscanf(token,"%d",&m_BezierC2.x);
break;
case 8:
sscanf(token,"%d",&m_BezierC2.y);
break;
default:
break;
}
}
if( m_Layer < FIRST_NO_COPPER_LAYER ) if( m_Layer < FIRST_NO_COPPER_LAYER )
m_Layer = FIRST_NO_COPPER_LAYER; m_Layer = FIRST_NO_COPPER_LAYER;
...@@ -235,7 +280,30 @@ void DRAWSEGMENT::Draw( WinEDA_DrawPanel* panel, wxDC* DC, ...@@ -235,7 +280,30 @@ void DRAWSEGMENT::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
rayon, m_Width, color ); rayon, m_Width, color );
} }
break; 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 == FILAIRE )
GRLine( &panel->m_ClipBox, 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->m_ClipBox, 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->m_ClipBox, DC,
m_BezierPoints[i].x, m_BezierPoints[i].y,
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
m_Width, color );
}
}
break;
default: default:
if( mode == FILAIRE ) if( mode == FILAIRE )
GRLine( &panel->m_ClipBox, DC, ux0, uy0, dx, dy, 0, color ); GRLine( &panel->m_ClipBox, DC, ux0, uy0, dx, dy, 0, color );
...@@ -274,19 +342,24 @@ void DRAWSEGMENT::DisplayInfo( WinEDA_DrawFrame* frame ) ...@@ -274,19 +342,24 @@ void DRAWSEGMENT::DisplayInfo( WinEDA_DrawFrame* frame )
wxString shape = _( "Shape" ); wxString shape = _( "Shape" );
if( m_Shape == S_CIRCLE ) switch( m_Shape ) {
Affiche_1_Parametre( frame, 10, shape, _( "Circle" ), RED ); case S_CIRCLE:
Affiche_1_Parametre( frame, 10, shape, _( "Circle" ), RED );
break;
else if( m_Shape == S_ARC ) case S_ARC:
{ Affiche_1_Parametre( frame, 10, shape, _( "Arc" ), RED );
Affiche_1_Parametre( frame, 10, shape, _( "Arc" ), RED );
msg.Printf( wxT( "%d.%d" ), m_Angle/10, m_Angle % 10 ); msg.Printf( wxT( "%d.%d" ), m_Angle/10, m_Angle % 10 );
Affiche_1_Parametre( frame, 18, _("Angle"), msg, RED ); Affiche_1_Parametre( frame, 18, _("Angle"), msg, RED );
} break;
else case S_CURVE:
Affiche_1_Parametre( frame, 10, shape, _( "Segment" ), RED ); Affiche_1_Parametre( frame, 10, shape, _( "Curve" ), RED );
break;
default:
Affiche_1_Parametre( frame, 10, shape, _( "Segment" ), RED );
}
wxString start; wxString start;
start << GetStart(); start << GetStart();
...@@ -322,37 +395,46 @@ bool DRAWSEGMENT::HitTest( const wxPoint& ref_pos ) ...@@ -322,37 +395,46 @@ bool DRAWSEGMENT::HitTest( const wxPoint& ref_pos )
int spot_cX = ref_pos.x - ux0; int spot_cX = ref_pos.x - ux0;
int spot_cY = ref_pos.y - uy0; int spot_cY = ref_pos.y - uy0;
if( m_Shape==S_CIRCLE || m_Shape==S_ARC ) switch(m_Shape){
{ case S_CIRCLE:
int rayon, dist, stAngle, endAngle, mouseAngle; case S_ARC:
rayon = (int) hypot( (double) (dx), (double) (dy) ); int rayon, dist, stAngle, endAngle, mouseAngle;
dist = (int) hypot( (double) (spot_cX), (double) (spot_cY) );
if( abs( rayon - dist ) <= ( m_Width / 2 ) ) rayon = (int) hypot( (double) (dx), (double) (dy) );
{ dist = (int) hypot( (double) (spot_cX), (double) (spot_cY) );
if( m_Shape == S_CIRCLE )
return true;
/* pour un arc, controle complementaire */ if( abs( rayon - dist ) <= ( m_Width / 2 ) )
mouseAngle = (int) ArcTangente( spot_cY, spot_cX );
stAngle = (int) ArcTangente( dy, dx );
endAngle = stAngle + m_Angle;
if( endAngle > 3600 )
{ {
stAngle -= 3600; if( m_Shape == S_CIRCLE )
endAngle -= 3600; return true;
/* pour un arc, controle complementaire */
mouseAngle = (int) ArcTangente( spot_cY, spot_cX );
stAngle = (int) ArcTangente( dy, dx );
endAngle = stAngle + m_Angle;
if( endAngle > 3600 )
{
stAngle -= 3600;
endAngle -= 3600;
}
if( mouseAngle >= stAngle && mouseAngle <= endAngle )
return true;
} }
break;
if( mouseAngle >= stAngle && mouseAngle <= endAngle ) case S_CURVE:
for( unsigned int i= 1; i < m_BezierPoints.size(); i++)
{
if( TestSegmentHit( ref_pos,m_BezierPoints[i-1],m_BezierPoints[i-1], m_Width / 2 ) )
return true;
}
break;
default:
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true; return true;
}
}
else
{
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true;
} }
return false; return false;
} }
......
...@@ -15,7 +15,10 @@ public: ...@@ -15,7 +15,10 @@ public:
int m_Shape; // Shape: line, Circle, Arc int m_Shape; // Shape: line, Circle, Arc
int m_Type; // Used in complex associations ( Dimensions.. ) int m_Type; // Used in complex associations ( Dimensions.. )
int m_Angle; // Used only for Arcs: Arc angle in 1/10 deg int m_Angle; // Used only for Arcs: Arc angle in 1/10 deg
wxPoint m_BezierC1; // Bezier Control Point 1
wxPoint m_BezierC2; // Bezier Control Point 1
std::vector<wxPoint> m_BezierPoints;
public: public:
DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype = TYPE_DRAWSEGMENT ); DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype = TYPE_DRAWSEGMENT );
~DRAWSEGMENT(); ~DRAWSEGMENT();
......
...@@ -46,8 +46,8 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin ...@@ -46,8 +46,8 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin
if( frame->m_DisplayPadFill == FILLED ) if( frame->m_DisplayPadFill == FILLED )
fillpad = 1; fillpad = 1;
#ifdef PCBNEW #if defined(PCBNEW) || defined(__WXMAC__)
if( m_Flags & IS_MOVED ) if( m_Flags & IS_MOVED || !DisplayOpt.DisplayPadFill )
fillpad = 0; fillpad = 0;
#endif #endif
......
...@@ -348,6 +348,8 @@ void WinEDA_PcbFrame::Install_Edit_Cotation( COTATION* Cotation, ...@@ -348,6 +348,8 @@ void WinEDA_PcbFrame::Install_Edit_Cotation( COTATION* Cotation,
WinEDA_CotationPropertiesFrame* frame = new WinEDA_CotationPropertiesFrame( this, WinEDA_CotationPropertiesFrame* frame = new WinEDA_CotationPropertiesFrame( this,
Cotation, DC, pos ); Cotation, DC, pos );
Ajuste_Details_Cotation( Cotation );
frame->ShowModal(); frame->ShowModal();
frame->Destroy(); frame->Destroy();
} }
......
...@@ -787,8 +787,11 @@ void DrawModuleOutlines( WinEDA_DrawPanel* panel, wxDC* DC, MODULE* module ) ...@@ -787,8 +787,11 @@ void DrawModuleOutlines( WinEDA_DrawPanel* panel, wxDC* DC, MODULE* module )
if( g_Show_Pads_Module_in_Move ) if( g_Show_Pads_Module_in_Move )
{ {
pad_fill_tmp = DisplayOpt.DisplayPadFill; pad_fill_tmp = DisplayOpt.DisplayPadFill;
#ifndef __WXMAC__
DisplayOpt.DisplayPadFill = true; /* Trace en SKETCH en deplacement */ DisplayOpt.DisplayPadFill = true; /* Trace en SKETCH en deplacement */
#else
DisplayOpt.DisplayPadFill = false;
#endif
pt_pad = module->m_Pads; pt_pad = module->m_Pads;
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() ) for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
{ {
......
...@@ -753,32 +753,69 @@ void PlotDrawSegment( DRAWSEGMENT* pt_segm, int Format, int masque_layer ) ...@@ -753,32 +753,69 @@ void PlotDrawSegment( DRAWSEGMENT* pt_segm, int Format, int masque_layer )
{ {
case PLOT_FORMAT_GERBER: case PLOT_FORMAT_GERBER:
SelectD_CODE_For_LineDraw( thickness ); SelectD_CODE_For_LineDraw( thickness );
if( pt_segm->m_Shape == S_CIRCLE )
PlotCircle( PLOT_FORMAT_GERBER, thickness, start, radius ); switch(pt_segm->m_Shape)
else if( pt_segm->m_Shape == S_ARC ) {
PlotArc( PLOT_FORMAT_GERBER, start, case S_CIRCLE:
PlotCircle( PLOT_FORMAT_GERBER, thickness, start, radius );
break;
case S_ARC:
PlotArc( PLOT_FORMAT_GERBER, start,
StAngle, EndAngle, radius, thickness ); StAngle, EndAngle, radius, thickness );
else break;
PlotGERBERLine( start, end, thickness ); case S_CURVE:
break; for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
PlotGERBERLine( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness);
}
break;
default:
PlotGERBERLine( start, end, thickness );
}
break;
case PLOT_FORMAT_HPGL: case PLOT_FORMAT_HPGL:
if( pt_segm->m_Shape == S_CIRCLE )
PlotCircle( PLOT_FORMAT_HPGL, thickness, start, radius );
else if( pt_segm->m_Shape == S_ARC )
PlotArc( PLOT_FORMAT_HPGL, start, StAngle, EndAngle, radius, thickness );
else
Plot_Filled_Segment_HPGL( start, end, thickness, (GRFillMode) g_Plot_Mode );
break;
switch(pt_segm->m_Shape)
{
case S_CIRCLE:
PlotCircle( PLOT_FORMAT_HPGL, thickness, start, radius );
break;
case S_ARC:
PlotArc( PLOT_FORMAT_HPGL, start, StAngle, EndAngle, radius, thickness );
break;
case S_CURVE:
for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
Plot_Filled_Segment_HPGL( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness,(GRFillMode) g_Plot_Mode);
}
break;
default:
Plot_Filled_Segment_HPGL( start, end, thickness, (GRFillMode) g_Plot_Mode );
}
break;
case PLOT_FORMAT_POST: case PLOT_FORMAT_POST:
if( pt_segm->m_Shape == S_CIRCLE ) switch(pt_segm->m_Shape)
PlotCircle( PLOT_FORMAT_POST, thickness, start, radius ); {
else if( pt_segm->m_Shape == S_ARC ) case S_CIRCLE:
PlotArc( PLOT_FORMAT_POST, start, PlotCircle( PLOT_FORMAT_POST, thickness, start, radius );
break;
case S_ARC:
PlotArc( PLOT_FORMAT_POST, start,
StAngle, EndAngle, radius, thickness ); StAngle, EndAngle, radius, thickness );
else break;
PlotFilledSegmentPS( start, end, thickness );
case S_CURVE:
for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
PlotFilledSegmentPS( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness);
}
break;
default:
PlotFilledSegmentPS( start, end, thickness );
}
break; break;
} }
} }
......
...@@ -9,11 +9,13 @@ ...@@ -9,11 +9,13 @@
#include "fctsys.h" #include "fctsys.h"
#include "PolyLine.h" #include "PolyLine.h"
#include "gr_basic.h"
#include "bezier_curves.h"
using namespace std; using namespace std;
#define pi 3.14159265359 #define pi M_PI
CPolyLine::CPolyLine() CPolyLine::CPolyLine()
{ {
...@@ -1571,3 +1573,21 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n ...@@ -1571,3 +1573,21 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n
Close( STRAIGHT ); Close( STRAIGHT );
} }
// Bezier Support
void CPolyLine::AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3) {
std::vector<wxPoint> bezier_points;
bezier_points = Bezier2Poly(x1,y1,x2,y2,x3,y3);
for( unsigned int i = 0; i < bezier_points.size() ; i++)
AppendCorner( bezier_points[i].x, bezier_points[i].y);
}
void CPolyLine::AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){
std::vector<wxPoint> bezier_points;
bezier_points = Bezier2Poly(x1,y1,x2,y2,x3,y3,x4,y4);
for( unsigned int i = 0; i < bezier_points.size() ; i++)
AppendCorner( bezier_points[i].x, bezier_points[i].y);
}
...@@ -243,6 +243,11 @@ public: ...@@ -243,6 +243,11 @@ public:
private: private:
Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data
bool bDrawn; bool bDrawn;
// Bezier Support
public:
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3);
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
}; };
#endif // #ifndef POLYLINE_H #endif // #ifndef POLYLINE_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment