From 5b3202d8f38bde3f9eb6a08322f0aa5aeacfb876 Mon Sep 17 00:00:00 2001 From: jean-pierre charras <jp.charras@wanadoo.fr> Date: Fri, 7 Dec 2018 10:07:43 +0100 Subject: [PATCH] dxf and svg import: accept unicode filenames Fixes: lp:1805613 https://bugs.launchpad.net/kicad/+bug/1805613 --- dxflib_qcad/dl_dxf.cpp | 32 +++++++++++++++++++++++++ dxflib_qcad/dl_dxf.h | 7 +++--- pcbnew/import_gfx/dxf_import_plugin.cpp | 14 +++++++---- pcbnew/import_gfx/nanosvg.cpp | 8 ++----- pcbnew/import_gfx/nanosvg.h | 5 +++- pcbnew/import_gfx/svg_import_plugin.cpp | 9 ++++++- 6 files changed, 58 insertions(+), 17 deletions(-) diff --git a/dxflib_qcad/dl_dxf.cpp b/dxflib_qcad/dl_dxf.cpp index 4f43db9a2b..a76cf1611f 100644 --- a/dxflib_qcad/dl_dxf.cpp +++ b/dxflib_qcad/dl_dxf.cpp @@ -117,12 +117,44 @@ DL_Dxf::~DL_Dxf() } +/** + * @brief Reads the given file and calls the appropriate functions in + * the given creation interface for every entity found in the file. + * + * @param file Input the file pointer to read + * @param creationInterface + * Pointer to the class which takes care of the entities in the file. + * + * @retval true if fp is valid (i.e. not NULL), false otherwise. + */ +bool DL_Dxf::in( FILE* fp, DL_CreationInterface* creationInterface ) +{ + firstCall = true; + currentObjectType = DL_UNKNOWN; + + if( fp ) + { + std::locale oldLocale = std::locale::global( std::locale( "C" ) ); // use dot in numbers + + while( readDxfGroups( fp, creationInterface ) ) + { + } + + std::locale::global( oldLocale ); + fclose( fp ); + return true; + } + + return false; +} + /** * @brief Reads the given file and calls the appropriate functions in * the given creation interface for every entity found in the file. * * @param file Input * Path and name of file to read + * Note: file is not very well utf8 compatible, depending on the platform. * @param creationInterface * Pointer to the class which takes care of the entities in the file. * diff --git a/dxflib_qcad/dl_dxf.h b/dxflib_qcad/dl_dxf.h index 16aa90eca4..fd0bfa9ebe 100644 --- a/dxflib_qcad/dl_dxf.h +++ b/dxflib_qcad/dl_dxf.h @@ -124,10 +124,9 @@ public: DL_Dxf(); ~DL_Dxf(); - bool in( const std::string& file, - DL_CreationInterface* creationInterface ); - bool readDxfGroups( FILE* fp, - DL_CreationInterface* creationInterface ); + bool in( FILE* fp, DL_CreationInterface* creationInterface ); + bool in( const std::string& file, DL_CreationInterface* creationInterface ); + bool readDxfGroups( FILE* fp, DL_CreationInterface* creationInterface ); static bool getStrippedLine( std::string& s, unsigned int size, FILE* stream, bool stripSpace = true ); diff --git a/pcbnew/import_gfx/dxf_import_plugin.cpp b/pcbnew/import_gfx/dxf_import_plugin.cpp index 086f4f1de5..776a03883b 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.cpp +++ b/pcbnew/import_gfx/dxf_import_plugin.cpp @@ -133,14 +133,18 @@ double DXF_IMPORT_PLUGIN::mapWidth( double aDxfWidth ) bool DXF_IMPORT_PLUGIN::ImportDxfFile( const wxString& aFile ) { - LOCALE_IO locale; - DL_Dxf dxf_reader; std::string filename = TO_UTF8( aFile ); - bool success = true; - if( !dxf_reader.in( filename, this ) ) // if file open failed - success = false; + // wxFopen takes care of unicode filenames across platforms + FILE* fp = wxFopen( aFile, "rt" ); + + if( fp == nullptr ) + return false; + + // Note the dxf reader takes care of switching to "C" locale before reading the file + // and will close the file after reading + bool success = dxf_reader.in( fp, this ); return success; } diff --git a/pcbnew/import_gfx/nanosvg.cpp b/pcbnew/import_gfx/nanosvg.cpp index 55a490e2cd..438467bf4e 100644 --- a/pcbnew/import_gfx/nanosvg.cpp +++ b/pcbnew/import_gfx/nanosvg.cpp @@ -28,7 +28,6 @@ #include "nanosvg.h" -#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> @@ -3668,17 +3667,14 @@ NSVGimage* nsvgParse( char* input, const char* units, float dpi ) } -NSVGimage* nsvgParseFromFile( const char* filename, const char* units, float dpi ) +NSVGimage* nsvgParseFromFile( FILE *fp, const char* units, float dpi ) { - FILE* fp = NULL; size_t size; char* data = NULL; NSVGimage* image = NULL; - fp = fopen( filename, "rb" ); - if( !fp ) - goto error; + return NULL; fseek( fp, 0, SEEK_END ); size = ftell( fp ); diff --git a/pcbnew/import_gfx/nanosvg.h b/pcbnew/import_gfx/nanosvg.h index c4ed0617a2..04f05f9342 100644 --- a/pcbnew/import_gfx/nanosvg.h +++ b/pcbnew/import_gfx/nanosvg.h @@ -66,6 +66,8 @@ nsvgDelete(image); */ +#include <stdio.h> + enum NSVGpaintType { NSVG_PAINT_NONE = 0, NSVG_PAINT_COLOR = 1, @@ -158,7 +160,8 @@ typedef struct NSVGimage } NSVGimage; // Parses SVG file from a file, returns SVG image as paths. -NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi); +// fp will be closed after reading the file +NSVGimage* nsvgParseFromFile( FILE* fp, const char* units, float dpi); // Parses SVG file from a null terminated string, returns SVG image as paths. // Important note: changes the string. diff --git a/pcbnew/import_gfx/svg_import_plugin.cpp b/pcbnew/import_gfx/svg_import_plugin.cpp index 13d4630f61..2d73e6a0dc 100644 --- a/pcbnew/import_gfx/svg_import_plugin.cpp +++ b/pcbnew/import_gfx/svg_import_plugin.cpp @@ -55,7 +55,14 @@ bool SVG_IMPORT_PLUGIN::Load( const wxString& aFileName ) { wxCHECK( m_importer, false ); - m_parsedImage = nsvgParseFromFile( aFileName.c_str(), "mm", 96 ); + // wxFopen takes care of unicode filenames across platforms + FILE* fp = wxFopen( aFileName, "rt" ); + + if( fp == nullptr ) + return false; + + // nsvgParseFromFile will close the file after reading + m_parsedImage = nsvgParseFromFile( fp, "mm", 96 ); wxCHECK( m_parsedImage, false );