Plot SVG embedded

ADDED: embedded image support for SVG files

Fixes #3643 | https://gitlab.com/kicad/code/kicad/issues/3643
This commit is contained in:
Seth Hillbrand
2019-12-08 08:57:33 -08:00
parent b6b805548d
commit fa133f3f5c
4 changed files with 250 additions and 8 deletions
+51 -8
View File
@@ -90,6 +90,8 @@
* flag_sweep : 0 = CCW, 1 = CW
* The center of ellipse is automatically calculated.
*/
#include <base64.h>
#include <fctsys.h>
#include <trigo.h>
#include <eda_base_frame.h>
@@ -100,6 +102,8 @@
#include <macros.h>
#include <kicad_string.h>
#include <cstdint>
#include <wx/mstream.h>
/**
@@ -499,7 +503,7 @@ void SVG_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i
setFillMode( NO_FILL );
SetCurrentLineWidth( width );
fprintf( outputFile, "<path d=\"M%g %g A%g %g 0.0 %d %d %g %g \" />\n",
fprintf( outputFile, "<path d=\"M%g %g A%g %g 0.0 %d %d %g %g\" />\n",
start.x, start.y, radius_dev, radius_dev,
flg_arc, flg_sweep,
end.x, end.y );
@@ -577,12 +581,51 @@ void SVG_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
void SVG_PLOTTER::PlotImage( const wxImage& aImage, const wxPoint& aPos,
double aScaleFactor )
{
// in svg file we must insert a link to a png image file to plot an image
// the image itself is not included in the svg file.
// So we prefer skip the image, and just draw a rectangle,
// like other plotters which do not support images
wxSize pix_size( aImage.GetWidth(), aImage.GetHeight() );
// Requested size (in IUs)
DPOINT drawsize( aScaleFactor * pix_size.x,
aScaleFactor * pix_size.y );
// calculate the bitmap start position
wxPoint start( aPos.x - drawsize.x / 2,
aPos.y - drawsize.y / 2);
// Rectangles having a 0 size value for height or width are just not drawn on Inscape,
// so use a line when happens.
if( drawsize.x == 0.0 || drawsize.y == 0.0 ) // Draw a line
{
PLOTTER::PlotImage( aImage, aPos, aScaleFactor );
}
else
{
wxMemoryOutputStream img_stream;
aImage.SaveFile( img_stream, wxBITMAP_TYPE_PNG );
size_t input_len = img_stream.GetOutputStreamBuffer()->GetBufferSize();
std::vector<uint8_t> buffer( input_len );
std::vector<uint8_t> encoded;
img_stream.CopyTo( buffer.data(), buffer.size() );
base64::encode( buffer, encoded );
fprintf( outputFile,
"<image x=\"%g\" y=\"%g\" xlink:href=\"data:image/png;base64,",
userToDeviceSize( start.x ), userToDeviceSize( start.y )
);
for( size_t i = 0; i < encoded.size(); i++ )
{
fprintf( outputFile, "%c", static_cast<char>( encoded[i] ) );
if( ( i % 64 ) == 63 )
fprintf( outputFile, "\n" );
}
fprintf( outputFile, "\"\npreserveAspectRatio=\"none\" height=\"%g\" width=\"%g\" />",
userToDeviceSize( drawsize.x ), userToDeviceSize( drawsize.y ) );
}
PLOTTER::PlotImage( aImage, aPos, aScaleFactor );
}
@@ -656,7 +699,7 @@ bool SVG_PLOTTER::StartPlot()
// Write viewport pos and size
wxPoint origin; // TODO set to actual value
fprintf( outputFile,
" width=\"%gcm\" height=\"%gcm\" viewBox=\"%d %d %d %d \">\n",
" width=\"%gcm\" height=\"%gcm\" viewBox=\"%d %d %d %d\">\n",
(double) paperSize.x / m_IUsPerDecimil * 2.54 / 10000,
(double) paperSize.y / m_IUsPerDecimil * 2.54 / 10000,
origin.x, origin.y,
@@ -683,7 +726,7 @@ bool SVG_PLOTTER::StartPlot()
m_brush_rgb_color, opacity, m_pen_rgb_color, opacity );
// output the pen cap and line joint
fputs( "stroke-linecap:round; stroke-linejoin:round; \"\n", outputFile );
fputs( "stroke-linecap:round; stroke-linejoin:round;\"\n", outputFile );
fputs( " transform=\"translate(0 0) scale(1 1)\">\n", outputFile );
return true;
}