2007-10-31 06:40:15 +00:00
|
|
|
/********************************/
|
|
|
|
/* Low level graphics routines */
|
|
|
|
/********************************/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <fctsys.h>
|
|
|
|
#include <gr_basic.h>
|
|
|
|
#include <common.h>
|
|
|
|
#include <trigo.h>
|
|
|
|
#include <macros.h>
|
|
|
|
#include <base_struct.h>
|
|
|
|
#include <class_base_screen.h>
|
|
|
|
#include <bezier_curves.h>
|
|
|
|
#include <math_for_graphics.h>
|
2010-10-09 08:08:29 +00:00
|
|
|
#include <wx/graphics.h>
|
2009-06-25 20:45:27 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
static const bool FILLED = true;
|
2013-07-29 07:33:56 +00:00
|
|
|
static const bool NOT_FILLED = false;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-02-16 10:28:46 +00:00
|
|
|
/* Important Note:
|
2009-11-23 15:16:50 +00:00
|
|
|
* These drawing functions clip draw item before send these items to wxDC draw
|
|
|
|
* functions. For guy who asks why i did it, see a sample of problems encountered
|
|
|
|
* when pixels
|
2009-02-20 14:31:16 +00:00
|
|
|
* coordinates overflow 16 bits values:
|
|
|
|
* http://trac.wxwidgets.org/ticket/10446
|
|
|
|
* Problems can be found under Windows **and** Linux (mainly when drawing arcs)
|
2011-09-30 18:15:37 +00:00
|
|
|
* (mainly at low zoom values (2, 1 or 0.5), in Pcbnew)
|
2009-02-20 14:31:16 +00:00
|
|
|
* some of these problems could be now fixed in recent distributions.
|
2009-02-16 10:28:46 +00:00
|
|
|
*
|
2009-11-23 15:16:50 +00:00
|
|
|
* Currently (feb 2009) there are overflow problems when drawing solid (filled)
|
|
|
|
* polygons under linux without clipping
|
2009-02-16 10:28:46 +00:00
|
|
|
*
|
2009-11-23 15:16:50 +00:00
|
|
|
* So before removing clipping functions, be aware these bug (they are not in
|
2011-09-30 18:15:37 +00:00
|
|
|
* KiCad or wxWidgets) are fixed by testing how are drawn complex lines arcs
|
2009-11-23 15:16:50 +00:00
|
|
|
* and solid polygons under Windows and Linux and remember users can have old
|
|
|
|
* versions with bugs
|
2009-02-16 10:28:46 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-04-05 20:49:15 +00:00
|
|
|
|
2010-02-22 16:45:35 +00:00
|
|
|
/* Definitions for enabling and disabling debugging features in gr_basic.cpp.
|
2010-10-05 19:54:27 +00:00
|
|
|
* Please remember to set these back to 0 before making LAUNCHPAD commits.
|
2010-02-22 16:45:35 +00:00
|
|
|
*/
|
|
|
|
#define DEBUG_DUMP_CLIP_ERROR_COORDS 0 // Set to 1 to dump clip algorithm errors.
|
|
|
|
#define DEBUG_DUMP_CLIP_COORDS 0 // Set to 1 to dump clipped coordinates.
|
|
|
|
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
// For draw mode = XOR GR_XOR or GR_NXOR by background color
|
2012-09-01 13:38:27 +00:00
|
|
|
GR_DRAWMODE g_XorMode = GR_NXOR;
|
2009-11-23 15:16:50 +00:00
|
|
|
|
|
|
|
// Background color of the design frame
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T g_DrawBgColor = WHITE;
|
2009-04-05 20:49:15 +00:00
|
|
|
|
|
|
|
|
2013-07-29 07:33:56 +00:00
|
|
|
static void ClipAndDrawPoly( EDA_RECT * ClipBox, wxDC * DC, wxPoint Points[],
|
|
|
|
int n );
|
2009-02-20 14:31:16 +00:00
|
|
|
|
2010-10-05 11:44:34 +00:00
|
|
|
/* These functions are used by corresponding functions
|
|
|
|
* ( GRSCircle is called by GRCircle for instance) after mapping coordinates
|
|
|
|
* from user units to screen units(pixels coordinates)
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
static void GRSRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1,
|
2012-09-02 12:06:47 +00:00
|
|
|
int x2, int y2, int aWidth, EDA_COLOR_T aColor,
|
2011-01-30 22:22:38 +00:00
|
|
|
wxPenStyle aStyle = wxPENSTYLE_SOLID );
|
|
|
|
|
2010-10-05 11:44:34 +00:00
|
|
|
/**/
|
2009-11-23 15:16:50 +00:00
|
|
|
|
|
|
|
static int GRLastMoveToX, GRLastMoveToY;
|
2010-10-05 11:44:34 +00:00
|
|
|
static bool s_ForceBlackPen; /* if true: draws in black instead of
|
2010-10-13 19:50:23 +00:00
|
|
|
* color for printing. */
|
2009-12-30 18:06:12 +00:00
|
|
|
static int xcliplo = 0,
|
|
|
|
ycliplo = 0,
|
|
|
|
xcliphi = 2000,
|
|
|
|
ycliphi = 2000;
|
2010-09-21 19:21:46 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
static EDA_COLOR_T s_DC_lastcolor = UNSPECIFIED_COLOR;
|
2010-10-13 19:50:23 +00:00
|
|
|
static int s_DC_lastwidth = -1;
|
2010-09-21 19:21:46 +00:00
|
|
|
static int s_DC_lastpenstyle = -1;
|
2012-09-02 12:06:47 +00:00
|
|
|
static EDA_COLOR_T s_DC_lastbrushcolor = UNSPECIFIED_COLOR;
|
|
|
|
static bool s_DC_lastbrushfill = false;
|
2010-10-13 19:50:23 +00:00
|
|
|
static wxDC* s_DC_lastDC = NULL;
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-12-30 18:06:12 +00:00
|
|
|
|
2010-02-11 19:57:47 +00:00
|
|
|
/**
|
|
|
|
* Test if any part of a line falls within the bounds of a rectangle.
|
|
|
|
*
|
|
|
|
* Please note that this is only accurate for lines that are one pixel wide.
|
|
|
|
*
|
2011-01-31 18:26:12 +00:00
|
|
|
* @param aClipBox - The rectangle to test.
|
2010-02-11 19:57:47 +00:00
|
|
|
* @param x1 - X coordinate of one end of a line.
|
|
|
|
* @param y1 - Y coordinate of one end of a line.
|
|
|
|
* @param x2 - X coordinate of the other end of a line.
|
|
|
|
* @param y2 - Y coordinate of the other end of a line.
|
|
|
|
*
|
|
|
|
* @return - False if any part of the line lies within the rectangle.
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
static bool clipLine( EDA_RECT* aClipBox, int& x1, int& y1, int& x2, int& y2 )
|
2010-02-11 19:57:47 +00:00
|
|
|
{
|
2010-12-20 17:44:25 +00:00
|
|
|
if( aClipBox->Contains( x1, y1 ) && aClipBox->Contains( x2, y2 ) )
|
2010-02-11 19:57:47 +00:00
|
|
|
return false;
|
|
|
|
|
2010-02-22 16:45:35 +00:00
|
|
|
wxRect rect = *aClipBox;
|
2010-10-13 19:50:23 +00:00
|
|
|
int minX = rect.GetLeft();
|
|
|
|
int maxX = rect.GetRight();
|
|
|
|
int minY = rect.GetTop();
|
|
|
|
int maxY = rect.GetBottom();
|
|
|
|
int clippedX, clippedY;
|
2010-02-22 16:45:35 +00:00
|
|
|
|
|
|
|
#if DEBUG_DUMP_CLIP_COORDS
|
2010-10-13 19:50:23 +00:00
|
|
|
int tmpX1, tmpY1, tmpX2, tmpY2;
|
2010-02-22 16:45:35 +00:00
|
|
|
tmpX1 = x1;
|
|
|
|
tmpY1 = y1;
|
|
|
|
tmpX2 = x2;
|
|
|
|
tmpY2 = y2;
|
|
|
|
#endif
|
2010-02-11 19:57:47 +00:00
|
|
|
|
2010-12-20 17:44:25 +00:00
|
|
|
if( aClipBox->Contains( x1, y1 ) )
|
2010-02-22 16:45:35 +00:00
|
|
|
{
|
|
|
|
if( x1 == x2 ) /* Vertical line, clip Y. */
|
|
|
|
{
|
|
|
|
if( y2 < minY )
|
|
|
|
{
|
|
|
|
y2 = minY;
|
|
|
|
return false;
|
|
|
|
}
|
2010-02-11 19:57:47 +00:00
|
|
|
|
2010-02-22 16:45:35 +00:00
|
|
|
if( y2 > maxY )
|
|
|
|
{
|
|
|
|
y2 = maxY;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( y1 == y2 ) /* Horizontal line, clip X. */
|
|
|
|
{
|
|
|
|
if( x2 < minX )
|
|
|
|
{
|
|
|
|
x2 = minX;
|
|
|
|
return false;
|
|
|
|
}
|
2010-02-11 19:57:47 +00:00
|
|
|
|
2010-02-22 16:45:35 +00:00
|
|
|
if( x2 > maxX )
|
|
|
|
{
|
|
|
|
x2 = maxX;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2010-02-11 19:57:47 +00:00
|
|
|
|
2010-02-22 16:45:35 +00:00
|
|
|
/* If we're here, it's a diagonal line. */
|
2010-02-11 19:57:47 +00:00
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, minX, maxY,
|
|
|
|
&clippedX, &clippedY ) /* Left */
|
|
|
|
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY,
|
|
|
|
&clippedX, &clippedY ) /* Top */
|
|
|
|
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY,
|
|
|
|
&clippedX, &clippedY ) /* Right */
|
|
|
|
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY,
|
|
|
|
&clippedX, &clippedY ) ) /* Bottom */
|
2010-02-22 16:45:35 +00:00
|
|
|
{
|
|
|
|
if( x2 != clippedX )
|
|
|
|
x2 = clippedX;
|
|
|
|
if( y2 != clippedY )
|
|
|
|
y2 = clippedY;
|
|
|
|
return false;
|
|
|
|
}
|
2010-02-11 19:57:47 +00:00
|
|
|
|
2010-02-22 16:45:35 +00:00
|
|
|
/* If we're here, something has gone terribly wrong. */
|
|
|
|
#if DEBUG_DUMP_CLIP_ERROR_COORDS
|
2011-01-30 22:22:38 +00:00
|
|
|
wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ),
|
2010-02-22 16:45:35 +00:00
|
|
|
tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 );
|
|
|
|
#endif
|
2010-02-11 19:57:47 +00:00
|
|
|
return false;
|
2010-02-22 16:45:35 +00:00
|
|
|
}
|
2010-12-20 17:44:25 +00:00
|
|
|
else if( aClipBox->Contains( x2, y2 ) )
|
2010-02-22 16:45:35 +00:00
|
|
|
{
|
|
|
|
if( x1 == x2 ) /* Vertical line, clip Y. */
|
|
|
|
{
|
|
|
|
if( y2 < minY )
|
|
|
|
{
|
|
|
|
y2 = minY;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( y2 > maxY )
|
|
|
|
{
|
|
|
|
y2 = maxY;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( y1 == y2 ) /* Horizontal line, clip X. */
|
|
|
|
{
|
|
|
|
if( x2 < minX )
|
|
|
|
{
|
|
|
|
x2 = minX;
|
|
|
|
return false;
|
|
|
|
}
|
2010-02-11 19:57:47 +00:00
|
|
|
|
2010-02-22 16:45:35 +00:00
|
|
|
if( x2 > maxX )
|
|
|
|
{
|
|
|
|
x2 = maxX;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2010-02-11 19:57:47 +00:00
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, minX, maxY,
|
|
|
|
&clippedX, &clippedY ) /* Left */
|
|
|
|
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY,
|
|
|
|
&clippedX, &clippedY ) /* Top */
|
|
|
|
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY,
|
|
|
|
&clippedX, &clippedY ) /* Right */
|
|
|
|
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY,
|
|
|
|
&clippedX, &clippedY ) ) /* Bottom */
|
2010-02-22 16:45:35 +00:00
|
|
|
{
|
|
|
|
if( x1 != clippedX )
|
|
|
|
x1 = clippedX;
|
|
|
|
if( y1 != clippedY )
|
|
|
|
y1 = clippedY;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we're here, something has gone terribly wrong. */
|
|
|
|
#if DEBUG_DUMP_CLIP_ERROR_COORDS
|
2011-01-30 22:22:38 +00:00
|
|
|
wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ),
|
2010-02-22 16:45:35 +00:00
|
|
|
tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 );
|
|
|
|
#endif
|
2010-02-11 19:57:47 +00:00
|
|
|
return false;
|
2010-02-22 16:45:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int* intersectX;
|
|
|
|
int* intersectY;
|
2010-10-13 19:50:23 +00:00
|
|
|
int intersectX1, intersectY1, intersectX2, intersectY2;
|
2010-02-22 16:45:35 +00:00
|
|
|
bool haveFirstPoint = false;
|
|
|
|
|
|
|
|
intersectX = &intersectX1;
|
|
|
|
intersectY = &intersectY1;
|
|
|
|
|
|
|
|
/* Left clip rectangle line. */
|
|
|
|
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, minX, maxY,
|
|
|
|
intersectX, intersectY ) )
|
|
|
|
{
|
2010-10-13 19:50:23 +00:00
|
|
|
intersectX = &intersectX2;
|
|
|
|
intersectY = &intersectY2;
|
2010-02-22 16:45:35 +00:00
|
|
|
haveFirstPoint = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Top clip rectangle line. */
|
|
|
|
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY,
|
|
|
|
intersectX, intersectY ) )
|
|
|
|
{
|
|
|
|
intersectX = &intersectX2;
|
|
|
|
intersectY = &intersectY2;
|
|
|
|
if( haveFirstPoint )
|
|
|
|
{
|
|
|
|
x1 = intersectX1;
|
|
|
|
y1 = intersectY1;
|
|
|
|
x2 = intersectX2;
|
|
|
|
y2 = intersectY2;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
haveFirstPoint = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Right clip rectangle line. */
|
|
|
|
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY,
|
|
|
|
intersectX, intersectY ) )
|
|
|
|
{
|
|
|
|
intersectX = &intersectX2;
|
|
|
|
intersectY = &intersectY2;
|
|
|
|
if( haveFirstPoint )
|
|
|
|
{
|
|
|
|
x1 = intersectX1;
|
|
|
|
y1 = intersectY1;
|
|
|
|
x2 = intersectX2;
|
|
|
|
y2 = intersectY2;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
haveFirstPoint = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Bottom clip rectangle line. */
|
|
|
|
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY,
|
|
|
|
intersectX, intersectY ) )
|
|
|
|
{
|
|
|
|
intersectX = &intersectX2;
|
|
|
|
intersectY = &intersectY2;
|
|
|
|
if( haveFirstPoint )
|
|
|
|
{
|
|
|
|
x1 = intersectX1;
|
|
|
|
y1 = intersectY1;
|
|
|
|
x2 = intersectX2;
|
|
|
|
y2 = intersectY2;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we're here and only one line of the clip box has been intersected,
|
|
|
|
* something has gone terribly wrong. */
|
|
|
|
#if DEBUG_DUMP_CLIP_ERROR_COORDS
|
|
|
|
if( haveFirstPoint )
|
2011-01-30 22:22:38 +00:00
|
|
|
wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ),
|
2010-02-22 16:45:35 +00:00
|
|
|
tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 );
|
|
|
|
#endif
|
|
|
|
}
|
2010-02-11 19:57:47 +00:00
|
|
|
|
|
|
|
/* Set this to one to verify that diagonal lines get clipped properly. */
|
2010-02-22 16:45:35 +00:00
|
|
|
#if DEBUG_DUMP_CLIP_COORDS
|
2010-02-11 19:57:47 +00:00
|
|
|
if( !( x1 == x2 || y1 == y2 ) )
|
|
|
|
wxLogDebug( wxT( "Clipped line (%d,%d):(%d,%d) from rectangle (%d,%d,%d,%d)" ),
|
2010-02-22 16:45:35 +00:00
|
|
|
tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY );
|
2010-02-11 19:57:47 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2010-10-13 19:50:23 +00:00
|
|
|
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
static void WinClipAndDrawLine( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color, int width = 1 )
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
|
|
|
GRLastMoveToX = x2;
|
|
|
|
GRLastMoveToY = y2;
|
|
|
|
|
|
|
|
if( ClipBox )
|
|
|
|
{
|
2011-04-13 10:22:58 +00:00
|
|
|
EDA_RECT clipbox(*ClipBox);
|
|
|
|
clipbox.Inflate(width/2);
|
|
|
|
if( clipLine( &clipbox, x1, y1, x2, y2 ) )
|
2007-10-31 17:44:51 +00:00
|
|
|
return;
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GRSetColorPen( DC, Color, width );
|
|
|
|
DC->DrawLine( x1, y1, x2, y2 );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/* Forcing a reset of the current pen.
|
|
|
|
* Must be called after changing the graphical device before any trace.
|
2007-06-05 12:10:51 +00:00
|
|
|
*/
|
2007-10-31 06:40:15 +00:00
|
|
|
void GRResetPenAndBrush( wxDC* DC )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSetBrush( DC, BLACK ); // Force no fill
|
2012-09-02 12:06:47 +00:00
|
|
|
s_DC_lastbrushcolor = UNSPECIFIED_COLOR;
|
|
|
|
s_DC_lastcolor = UNSPECIFIED_COLOR;
|
2010-10-13 19:50:23 +00:00
|
|
|
s_DC_lastDC = NULL;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2008-04-02 14:16:14 +00:00
|
|
|
/**
|
|
|
|
* Function GRSetColorPen
|
|
|
|
* sets a pen style, width, color, and alpha into the given device context.
|
2009-02-16 10:28:46 +00:00
|
|
|
*/
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRSetColorPen( wxDC* DC, EDA_COLOR_T Color, int width, wxPenStyle style )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2010-02-22 19:56:32 +00:00
|
|
|
if( width < 0 )
|
|
|
|
width = 0;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2012-01-10 19:52:48 +00:00
|
|
|
#ifdef __WXMAC__
|
2013-02-14 19:56:45 +00:00
|
|
|
// Under OSX when wxPen is set to 0, cocoa follows the request drawing nothing &
|
|
|
|
// in the bitmap world the minimum is enough to light a pixel, in vectorial one not
|
|
|
|
if( width <= 1 )
|
2012-01-10 19:52:48 +00:00
|
|
|
width = DC->DeviceToLogicalXRel( 1 );
|
|
|
|
#endif
|
|
|
|
|
2010-10-05 11:44:34 +00:00
|
|
|
if( s_ForceBlackPen )
|
2008-04-02 14:16:14 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
Color = BLACK;
|
2008-04-02 14:16:14 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
if( s_DC_lastcolor != Color
|
2011-01-30 22:22:38 +00:00
|
|
|
|| s_DC_lastwidth != width
|
|
|
|
|| s_DC_lastpenstyle != style
|
|
|
|
|| s_DC_lastDC != DC )
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
2009-02-16 10:28:46 +00:00
|
|
|
wxPen pen;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2009-02-16 10:28:46 +00:00
|
|
|
wxColour wx_color = MakeColour( Color );
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
pen.SetColour( wx_color );
|
|
|
|
pen.SetWidth( width );
|
|
|
|
pen.SetStyle( style );
|
|
|
|
|
|
|
|
DC->SetPen( pen );
|
|
|
|
|
2010-09-21 19:21:46 +00:00
|
|
|
s_DC_lastcolor = Color;
|
|
|
|
s_DC_lastwidth = width;
|
|
|
|
s_DC_lastpenstyle = style;
|
2010-10-13 19:50:23 +00:00
|
|
|
s_DC_lastDC = DC;
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRSetBrush( wxDC* DC, EDA_COLOR_T Color, bool fill )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2010-10-05 11:44:34 +00:00
|
|
|
if( s_ForceBlackPen )
|
2007-10-31 06:40:15 +00:00
|
|
|
Color = BLACK;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
if( s_DC_lastbrushcolor != Color
|
2011-01-30 22:22:38 +00:00
|
|
|
|| s_DC_lastbrushfill != fill
|
|
|
|
|| s_DC_lastDC != DC )
|
2010-09-21 19:21:46 +00:00
|
|
|
{
|
2014-01-08 01:34:04 +00:00
|
|
|
wxBrush brush;
|
|
|
|
|
|
|
|
brush.SetColour( MakeColour( Color ) );
|
2010-09-21 19:21:46 +00:00
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
if( fill )
|
2014-01-08 01:34:04 +00:00
|
|
|
#if wxCHECK_VERSION( 3, 0, 0 )
|
|
|
|
brush.SetStyle( wxBRUSHSTYLE_SOLID );
|
|
|
|
else
|
|
|
|
brush.SetStyle( wxBRUSHSTYLE_TRANSPARENT );
|
|
|
|
#else
|
|
|
|
brush.SetStyle( wxSOLID );
|
2010-10-13 19:50:23 +00:00
|
|
|
else
|
2014-01-08 01:34:04 +00:00
|
|
|
brush.SetStyle( wxTRANSPARENT );
|
|
|
|
#endif
|
2010-09-21 19:21:46 +00:00
|
|
|
|
2014-01-08 01:34:04 +00:00
|
|
|
DC->SetBrush( brush );
|
2010-09-21 19:21:46 +00:00
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
s_DC_lastbrushcolor = Color;
|
|
|
|
s_DC_lastbrushfill = fill;
|
|
|
|
s_DC_lastDC = DC;
|
2010-09-21 19:21:46 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2010-11-12 16:36:43 +00:00
|
|
|
/**
|
|
|
|
* Function GRForceBlackPen
|
2008-08-09 08:05:42 +00:00
|
|
|
* @param flagforce True to force a black pen whenever the asked color
|
|
|
|
*/
|
2009-11-23 15:16:50 +00:00
|
|
|
void GRForceBlackPen( bool flagforce )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2010-10-05 11:44:34 +00:00
|
|
|
s_ForceBlackPen = flagforce;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2009-02-16 10:28:46 +00:00
|
|
|
|
2010-11-12 16:36:43 +00:00
|
|
|
/**
|
|
|
|
* Function GetGRForceBlackPenState
|
2010-10-05 11:44:34 +00:00
|
|
|
* @return s_ForceBlackPen (True if a black pen was forced)
|
2008-08-09 08:05:42 +00:00
|
|
|
*/
|
2009-11-23 15:16:50 +00:00
|
|
|
bool GetGRForceBlackPenState( void )
|
2008-08-09 08:05:42 +00:00
|
|
|
{
|
2010-10-05 11:44:34 +00:00
|
|
|
return s_ForceBlackPen;
|
2008-08-09 08:05:42 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*************************************/
|
|
|
|
/* Set the device context draw mode. */
|
|
|
|
/*************************************/
|
2012-09-01 13:38:27 +00:00
|
|
|
void GRSetDrawMode( wxDC* DC, GR_DRAWMODE draw_mode )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
if( draw_mode & GR_OR )
|
2009-11-23 15:16:50 +00:00
|
|
|
#if defined(__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION( 2, 9, 0 ) )
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2010-02-08 18:15:42 +00:00
|
|
|
DC->SetLogicalFunction( wxCOPY );
|
|
|
|
#elif defined( USE_WX_GRAPHICS_CONTEXT )
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2008-04-02 14:16:14 +00:00
|
|
|
DC->SetLogicalFunction( wxCOPY );
|
|
|
|
#else
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
DC->SetLogicalFunction( wxOR );
|
2008-04-02 14:16:14 +00:00
|
|
|
#endif
|
2007-10-31 06:40:15 +00:00
|
|
|
else if( draw_mode & GR_XOR )
|
2010-02-08 18:15:42 +00:00
|
|
|
#if defined( USE_WX_GRAPHICS_CONTEXT )
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2010-02-08 18:15:42 +00:00
|
|
|
DC->SetLogicalFunction( wxCOPY );
|
|
|
|
#else
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
DC->SetLogicalFunction( wxXOR );
|
2010-02-08 18:15:42 +00:00
|
|
|
#endif
|
2007-10-31 06:40:15 +00:00
|
|
|
else if( draw_mode & GR_NXOR )
|
2009-11-23 15:16:50 +00:00
|
|
|
#if defined(__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION( 2, 9, 0 ) )
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
DC->SetLogicalFunction( wxXOR );
|
2010-02-08 18:15:42 +00:00
|
|
|
#elif defined( USE_WX_GRAPHICS_CONTEXT )
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2010-02-08 18:15:42 +00:00
|
|
|
DC->SetLogicalFunction( wxCOPY );
|
2009-03-26 19:27:50 +00:00
|
|
|
#else
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
DC->SetLogicalFunction( wxEQUIV );
|
2010-10-05 11:44:34 +00:00
|
|
|
#endif
|
|
|
|
else if( draw_mode & GR_INVERT )
|
|
|
|
#if defined( USE_WX_GRAPHICS_CONTEXT )
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2010-10-05 11:44:34 +00:00
|
|
|
DC->SetLogicalFunction( wxCOPY );
|
|
|
|
#else
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2010-10-05 11:44:34 +00:00
|
|
|
DC->SetLogicalFunction( wxINVERT );
|
2009-03-26 19:27:50 +00:00
|
|
|
#endif
|
2009-11-23 15:16:50 +00:00
|
|
|
else
|
2007-10-31 06:40:15 +00:00
|
|
|
DC->SetLogicalFunction( wxCOPY );
|
2010-12-17 22:57:09 +00:00
|
|
|
|
|
|
|
#ifdef USE_WX_OVERLAY
|
|
|
|
DC->SetLogicalFunction( wxCOPY );
|
|
|
|
#endif
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRPutPixel( EDA_RECT* ClipBox, wxDC* DC, int x, int y, EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2010-12-20 17:44:25 +00:00
|
|
|
if( ClipBox && !ClipBox->Contains( x, y ) )
|
2009-04-08 18:06:22 +00:00
|
|
|
return;
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSetColorPen( DC, Color );
|
|
|
|
DC->DrawPoint( x, y );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw a line, in object space.
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRLine( EDA_RECT* ClipBox,
|
2009-11-23 15:16:50 +00:00
|
|
|
wxDC* DC,
|
|
|
|
int x1,
|
|
|
|
int y1,
|
|
|
|
int x2,
|
|
|
|
int y2,
|
|
|
|
int width,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
WinClipAndDrawLine( ClipBox, DC, x1, y1, x2, y2, Color, width );
|
|
|
|
GRLastMoveToX = x2;
|
|
|
|
GRLastMoveToY = y2;
|
2009-05-25 16:07:33 +00:00
|
|
|
}
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRLine( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd, int aWidth, EDA_COLOR_T aColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
GRLine( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aWidth, aColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRDashedLineTo( EDA_RECT* ClipBox, wxDC* DC, int x2, int y2, int width, EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2012-09-02 12:06:47 +00:00
|
|
|
s_DC_lastcolor = UNSPECIFIED_COLOR;
|
2010-10-06 20:16:31 +00:00
|
|
|
GRSetColorPen( DC, Color, width, wxPENSTYLE_SHORT_DASH );
|
2011-01-30 22:22:38 +00:00
|
|
|
GRLine( ClipBox, DC, GRLastMoveToX, GRLastMoveToY, x2, y2, width, Color );
|
2012-09-02 12:06:47 +00:00
|
|
|
s_DC_lastcolor = UNSPECIFIED_COLOR;
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSetColorPen( DC, Color, width );
|
|
|
|
GRLastMoveToX = x2;
|
|
|
|
GRLastMoveToY = y2;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
2007-10-31 06:40:15 +00:00
|
|
|
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRDashedLine( EDA_RECT* ClipBox,
|
2007-10-31 06:40:15 +00:00
|
|
|
wxDC* DC,
|
|
|
|
int x1,
|
|
|
|
int y1,
|
|
|
|
int x2,
|
|
|
|
int y2,
|
|
|
|
int width,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
GRLastMoveToX = x2;
|
|
|
|
GRLastMoveToY = y2;
|
2012-09-02 12:06:47 +00:00
|
|
|
s_DC_lastcolor = UNSPECIFIED_COLOR;
|
2011-01-30 22:22:38 +00:00
|
|
|
GRSetColorPen( DC, Color, width, wxPENSTYLE_SHORT_DASH );
|
|
|
|
GRLine( ClipBox, DC, x1, y1, x2, y2, width, Color );
|
2012-09-02 12:06:47 +00:00
|
|
|
s_DC_lastcolor = UNSPECIFIED_COLOR;
|
2011-01-30 22:22:38 +00:00
|
|
|
GRSetColorPen( DC, Color, width );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Move to a new position, in object space.
|
|
|
|
*/
|
2007-10-31 06:40:15 +00:00
|
|
|
void GRMoveTo( int x, int y )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
GRLastMoveToX = x;
|
|
|
|
GRLastMoveToY = y;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw line to a new position, in object space.
|
|
|
|
*/
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRLineTo( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int width, EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
int GRLineToX, GRLineToY;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-01-30 22:22:38 +00:00
|
|
|
GRLineToX = x;
|
|
|
|
GRLineToY = y;
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2011-01-30 22:22:38 +00:00
|
|
|
GRLine( ClipBox, DC, GRLastMoveToX, GRLastMoveToY, GRLineToX, GRLineToY, width, Color );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRMixedLine( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
int width, EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2010-10-06 20:16:31 +00:00
|
|
|
GRSetColorPen( DC, Color, width, wxPENSTYLE_DOT_DASH );
|
2011-01-30 22:22:38 +00:00
|
|
|
GRLine( ClipBox, DC, x1, y1, x2, y2, width, Color );
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSetColorPen( DC, Color, width );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2010-11-12 16:36:43 +00:00
|
|
|
/**
|
|
|
|
* Function GRLineArray
|
2010-10-13 19:50:23 +00:00
|
|
|
* draws an array of lines (not a polygon).
|
|
|
|
* @param aClipBox = the clip box
|
|
|
|
* @param aDC = the device context into which drawing should occur.
|
|
|
|
* @param aLines = a list of pair of coordinate in user space: a pair for each line.
|
|
|
|
* @param aWidth = the width of each line.
|
|
|
|
* @param aColor = an index into our color table of RGB colors.
|
2012-03-26 23:47:08 +00:00
|
|
|
* @see EDA_COLOR_T and colors.h
|
2010-10-13 19:50:23 +00:00
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRLineArray( EDA_RECT* aClipBox, wxDC* aDC, std::vector<wxPoint>& aLines,
|
2012-09-02 12:06:47 +00:00
|
|
|
int aWidth, EDA_COLOR_T aColor )
|
2010-10-09 08:08:29 +00:00
|
|
|
{
|
2010-10-13 19:50:23 +00:00
|
|
|
GRSetColorPen( aDC, aColor, aWidth );
|
2011-01-30 22:22:38 +00:00
|
|
|
|
2011-04-14 18:44:46 +00:00
|
|
|
if( aClipBox )
|
|
|
|
aClipBox->Inflate(aWidth/2);
|
|
|
|
for( unsigned i = 0; i < aLines.size(); i += 2)
|
2010-10-09 08:08:29 +00:00
|
|
|
{
|
2011-04-14 18:44:46 +00:00
|
|
|
int x1 = aLines[i].x;
|
|
|
|
int y1 = aLines[i].y;
|
|
|
|
int x2 = aLines[i+1].x;
|
|
|
|
int y2 = aLines[i+1].y;
|
|
|
|
GRLastMoveToX = x2;
|
|
|
|
GRLastMoveToY = y2;
|
2011-04-15 14:10:20 +00:00
|
|
|
if( ( aClipBox == NULL ) || !clipLine( aClipBox, x1, y1, x2, y2 ) )
|
2011-04-14 18:44:46 +00:00
|
|
|
aDC->DrawLine( x1, y1, x2, y2 );
|
2010-10-09 08:08:29 +00:00
|
|
|
}
|
2011-04-14 18:44:46 +00:00
|
|
|
if( aClipBox )
|
|
|
|
aClipBox->Inflate(-aWidth/2);
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
int width, int aPenSize, EDA_COLOR_T Color )
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
2009-11-23 15:16:50 +00:00
|
|
|
long radius;
|
2007-12-22 07:16:45 +00:00
|
|
|
int dwx, dwy;
|
2007-10-31 06:40:15 +00:00
|
|
|
long dx, dy, dwx2, dwy2;
|
2009-11-23 15:16:50 +00:00
|
|
|
long sx1, sy1, ex1, ey1;
|
|
|
|
long sx2, sy2, ex2, ey2;
|
2010-09-21 06:35:11 +00:00
|
|
|
bool swap_ends = false;
|
2007-10-31 06:40:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
GRLastMoveToX = x2;
|
|
|
|
GRLastMoveToY = y2;
|
|
|
|
|
|
|
|
if( ClipBox )
|
|
|
|
{
|
2011-04-13 10:22:58 +00:00
|
|
|
EDA_RECT clipbox(*ClipBox);
|
|
|
|
clipbox.Inflate(width/2);
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2011-04-13 10:22:58 +00:00
|
|
|
if( clipLine( &clipbox, x1, y1, x2, y2 ) )
|
2007-10-31 17:44:51 +00:00
|
|
|
return;
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
if( width <= 2 ) /* single line or 2 pixels */
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
|
|
|
GRSetColorPen( DC, Color, width );
|
|
|
|
DC->DrawLine( x1, y1, x2, y2 );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-02-22 19:56:32 +00:00
|
|
|
GRSetColorPen( DC, Color, aPenSize );
|
2010-09-21 06:35:11 +00:00
|
|
|
GRSetBrush( DC, Color, false );
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
radius = (width + 1) >> 1;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
dx = x2 - x1;
|
2007-12-22 07:16:45 +00:00
|
|
|
dy = y2 - y1;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
if( dx == 0 ) /* segment vertical */
|
|
|
|
{
|
2009-11-23 15:16:50 +00:00
|
|
|
dwx = radius;
|
2007-10-31 06:40:15 +00:00
|
|
|
if( dy >= 0 )
|
|
|
|
dwx = -dwx;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
sx1 = x1 - dwx;
|
2007-12-22 07:16:45 +00:00
|
|
|
sy1 = y1;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
ex1 = x2 - dwx;
|
2007-12-22 07:16:45 +00:00
|
|
|
ey1 = y2;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
DC->DrawLine( sx1, sy1, ex1, ey1 );
|
|
|
|
|
2008-04-02 14:16:14 +00:00
|
|
|
sx2 = x1 + dwx;
|
2007-12-22 07:16:45 +00:00
|
|
|
sy2 = y1;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
ex2 = x2 + dwx;
|
2007-12-22 07:16:45 +00:00
|
|
|
ey2 = y2;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
DC->DrawLine( sx2, sy2, ex2, ey2 );
|
|
|
|
}
|
|
|
|
else if( dy == 0 ) /* segment horizontal */
|
|
|
|
{
|
2009-11-23 15:16:50 +00:00
|
|
|
dwy = radius;
|
2007-10-31 06:40:15 +00:00
|
|
|
if( dx < 0 )
|
|
|
|
dwy = -dwy;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2007-12-22 07:16:45 +00:00
|
|
|
sx1 = x1;
|
|
|
|
sy1 = y1 - dwy;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
ex1 = x2;
|
2007-12-22 07:16:45 +00:00
|
|
|
ey1 = y2 - dwy;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
DC->DrawLine( sx1, sy1, ex1, ey1 );
|
|
|
|
|
2008-04-02 14:16:14 +00:00
|
|
|
sx2 = x1;
|
2007-12-22 07:16:45 +00:00
|
|
|
sy2 = y1 + dwy;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
ex2 = x2;
|
2007-12-22 07:16:45 +00:00
|
|
|
ey2 = y2 + dwy;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
DC->DrawLine( sx2, sy2, ex2, ey2 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-09-22 11:19:37 +00:00
|
|
|
if( std::abs( dx ) == std::abs( dy ) ) // segment 45 degrees
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
2009-11-23 15:16:50 +00:00
|
|
|
dwx = dwy = ( (width * 5) + 4 ) / 7; // = width / 2 * 0.707
|
2007-10-31 06:40:15 +00:00
|
|
|
if( dy < 0 )
|
|
|
|
{
|
|
|
|
if( dx <= 0 )
|
|
|
|
{
|
2010-09-21 06:35:11 +00:00
|
|
|
dwx = -dwx; swap_ends = true;
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
|
|
|
}
|
2010-09-21 06:35:11 +00:00
|
|
|
else // dy >= 0
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
|
|
|
if( dx > 0 )
|
|
|
|
{
|
2010-09-21 06:35:11 +00:00
|
|
|
dwy = -dwy; swap_ends = true;
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
2010-09-21 06:35:11 +00:00
|
|
|
else
|
|
|
|
swap_ends = true;
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-05-05 07:17:48 +00:00
|
|
|
double delta_angle = ArcTangente( dy, dx );
|
2008-04-02 14:16:14 +00:00
|
|
|
dwx = 0;
|
2007-12-22 07:16:45 +00:00
|
|
|
dwy = width;
|
|
|
|
RotatePoint( &dwx, &dwy, -delta_angle );
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
2008-04-02 14:16:14 +00:00
|
|
|
dwx2 = dwx >> 1;
|
2007-12-22 07:16:45 +00:00
|
|
|
dwy2 = dwy >> 1;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
sx1 = x1 - dwx2;
|
2007-12-22 07:16:45 +00:00
|
|
|
sy1 = y1 - dwy2;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
ex1 = x2 - dwx2;
|
2007-12-22 07:16:45 +00:00
|
|
|
ey1 = y2 - dwy2;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
DC->DrawLine( sx1, sy1, ex1, ey1 );
|
|
|
|
|
2008-04-02 14:16:14 +00:00
|
|
|
sx2 = x1 + dwx2;
|
2007-12-22 07:16:45 +00:00
|
|
|
sy2 = y1 + dwy2;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
|
|
|
ex2 = x2 + dwx2;
|
2007-12-22 07:16:45 +00:00
|
|
|
ey2 = y2 + dwy2;
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
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 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
int width, EDA_COLOR_T Color )
|
2011-01-30 22:22:38 +00:00
|
|
|
{
|
|
|
|
GRCSegm( ClipBox, DC, x1, y1, x2, y2, width, 0, Color );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRCSegm( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd,
|
2012-09-02 12:06:47 +00:00
|
|
|
int aWidth, EDA_COLOR_T aColor )
|
2011-01-30 22:22:38 +00:00
|
|
|
{
|
|
|
|
GRCSegm( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aWidth, 0, aColor );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Draw segment (full) with rounded ends in object space (real coords.).
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRFillCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
int width, EDA_COLOR_T Color )
|
2011-01-30 22:22:38 +00:00
|
|
|
{
|
|
|
|
WinClipAndDrawLine( ClipBox, DC, x1, y1, x2, y2, Color, width );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRFilledSegment( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd,
|
2012-09-02 12:06:47 +00:00
|
|
|
int aWidth, EDA_COLOR_T aColor )
|
2011-01-30 22:22:38 +00:00
|
|
|
{
|
|
|
|
WinClipAndDrawLine( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aColor, aWidth );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
static bool IsGRSPolyDrawable( EDA_RECT* ClipBox, int n, wxPoint Points[] )
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
2010-10-13 19:50:23 +00:00
|
|
|
if( !ClipBox )
|
2010-09-11 16:33:43 +00:00
|
|
|
return true;
|
|
|
|
|
2010-10-01 19:11:30 +00:00
|
|
|
if( n <= 0 )
|
|
|
|
return false;
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
int Xmin, Xmax, Ymin, Ymax;
|
|
|
|
|
2008-12-29 18:02:54 +00:00
|
|
|
Xmin = Xmax = Points[0].x;
|
|
|
|
Ymin = Ymax = Points[0].y;
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
for( int ii = 1; ii < n; ii++ ) // calculate rectangle
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
2012-09-22 11:19:37 +00:00
|
|
|
Xmin = std::min( Xmin, Points[ii].x );
|
|
|
|
Xmax = std::max( Xmax, Points[ii].x );
|
|
|
|
Ymin = std::min( Ymin, Points[ii].y );
|
|
|
|
Ymax = std::max( Ymax, Points[ii].y );
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
xcliplo = ClipBox->GetX();
|
|
|
|
ycliplo = ClipBox->GetY();
|
|
|
|
xcliphi = ClipBox->GetRight();
|
2009-04-17 12:45:22 +00:00
|
|
|
ycliphi = ClipBox->GetBottom();
|
2007-10-31 06:40:15 +00:00
|
|
|
|
|
|
|
if( Xmax < xcliplo )
|
2010-09-21 06:35:11 +00:00
|
|
|
return false;
|
2007-10-31 06:40:15 +00:00
|
|
|
if( Xmin > xcliphi )
|
2010-09-21 06:35:11 +00:00
|
|
|
return false;
|
2007-10-31 06:40:15 +00:00
|
|
|
if( Ymax < ycliplo )
|
2010-09-21 06:35:11 +00:00
|
|
|
return false;
|
2007-10-31 06:40:15 +00:00
|
|
|
if( Ymin > ycliphi )
|
2010-09-21 06:35:11 +00:00
|
|
|
return false;
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2010-09-21 06:35:11 +00:00
|
|
|
return true;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
2007-10-31 06:40:15 +00:00
|
|
|
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw a new polyline and fill it if Fill, in screen space.
|
|
|
|
*/
|
2013-07-29 07:33:56 +00:00
|
|
|
static void GRSPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
|
|
|
|
bool Fill, int width,
|
|
|
|
EDA_COLOR_T Color, EDA_COLOR_T BgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
if( !IsGRSPolyDrawable( ClipBox, n, Points ) )
|
|
|
|
return;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSetColorPen( DC, Color, width );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
if( Fill && ( n > 2 ) )
|
|
|
|
{
|
|
|
|
GRSetBrush( DC, BgColor, FILLED );
|
2009-02-20 14:31:16 +00:00
|
|
|
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/* clip before send the filled polygon to wxDC, because under linux
|
|
|
|
* (GTK?) polygons having large coordinates are incorrectly drawn
|
2013-07-29 07:33:56 +00:00
|
|
|
* (integer overflow in coordinates, I am guessing)
|
2009-02-20 14:31:16 +00:00
|
|
|
*/
|
2013-07-29 07:33:56 +00:00
|
|
|
ClipAndDrawPoly( ClipBox, DC, Points, n );
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-16 10:28:46 +00:00
|
|
|
wxPoint endPt = Points[n - 1];
|
2008-04-02 14:16:14 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSetBrush( DC, Color );
|
2008-12-29 18:02:54 +00:00
|
|
|
DC->DrawLines( n, Points );
|
|
|
|
|
2008-10-31 17:02:24 +00:00
|
|
|
// The last point is not drawn by DrawLine and DrawLines
|
|
|
|
// Add it if the polygon is not closed
|
2008-12-29 18:02:54 +00:00
|
|
|
if( endPt != Points[0] )
|
2009-02-16 10:28:46 +00:00
|
|
|
DC->DrawPoint( endPt.x, endPt.y );
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw a new closed polyline and fill it if Fill, in screen space.
|
|
|
|
*/
|
2013-07-29 07:33:56 +00:00
|
|
|
static void GRSClosedPoly( EDA_RECT* aClipBox, wxDC* aDC,
|
|
|
|
int aPointCount, wxPoint aPoints[],
|
|
|
|
bool aFill, int aWidth,
|
|
|
|
EDA_COLOR_T aColor,
|
|
|
|
EDA_COLOR_T aBgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2013-07-29 07:33:56 +00:00
|
|
|
if( !IsGRSPolyDrawable( aClipBox, aPointCount, aPoints ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2013-07-29 07:33:56 +00:00
|
|
|
GRSetColorPen( aDC, aColor, aWidth );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2013-07-29 07:33:56 +00:00
|
|
|
if( aFill && ( aPointCount > 2 ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
2011-04-14 18:44:46 +00:00
|
|
|
GRLastMoveToX = aPoints[aPointCount - 1].x;
|
|
|
|
GRLastMoveToY = aPoints[aPointCount - 1].y;
|
2013-07-29 07:33:56 +00:00
|
|
|
GRSetBrush( aDC, aBgColor, FILLED );
|
|
|
|
ClipAndDrawPoly( aClipBox, aDC, aPoints, aPointCount );
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-07-29 07:33:56 +00:00
|
|
|
GRSetBrush( aDC, aBgColor );
|
|
|
|
aDC->DrawLines( aPointCount, aPoints );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2013-07-29 07:33:56 +00:00
|
|
|
int lastpt = aPointCount - 1;
|
2009-11-23 15:16:50 +00:00
|
|
|
/* Close the polygon. */
|
2013-07-29 07:33:56 +00:00
|
|
|
if( aPoints[lastpt] != aPoints[0] )
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
2013-07-29 07:33:56 +00:00
|
|
|
GRLine( aClipBox, aDC, aPoints[0].x, aPoints[0].y,
|
|
|
|
aPoints[lastpt].x, aPoints[lastpt].y,
|
|
|
|
aWidth, aColor );
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2009-02-16 10:28:46 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw a new polyline and fill it if Fill, in drawing space.
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
|
2012-09-02 12:06:47 +00:00
|
|
|
bool Fill, int width, EDA_COLOR_T Color, EDA_COLOR_T BgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSPoly( ClipBox, DC, n, Points, Fill, width, Color, BgColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw a closed polyline and fill it if Fill, in object space.
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
|
2012-09-02 12:06:47 +00:00
|
|
|
bool Fill, EDA_COLOR_T Color, EDA_COLOR_T BgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
GRClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
|
2012-09-02 12:06:47 +00:00
|
|
|
bool Fill, int width, EDA_COLOR_T Color, EDA_COLOR_T BgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSClosedPoly( ClipBox, DC, n, Points, Fill, width, Color, BgColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRCircle( EDA_RECT* ClipBox, wxDC* DC, int xc, int yc, int r, int width, EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
/* Clip circles off screen. */
|
|
|
|
if( ClipBox )
|
|
|
|
{
|
|
|
|
int x0, y0, xm, ym;
|
|
|
|
x0 = ClipBox->GetX();
|
|
|
|
y0 = ClipBox->GetY();
|
|
|
|
xm = ClipBox->GetRight();
|
|
|
|
ym = ClipBox->GetBottom();
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-01-30 22:22:38 +00:00
|
|
|
if( xc < ( x0 - r - width ) )
|
|
|
|
return;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-01-30 22:22:38 +00:00
|
|
|
if( yc < ( y0 - r - width ) )
|
|
|
|
return;
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2011-01-30 22:22:38 +00:00
|
|
|
if( xc > ( r + xm + width ) )
|
|
|
|
return;
|
2010-09-28 14:42:05 +00:00
|
|
|
|
2011-01-30 22:22:38 +00:00
|
|
|
if( yc > ( r + ym + width ) )
|
|
|
|
return;
|
|
|
|
}
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2011-01-30 22:22:38 +00:00
|
|
|
GRSetColorPen( DC, Color, width );
|
|
|
|
GRSetBrush( DC, Color, false );
|
|
|
|
DC->DrawEllipse( xc - r, yc - r, r + r, r + r );
|
2010-09-28 14:42:05 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRCircle( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int r, EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
GRCircle( ClipBox, DC, x, y, r, 0, Color );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRCircle( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, int aWidth, EDA_COLOR_T aColor )
|
2010-09-28 14:42:05 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
GRCircle( aClipBox, aDC, aPos.x, aPos.y, aRadius, aWidth, aColor );
|
2010-09-28 14:42:05 +00:00
|
|
|
}
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRFilledCircle( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int r,
|
2012-09-02 12:06:47 +00:00
|
|
|
int width, EDA_COLOR_T Color, EDA_COLOR_T BgColor )
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
2009-11-23 15:16:50 +00:00
|
|
|
/* Clip circles off screen. */
|
2007-10-31 06:40:15 +00:00
|
|
|
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, width );
|
|
|
|
GRSetBrush( DC, BgColor, FILLED );
|
|
|
|
DC->DrawEllipse( x - r, y - r, r + r, r + r );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRFilledCircle( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, EDA_COLOR_T aColor )
|
2009-11-23 15:16:50 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
GRFilledCircle( aClipBox, aDC, aPos.x, aPos.y, aRadius, 0, aColor, aColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw an arc in user space.
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRArc1( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
int xc, int yc, EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
GRArc1( ClipBox, DC, x1, y1, x2, y2, xc, yc, 0, Color );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw an arc, width = width in user space.
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRArc1( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
int xc, int yc, int width, EDA_COLOR_T Color )
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
2009-11-23 15:16:50 +00:00
|
|
|
/* Clip arcs off screen. */
|
2007-10-31 06:40:15 +00:00
|
|
|
if( ClipBox )
|
|
|
|
{
|
|
|
|
int x0, y0, xm, ym, r;
|
|
|
|
x0 = ClipBox->GetX();
|
|
|
|
y0 = ClipBox->GetY();
|
|
|
|
xm = ClipBox->GetRight();
|
|
|
|
ym = ClipBox->GetBottom();
|
2013-05-01 17:32:36 +00:00
|
|
|
r = KiROUND( Distance( x1, y1, xc, yc ) );
|
2009-11-23 15:16:50 +00:00
|
|
|
if( xc < ( x0 - r ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2009-11-23 15:16:50 +00:00
|
|
|
if( yc < ( y0 - r ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2009-11-23 15:16:50 +00:00
|
|
|
if( xc > ( r + xm ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2009-11-23 15:16:50 +00:00
|
|
|
if( yc > ( r + ym ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
GRSetColorPen( DC, Color, width );
|
|
|
|
GRSetBrush( DC, Color );
|
|
|
|
DC->DrawArc( x1, y1, x2, y2, xc, yc );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRArc1( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd,
|
2012-09-02 12:06:47 +00:00
|
|
|
wxPoint aCenter, int aWidth, EDA_COLOR_T aColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
GRArc1( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aCenter.x, aCenter.y,
|
|
|
|
aWidth, aColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
2011-01-30 22:22:38 +00:00
|
|
|
* Draw a filled arc in drawing space.
|
2009-11-23 15:16:50 +00:00
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRFilledArc( EDA_RECT* ClipBox,
|
2011-01-30 22:22:38 +00:00
|
|
|
wxDC* DC,
|
|
|
|
int x,
|
|
|
|
int y,
|
2013-05-05 07:17:48 +00:00
|
|
|
double StAngle,
|
|
|
|
double EndAngle,
|
2011-01-30 22:22:38 +00:00
|
|
|
int r,
|
|
|
|
int width,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color,
|
|
|
|
EDA_COLOR_T BgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
int x1, y1, x2, y2;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/* Clip arcs off screen */
|
2007-10-31 06:40:15 +00:00
|
|
|
if( ClipBox )
|
|
|
|
{
|
|
|
|
int x0, y0, xm, ym;
|
|
|
|
x0 = ClipBox->GetX();
|
|
|
|
y0 = ClipBox->GetY();
|
|
|
|
xm = ClipBox->GetRight();
|
|
|
|
ym = ClipBox->GetBottom();
|
2011-01-30 22:22:38 +00:00
|
|
|
|
|
|
|
if( x < ( x0 - r - 1 ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2011-01-30 22:22:38 +00:00
|
|
|
|
|
|
|
if( y < ( y0 - r - 1 ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2011-01-30 22:22:38 +00:00
|
|
|
|
|
|
|
if( x > ( r + xm + 1 ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2011-01-30 22:22:38 +00:00
|
|
|
|
|
|
|
if( y > ( r + ym + 1 ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
x1 = r;
|
|
|
|
y1 = 0;
|
2007-10-31 06:40:15 +00:00
|
|
|
RotatePoint( &x1, &y1, EndAngle );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
x2 = r;
|
|
|
|
y2 = 0;
|
2007-10-31 06:40:15 +00:00
|
|
|
RotatePoint( &x2, &y2, StAngle );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSetBrush( DC, BgColor, FILLED );
|
|
|
|
GRSetColorPen( DC, Color, width );
|
2011-01-30 22:22:38 +00:00
|
|
|
DC->DrawArc( x + x1, y - y1, x + x2, y - y2, x, y );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRFilledArc( EDA_RECT* ClipBox, wxDC* DC, int x, int y,
|
2013-07-29 07:33:56 +00:00
|
|
|
double StAngle, double EndAngle, int r,
|
2013-05-05 07:17:48 +00:00
|
|
|
EDA_COLOR_T Color, EDA_COLOR_T BgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
GRFilledArc( ClipBox, DC, x, y, StAngle, EndAngle, r, 0, Color, BgColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw an arc in drawing space.
|
|
|
|
*/
|
2013-05-05 07:17:48 +00:00
|
|
|
void GRArc( EDA_RECT* ClipBox, wxDC* DC, int xc, int yc, double StAngle,
|
|
|
|
double EndAngle, int r, EDA_COLOR_T Color )
|
2007-10-31 06:40:15 +00:00
|
|
|
{
|
|
|
|
int x1, y1, x2, y2;
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/* Clip arcs off screen */
|
2007-10-31 06:40:15 +00:00
|
|
|
if( ClipBox )
|
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
int radius = r + 1;
|
2007-10-31 06:40:15 +00:00
|
|
|
int x0, y0, xm, ym, x, y;
|
|
|
|
x0 = ClipBox->GetX();
|
|
|
|
y0 = ClipBox->GetY();
|
|
|
|
xm = ClipBox->GetRight();
|
|
|
|
ym = ClipBox->GetBottom();
|
2011-01-30 22:22:38 +00:00
|
|
|
x = xc;
|
|
|
|
y = yc;
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
if( x < ( x0 - radius ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2009-11-23 15:16:50 +00:00
|
|
|
if( y < ( y0 - radius ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2009-11-23 15:16:50 +00:00
|
|
|
if( x > ( xm + radius ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
2009-11-23 15:16:50 +00:00
|
|
|
if( y > ( ym + radius ) )
|
2007-10-31 06:40:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
x1 = r;
|
|
|
|
y1 = 0;
|
2007-10-31 06:40:15 +00:00
|
|
|
RotatePoint( &x1, &y1, EndAngle );
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
x2 = r;
|
|
|
|
y2 = 0;
|
2007-10-31 06:40:15 +00:00
|
|
|
RotatePoint( &x2, &y2, StAngle );
|
|
|
|
|
|
|
|
GRSetColorPen( DC, Color );
|
2010-09-21 06:35:11 +00:00
|
|
|
GRSetBrush( DC, Color, false );
|
2011-01-30 22:22:38 +00:00
|
|
|
DC->DrawArc( xc + x1, yc - y1, xc + x2, yc - y2, xc, yc );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw an arc with width = width in drawing space.
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRArc( EDA_RECT* ClipBox,
|
2009-11-23 15:16:50 +00:00
|
|
|
wxDC* DC,
|
|
|
|
int x,
|
|
|
|
int y,
|
2013-05-05 07:17:48 +00:00
|
|
|
double StAngle,
|
|
|
|
double EndAngle,
|
2009-11-23 15:16:50 +00:00
|
|
|
int r,
|
|
|
|
int width,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
int x1, y1, x2, y2;
|
|
|
|
|
|
|
|
/* Clip arcs off screen. */
|
|
|
|
if( ClipBox )
|
|
|
|
{
|
|
|
|
int x0, y0, xm, ym;
|
|
|
|
x0 = ClipBox->GetX();
|
|
|
|
y0 = ClipBox->GetY();
|
|
|
|
xm = ClipBox->GetRight();
|
|
|
|
ym = ClipBox->GetBottom();
|
|
|
|
|
|
|
|
if( x < ( x0 - r - width ) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( y < ( y0 - r - width ) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( x > ( r + xm + width ) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( y > ( 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( x + x1, y - y1, x + x2, y - y2, x, y );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw a rectangle in drawing space.
|
|
|
|
*/
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y2, EDA_COLOR_T aColor )
|
2009-11-23 15:16:50 +00:00
|
|
|
{
|
2010-10-05 11:44:34 +00:00
|
|
|
GRSRect( aClipBox, aDC, x1, y1, x2, y2, 0, aColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRRectPs( EDA_RECT* aClipBox, wxDC* aDC, const EDA_RECT& aRect, EDA_COLOR_T aColor, wxPenStyle aStyle )
|
2009-12-30 18:06:12 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
int x1 = aRect.GetX();
|
|
|
|
int y1 = aRect.GetY();
|
|
|
|
int x2 = aRect.GetRight();
|
|
|
|
int y2 = aRect.GetBottom();
|
2009-12-30 18:06:12 +00:00
|
|
|
|
2010-10-05 11:44:34 +00:00
|
|
|
GRSRect( aClipBox, aDC, x1, y1, x2, y2, 0, aColor, aStyle );
|
2009-12-30 18:06:12 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
2009-12-30 18:06:12 +00:00
|
|
|
* Draw a rectangle (thick lines) in drawing space.
|
2009-11-23 15:16:50 +00:00
|
|
|
*/
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRRect( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2, int width, EDA_COLOR_T Color )
|
2009-11-23 15:16:50 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSRect( ClipBox, DC, x1, y1, x2, y2, width, Color );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2010-10-13 19:50:23 +00:00
|
|
|
|
2012-09-02 12:06:47 +00:00
|
|
|
void GRRect( EDA_RECT* aClipBox, wxDC* aDC, const EDA_RECT& aRect, int aWidth, EDA_COLOR_T aColor )
|
2009-12-30 18:06:12 +00:00
|
|
|
{
|
2011-01-30 22:22:38 +00:00
|
|
|
int x1 = aRect.GetX();
|
|
|
|
int y1 = aRect.GetY();
|
|
|
|
int x2 = aRect.GetRight();
|
|
|
|
int y2 = aRect.GetBottom();
|
2009-12-30 18:06:12 +00:00
|
|
|
|
2011-01-30 22:22:38 +00:00
|
|
|
GRSRect( aClipBox, aDC, x1, y1, x2, y2, aWidth, aColor );
|
2009-12-30 18:06:12 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw a rectangle (filled with AreaColor) in drawing space.
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRFilledRect( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color, EDA_COLOR_T BgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSFilledRect( ClipBox, DC, x1, y1, x2, y2, 0, Color, BgColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw a rectangle (filled with AreaColor) in drawing space.
|
|
|
|
*/
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRFilledRect( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
int width, EDA_COLOR_T Color, EDA_COLOR_T BgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-31 06:40:15 +00:00
|
|
|
GRSFilledRect( ClipBox, DC, x1, y1, x2, y2, width, Color, BgColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-31 06:40:15 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
/*
|
|
|
|
* Draw a rectangle in screen space.
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRSRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
int aWidth, EDA_COLOR_T aColor, wxPenStyle aStyle )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-04-12 17:21:22 +00:00
|
|
|
wxPoint points[5];
|
|
|
|
points[0] = wxPoint(x1, y1);
|
|
|
|
points[1] = wxPoint(x1, y2);
|
|
|
|
points[2] = wxPoint(x2, y2);
|
|
|
|
points[3] = wxPoint(x2, y1);
|
|
|
|
points[4] = points[0];
|
2013-07-29 07:33:56 +00:00
|
|
|
GRSClosedPoly( aClipBox, aDC, 5, points, NOT_FILLED, aWidth,
|
|
|
|
aColor, aColor );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-13 10:22:58 +00:00
|
|
|
void GRSFilledRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y2,
|
2012-09-02 12:06:47 +00:00
|
|
|
int aWidth, EDA_COLOR_T aColor, EDA_COLOR_T aBgColor )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-04-12 17:21:22 +00:00
|
|
|
wxPoint points[5];
|
|
|
|
points[0] = wxPoint(x1, y1);
|
|
|
|
points[1] = wxPoint(x1, y2);
|
|
|
|
points[2] = wxPoint(x2, y2);
|
|
|
|
points[3] = wxPoint(x2, y1);
|
|
|
|
points[4] = points[0];
|
2011-04-13 10:22:58 +00:00
|
|
|
GRSetBrush( aDC, aBgColor, FILLED );
|
|
|
|
GRSetColorPen( aDC, aBgColor, aWidth );
|
2013-07-29 07:33:56 +00:00
|
|
|
|
2011-04-13 10:22:58 +00:00
|
|
|
if( aClipBox && (aWidth > 0) )
|
|
|
|
{
|
|
|
|
EDA_RECT clipbox(*aClipBox);
|
|
|
|
clipbox.Inflate(aWidth);
|
2013-07-29 07:33:56 +00:00
|
|
|
ClipAndDrawPoly(&clipbox, aDC, points, 5); // polygon approach is more accurate
|
2011-04-13 10:22:58 +00:00
|
|
|
}
|
|
|
|
else
|
2013-07-29 07:33:56 +00:00
|
|
|
ClipAndDrawPoly(aClipBox, aDC, points, 5 );
|
2007-10-31 06:40:15 +00:00
|
|
|
}
|
|
|
|
|
2010-11-12 16:36:43 +00:00
|
|
|
/**
|
2013-07-29 07:33:56 +00:00
|
|
|
* Function ClipAndDrawPoly
|
2009-02-20 14:31:16 +00:00
|
|
|
* Used to clip a polygon and draw it as Filled Polygon
|
2009-11-23 15:16:50 +00:00
|
|
|
* uses the Sutherland and Hodgman algo to clip the given poly against a
|
|
|
|
* rectangle. This rectangle is the drawing area this is useful under
|
|
|
|
* Linux (2009) because filled polygons are incorrectly drawn if they have
|
|
|
|
* too large coordinates (seems due to integer overflows in calculations)
|
|
|
|
* Could be removed in some years, if become unnecessary.
|
2009-02-20 14:31:16 +00:00
|
|
|
*/
|
2010-10-25 16:48:05 +00:00
|
|
|
|
|
|
|
/* Note: aClipBox == NULL is legal, so if aClipBox == NULL,
|
|
|
|
* the polygon is drawn, but not clipped
|
|
|
|
*/
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <SutherlandHodgmanClipPoly.h>
|
2011-01-30 22:22:38 +00:00
|
|
|
|
2013-07-29 07:33:56 +00:00
|
|
|
void ClipAndDrawPoly( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPoints[], int n )
|
2009-02-20 14:31:16 +00:00
|
|
|
{
|
2010-10-25 16:48:05 +00:00
|
|
|
if( aClipBox == NULL )
|
|
|
|
{
|
|
|
|
aDC->DrawPolygon( n, aPoints );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A clip box exists: clip and draw the polygon.
|
2013-12-13 16:27:30 +00:00
|
|
|
static std::vector<wxPoint> clippedPolygon;
|
|
|
|
static pointVector inputPolygon, outputPolygon;
|
2009-02-20 14:31:16 +00:00
|
|
|
|
|
|
|
inputPolygon.clear();
|
|
|
|
outputPolygon.clear();
|
|
|
|
clippedPolygon.clear();
|
2011-01-30 22:22:38 +00:00
|
|
|
|
2009-02-20 14:31:16 +00:00
|
|
|
for( int ii = 0; ii < n; ii++ )
|
2011-01-30 22:22:38 +00:00
|
|
|
inputPolygon.push_back( PointF( (REAL) aPoints[ii].x, (REAL) aPoints[ii].y ) );
|
2009-02-20 14:31:16 +00:00
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
RectF window( (REAL) aClipBox->GetX(), (REAL) aClipBox->GetY(),
|
2011-01-30 22:22:38 +00:00
|
|
|
(REAL) aClipBox->GetWidth(), (REAL) aClipBox->GetHeight() );
|
2009-02-20 14:31:16 +00:00
|
|
|
|
|
|
|
SutherlandHodgman sh( window );
|
|
|
|
sh.Clip( inputPolygon, outputPolygon );
|
|
|
|
|
2011-01-30 22:22:38 +00:00
|
|
|
for( cpointIterator cit = outputPolygon.begin(); cit != outputPolygon.end(); ++cit )
|
2009-02-20 14:31:16 +00:00
|
|
|
{
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
clippedPolygon.push_back( wxPoint( KiROUND( cit->X ), KiROUND( cit->Y ) ) );
|
2009-02-20 14:31:16 +00:00
|
|
|
}
|
|
|
|
|
2009-11-23 15:16:50 +00:00
|
|
|
if( clippedPolygon.size() )
|
2009-02-20 14:31:16 +00:00
|
|
|
aDC->DrawPolygon( clippedPolygon.size(), &clippedPolygon[0] );
|
|
|
|
}
|
2009-11-23 15:16:50 +00:00
|
|
|
|
2009-12-30 18:06:12 +00:00
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRBezier( EDA_RECT* ClipBox,
|
2009-06-25 20:45:27 +00:00
|
|
|
wxDC* DC,
|
|
|
|
int x1,
|
|
|
|
int y1,
|
|
|
|
int x2,
|
|
|
|
int y2,
|
|
|
|
int x3,
|
|
|
|
int y3,
|
|
|
|
int width,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color )
|
2009-06-25 20:45:27 +00:00
|
|
|
{
|
|
|
|
std::vector<wxPoint> Points = Bezier2Poly( x1, y1, x2, y2, x3, y3 );
|
2012-09-02 12:06:47 +00:00
|
|
|
GRPoly( ClipBox, DC, Points.size(), &Points[0], false, width, Color, Color );
|
2009-06-25 20:45:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
void GRBezier( EDA_RECT* ClipBox,
|
2009-06-25 20:45:27 +00:00
|
|
|
wxDC* DC,
|
|
|
|
int x1,
|
|
|
|
int y1,
|
|
|
|
int x2,
|
|
|
|
int y2,
|
|
|
|
int x3,
|
|
|
|
int y3,
|
|
|
|
int x4,
|
|
|
|
int y4,
|
|
|
|
int width,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color )
|
2009-06-25 20:45:27 +00:00
|
|
|
{
|
|
|
|
std::vector<wxPoint> Points = Bezier2Poly( x1, y1, x2, y2, x3, y3, x4, y4 );
|
2012-09-02 12:06:47 +00:00
|
|
|
GRPoly( ClipBox, DC, Points.size(), &Points[0], false, width, Color, Color );
|
2009-06-25 20:45:27 +00:00
|
|
|
}
|
2013-04-04 21:35:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
EDA_COLOR_T ColorMix( EDA_COLOR_T aColor1, EDA_COLOR_T aColor2 )
|
|
|
|
{
|
|
|
|
/* Memoization storage. This could be potentially called for each
|
2013-04-06 12:01:53 +00:00
|
|
|
* color merge so a cache is useful (there are few colours anyway) */
|
2013-04-04 21:35:01 +00:00
|
|
|
static EDA_COLOR_T mix_cache[NBCOLORS][NBCOLORS];
|
|
|
|
|
|
|
|
// TODO how is alpha used? it's a mac only thing, I have no idea
|
|
|
|
aColor1 = ColorGetBase( aColor1 );
|
|
|
|
aColor2 = ColorGetBase( aColor2 );
|
|
|
|
|
|
|
|
// First easy thing: a black gives always the other colour
|
|
|
|
if( aColor1 == BLACK )
|
|
|
|
return aColor2;
|
|
|
|
if( aColor2 == BLACK)
|
|
|
|
return aColor1;
|
|
|
|
|
2013-04-06 12:01:53 +00:00
|
|
|
/* Now we are sure that black can't occur, so the rule is:
|
2013-04-04 21:35:01 +00:00
|
|
|
* BLACK means not computed yet. If we're lucky we already have
|
|
|
|
* an answer */
|
|
|
|
EDA_COLOR_T candidate = mix_cache[aColor1][aColor2];
|
|
|
|
if( candidate != BLACK )
|
|
|
|
return candidate;
|
|
|
|
|
|
|
|
// Blend the two colors (i.e. OR the RGB values)
|
2013-04-06 12:01:53 +00:00
|
|
|
const StructColors &c1 = g_ColorRefs[aColor1];
|
|
|
|
const StructColors &c2 = g_ColorRefs[aColor2];
|
2013-04-04 21:35:01 +00:00
|
|
|
|
|
|
|
// Ask the palette for the nearest color to the mix
|
2013-04-06 12:01:53 +00:00
|
|
|
wxColour mixed( c1.m_Red | c2.m_Red,
|
2013-04-04 21:35:01 +00:00
|
|
|
c1.m_Green | c2.m_Green,
|
|
|
|
c1.m_Blue | c2.m_Blue );
|
|
|
|
candidate = ColorFindNearest( mixed );
|
|
|
|
|
|
|
|
/* Here, BLACK is *not* a good answer, since it would recompute the next time.
|
|
|
|
* Even theorically its not possible (with the current rules), but
|
|
|
|
* maybe the metric will change in the future */
|
2013-04-06 12:01:53 +00:00
|
|
|
if( candidate == BLACK)
|
2013-04-04 21:35:01 +00:00
|
|
|
candidate = DARKDARKGRAY;
|
|
|
|
|
|
|
|
// Store the result in the cache. The operation is commutative, too
|
|
|
|
mix_cache[aColor1][aColor2] = candidate;
|
|
|
|
mix_cache[aColor2][aColor1] = candidate;
|
|
|
|
return candidate;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EDA_COLOR_T ColorByName( const wxChar *aName )
|
|
|
|
{
|
|
|
|
// look for a match in the palette itself
|
2013-04-06 12:01:53 +00:00
|
|
|
for( EDA_COLOR_T trying = BLACK; trying < NBCOLORS; trying = NextColor(trying) )
|
2013-04-04 21:35:01 +00:00
|
|
|
{
|
|
|
|
if( 0 == wxStricmp( aName, g_ColorRefs[trying].m_Name ) )
|
|
|
|
return trying;
|
|
|
|
}
|
2013-04-06 12:01:53 +00:00
|
|
|
|
2013-04-04 21:35:01 +00:00
|
|
|
// Not found, no idea...
|
|
|
|
return UNSPECIFIED_COLOR;
|
|
|
|
}
|
|
|
|
|
2013-04-09 17:16:53 +00:00
|
|
|
bool ColorIsLight( EDA_COLOR_T aColor )
|
|
|
|
{
|
|
|
|
const StructColors &c = g_ColorRefs[ColorGetBase( aColor )];
|
|
|
|
int r = c.m_Red;
|
|
|
|
int g = c.m_Green;
|
|
|
|
int b = c.m_Blue;
|
|
|
|
return ((r * r) + (g * g) + (b * b)) > (128 * 128 * 3);
|
|
|
|
}
|
2013-04-04 21:35:01 +00:00
|
|
|
|
|
|
|
EDA_COLOR_T ColorFindNearest( const wxColour &aColor )
|
|
|
|
{
|
2013-09-11 09:11:27 +00:00
|
|
|
return ColorFindNearest( aColor.Red(), aColor.Green(), aColor.Blue() );
|
|
|
|
}
|
2013-04-04 21:35:01 +00:00
|
|
|
|
2013-09-11 09:11:27 +00:00
|
|
|
EDA_COLOR_T ColorFindNearest( int aR, int aG, int aB )
|
|
|
|
{
|
|
|
|
EDA_COLOR_T candidate = BLACK;
|
2013-04-04 21:35:01 +00:00
|
|
|
|
|
|
|
/* Find the 'nearest' color in the palette. This is fun. There is
|
|
|
|
a gazilion of metrics for the color space and no one of the
|
|
|
|
useful one is in the RGB color space. Who cares, this is a CAD,
|
2013-04-06 12:01:53 +00:00
|
|
|
not a photosomething...
|
|
|
|
|
2013-04-04 21:35:01 +00:00
|
|
|
I hereby declare that the distance is the sum of the square of the
|
|
|
|
component difference. Think about the RGB color cube. Now get the
|
2013-04-06 12:01:53 +00:00
|
|
|
euclidean distance, but without the square root... for ordering
|
2013-04-04 21:35:01 +00:00
|
|
|
purposes it's the same, obviously. Also each component can't be
|
|
|
|
less of the target one, since I found this currently work better...
|
|
|
|
*/
|
|
|
|
int nearest_distance = 255 * 255 * 3 + 1; // Can't beat this
|
|
|
|
|
2013-04-06 12:01:53 +00:00
|
|
|
for( EDA_COLOR_T trying = BLACK; trying < NBCOLORS; trying = NextColor(trying) )
|
2013-04-04 21:35:01 +00:00
|
|
|
{
|
2013-04-06 12:01:53 +00:00
|
|
|
const StructColors &c = g_ColorRefs[trying];
|
2013-09-11 09:11:27 +00:00
|
|
|
int distance = (aR - c.m_Red) * (aR - c.m_Red) +
|
|
|
|
(aG - c.m_Green) * (aG - c.m_Green) +
|
|
|
|
(aB - c.m_Blue) * (aB - c.m_Blue);
|
|
|
|
if( distance < nearest_distance && c.m_Red >= aR &&
|
|
|
|
c.m_Green >= aG && c.m_Blue >= aB )
|
2013-04-04 21:35:01 +00:00
|
|
|
{
|
|
|
|
nearest_distance = distance;
|
|
|
|
candidate = trying;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return candidate;
|
|
|
|
}
|
2013-04-09 16:00:46 +00:00
|
|
|
|
2013-07-29 07:33:56 +00:00
|
|
|
void GRDrawAnchor( EDA_RECT *aClipBox, wxDC *aDC, int x, int y,
|
2013-04-09 16:00:46 +00:00
|
|
|
int aSize, EDA_COLOR_T aColor )
|
|
|
|
{
|
|
|
|
int anchor_size = aDC->DeviceToLogicalXRel( aSize );
|
|
|
|
|
|
|
|
GRLine( aClipBox, aDC,
|
|
|
|
x - anchor_size, y,
|
|
|
|
x + anchor_size, y, 0, aColor );
|
|
|
|
GRLine( aClipBox, aDC,
|
|
|
|
x, y - anchor_size,
|
|
|
|
x, y + anchor_size, 0, aColor );
|
|
|
|
}
|