Lazy context handling for SVG plotting.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15325
This commit is contained in:
parent
256c7fa788
commit
f43b90b15f
|
@ -178,20 +178,13 @@ void PSLIKE_PLOTTER::FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I&
|
||||||
int aCornerRadius, const EDA_ANGLE& aOrient,
|
int aCornerRadius, const EDA_ANGLE& aOrient,
|
||||||
OUTLINE_MODE aTraceMode, void* aData )
|
OUTLINE_MODE aTraceMode, void* aData )
|
||||||
{
|
{
|
||||||
VECTOR2I size( aSize );
|
|
||||||
|
|
||||||
if( aTraceMode == FILLED )
|
if( aTraceMode == FILLED )
|
||||||
{
|
|
||||||
SetCurrentLineWidth( 0 );
|
SetCurrentLineWidth( 0 );
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SHAPE_POLY_SET outline;
|
SHAPE_POLY_SET outline;
|
||||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient, aCornerRadius, 0.0, 0,
|
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient, aCornerRadius, 0.0, 0,
|
||||||
0, GetPlotterArcHighDef(), ERROR_INSIDE );
|
0, GetPlotterArcHighDef(), ERROR_INSIDE );
|
||||||
|
|
||||||
std::vector<VECTOR2I> cornerList;
|
std::vector<VECTOR2I> cornerList;
|
||||||
|
@ -215,17 +208,10 @@ void PSLIKE_PLOTTER::FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aS
|
||||||
const EDA_ANGLE& aOrient, SHAPE_POLY_SET* aPolygons,
|
const EDA_ANGLE& aOrient, SHAPE_POLY_SET* aPolygons,
|
||||||
OUTLINE_MODE aTraceMode, void* aData )
|
OUTLINE_MODE aTraceMode, void* aData )
|
||||||
{
|
{
|
||||||
VECTOR2I size( aSize );
|
|
||||||
|
|
||||||
if( aTraceMode == FILLED )
|
if( aTraceMode == FILLED )
|
||||||
{
|
|
||||||
SetCurrentLineWidth( 0 );
|
SetCurrentLineWidth( 0 );
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<VECTOR2I> cornerList;
|
std::vector<VECTOR2I> cornerList;
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,9 @@ static wxString XmlEsc( const wxString& aStr, bool isAttribute = false )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
escaped.append(c);
|
escaped.append(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,15 +205,6 @@ void SVG_PLOTTER::SetSvgCoordinatesFormat( unsigned aPrecision )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SVG_PLOTTER::SetColor( const COLOR4D& color )
|
|
||||||
{
|
|
||||||
PSLIKE_PLOTTER::SetColor( color );
|
|
||||||
|
|
||||||
if( m_graphics_changed )
|
|
||||||
setSVGPlotStyle( GetCurrentLineWidth() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SVG_PLOTTER::setFillMode( FILL_T fill )
|
void SVG_PLOTTER::setFillMode( FILL_T fill )
|
||||||
{
|
{
|
||||||
if( m_fillMode != fill )
|
if( m_fillMode != fill )
|
||||||
|
@ -322,30 +315,19 @@ void SVG_PLOTTER::SetCurrentLineWidth( int aWidth, void* aData )
|
||||||
m_graphics_changed = true;
|
m_graphics_changed = true;
|
||||||
m_currentPenWidth = aWidth;
|
m_currentPenWidth = aWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_graphics_changed )
|
|
||||||
setSVGPlotStyle( aWidth );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SVG_PLOTTER::StartBlock( void* aData )
|
void SVG_PLOTTER::StartBlock( void* aData )
|
||||||
{
|
{
|
||||||
std::string* idstr = reinterpret_cast<std::string*>( aData );
|
// We can't use <g></g> for blocks because we're already using it for graphics context, and
|
||||||
|
// our graphics context handling is lazy (ie: it leaves the last group open until the context
|
||||||
fputs( "<g ", m_outputFile );
|
// changes).
|
||||||
|
|
||||||
if( idstr )
|
|
||||||
fprintf( m_outputFile, "id=\"%s\"", idstr->c_str() );
|
|
||||||
|
|
||||||
fprintf( m_outputFile, ">\n" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SVG_PLOTTER::EndBlock( void* aData )
|
void SVG_PLOTTER::EndBlock( void* aData )
|
||||||
{
|
{
|
||||||
fprintf( m_outputFile, "</g>\n" );
|
|
||||||
|
|
||||||
m_graphics_changed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -399,6 +381,9 @@ void SVG_PLOTTER::Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T fill, int
|
||||||
setFillMode( fill );
|
setFillMode( fill );
|
||||||
SetCurrentLineWidth( width );
|
SetCurrentLineWidth( width );
|
||||||
|
|
||||||
|
if( m_graphics_changed )
|
||||||
|
setSVGPlotStyle( GetCurrentLineWidth() );
|
||||||
|
|
||||||
// Rectangles having a 0 size value for height or width are just not drawn on Inkscape,
|
// Rectangles having a 0 size value for height or width are just not drawn on Inkscape,
|
||||||
// so use a line when happens.
|
// so use a line when happens.
|
||||||
if( rect_dev.GetSize().x == 0.0 || rect_dev.GetSize().y == 0.0 ) // Draw a line
|
if( rect_dev.GetSize().x == 0.0 || rect_dev.GetSize().y == 0.0 ) // Draw a line
|
||||||
|
@ -427,6 +412,9 @@ void SVG_PLOTTER::Circle( const VECTOR2I& pos, int diametre, FILL_T fill, int wi
|
||||||
setFillMode( fill );
|
setFillMode( fill );
|
||||||
SetCurrentLineWidth( width );
|
SetCurrentLineWidth( width );
|
||||||
|
|
||||||
|
if( m_graphics_changed )
|
||||||
|
setSVGPlotStyle( GetCurrentLineWidth() );
|
||||||
|
|
||||||
// If diameter is less than width, switch to filled mode
|
// If diameter is less than width, switch to filled mode
|
||||||
if( fill == FILL_T::NO_FILL && diametre < width )
|
if( fill == FILL_T::NO_FILL && diametre < width )
|
||||||
{
|
{
|
||||||
|
@ -524,6 +512,9 @@ void SVG_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||||
setFillMode( aFill );
|
setFillMode( aFill );
|
||||||
SetCurrentLineWidth( 0 );
|
SetCurrentLineWidth( 0 );
|
||||||
|
|
||||||
|
if( m_graphics_changed )
|
||||||
|
setSVGPlotStyle( GetCurrentLineWidth() );
|
||||||
|
|
||||||
fprintf( m_outputFile, "<path d=\"M%.*f %.*f A%.*f %.*f 0.0 %d %d %.*f %.*f L %.*f %.*f Z\" />\n",
|
fprintf( m_outputFile, "<path d=\"M%.*f %.*f A%.*f %.*f 0.0 %d %d %.*f %.*f L %.*f %.*f Z\" />\n",
|
||||||
m_precision, start.x, m_precision, start.y,
|
m_precision, start.x, m_precision, start.y,
|
||||||
m_precision, radius_device, m_precision, radius_device,
|
m_precision, radius_device, m_precision, radius_device,
|
||||||
|
@ -534,6 +525,10 @@ void SVG_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||||
|
|
||||||
setFillMode( FILL_T::NO_FILL );
|
setFillMode( FILL_T::NO_FILL );
|
||||||
SetCurrentLineWidth( aWidth );
|
SetCurrentLineWidth( aWidth );
|
||||||
|
|
||||||
|
if( m_graphics_changed )
|
||||||
|
setSVGPlotStyle( GetCurrentLineWidth() );
|
||||||
|
|
||||||
fprintf( m_outputFile, "<path d=\"M%.*f %.*f A%.*f %.*f 0.0 %d %d %.*f %.*f\" />\n",
|
fprintf( m_outputFile, "<path d=\"M%.*f %.*f A%.*f %.*f 0.0 %d %d %.*f %.*f\" />\n",
|
||||||
m_precision, start.x, m_precision, start.y,
|
m_precision, start.x, m_precision, start.y,
|
||||||
m_precision, radius_device, m_precision, radius_device,
|
m_precision, radius_device, m_precision, radius_device,
|
||||||
|
@ -550,6 +545,9 @@ void SVG_PLOTTER::BezierCurve( const VECTOR2I& aStart, const VECTOR2I& aControl1
|
||||||
setFillMode( FILL_T::NO_FILL );
|
setFillMode( FILL_T::NO_FILL );
|
||||||
SetCurrentLineWidth( aLineThickness );
|
SetCurrentLineWidth( aLineThickness );
|
||||||
|
|
||||||
|
if( m_graphics_changed )
|
||||||
|
setSVGPlotStyle( GetCurrentLineWidth() );
|
||||||
|
|
||||||
VECTOR2D start = userToDeviceCoordinates( aStart );
|
VECTOR2D start = userToDeviceCoordinates( aStart );
|
||||||
VECTOR2D ctrl1 = userToDeviceCoordinates( aControl1 );
|
VECTOR2D ctrl1 = userToDeviceCoordinates( aControl1 );
|
||||||
VECTOR2D ctrl2 = userToDeviceCoordinates( aControl2 );
|
VECTOR2D ctrl2 = userToDeviceCoordinates( aControl2 );
|
||||||
|
@ -633,7 +631,9 @@ void SVG_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double
|
||||||
wxMemoryOutputStream img_stream;
|
wxMemoryOutputStream img_stream;
|
||||||
|
|
||||||
if( m_colorMode )
|
if( m_colorMode )
|
||||||
|
{
|
||||||
aImage.SaveFile( img_stream, wxBITMAP_TYPE_PNG );
|
aImage.SaveFile( img_stream, wxBITMAP_TYPE_PNG );
|
||||||
|
}
|
||||||
else // Plot in B&W
|
else // Plot in B&W
|
||||||
{
|
{
|
||||||
wxImage image = aImage.ConvertToGreyscale();
|
wxImage image = aImage.ConvertToGreyscale();
|
||||||
|
@ -686,10 +686,10 @@ void SVG_PLOTTER::PenTo( const VECTOR2I& pos, char plume )
|
||||||
// Ensure we do not use a fill mode when moving the pen,
|
// Ensure we do not use a fill mode when moving the pen,
|
||||||
// in SVG mode (i;e. we are plotting only basic lines, not a filled area
|
// in SVG mode (i;e. we are plotting only basic lines, not a filled area
|
||||||
if( m_fillMode != FILL_T::NO_FILL )
|
if( m_fillMode != FILL_T::NO_FILL )
|
||||||
{
|
|
||||||
setFillMode( FILL_T::NO_FILL );
|
setFillMode( FILL_T::NO_FILL );
|
||||||
|
|
||||||
|
if( m_graphics_changed )
|
||||||
setSVGPlotStyle( GetCurrentLineWidth() );
|
setSVGPlotStyle( GetCurrentLineWidth() );
|
||||||
}
|
|
||||||
|
|
||||||
fprintf( m_outputFile, "<path d=\"M%.*f %.*f\n",
|
fprintf( m_outputFile, "<path d=\"M%.*f %.*f\n",
|
||||||
m_precision, pos_dev.x,
|
m_precision, pos_dev.x,
|
||||||
|
@ -697,6 +697,9 @@ void SVG_PLOTTER::PenTo( const VECTOR2I& pos, char plume )
|
||||||
}
|
}
|
||||||
else if( m_penState != plume || pos != m_penLastpos )
|
else if( m_penState != plume || pos != m_penLastpos )
|
||||||
{
|
{
|
||||||
|
if( m_graphics_changed )
|
||||||
|
setSVGPlotStyle( GetCurrentLineWidth() );
|
||||||
|
|
||||||
VECTOR2D pos_dev = userToDeviceCoordinates( pos );
|
VECTOR2D pos_dev = userToDeviceCoordinates( pos );
|
||||||
|
|
||||||
fprintf( m_outputFile, "L%.*f %.*f\n",
|
fprintf( m_outputFile, "L%.*f %.*f\n",
|
||||||
|
|
|
@ -530,8 +530,6 @@ public:
|
||||||
return PLOT_FORMAT::SVG;
|
return PLOT_FORMAT::SVG;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetColor( const COLOR4D& color ) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create SVG file header.
|
* Create SVG file header.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -87,7 +87,7 @@ public:
|
||||||
|
|
||||||
void PlotDimension( const PCB_DIMENSION_BASE* aDim );
|
void PlotDimension( const PCB_DIMENSION_BASE* aDim );
|
||||||
void PlotPcbTarget( const PCB_TARGET* aMire );
|
void PlotPcbTarget( const PCB_TARGET* aMire );
|
||||||
void PlotZones( const ZONE* aZone, PCB_LAYER_ID aLayer, const SHAPE_POLY_SET& aPolysList );
|
void PlotZone( const ZONE* aZone, PCB_LAYER_ID aLayer, const SHAPE_POLY_SET& aPolysList );
|
||||||
void PlotText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, bool aIsKnockout,
|
void PlotText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, bool aIsKnockout,
|
||||||
const KIFONT::METRICS& aFontMetrics );
|
const KIFONT::METRICS& aFontMetrics );
|
||||||
void PlotShape( const PCB_SHAPE* aShape );
|
void PlotShape( const PCB_SHAPE* aShape );
|
||||||
|
|
|
@ -691,13 +691,13 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
itemplotter.PlotZones( zone, layer, mainArea );
|
itemplotter.PlotZone( zone, layer, mainArea );
|
||||||
|
|
||||||
if( !islands.IsEmpty() )
|
if( !islands.IsEmpty() )
|
||||||
{
|
{
|
||||||
ZONE dummy( *zone );
|
ZONE dummy( *zone );
|
||||||
dummy.SetNet( &nonet );
|
dummy.SetNet( &nonet );
|
||||||
itemplotter.PlotZones( &dummy, layer, islands );
|
itemplotter.PlotZone( &dummy, layer, islands );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -994,7 +994,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||||
areas.BooleanAdd( initialPolys, SHAPE_POLY_SET::PM_FAST );
|
areas.BooleanAdd( initialPolys, SHAPE_POLY_SET::PM_FAST );
|
||||||
areas.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
areas.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
|
||||||
itemplotter.PlotZones( &zone, layer, areas );
|
itemplotter.PlotZone( &zone, layer, areas );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -621,8 +621,8 @@ void BRDITEMS_PLOTTER::PlotText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BRDITEMS_PLOTTER::PlotZones( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
void BRDITEMS_PLOTTER::PlotZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||||
const SHAPE_POLY_SET& aPolysList )
|
const SHAPE_POLY_SET& aPolysList )
|
||||||
{
|
{
|
||||||
if( aPolysList.IsEmpty() )
|
if( aPolysList.IsEmpty() )
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -98,8 +98,6 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
||||||
connectivity->ClearRatsnest();
|
connectivity->ClearRatsnest();
|
||||||
connectivity->Build( m_board, m_progressReporter );
|
connectivity->Build( m_board, m_progressReporter );
|
||||||
|
|
||||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
|
||||||
|
|
||||||
m_worstClearance = m_board->GetMaxClearanceValue();
|
m_worstClearance = m_board->GetMaxClearanceValue();
|
||||||
|
|
||||||
if( m_progressReporter )
|
if( m_progressReporter )
|
||||||
|
|
Loading…
Reference in New Issue