/********************************/ /* Low level graphics routines */ /********************************/ #include "fctsys.h" #include "gr_basic.h" #include "common.h" #ifdef PCBNEW #include "pcbnew.h" #endif #ifdef EESCHEMA #include "program.h" #include "libcmp.h" #include "general.h" #endif #ifdef CVPCB #include "pcbnew.h" #include "cvpcb.h" #endif #include "trigo.h" #ifndef FILLED #define FILLED 1 #endif #ifndef EXCHG #define EXCHG(a,b) { int __temp__ = (a); (a) = (b); (b) = __temp__; } #endif /* Variables locales */ static int GRLastMoveToX , GRLastMoveToY; static int Text_Color = LIGHTGRAY; static int PenMinWidth = 1; /* largeur minimum de la plume (DOIT etre > 0) (utile pour trace sur imprimante) */ static int ForceBlackPen; /* si != 0 : traces en noir (utilise pour trace sur imprimante */ static int xcliplo = 0, ycliplo = 0, xcliphi = 2000, ycliphi = 2000; /* coord de la surface de trace */ static int lastcolor = -1; static int lastwidth = -1; static wxDC * lastDC = NULL; /* Macro de clipping du trace d'une ligne: la ligne (x1,y1 x2,y2) est clippee pour rester dans le cadre (xcliplo,ycliplo xcliphi,ycliphi) (variables globales,locales a ce fichier) Ceci est necessaire sous WIN95 car les coord de trace (bien que en int 32bits) sont tronquees en 16 bits (stupide BG) */ #ifndef us #define us unsigned int #endif static inline int USCALE(us arg, us num, us den) { int ii; ii = (int)( ((float) arg * num) / den); return( ii ); } #ifdef WX_ZOOM #define GET_ZOOM 1 #else #define GET_ZOOM ActiveScreen->GetZoom() #endif static int inline ZoomValue(int value_to_zoom) { int zoom = GET_ZOOM; if ( value_to_zoom >= 0 ) return( (value_to_zoom + (zoom >> 1 ) ) /zoom ); else return( (value_to_zoom - (zoom >> 1 ) ) /zoom ); } /****************************************/ /* External reference for the mappings. */ /****************************************/ int GRMapX(int x) { int coord = x - ActiveScreen->m_DrawOrg.x; #ifndef WX_ZOOM coord = ZoomValue(coord); coord -= ActiveScreen->m_StartVisu.x; #endif return coord; } int GRMapY(int y) { int coord = y - ActiveScreen->m_DrawOrg.y; #ifndef WX_ZOOM coord = ZoomValue(coord); coord -= ActiveScreen->m_StartVisu.y; #endif return coord; } #define WHEN_OUTSIDE return #define WHEN_INSIDE #define CLIP_LINE(x1,y1,x2,y2) \ {\ int temp;\ do {\ if(x1 > x2) { EXCHG(x1,x2); EXCHG(y1,y2); }\ if((x2 < xcliplo) || (x1 > xcliphi)) { WHEN_OUTSIDE; }\ if(y1 < y2)\ {\ if((y2 < ycliplo) || (y1 > ycliphi)) { WHEN_OUTSIDE;}\ if(y1 < ycliplo)\ {\ temp = USCALE((x2 - x1),(ycliplo - y1),(y2 - y1));\ if((x1 += temp) > xcliphi) { WHEN_OUTSIDE; }\ y1 = ycliplo;\ WHEN_INSIDE;\ }\ if(y2 > ycliphi)\ {\ temp = USCALE((x2 - x1),(y2 - ycliphi),(y2 - y1));\ if((x2 -= temp) < xcliplo) { WHEN_OUTSIDE; }\ y2 = ycliphi;\ WHEN_INSIDE;\ }\ if(x1 < xcliplo)\ {\ temp = USCALE((y2 - y1),(xcliplo - x1),(x2 - x1));\ y1 += temp; x1 = xcliplo;\ WHEN_INSIDE;\ }\ if(x2 > xcliphi)\ {\ temp = USCALE((y2 - y1),(x2 - xcliphi),(x2 - x1));\ y2 -= temp; x2 = xcliphi;\ WHEN_INSIDE;\ }\ }\ else\ {\ if((y1 < ycliplo) || (y2 > ycliphi)) { WHEN_OUTSIDE; }\ if(y1 > ycliphi)\ {\ temp = USCALE((x2 - x1),(y1 - ycliphi),(y1 - y2));\ if((x1 += temp) > xcliphi) { WHEN_OUTSIDE; }\ y1 = ycliphi;\ WHEN_INSIDE;\ }\ if(y2 < ycliplo)\ {\ temp = USCALE((x2 - x1),(ycliplo - y2),(y1 - y2));\ if((x2 -= temp) < xcliplo) { WHEN_OUTSIDE; }\ y2 = ycliplo;\ WHEN_INSIDE;\ }\ if(x1 < xcliplo)\ {\ temp = USCALE((y1 - y2),(xcliplo - x1),(x2 - x1));\ y1 -= temp; x1 = xcliplo;\ WHEN_INSIDE;\ }\ if(x2 > xcliphi)\ {\ temp = USCALE((y1 - y2),(x2 - xcliphi),(x2 - x1));\ y2 += temp; x2 = xcliphi;\ WHEN_INSIDE;\ }\ }\ } while(0);\ } static void WinClipAndDrawLine(EDA_Rect * ClipBox, wxDC * DC, int x1, int y1, int x2, int y2, int Color, int width = 1 ) { GRLastMoveToX = x2; GRLastMoveToY = y2; if ( ClipBox ) { xcliplo = ClipBox->GetX(); ycliplo = ClipBox->GetY(); xcliphi = ClipBox->GetRight(); ycliphi = ClipBox->GetBottom(); xcliplo -= width; ycliplo -= width; xcliphi += width; ycliphi += width; CLIP_LINE(x1, y1, x2, y2); } GRSetColorPen(DC, Color, width); DC->DrawLine(x1, y1, x2, y2); } /* Routine de forcage de la reinit de la plume courante. Doit etre appelee par securite apres changement de contexte graphique avant tout trace */ void GRResetPenAndBrush(wxDC * DC) { lastcolor = -1; GRSetBrush(DC, BLACK); // Force no fill lastDC = NULL; } /* routine d'ajustage de la largeur mini de plume */ void SetPenMinWidth(int minwidth) { PenMinWidth = minwidth; if( PenMinWidth < 1 ) PenMinWidth = 1; } /* Routine de changement de couleurs et epaisseur de la plume courante */ void GRSetColorPen(wxDC * DC, int Color , int width) { Color &= MASKCOLOR; // Pour 32 couleurs Max if(width < PenMinWidth) width = PenMinWidth; if( ForceBlackPen && Color != WHITE ) Color = BLACK; if( (lastcolor != Color) || (lastwidth != width) || (lastDC != DC ) ) { DrawPen->SetColour( ColorRefs[Color].m_Red, ColorRefs[Color].m_Green, ColorRefs[Color].m_Blue ); DrawPen->SetWidth(width); if ( &DC->GetPen() != DrawPen ) DC->SetPen(*DrawPen); lastcolor = Color; lastwidth = width; lastDC = DC; } } /***********************************************/ void GRSetBrush(wxDC * DC, int Color , int fill) /***********************************************/ { Color &= MASKCOLOR; // Pour 32 couleurs Max if( ForceBlackPen && Color != WHITE ) Color = BLACK; DrawBrush->SetColour( ColorRefs[Color].m_Red, ColorRefs[Color].m_Green, ColorRefs[Color].m_Blue ); if ( fill ) DrawBrush->SetStyle(wxSOLID); else DrawBrush->SetStyle(wxTRANSPARENT); if ( &DC->GetBrush() != DrawBrush ) DC->SetBrush(*DrawBrush); } /*************************************/ void GRForceBlackPen(bool flagforce ) /*************************************/ { ForceBlackPen = flagforce; } /************************************************************/ /* routines de controle et positionnement du curseur souris */ /************************************************************/ /* positionne la souris au point de coord pos */ void GRMouseWarp(WinEDA_DrawPanel * panel, const wxPoint& pos) { if( panel == NULL ) return; panel->WarpPointer(pos.x, pos.y); } /**********************************************/ /* Routine pour selectionner le mode de trace */ /**********************************************/ void GRSetDrawMode(wxDC * DC, int draw_mode) { if( draw_mode & GR_OR ) DC->SetLogicalFunction(wxOR); else if( draw_mode & GR_XOR ) DC->SetLogicalFunction(wxXOR); else if( draw_mode & GR_NXOR ) DC->SetLogicalFunction(wxEQUIV); else DC->SetLogicalFunction(wxCOPY); } /*********************************************************************/ void GRPutPixel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int Color) /*********************************************************************/ { GRSPutPixel(ClipBox, DC, GRMapX(x), GRMapY(y), Color); } /********************************************************************/ void GRSPutPixel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int Color) /********************************************************************/ { if ( ClipBox ) /* suppression des pixels hors ecran */ { if ( x < ClipBox->GetX() ) return; if ( y < ClipBox->GetY() ) return; if ( x > (ClipBox->GetRight()) ) return; if ( y > (ClipBox->GetBottom()) ) return; } GRSetColorPen(DC, Color ); DC->DrawPoint( x, y); } /*******************************************/ /* int GRGetPixel(wxDC * DC, int x, int y) */ /*******************************************/ int GRGetPixel(wxDC * DC, int x, int y) { wxColour colour; unsigned char r, g, b; int ii; DC->GetPixel( (long)x, (long)y, &colour); r = colour.Red(); b = colour.Blue(); g = colour.Green(); for ( ii = 0; ii < NBCOLOR; ii++ ) { if( ( r == ColorRefs[ii].m_Red ) && ( g == ColorRefs[ii].m_Green ) && ( b == ColorRefs[ii].m_Blue ) ) break; } return ii; } /**************************************************************************** * Routine to draw a line, in Object spaces. * ****************************************************************************/ void GRLine(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color) { GRSLine(ClipBox, DC, GRMapX(x1), GRMapY(y1), GRMapX(x2), GRMapY(y2), Color); } /***************************************************/ /* Routine to draw a Dashed line, in Screen space. */ /***************************************************/ void GRSDashedLine(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color) { GRLastMoveToX = x2; GRLastMoveToY = y2; lastcolor = -1; DrawPen->SetStyle(wxSHORT_DASH); GRSLine(ClipBox, DC, x1, y1, x2, y2, Color); lastcolor = -1; DrawPen->SetStyle(wxSOLID); } void GRSDashedLineTo(EDA_Rect * ClipBox,wxDC * DC, int x2, int y2, int Color) { lastcolor = -1; DrawPen->SetStyle(wxSHORT_DASH); GRSLine(ClipBox, DC, GRLastMoveToX, GRLastMoveToY, x2, y2, Color); lastcolor = -1; DrawPen->SetStyle(wxSOLID); GRLastMoveToX = x2; GRLastMoveToY = y2; } /**************************************************************************** * Routine to draw a Dashed line, in Object spaces. * ****************************************************************************/ void GRDashedLineTo(EDA_Rect * ClipBox,wxDC * DC,int x2, int y2, int Color) { GRSDashedLineTo(ClipBox, DC, GRMapX(x2), GRMapY(y2), Color); } void GRDashedLine(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color) { GRSDashedLine(ClipBox, DC, GRMapX(x1), GRMapY(y1), GRMapX(x2), GRMapY(y2), Color); } /*************************************************/ /* Routine to draw a Bus line, in Object spaces. */ /*************************************************/ void GRBusLine(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color) { x1 = GRMapX(x1); x2 = GRMapX(x2); y1 = GRMapY(y1); y2 = GRMapY(y2); GRSBusLine(ClipBox, DC, x1, y1, x2, y2, Color); } /**************************************************************** * Routine to draw a Bus Line, in Screen (pixels) space. * ****************************************************************************/ void GRSBusLine(EDA_Rect * ClipBox, wxDC * DC, int x1, int y1, int x2, int y2, int Color) { GRSFillCSegm(ClipBox, DC, x1, y1, x2, y2, 3*PenMinWidth, Color); GRLastMoveToX = x2; GRLastMoveToY = y2; } /**************************************************************************** * Routine to move to a new position, in Object space. * ****************************************************************************/ void GRMoveTo(int x, int y) { GRLastMoveToX = GRMapX(x); GRLastMoveToY = GRMapY(y); } /*******************************************************/ /* Routine to draw to a new position, in Object space. */ /*******************************************************/ void GRLineTo(EDA_Rect * ClipBox,wxDC * DC, int x, int y, int Color) { int GRLineToX, GRLineToY; GRLineToX = GRMapX(x); GRLineToY = GRMapY(y); GRSLine(ClipBox, DC, GRLastMoveToX, GRLastMoveToY, GRLineToX, GRLineToY, Color); } /*************************************************/ /* Routine to draw a Mixed line, in Object space */ /*************************************************/ void GRMixedLine(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color) { GRSMixedLine(ClipBox, DC, GRMapX(x1), GRMapY(y1), GRMapX(x2), GRMapY(y2), Color); } /***********************************************************/ /* Routine to draw a Mixed line, in Screen (Pixels) space */ /***********************************************************/ void GRSMixedLine(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color) { DrawPen->SetStyle(wxDOT_DASH); GRSLine(ClipBox, DC, x1, y1, x2, y2, Color); DrawPen->SetStyle(wxSOLID); } /*******************************************************************/ /* Routine to draw a Bus line to a new position, in Object spaces. */ /*******************************************************************/ void GRBusLineTo(EDA_Rect * ClipBox,wxDC * DC, int x, int y, int Color) { int GRLineToX, GRLineToY; GRLineToX = GRMapX(x); GRLineToY = GRMapY(y); GRSBusLine(ClipBox, DC, GRLastMoveToX, GRLastMoveToY, GRLineToX, GRLineToY, Color); GRLastMoveToX = GRLineToX; GRLastMoveToY = GRLineToY; } /**************************************************************************** * Routine to move to a new position, in Screen (pixels) space. * ****************************************************************************/ void GRSMoveTo(int x, int y) { GRLastMoveToX = x; GRLastMoveToY = y; } /**************************************************************************** * Routine to draw to a new position, in Screen (pixels) space. * ****************************************************************************/ void GRSLineTo(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int Color) { GRSLine(ClipBox, DC, GRLastMoveToX, GRLastMoveToY, x, y, Color); GRLastMoveToX = x; GRLastMoveToY = y; } /**************************************************************************** * Routine to draw to a new position, in Screen (pixels) space. * ****************************************************************************/ void GRSLine(EDA_Rect * ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int Color) { WinClipAndDrawLine(ClipBox, DC, x1, y1, x2, y2, Color); GRLastMoveToX = x2; GRLastMoveToY = y2; } /****************************************************************************/ /* Routine to move to a new position relative to current one, as in Object */ /* space. */ /****************************************************************************/ void GRMoveRel(int x, int y) { GRLastMoveToX += ZoomValue(x); GRLastMoveToY += ZoomValue(y); } /**************************************************************************** * Routine to line to a new position relative to current one, as in Object * * space. * ****************************************************************************/ void GRLineRel(EDA_Rect * ClipBox,wxDC * DC, int x, int y, int Color) { int GRLineToX = GRLastMoveToX, GRLineToY = GRLastMoveToY; GRLineToX += ZoomValue(x); GRLineToY += ZoomValue(y); GRSLine(ClipBox, DC, GRLastMoveToX, GRLastMoveToY, GRLineToX, GRLineToY, Color); } /**************************************************************************** * Routine to move to a new position relative to current one, as in Screen * * space (pixel coords.). * ****************************************************************************/ void GRSMoveRel(int x, int y) { GRLastMoveToX += x; GRLastMoveToY += y; } /**************************************************************************** * Routine to line to a new position relative to current one, as in Screen * * space (pixel coords.). * ****************************************************************************/ void GRSLineRel(EDA_Rect * ClipBox,wxDC * DC, int x, int y, int Color) { long GRLineToX = GRLastMoveToX + x, GRLineToY = GRLastMoveToY + y; GRSLine(ClipBox, DC, GRLastMoveToX, GRLastMoveToY, GRLineToX, GRLineToY, Color); GRLastMoveToX = GRLineToX; GRLastMoveToY = GRLineToY; } /**************************************************/ /* Routine de trace d'un segment a bouts arrondis */ /* Object space = real coords.). */ /**************************************************/ void GRCSegm(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int width, int Color) { GRSCSegm(ClipBox, DC, GRMapX(x1), GRMapY(y1), GRMapX(x2), GRMapY(y2), ZoomValue(width), Color); } /******************************************************************* * Routine de trace d'un segment (plein) a bouts arrondis in Object * * space (real coords.). * ********************************************************************/ void GRFillCSegm(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int width, int Color) { GRSFillCSegm(ClipBox, DC, GRMapX(x1), GRMapY(y1), GRMapX(x2), GRMapY(y2), ZoomValue(width), Color); } /**********************************************************/ /* Routine de trace d'un segment (plein) a bouts arrondis */ /* ( Screen space = pixel coords.). */ /**********************************************************/ void GRSFillCSegm(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int width, int Color) { WinClipAndDrawLine(ClipBox, DC, x1,y1,x2,y2, Color, width); } /****************************************************************/ /* Routine de trace d'un segment a bouts arrondis (Mode SKETCH) */ /* Screen space (pixel coords.). */ /****************************************************************/ void GRSCSegm(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int width, int Color) { long rayon, dwx, dwy; long dx, dy, dwx2, dwy2; long sx1, sy1, ex1, ey1; /* coord du 1er bord */ long sx2, sy2, ex2, ey2; /* coord du 1eme bord */ bool swap_ends = FALSE; GRLastMoveToX = x2; GRLastMoveToY = y2; if ( ClipBox ) { xcliplo = ClipBox->GetX(); ycliplo = ClipBox->GetY(); xcliphi = ClipBox->GetRight(); ycliphi = ClipBox->GetHeight(); xcliplo -= width; ycliplo -= width; xcliphi += width; ycliphi += width; CLIP_LINE(x1, y1, x2, y2); } if ( width <= 2 ) /* ligne simple ou epaisse de 2 pixels*/ { GRSetColorPen(DC, Color, width ); DC->DrawLine(x1, y1, x2, y2); return; } GRSetColorPen(DC, Color ); GRSetBrush(DC,Color,FALSE); rayon = (width+1) >> 1; dx = x2 - x1; dy = y2 - y1; if ( dx == 0 ) /* segment vertical */ { dwx = rayon; if ( dy >= 0 ) dwx = -dwx; sx1 = x1 - dwx; sy1 = y1; ex1 = x2 - dwx; ey1 = y2; DC->DrawLine(sx1 , sy1, ex1, ey1); sx2 = x1 + dwx; sy2 = y1; ex2 = x2 + dwx; ey2 = y2; DC->DrawLine(sx2, sy2, ex2, ey2); } else if ( dy == 0 ) /* segment horizontal */ { dwy = rayon; if ( dx < 0 ) dwy = -dwy; sx1 = x1, sy1 = y1 - dwy; ex1 = x2; ey1 = y2 - dwy; DC->DrawLine(sx1, sy1, ex1 , ey1); sx2 = x1; sy2 = y1 + dwy; ex2 = x2; ey2 = y2 + dwy; DC->DrawLine(sx2, sy2, ex2 , ey2); } else { if ( ABS(dx) == ABS(dy) ) /* segment a 45 degre */ { dwx = dwy = ((width * 5)+ 4) / 7; // = width/2 * 0.707 if ( dy < 0 ) { if ( dx <= 0 ) { dwx = -dwx; swap_ends = TRUE; } } else { if( dx > 0 ) { dwy = -dwy; swap_ends = TRUE; } } } else { int delta_angle = ArcTangente(dy, dx); dwx = 0; dwy = width; RotatePoint( (int*)&dwx, (int*)&dwy, -delta_angle); } dwx2 = dwx >> 1; dwy2 = dwy >> 1; sx1 = x1 - dwx2; sy1 = y1 - dwy2; ex1 = x2 - dwx2; ey1 = y2 - dwy2; DC->DrawLine(sx1, sy1, ex1, ey1); sx2 = x1 + dwx2; sy2 = y1 + dwy2; ex2 = x2 + dwx2; ey2 = y2 + dwy2; DC->DrawLine(sx2, sy2, ex2, ey2); } if ( swap_ends ) { DC->DrawArc(sx2, sy2, sx1 , sy1, x1, y1); DC->DrawArc(ex1, ey1, ex2, ey2, x2, y2); } else { DC->DrawArc(sx1, sy1, sx2 , sy2, x1, y1); DC->DrawArc(ex2, ey2, ex1, ey1, x2, y2); } } static bool IsGRSPolyDrawable( EDA_Rect * ClipBox,int n, int *Points) { int ii; int Xmin, Xmax, Ymin, Ymax; Xmin = Xmax = Points[0]; Ymin = Ymax = Points[1]; for ( ii = 1; ii < n; ii++) // calcul du rectangle d'encadrement { int jj = ii * 2; Xmin = MIN(Xmin,Points[jj]); Xmax = MAX(Xmax,Points[jj]); Ymin = MIN(Ymin,Points[jj+1]); Ymax = MAX(Ymax,Points[jj+1]); } xcliplo = ClipBox->GetX(); ycliplo = ClipBox->GetY(); xcliphi = ClipBox->GetRight(); ycliphi = ClipBox->GetHeight(); if ( Xmax < xcliplo ) return FALSE; if ( Xmin > xcliphi ) return FALSE; if ( Ymax < ycliplo ) return FALSE; if ( Ymin > ycliphi ) return FALSE; return TRUE; } /************************************************************************/ /* Routine to draw a new polyline and fill it if Fill, in screen space. */ /************************************************************************/ void GRSPoly(EDA_Rect * ClipBox,wxDC * DC, int n, int *Points, int Fill, int Color, int BgColor) { int startx, starty; if ( ! IsGRSPolyDrawable(ClipBox, n, Points) ) return; GRSetColorPen(DC, Color ); if( Fill && ( n > 2 ) ) { GRSetBrush(DC, BgColor, FILLED); DC->DrawPolygon(n, (wxPoint*)Points); } else { startx = Points[n * 2 - 2]; starty = Points[n * 2 - 1]; GRSetBrush(DC, Color); DC->DrawLines(n, (wxPoint*)Points); } } /************************************************************************/ /* Routine to draw a new polyline (line width = Width), in screen space. */ /************************************************************************/ void GRSPolyLines(EDA_Rect * ClipBox,wxDC * DC, int n, int *Points, int Color, int BgColor, int Width) { int startx, starty; if ( ! IsGRSPolyDrawable(ClipBox, n, Points) ) return; GRSetColorPen(DC, Color, Width ); startx = Points[n * 2 - 2]; starty = Points[n * 2 - 1]; GRSetBrush(DC, Color); DC->DrawLines(n, (wxPoint*)Points); } /******************************************************************************/ /* Routine to draw a new closed polyline and fill it if Fill, in screen space */ /******************************************************************************/ void GRSClosedPoly(EDA_Rect * ClipBox,wxDC * DC, int n, int *Points, int Fill, int Color, int BgColor) { int startx, starty; if ( ! IsGRSPolyDrawable(ClipBox, n, Points) ) return; GRSetColorPen(DC, Color ); if( Fill && ( n > 2 ) ) { GRSMoveTo(Points[n * 2 - 2], Points[n * 2 - 1]); GRSetBrush(DC, BgColor, FILLED); DC->DrawPolygon(n, (wxPoint*) Points, 0, 0,wxODDEVEN_RULE ); } else { startx = Points[n * 2 - 2]; starty = Points[n * 2 - 1]; GRSetBrush(DC, BgColor); DC->DrawLines(n, (wxPoint*)Points); /* Fermeture du polygone */ if( (startx != Points[0]) || (starty != Points[1]) ) { GRSLine(ClipBox, DC, Points[0], Points[1], startx, starty, Color); } } } /************************************************************************/ /* Routine to draw a new polyline and fill it if Fill, in drawing space. */ /************************************************************************/ void GRPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, int Fill, int Color, int BgColor) { int ii, jj; for (ii = 0; ii < n; ii++) { jj = ii << 1; Points[jj] = GRMapX(Points[jj]); jj++; Points[jj] = GRMapY(Points[jj]); } GRSPoly(ClipBox, DC, n, Points, Fill, Color, BgColor); } void GRPolyLines(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, int Color, int BgColor, int width) { int ii, jj; width = ZoomValue(width); for (ii = 0; ii < n; ii++) { jj = ii << 1; Points[jj] = GRMapX(Points[jj]); jj++; Points[jj] = GRMapY(Points[jj]); } if ( width <= 1 ) GRSPoly(ClipBox, DC, n, Points, 0, Color, BgColor); else GRSPolyLines(ClipBox, DC, n, Points, Color, BgColor, width); } /**************************************************************************/ /* Routine to draw a closed polyline and fill it if Fill, in object space */ /**************************************************************************/ void GRClosedPoly(EDA_Rect * ClipBox,wxDC * DC, int n, int *Points, int Fill, int Color, int BgColor) { int ii, jj; for (ii = 0; ii < n; ii++) { jj = ii << 1; Points[jj] = GRMapX(Points[jj]); jj++; Points[jj] = GRMapY(Points[jj]); } GRSClosedPoly(ClipBox, DC, n, Points, Fill, Color, BgColor); } /***********************************************/ /* Routine to draw a circle, in object space. */ /***********************************************/ void GRCircle(EDA_Rect * ClipBox,wxDC * DC, int x, int y, int r, int Color) { int cx = GRMapX(x); int cy = GRMapY(y); int rayon = ZoomValue(r); GRSCircle(ClipBox, DC, cx, cy, rayon, Color ); } /*****************************************************/ /* Routine to draw a Filled circle, in object space. */ /*****************************************************/ void GRFilledCircle(EDA_Rect * ClipBox,wxDC * DC, int x, int y, int r, int Color, int BgColor) { r = ZoomValue(r); GRSFilledCircle(ClipBox, DC, GRMapX(x), GRMapY(y), r, Color, BgColor ); } /***********************************************************/ /* Routine to draw un anneau, epaisseur w, in object space. */ /***********************************************************/ void GRCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, int width, int Color) { r = ZoomValue(r); width = ZoomValue(width); GRSCircle(ClipBox, DC, GRMapX(x), GRMapY(y), r, width, Color); } /***********************************************/ /* Routine to draw a circle, in drawing space. */ /***********************************************/ void GRSCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, int Color) { int d = r + r; /* suppression des cercles hors ecran */ if ( ClipBox ) { int x0, y0, xm, ym; x0 = ClipBox->GetX(); y0 = ClipBox->GetY(); xm = ClipBox->GetRight(); ym = ClipBox->GetBottom(); if ( x < (x0-r) ) return; if ( y < (y0-r) ) return; if ( x > (r+xm) ) return; if ( y > (r+ym) ) return; } GRSetColorPen(DC, Color); GRSetBrush(DC,Color,FALSE); DC->DrawEllipse(x-r,y-r, d, d); } /******************************************************/ /* Routine to draw a FILLED circle, in drawing space. */ /******************************************************/ void GRSFilledCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, int Color, int BgColor) { /* suppression des cercles hors ecran */ if ( ClipBox ) { int x0, y0, xm, ym; x0 = ClipBox->GetX(); y0 = ClipBox->GetY(); xm = ClipBox->GetRight(); ym = ClipBox->GetBottom(); if ( x < (x0-r) ) return; if ( y < (y0-r) ) return; if ( x > (r+xm) ) return; if ( y > (r+ym) ) return; } GRSetColorPen(DC, Color ); GRSetBrush(DC, BgColor, FILLED); DC->DrawEllipse(x-r, y-r, r+r, r+r); } /***********************************************************************/ /* Routine de trace d'un cercle epais ( Screen space = pixel coords.) */ /***********************************************************************/ void GRSCircle(EDA_Rect * ClipBox,wxDC * DC, int xc, int yc, int r, int width, int Color) { /* suppression des cercles hors ecran */ if ( ClipBox ) { int x0, y0, xm, ym; x0 = ClipBox->GetX(); y0 = ClipBox->GetY(); xm = ClipBox->GetRight(); ym = ClipBox->GetBottom(); if ( xc < (x0-r - width) ) return; if ( yc < (y0-r - width) ) return; if ( xc > (r+xm + width) ) return; if ( yc > (r+ym + width) ) return; } GRSetColorPen(DC, Color, width); GRSetBrush(DC, Color, FALSE); DC->DrawEllipse(xc-r, yc-r, r+r, r+r); } /************************************************/ /* Routine to draw an arc, in USER space. */ /* Debut et fin de l'arc donnes par leur coord. */ /************************************************/ void GRArc1(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int xc, int yc, int Color) { GRSArc1(ClipBox, DC, GRMapX(x1), GRMapY(y1), GRMapX(x2), GRMapY(y2), GRMapX(xc), GRMapY(yc), Color); } /************************************************/ /* Routine to draw an arc, width = width in USER space. */ /* Debut et fin de l'arc donnes par leur coord. */ /************************************************/ void GRArc1(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int xc, int yc, int width, int Color) { GRSArc1(ClipBox, DC, GRMapX(x1), GRMapY(y1), GRMapX(x2), GRMapY(y2), GRMapX(xc), GRMapY(yc), ZoomValue(width), Color); } /************************************************/ /* Routine to draw an arc, in screen space. */ /* Debut et fin de l'arc donnes par leur coord. */ /************************************************/ void GRSArc1(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int xc, int yc, int Color) { /* suppression des cercles hors ecran */ if ( ClipBox ) { int x0, y0, xm, ym, r; x0 = ClipBox->GetX(); y0 = ClipBox->GetY(); xm = ClipBox->GetRight(); ym = ClipBox->GetBottom(); r = (int)hypot(x1-xc, y1-yc); if ( xc < (x0-r) ) return; if ( yc < (y0-r) ) return; if ( xc > (r+xm) ) return; if ( yc > (r+ym) ) return; } GRSetColorPen(DC, Color ); GRSetBrush(DC,Color,FALSE); DC->DrawArc(x1, y1, x2, y2, xc, yc); } /************************************************/ /* Routine to draw an arc, width = width, in screen space. */ /* Debut et fin de l'arc donnes par leur coord. */ /************************************************/ void GRSArc1(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int xc, int yc, int width, int Color) { /* suppression des cercles hors ecran */ if ( ClipBox ) { int x0, y0, xm, ym, r; x0 = ClipBox->GetX(); y0 = ClipBox->GetY(); xm = ClipBox->GetRight(); ym = ClipBox->GetBottom(); r = (int)hypot(x1-xc, y1-yc); if ( xc < (x0-r) ) return; if ( yc < (y0-r) ) return; if ( xc > (r+xm) ) return; if ( yc > (r+ym) ) return; } GRSetColorPen(DC, Color , width); GRSetBrush(DC, Color); DC->DrawArc(x1, y1, x2, y2, xc, yc); } /********************************************************************/ /* Routine to draw an arc, in screen space. */ /* As the Y axe is inverted the Angles should be inverted as well. */ /********************************************************************/ void GRSArc(EDA_Rect * ClipBox,wxDC * DC, int xc, int yc, int StAngle, int EndAngle, int r, int Color) { int x1, y1, x2, y2; /* suppression des cercles hors ecran */ if ( ClipBox ) { int x0, y0, xm, ym; x0 = ClipBox->GetX(); y0 = ClipBox->GetY(); xm = ClipBox->GetRight(); ym = ClipBox->GetBottom(); if ( xc < (x0-r - 1) ) return; if ( yc < (y0-r - 1) ) return; if ( xc > (r+xm + 1) ) return; if ( yc > (r+ym + 1) ) return; } x1 = r; y1 = 0; RotatePoint( &x1, & y1, EndAngle); x2 = r; y2 = 0; RotatePoint( &x2, & y2, StAngle); GRSetColorPen(DC, Color); GRSetBrush(DC,Color,FALSE); DC->DrawArc(xc + x1, yc - y1, xc + x2, yc - y2, xc, yc); } /********************************************************************/ /* Routine to draw an arc, width = width, in screen space. */ /* As the Y axe is inverted the Angles should be inverted as well. */ /********************************************************************/ void GRSArc(EDA_Rect * ClipBox,wxDC * DC, int xc, int yc, int StAngle, int EndAngle, int r, int width, int Color) { int x1, y1, x2, y2; /* suppression des cercles hors ecran */ if ( ClipBox ) { int x0, y0, xm, ym; x0 = ClipBox->GetX(); y0 = ClipBox->GetY(); xm = ClipBox->GetRight(); ym = ClipBox->GetBottom(); if ( xc < (x0-r - width) ) return; if ( yc < (y0-r - width) ) return; if ( xc > (r+xm + width) ) return; if ( yc > (r+ym + width) ) return; } x1 = r; y1 = 0; RotatePoint( &x1, & y1, EndAngle); x2 = r; y2 = 0; RotatePoint( &x2, & y2, StAngle); GRSetColorPen(DC, Color , width); GRSetBrush(DC, Color); DC->DrawArc(xc + x1, yc - y1, xc + x2, yc - y2, xc, yc); } /********************************************************************/ /* Routine to draw an Filled arc, in screen space. */ /* As the Y axes is inverted the Angles should be inverted as well. */ /********************************************************************/ void GRSFilledArc(EDA_Rect * ClipBox,wxDC * DC, int xc, int yc, int StAngle, int EndAngle, int r, int Color, int BgColor) { int x1, y1, x2, y2; /* suppression des cercles hors ecran */ if ( ClipBox ) { int x0, y0, xm, ym; x0 = ClipBox->GetX(); y0 = ClipBox->GetY(); xm = ClipBox->GetRight(); ym = ClipBox->GetBottom(); if ( xc < (x0-r - 1) ) return; if ( yc < (y0-r - 1) ) return; if ( xc > (r+xm + 1) ) return; if ( yc > (r+ym + 1) ) return; } x1 = r; y1 = 0; RotatePoint( &x1, & y1, EndAngle); x2 = r; y2 = 0; RotatePoint( &x2, & y2, StAngle); GRSetBrush(DC, BgColor, FILLED); GRSetColorPen(DC, Color); DC->DrawArc(xc + x1, yc - y1, xc + x2, yc - y2, xc, yc); } /********************************************************************/ /* Routine to draw a Filled arc, in drawing space. */ /* As the Y axes is inverted the Angles should be inverted as well. */ /********************************************************************/ void GRFilledArc(EDA_Rect * ClipBox,wxDC * DC, int x, int y, int StAngle, int EndAngle, int r, int Color, int BgColor) { GRSFilledArc(ClipBox, DC, GRMapX(x), GRMapY(y), StAngle, EndAngle, ZoomValue(r), Color, BgColor); } /********************************************************************/ /* Routine to draw an arc, in drawing space. */ /* As the Y axes is inverted the Angles should be inverted as well. */ /********************************************************************/ void GRArc(EDA_Rect * ClipBox,wxDC * DC, int xc, int yc, int StAngle, int EndAngle, int r, int Color) { int x1, y1, x2, y2; /* suppression des cercles hors ecran */ if ( ClipBox ) { int rayon = ZoomValue(r) + 1; int x0, y0, xm, ym, x, y; x0 = ClipBox->GetX(); y0 = ClipBox->GetY(); xm = ClipBox->GetRight(); ym = ClipBox->GetBottom(); x = GRMapX(xc); y = GRMapY(yc); if ( x < (x0 - rayon) ) return; if ( y < (y0 - rayon) ) return; if ( x > (xm + rayon) ) return; if ( y > (ym + rayon) ) return; } x1 = r; y1 = 0; RotatePoint( &x1, & y1, EndAngle); x2 = r; y2 = 0; RotatePoint( &x2, & y2, StAngle); GRSetColorPen(DC, Color); GRSetBrush(DC,Color,FALSE); DC->DrawArc(GRMapX(xc + x1), GRMapY(yc - y1), GRMapX(xc + x2), GRMapY(yc - y2), GRMapX(xc), GRMapY(yc) ); } /********************************************************************/ /* Routine to draw an arc, width = width, in drawing space. */ /* As the Y axes is inverted the Angles should be inverted as well. */ /********************************************************************/ void GRArc(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int StAngle, int EndAngle, int r, int width, int Color) { GRSArc(ClipBox, DC, GRMapX(x), GRMapY(y), StAngle, EndAngle, ZoomValue(r), ZoomValue(width), Color); } /**************************************************/ /* Routine to draw a Rectangle, in drawing space. */ /**************************************************/ void GRRect(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color) { x1 = GRMapX(x1); y1 = GRMapY(y1); x2 = GRMapX(x2); y2 = GRMapY(y2); GRSRect(ClipBox, DC, x1, y1, x2, y2, Color ); } /************************************************************************************/ void GRFilledRect(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color, int BgColor) /************************************************************************************/ /* Routine to draw a Rectangle (filled with AreaColor), in drawing space. */ { x1 = GRMapX(x1); y1 = GRMapY(y1); x2 = GRMapX(x2); y2 = GRMapY(y2); GRSFilledRect(ClipBox, DC, x1, y1, x2, y2, Color, BgColor ); } /*************************************************/ /* Routine to draw a Rectangle, in screen space. */ /*************************************************/ void GRSRect(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color) { if(x1 > x2) EXCHG(x1,x2); if(y1 > y2) EXCHG(y1,y2); /* Clipping des coordonnees */ if ( ClipBox ) { int xmin = ClipBox->GetX(); int ymin = ClipBox->GetY(); int xmax = ClipBox->GetRight(); int ymax = ClipBox->GetBottom(); if ( x1 > xmax ) return; if ( x2 < xmin ) return; if ( y1 > ymax ) return; if ( y2 < ymin ) return; } GRSetColorPen(DC, Color ); if ( (x1 == x2) || (y1 == y2) ) DC->DrawLine(x1, y1, x2, y2); else { GRSetBrush(DC, BLACK ); DC->DrawRectangle(x1, y1, x2 - x1, y2 - y1); } } /***************************************************************************************/ void GRSFilledRect(EDA_Rect * ClipBox,wxDC * DC, int x1, int y1, int x2, int y2, int Color, int BgColor) /***************************************************************************************/ /* Routine to draw a Filled Rectangle, in screen space. */ { if(x1 > x2) EXCHG(x1,x2); if(y1 > y2) EXCHG(y1,y2); if ( ClipBox ) { int xmin = ClipBox->GetX(); int ymin = ClipBox->GetY(); int xmax = ClipBox->GetRight(); int ymax = ClipBox->GetBottom(); if ( x1 > xmax ) return; if ( x2 < xmin ) return; if ( y1 > ymax ) return; if ( y2 < ymin ) return; // Clipping des coordonnees if ( x1 < xmin )x1 = xmin -1; if ( y1 < ymin )y1 = ymin -1; if ( x2 > xmax ) x2 = xmax +1; if ( y2 > ymax ) y2 = ymax +1; } GRSetColorPen(DC, Color ); if ( (x1 == x2) || (y1 == y2) ) DC->DrawLine(x1, y1, x2, y2); else { GRSetBrush(DC, BgColor, FILLED); DC->DrawRectangle(x1, y1, x2 - x1, y2 - y1); } } /****************************************/ /* Routines relatives au trace de texte */ /****************************************/ /*********************************************/ /* Routine de selection de la fonte courante */ /*********************************************/ void GRSetFont(wxDC * DC, wxFont * Font) { DC->SetFont(*Font); } /*********************************************************/ /* void GRSetTextFgColor(wxFont * Font, int Color) */ /*********************************************************/ /* Mise a la valeur Color des textes a afficher */ void GRSetTextFgColor(wxDC * DC, int Color) { DC->SetTextForeground(wxColour( ColorRefs[Color].m_Red, ColorRefs[Color].m_Green, ColorRefs[Color].m_Blue) ); } /* Mise a la valeur Color des textes a afficher */ void GRSetTextFgColor(wxDC * DC, wxFont *, int Color) { DC->SetTextForeground(wxColour( ColorRefs[Color].m_Red, ColorRefs[Color].m_Green, ColorRefs[Color].m_Blue) ); } /*****************************************************************************/ void GRGetTextExtent(wxDC * DC, const wxChar * Text, long * width, long * height) /*****************************************************************************/ /* donne la taille du rectangle d'encadrement du texte Text */ { long w = 0, h = 0; if ( Text ) { DC->GetTextExtent(Text, &w, &h ); } if ( width ) *width = w; if ( height ) * height = h; } /********************************/ /* void GRReseTextFgColor() */ /********************************/ /* Mise a la couleur par defaut des textes a afficher */ void GRResetTextFgColor(wxDC * DC) { GRSetTextFgColor(DC, Text_Color); } /*********************************************************/ /* void GRSetTextBgColor(wxFont * Font, int Color) */ /*********************************************************/ /* Mise a la valeur Color du fond pour les textes a afficher */ void GRSetTextBgColor(wxDC * DC, int Color) { Color &= MASKCOLOR; // Pour 32 couleurs Max DC->SetTextBackground(wxColour( ColorRefs[Color].m_Red, ColorRefs[Color].m_Green, ColorRefs[Color].m_Blue) ); } void GRSetTextBgColor(wxDC * DC, wxFont *, int Color) { Color &= MASKCOLOR; // Pour 32 couleurs Max DC->SetTextBackground(wxColour( ColorRefs[Color].m_Red, ColorRefs[Color].m_Green, ColorRefs[Color].m_Blue) ); }