23#include <wx/filename.h>
28#include <wx/imagpng.h>
34 wxFileName fn = wxFileName::CreateTempFileName( aPrefix );
36 return fn.GetFullPath();
73 std::string aggregate = aBuffer;
78 size_t streamPos = aBuffer.find(
"stream\n", pos );
80 if( streamPos == std::string::npos )
83 size_t endPos = aBuffer.find(
"endstream", streamPos );
85 if( endPos == std::string::npos )
88 size_t dataStart = streamPos + 7;
89 size_t dataLen = ( endPos > dataStart ) ? ( endPos - dataStart ) : 0;
93 const unsigned char* data =
reinterpret_cast<const unsigned char*
>( aBuffer.data() + dataStart );
95 zs.next_in =
const_cast<Bytef*
>( data );
96 zs.avail_in =
static_cast<uInt
>( dataLen );
98 if( inflateInit( &zs ) == Z_OK )
101 out.resize( dataLen * 4 + 64 );
102 zs.next_out =
reinterpret_cast<Bytef*
>( out.data() );
103 zs.avail_out =
static_cast<uInt
>( out.size() );
104 int ret = inflate( &zs, Z_FINISH );
106 if( ret == Z_STREAM_END )
108 out.resize( zs.total_out );
119 aBuffer.swap( aggregate );
124 wxFFile file( aPdfPath,
"rb" );
126 if( !file.IsOpened() )
129 wxFileOffset len = file.Length();
133 aOutBuffer.resize(
static_cast<size_t>( len ) );
134 file.Read( aOutBuffer.data(), len );
142 if( aNeedle.empty() )
150 size_t p = aHaystack.find( aNeedle, pos );
151 if( p == std::string::npos )
161 long& aOutDarkPixels )
165 wxString rasterBase = wxFileName::CreateTempFileName( wxT(
"kicad_pdf_raster" ) );
166 wxString cmd = wxString::Format( wxT(
"pdftoppm -r %d -singlefile -png \"%s\" \"%s\"" ),
167 aDpi, aPdfPath, rasterBase );
168 int ret = wxExecute( cmd, wxEXEC_SYNC );
173 wxString pngPath = rasterBase + wxT(
".png" );
175 if( !wxFileExists( pngPath ) )
178 if( !wxImage::FindHandler( wxBITMAP_TYPE_PNG ) )
179 wxImage::AddHandler(
new wxPNGHandler );
181 wxImage img( pngPath );
185 int w = img.GetWidth();
186 int h = img.GetHeight();
189 for(
int y = 0; y < h; ++y )
191 for(
int x = 0; x < w; ++x )
193 unsigned char r = img.GetRed( x, y );
194 unsigned char g = img.GetGreen( x, y );
195 unsigned char b = img.GetBlue( x, y );
197 if( r < aNearWhiteThresh || g < aNearWhiteThresh || b < aNearWhiteThresh )
202 aOutDarkPixels = dark;
205 wxRemoveFile( pngPath );
212 if( !wxGetEnv( aEnvVar, &keepEnv ) || keepEnv.IsEmpty() )
213 wxRemoveFile( aPath );
static STROKE_FONT * LoadFont(const wxString &aFontName)
Load a stroke font.
A color representation with 4 components: red, green, blue, alpha.
An abstract base class for deriving all objects that can be added to a VIEW.
KIGFX::COLOR4D m_background
KIGFX::COLOR4D GetColor(const KIGFX::VIEW_ITEM *, int) const override
Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer using curr...
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
static constexpr EDA_ANGLE ANGLE_0
int CountOccurrences(const std::string &aHaystack, const std::string &aNeedle)
Count occurrences of a substring in a string (overlapping allowed).
bool ReadPdfWithDecompressedStreams(const wxString &aPdfPath, std::string &aOutBuffer)
Read a PDF file and append best-effort decompressed contents of any Flate streams to the returned buf...
std::unique_ptr< KIFONT::STROKE_FONT > LoadStrokeFontUnique()
Load the default stroke font and return a unique_ptr for RAII deletion.
bool RasterizePdfCountDark(const wxString &aPdfPath, int aDpi, int aNearWhiteThresh, long &aOutDarkPixels)
Rasterize a PDF page to PNG using pdftoppm if available and count non-near-white pixels.
static void append_decompressed_streams(std::string &aBuffer)
wxString MakeTempPdfPath(const wxString &aPrefix)
Make a temporary file path with .pdf extension using a given prefix.
TEXT_ATTRIBUTES BuildTextAttributes(int aSizeIu, int aStrokeWidth, bool aBold, bool aItalic)
Build a commonly used set of text attributes for plotting text in tests.
void MaybeRemoveFile(const wxString &aPath, const wxString &aEnvVar)
Remove a file unless the given environment variable is set (defaults to KICAD_KEEP_TEST_PDF).
VECTOR2< int32_t > VECTOR2I