Minor plotter code improvements.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -115,7 +115,7 @@ static const char* getDXFLineType( PLOT_DASH_TYPE aType )
|
||||
|
||||
// A helper function to create a color name acceptable in DXF files
|
||||
// DXF files do not use a RGB definition
|
||||
static wxString getDXFColorName( COLOR4D aColor )
|
||||
static wxString getDXFColorName( const COLOR4D& aColor )
|
||||
{
|
||||
EDA_COLOR_T color = COLOR4D::FindNearestLegacyColor( int( aColor.r * 255 ),
|
||||
int( aColor.g * 255 ),
|
||||
@@ -144,11 +144,6 @@ void DXF_PLOTTER::SetUnits( DXF_UNITS aUnit )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the scale/position for the DXF plot
|
||||
* The DXF engine doesn't support line widths and mirroring. The output
|
||||
* coordinate system is in the first quadrant (in mm)
|
||||
*/
|
||||
void DXF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
|
||||
double aScale, bool aMirror )
|
||||
{
|
||||
@@ -172,9 +167,7 @@ void DXF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
|
||||
m_currentColor = COLOR4D::BLACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the DXF plot with a skeleton header
|
||||
*/
|
||||
|
||||
bool DXF_PLOTTER::StartPlot()
|
||||
{
|
||||
wxASSERT( m_outputFile );
|
||||
@@ -404,10 +397,7 @@ bool DXF_PLOTTER::EndPlot()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The DXF exporter handles 'colors' as layers...
|
||||
*/
|
||||
void DXF_PLOTTER::SetColor( COLOR4D color )
|
||||
void DXF_PLOTTER::SetColor( const COLOR4D& color )
|
||||
{
|
||||
if( ( m_colorMode )
|
||||
|| ( color == COLOR4D::BLACK )
|
||||
@@ -421,9 +411,7 @@ void DXF_PLOTTER::SetColor( COLOR4D color )
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DXF rectangle: fill not supported
|
||||
*/
|
||||
|
||||
void DXF_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, int width )
|
||||
{
|
||||
wxASSERT( m_outputFile );
|
||||
@@ -435,17 +423,12 @@ void DXF_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, in
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DXF circle: full functionality; it even does 'fills' drawing a
|
||||
* circle with a dual-arc polyline wide as the radius.
|
||||
*
|
||||
* I could use this trick to do other filled primitives
|
||||
*/
|
||||
void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill, int width )
|
||||
{
|
||||
wxASSERT( m_outputFile );
|
||||
double radius = userToDeviceSize( diameter / 2 );
|
||||
DPOINT centre_dev = userToDeviceCoordinates( centre );
|
||||
|
||||
if( radius > 0 )
|
||||
{
|
||||
wxString cname = getDXFColorName( m_currentColor );
|
||||
@@ -460,29 +443,23 @@ void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill, i
|
||||
if( fill == FILL_TYPE::FILLED_SHAPE )
|
||||
{
|
||||
double r = radius*0.5;
|
||||
fprintf( m_outputFile, "0\nPOLYLINE\n");
|
||||
fprintf( m_outputFile, "8\n%s\n66\n1\n70\n1\n", TO_UTF8( cname ));
|
||||
fprintf( m_outputFile, "0\nPOLYLINE\n" );
|
||||
fprintf( m_outputFile, "8\n%s\n66\n1\n70\n1\n", TO_UTF8( cname ) );
|
||||
fprintf( m_outputFile, "40\n%g\n41\n%g\n", radius, radius);
|
||||
fprintf( m_outputFile, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ));
|
||||
fprintf( m_outputFile, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ) );
|
||||
fprintf( m_outputFile, "10\n%g\n 20\n%g\n42\n1.0\n",
|
||||
centre_dev.x-r, centre_dev.y );
|
||||
fprintf( m_outputFile, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ));
|
||||
centre_dev.x-r, centre_dev.y );
|
||||
fprintf( m_outputFile, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ) );
|
||||
fprintf( m_outputFile, "10\n%g\n 20\n%g\n42\n1.0\n",
|
||||
centre_dev.x+r, centre_dev.y );
|
||||
centre_dev.x+r, centre_dev.y );
|
||||
fprintf( m_outputFile, "0\nSEQEND\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DXF polygon: doesn't fill it but at least it close the filled ones
|
||||
* DXF does not know thick outline.
|
||||
* It does not know thick segments, therefore filled polygons with thick outline
|
||||
* are converted to inflated polygon by aWidth/2
|
||||
*/
|
||||
void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
|
||||
FILL_TYPE aFill, int aWidth, void * aData )
|
||||
FILL_TYPE aFill, int aWidth, void* aData )
|
||||
{
|
||||
if( aCornerList.size() <= 1 )
|
||||
return;
|
||||
@@ -509,7 +486,6 @@ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if the polygon outline has thickness, and is not filled
|
||||
// (i.e. is a polyline) plot outlines with thick segments
|
||||
if( aWidth > 0 && aFill == FILL_TYPE::NO_FILL )
|
||||
@@ -517,8 +493,7 @@ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
|
||||
MoveTo( aCornerList[0] );
|
||||
|
||||
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
|
||||
ThickSegment( aCornerList[ii-1], aCornerList[ii],
|
||||
aWidth, FILLED, NULL );
|
||||
ThickSegment( aCornerList[ii-1], aCornerList[ii], aWidth, FILLED, NULL );
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -591,6 +566,7 @@ void DXF_PLOTTER::PenTo( const wxPoint& pos, char plume )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DPOINT pos_dev = userToDeviceCoordinates( pos );
|
||||
DPOINT pen_lastpos_dev = userToDeviceCoordinates( m_penLastpos );
|
||||
|
||||
@@ -605,6 +581,7 @@ void DXF_PLOTTER::PenTo( const wxPoint& pos, char plume )
|
||||
TO_UTF8( cname ), lname,
|
||||
pen_lastpos_dev.x, pen_lastpos_dev.y, pos_dev.x, pos_dev.y );
|
||||
}
|
||||
|
||||
m_penLastpos = pos;
|
||||
}
|
||||
|
||||
@@ -628,6 +605,7 @@ void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int
|
||||
const SHAPE_LINE_CHAIN& path = outlineBuffer.COutline( 0 );
|
||||
|
||||
cornerList.reserve( path.PointCount() );
|
||||
|
||||
for( int jj = 0; jj < path.PointCount(); jj++ )
|
||||
cornerList.emplace_back( path.CPoint( jj ).x, path.CPoint( jj ).y );
|
||||
|
||||
@@ -644,6 +622,7 @@ void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Plot an arc in DXF format
|
||||
* Filling is not supported
|
||||
*/
|
||||
@@ -675,9 +654,7 @@ void DXF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i
|
||||
StAngle / 10.0, EndAngle / 10.0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* DXF oval pad: always done in sketch mode
|
||||
*/
|
||||
|
||||
void DXF_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double orient,
|
||||
OUTLINE_MODE trace_mode, void* aData )
|
||||
{
|
||||
@@ -696,21 +673,14 @@ void DXF_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DXF round pad: always done in sketch mode; it could be filled but it isn't
|
||||
* pretty if other kinds of pad aren't...
|
||||
*/
|
||||
void DXF_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre,
|
||||
OUTLINE_MODE trace_mode, void* aData )
|
||||
OUTLINE_MODE trace_mode, void* aData )
|
||||
{
|
||||
wxASSERT( m_outputFile );
|
||||
Circle( pos, diametre, FILL_TYPE::NO_FILL );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DXF rectangular pad: always done in sketch mode
|
||||
*/
|
||||
void DXF_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
|
||||
double orient, OUTLINE_MODE trace_mode, void* aData )
|
||||
{
|
||||
@@ -723,6 +693,7 @@ void DXF_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
|
||||
|
||||
if( size.x < 0 )
|
||||
size.x = 0;
|
||||
|
||||
if( size.y < 0 )
|
||||
size.y = 0;
|
||||
|
||||
@@ -739,6 +710,7 @@ void DXF_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
|
||||
FinishTo( wxPoint( fx, fy ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( size.y == 0 )
|
||||
{
|
||||
ox = pos.x - size.x;
|
||||
@@ -775,13 +747,14 @@ void DXF_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
|
||||
FinishTo( wxPoint( ox, oy ) );
|
||||
}
|
||||
|
||||
|
||||
void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
|
||||
int aCornerRadius, double aOrient,
|
||||
OUTLINE_MODE aTraceMode, void* aData )
|
||||
{
|
||||
SHAPE_POLY_SET outline;
|
||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
|
||||
aCornerRadius, 0.0, 0, GetPlotterArcHighDef(), ERROR_INSIDE );
|
||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient, aCornerRadius,
|
||||
0.0, 0, GetPlotterArcHighDef(), ERROR_INSIDE );
|
||||
|
||||
// TransformRoundRectToPolygon creates only one convex polygon
|
||||
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
||||
@@ -812,9 +785,6 @@ void DXF_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DXF trapezoidal pad: only sketch mode is supported
|
||||
*/
|
||||
void DXF_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
|
||||
double aPadOrient, OUTLINE_MODE aTrace_Mode, void* aData )
|
||||
{
|
||||
@@ -837,9 +807,8 @@ void DXF_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorner
|
||||
}
|
||||
|
||||
|
||||
void DXF_PLOTTER::FlashRegularPolygon( const wxPoint& aShapePos,
|
||||
int aRadius, int aCornerCount,
|
||||
double aOrient, OUTLINE_MODE aTraceMode, void* aData )
|
||||
void DXF_PLOTTER::FlashRegularPolygon( const wxPoint& aShapePos, int aRadius, int aCornerCount,
|
||||
double aOrient, OUTLINE_MODE aTraceMode, void* aData )
|
||||
{
|
||||
// Do nothing
|
||||
wxASSERT( 0 );
|
||||
@@ -847,10 +816,12 @@ void DXF_PLOTTER::FlashRegularPolygon( const wxPoint& aShapePos,
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a given string contains non-ASCII characters.
|
||||
* FIXME: the performance of this code is really poor, but in this case it can be
|
||||
* acceptable because the plot operation is not called very often.
|
||||
* @param string String to check
|
||||
* Check if a given string contains non-ASCII characters.
|
||||
*
|
||||
* @fixme The performance of this code is really poor, but in this case it can be
|
||||
* acceptable because the plot operation is not called very often.
|
||||
*
|
||||
* @param string String to check.
|
||||
* @return true if it contains some non-ASCII character, false if all characters are
|
||||
* inside ASCII range (<=255).
|
||||
*/
|
||||
@@ -865,8 +836,9 @@ bool containsNonAsciiChars( const wxString& string )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void DXF_PLOTTER::Text( const wxPoint& aPos,
|
||||
COLOR4D aColor,
|
||||
const COLOR4D& aColor,
|
||||
const wxString& aText,
|
||||
double aOrient,
|
||||
const wxSize& aSize,
|
||||
@@ -901,6 +873,7 @@ void DXF_PLOTTER::Text( const wxPoint& aPos,
|
||||
wxString cname = getDXFColorName( m_currentColor );
|
||||
DPOINT size_dev = userToDeviceSize( aSize );
|
||||
int h_code = 0, v_code = 0;
|
||||
|
||||
switch( aH_justify )
|
||||
{
|
||||
case GR_TEXT_HJUSTIFY_LEFT:
|
||||
@@ -913,6 +886,7 @@ void DXF_PLOTTER::Text( const wxPoint& aPos,
|
||||
h_code = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch( aV_justify )
|
||||
{
|
||||
case GR_TEXT_VJUSTIFY_TOP:
|
||||
@@ -1042,6 +1016,7 @@ void DXF_PLOTTER::Text( const wxPoint& aPos,
|
||||
putc( ch, m_outputFile );
|
||||
}
|
||||
}
|
||||
|
||||
putc( '\n', m_outputFile );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user