Pcbnew: First work to add a DXF file import to create board outlines. The DXF import is based on DXF lib import/export from LibreCad.

This commit is contained in:
jean-pierre charras 2013-10-24 20:47:07 +02:00
commit 40eb9c9cc2
31 changed files with 73392 additions and 4 deletions

View File

@ -360,6 +360,7 @@ add_subdirectory( cvpcb )
add_subdirectory( eeschema )
add_subdirectory( gerbview )
add_subdirectory( kicad )
add_subdirectory( lib_dxf )
add_subdirectory( pcbnew )
add_subdirectory( polygon )
add_subdirectory( pagelayout_editor )

12
lib_dxf/CMakeLists.txt Normal file
View File

@ -0,0 +1,12 @@
include_directories(intern)
set(LIBDXF_SRCS
libdxfrw.cpp
intern/dxfwriter.cpp
intern/drw_textcodec.cpp
intern/dxfreader.cpp
drw_objects.cpp
drw_entities.cpp
)
add_library(lib_dxf STATIC ${LIBDXF_SRCS})

4
lib_dxf/CREDITS.txt Normal file
View File

@ -0,0 +1,4 @@
This library comes from the LibreCAD project, a 2D CAD program.
see http://sourceforge.net/projects/libdxfrw/
the latest sources are on:
https://github.com/LibreCAD/LibreCAD/tree/master/libraries/libdxfrw/src

473
lib_dxf/drw_base.h Normal file
View File

@ -0,0 +1,473 @@
/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011 Rallaz, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/
#ifndef DRW_BASE_H
#define DRW_BASE_H
#define DRW_VERSION "0.5.10"
#include <string>
#include <cmath>
using std::string;
#define UTF8STRING std::string
#define DRW_UNUSED( x ) (void) x
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
# define DRW_WIN
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
# define DRW_WIN
#elif defined(__MWERKS__) && defined(__INTEL__)
# define DRW_WIN
#else
# define DRW_POSIX
#endif
#ifndef M_PI
#define M_PI 3.141592653589793238462643
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
#define M_PIx2 6.283185307179586 // 2*PI
#define ARAD 57.29577951308232
namespace DRW {
// ! Version numbers for the DXF Format.
enum Version {
UNKNOWNV, /*!< UNKNOWN VERSION. */
AC1006, /*!< R10. */
AC1009, /*!< R11 & R12. */
AC1012, /*!< R13. */
AC1014, /*!< R14. */
AC1015, /*!< ACAD 2000. */
AC1018, /*!< ACAD 2004. */
AC1021, /*!< ACAD 2007. */
AC1024 /*!< ACAD 2010. */
};
enum error {
BAD_NONE, /*!< No error. */
BAD_UNKNOWN, /*!< UNKNOWN. */
BAD_OPEN, /*!< error opening file. */
BAD_VERSION, /*!< unsupported version. */
BAD_READ_FILE_HEADER, /*!< error in file header read process. */
BAD_READ_HEADER, /*!< error in header vars read process. */
BAD_READ_OFFSETS, /*!< error in object map read process. */
BAD_READ_CLASSES, /*!< error in classes read process. */
BAD_READ_TABLES, /*!< error in tables read process. */
BAD_READ_ENTITIES /*!< error in entities read process. */
};
}
// ! Class to handle 3D coordinate point
/*!
* Class to handle 3D coordinate point
* @author Rallaz
*/
class DRW_Coord
{
public:
DRW_Coord() { x = 0; y = 0; z = 0; }
DRW_Coord( double ix, double iy, double iz )
{
x = ix; y = iy; z = iz;
}
DRW_Coord operator =( const DRW_Coord& data )
{
x = data.x; y = data.y; z = data.z;
return *this;
}
/*!< convert to unitary vector */
void unitize()
{
double dist;
dist = sqrt( x * x + y * y + z * z );
if( dist > 0.0 )
{
x = x / dist;
y = y / dist;
z = z / dist;
}
}
public:
double x;
double y;
double z;
};
// ! Class to handle vertex
/*!
* Class to handle vertex for lwpolyline entity
* @author Rallaz
*/
class DRW_Vertex2D
{
public:
DRW_Vertex2D()
{
// eType = DRW::LWPOLYLINE;
stawidth = endwidth = bulge = 0;
}
DRW_Vertex2D( double sx, double sy, double b )
{
stawidth = endwidth = 0;
x = sx;
y = sy;
bulge = b;
}
public:
double x; /*!< x coordinate, code 10 */
double y; /*!< y coordinate, code 20 */
double stawidth; /*!< Start width, code 40 */
double endwidth; /*!< End width, code 41 */
double bulge; /*!< bulge, code 42 */
};
// ! Class to handle header vars
/*!
* Class to handle header vars
* @author Rallaz
*/
class DRW_Variant
{
public:
enum TYPE {
STRING,
INTEGER,
DOUBLE,
COORD,
INVALID
};
DRW_Variant()
{
type = INVALID;
}
~DRW_Variant()
{
if( type == COORD )
delete content.v;
}
enum TYPE type;
void addString( UTF8STRING s ) { setType( STRING ); data = s; content.s = &data; }
void addInt( int i ) { setType( INTEGER ); content.i = i; }
void addDouble( double d ) { setType( DOUBLE ); content.d = d; }
void addCoord( DRW_Coord* v ) { setType( COORD ); content.v = v; }
void setType( enum TYPE t )
{
if( type == COORD )
delete content.v;
type = t;
}
void setCoordX( double d ) { if( type == COORD ) content.v->x = d; }
void setCoordY( double d ) { if( type == COORD ) content.v->y = d; }
void setCoordZ( double d ) { if( type == COORD ) content.v->z = d; }
private:
typedef union
{
UTF8STRING* s;
int i;
double d;
DRW_Coord* v;
} DRW_VarContent;
public:
DRW_VarContent content;
public:
int code;
// string version;
// string codepage;
private:
// DRW_VarContent content;
string data;
};
// ! Class to convert between line width and integer
/*!
* Class to convert between line width and integer
* verifing valid values, if value is not valid
* returns widthDefault.
* @author Rallaz
*/
class DRW_LW_Conv
{
public:
enum lineWidth {
width00 = 0, /*!< 0.00mm (dxf 0)*/
width01 = 1, /*!< 0.05mm (dxf 5)*/
width02 = 2, /*!< 0.09mm (dxf 9)*/
width03 = 3, /*!< 0.13mm (dxf 13)*/
width04 = 4, /*!< 0.15mm (dxf 15)*/
width05 = 5, /*!< 0.18mm (dxf 18)*/
width06 = 6, /*!< 0.20mm (dxf 20)*/
width07 = 7, /*!< 0.25mm (dxf 25)*/
width08 = 8, /*!< 0.30mm (dxf 30)*/
width09 = 9, /*!< 0.35mm (dxf 35)*/
width10 = 10, /*!< 0.40mm (dxf 40)*/
width11 = 11, /*!< 0.50mm (dxf 50)*/
width12 = 12, /*!< 0.53mm (dxf 53)*/
width13 = 13, /*!< 0.60mm (dxf 60)*/
width14 = 14, /*!< 0.70mm (dxf 70)*/
width15 = 15, /*!< 0.80mm (dxf 80)*/
width16 = 16, /*!< 0.90mm (dxf 90)*/
width17 = 17, /*!< 1.00mm (dxf 100)*/
width18 = 18, /*!< 1.06mm (dxf 106)*/
width19 = 19, /*!< 1.20mm (dxf 120)*/
width20 = 20, /*!< 1.40mm (dxf 140)*/
width21 = 21, /*!< 1.58mm (dxf 158)*/
width22 = 22, /*!< 2.00mm (dxf 200)*/
width23 = 23, /*!< 2.11mm (dxf 211)*/
widthByLayer = 29, /*!< by layer (dxf -1) */
widthByBlock = 30, /*!< by block (dxf -2) */
widthDefault = 31 /*!< by default (dxf -3) */
};
static int lineWidth2dxfInt( enum lineWidth lw )
{
switch( lw )
{
case widthByLayer:
return -1;
case widthByBlock:
return -2;
case widthDefault:
return -3;
case width00:
return 0;
case width01:
return 5;
case width02:
return 9;
case width03:
return 13;
case width04:
return 15;
case width05:
return 18;
case width06:
return 20;
case width07:
return 25;
case width08:
return 30;
case width09:
return 35;
case width10:
return 40;
case width11:
return 50;
case width12:
return 53;
case width13:
return 60;
case width14:
return 70;
case width15:
return 80;
case width16:
return 90;
case width17:
return 100;
case width18:
return 106;
case width19:
return 120;
case width20:
return 140;
case width21:
return 158;
case width22:
return 200;
case width23:
return 211;
default:
return -3;
}
return static_cast<int> (lw);
}
static int lineWidth2dwgInt( enum lineWidth lw )
{
return static_cast<int> (lw);
}
static enum lineWidth dxfInt2lineWidth( int i )
{
if( i<0 )
{
if( i==-1 )
return widthByLayer;
else if( i==-2 )
return widthByBlock;
else if( i==-3 )
return widthDefault;
}
else if( i<3 )
{
return width00;
}
else if( i<7 )
{
return width01;
}
else if( i<11 )
{
return width02;
}
else if( i<14 )
{
return width03;
}
else if( i<16 )
{
return width04;
}
else if( i<19 )
{
return width05;
}
else if( i<22 )
{
return width06;
}
else if( i<27 )
{
return width07;
}
else if( i<32 )
{
return width08;
}
else if( i<37 )
{
return width09;
}
else if( i<45 )
{
return width10;
}
else if( i<52 )
{
return width11;
}
else if( i<57 )
{
return width12;
}
else if( i<65 )
{
return width13;
}
else if( i<75 )
{
return width14;
}
else if( i<85 )
{
return width15;
}
else if( i<95 )
{
return width16;
}
else if( i<103 )
{
return width17;
}
else if( i<112 )
{
return width18;
}
else if( i<130 )
{
return width19;
}
else if( i<149 )
{
return width20;
}
else if( i<180 )
{
return width21;
}
else if( i<205 )
{
return width22;
}
else
{
return width23;
}
// default by default
return widthDefault;
}
static enum lineWidth dwgInt2lineWidth( int i )
{
if( (i>-1 && i<24) || (i>28 && i<32) )
{
return static_cast<lineWidth> (i);
}
// default by default
return widthDefault;
}
};
#endif
// EOF

1429
lib_dxf/drw_entities.cpp Normal file

File diff suppressed because it is too large Load Diff

1300
lib_dxf/drw_entities.h Normal file

File diff suppressed because it is too large Load Diff

223
lib_dxf/drw_interface.h Normal file
View File

@ -0,0 +1,223 @@
/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011 Rallaz, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/
#ifndef DRW_INTERFACE_H
#define DRW_INTERFACE_H
#include <string.h>
#include "drw_entities.h"
#include "drw_objects.h"
// #include "dl_extrusion.h"
/**
* Abstract class (interface) for comunicate dxfReader with the application.
* Inherit your class which takes care of the entities in the
* processed DXF file from this interface.
*
* @author Rallaz
*/
class DRW_Interface
{
public:
DRW_Interface()
{
// extrusion = new DL_Extrusion;
}
virtual ~DRW_Interface()
{
// delete extrusion;
}
/** Called when header is parsed. */
virtual void addHeader( const DRW_Header* data ) = 0;
/** Called for every line Type. */
virtual void addLType( const DRW_LType& data ) = 0;
/** Called for every layer. */
virtual void addLayer( const DRW_Layer& data ) = 0;
/** Called for every dim style. */
virtual void addDimStyle( const DRW_Dimstyle& data ) = 0;
/** Called for every VPORT table. */
virtual void addVport( const DRW_Vport& data ) = 0;
/** Called for every text style. */
virtual void addTextStyle( const DRW_Textstyle& data ) = 0;
/**
* Called for every block. Note: all entities added after this
* command go into this block until endBlock() is called.
*
* @see endBlock()
*/
virtual void addBlock( const DRW_Block& data ) = 0;
/**
* In DWG called when the following entities corresponding to a
* block different from the current. Note: all entities added after this
* command go into this block until setBlock() is called already.
*
* int handle are the value of DRW_Block::handleBlock added with addBlock()
*/
virtual void setBlock( const int handle ) = 0;
/** Called to end the current block */
virtual void endBlock() = 0;
/** Called for every point */
virtual void addPoint( const DRW_Point& data ) = 0;
/** Called for every line */
virtual void addLine( const DRW_Line& data ) = 0;
/** Called for every ray */
virtual void addRay( const DRW_Ray& data ) = 0;
/** Called for every xline */
virtual void addXline( const DRW_Xline& data ) = 0;
/** Called for every arc */
virtual void addArc( const DRW_Arc& data ) = 0;
/** Called for every circle */
virtual void addCircle( const DRW_Circle& data ) = 0;
/** Called for every ellipse */
virtual void addEllipse( const DRW_Ellipse& data ) = 0;
/** Called for every lwpolyline */
virtual void addLWPolyline( const DRW_LWPolyline& data ) = 0;
/** Called for every polyline start */
virtual void addPolyline( const DRW_Polyline& data ) = 0;
/** Called for every spline */
virtual void addSpline( const DRW_Spline* data ) = 0;
/** Called for every spline knot value */
virtual void addKnot( const DRW_Entity& data ) = 0;
/** Called for every insert. */
virtual void addInsert( const DRW_Insert& data ) = 0;
/** Called for every trace start */
virtual void addTrace( const DRW_Trace& data ) = 0;
/** Called for every 3dface start */
virtual void add3dFace( const DRW_3Dface& data ) = 0;
/** Called for every solid start */
virtual void addSolid( const DRW_Solid& data ) = 0;
/** Called for every Multi Text entity. */
virtual void addMText( const DRW_MText& data ) = 0;
/** Called for every Text entity. */
virtual void addText( const DRW_Text& data ) = 0;
/**
* Called for every aligned dimension entity.
*/
virtual void addDimAlign( const DRW_DimAligned* data ) = 0;
/**
* Called for every linear or rotated dimension entity.
*/
virtual void addDimLinear( const DRW_DimLinear* data ) = 0;
/**
* Called for every radial dimension entity.
*/
virtual void addDimRadial( const DRW_DimRadial* data ) = 0;
/**
* Called for every diametric dimension entity.
*/
virtual void addDimDiametric( const DRW_DimDiametric* data ) = 0;
/**
* Called for every angular dimension (2 lines version) entity.
*/
virtual void addDimAngular( const DRW_DimAngular* data ) = 0;
/**
* Called for every angular dimension (3 points version) entity.
*/
virtual void addDimAngular3P( const DRW_DimAngular3p* data ) = 0;
/**
* Called for every ordinate dimension entity.
*/
virtual void addDimOrdinate( const DRW_DimOrdinate* data ) = 0;
/**
* Called for every leader start.
*/
virtual void addLeader( const DRW_Leader* data ) = 0;
/**
* Called for every hatch entity.
*/
virtual void addHatch( const DRW_Hatch* data ) = 0;
/**
* Called for every viewport entity.
*/
virtual void addViewport( const DRW_Viewport& data ) = 0;
/**
* Called for every image entity.
*/
virtual void addImage( const DRW_Image* data ) = 0;
/**
* Called for every image definition.
*/
virtual void linkImage( const DRW_ImageDef* data ) = 0;
/**
* Called for every comment in the DXF file (code 999).
*/
virtual void addComment( const char* comment ) = 0;
/** Sets the current attributes for entities. */
/* void setExtrusion(double dx, double dy, double dz, double elevation) {
* extrusion->setDirection(dx, dy, dz);
* extrusion->setElevation(elevation);
* }*/
/** @return the current attributes used for new entities. */
// DL_Extrusion* getExtrusion() {
// return extrusion;
// }
virtual void writeHeader( DRW_Header& data ) = 0;
virtual void writeBlocks() = 0;
virtual void writeBlockRecords() = 0;
virtual void writeEntities() = 0;
virtual void writeLTypes() = 0;
virtual void writeLayers() = 0;
virtual void writeTextstyles() = 0;
virtual void writeVports() = 0;
virtual void writeDimstyles() = 0;
protected:
// DL_Attributes attributes;
// DL_Extrusion *extrusion;
};
#endif

1315
lib_dxf/drw_objects.cpp Normal file

File diff suppressed because it is too large Load Diff

680
lib_dxf/drw_objects.h Normal file
View File

@ -0,0 +1,680 @@
/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011 Rallaz, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/
#ifndef DRW_OBJECTS_H
#define DRW_OBJECTS_H
#include <string>
#include <vector>
#include <map>
#include "drw_base.h"
class dxfReader;
class dxfWriter;
using std::string;
namespace DRW {
// ! Table entries type.
enum TTYPE {
UNKNOWNT,
LTYPE,
LAYER,
STYLE,
DIMSTYLE,
VPORT,
BLOCK_RECORD
};
}
// ! Base class for tables entries
/*!
* Base class for tables entries
* @author Rallaz
*/
class DRW_TableEntry
{
public:
// initializes default values
DRW_TableEntry()
{
tType = DRW::UNKNOWNT;
flags = 0;
}
virtual ~DRW_TableEntry() {}
protected:
void parseCode( int code, dxfReader* reader );
public:
enum DRW::TTYPE tType; /*!< enum: entity type, code 0 */
int handle; /*!< entity identifier, code 5 */
int handleBlock; /*!< Soft-pointer ID/handle to owner BLOCK_RECORD object, code 330 */
UTF8STRING name; /*!< entry name, code 2 */
int flags; /*!< Flags relevant to entry, code 70 */
};
// ! Class to handle dimstyle entries
/*!
* Class to handle dim style symbol table entries
* @author Rallaz
*/
class DRW_Dimstyle : public DRW_TableEntry
{
public:
DRW_Dimstyle() { reset(); }
void reset()
{
tType = DRW::DIMSTYLE;
dimasz = dimtxt = dimexe = 0.18;
dimexo = 0.0625;
dimgap = dimcen = 0.09;
dimtxsty = "Standard";
dimscale = dimlfac = dimtfac = 1.0;
dimdli = 0.38;
dimrnd = dimdle = dimtp = dimtm = dimtsz = dimtvp = 0.0;
dimaltf = 25.4;
dimtol = dimlim = dimse1 = dimse2 = dimtad = dimzin = 0;
dimtoh = dimtolj = 1;
dimalt = dimtofl = dimsah = dimtix = dimsoxd = 0;
dimaltd = dimunit = dimaltu = dimalttd = dimlunit = 2;
dimclrd = dimclre = dimclrt = dimjust = dimupt = 0;
dimazin = dimaltz = dimaltttz = dimtzin = dimfrac = 0;
dimtih = dimadec = dimaunit = dimsd1 = dimsd2 = dimtmove = 0;
dimaltrnd = 0.0;
dimdec = dimtdec = 4;
dimfit = dimatfit = 3;
dimdsep = '.';
dimlwd = dimlwe = -2;
}
void parseCode( int code, dxfReader* reader );
public:
// V12
UTF8STRING dimpost; /*!< code 3 */
UTF8STRING dimapost; /*!< code 4 */
/* handle are code 105 */
UTF8STRING dimblk; /*!< code 5, code 342 V2000+ */
UTF8STRING dimblk1; /*!< code 6, code 343 V2000+ */
UTF8STRING dimblk2; /*!< code 7, code 344 V2000+ */
double dimscale; /*!< code 40 */
double dimasz; /*!< code 41 */
double dimexo; /*!< code 42 */
double dimdli; /*!< code 43 */
double dimexe; /*!< code 44 */
double dimrnd; /*!< code 45 */
double dimdle; /*!< code 46 */
double dimtp; /*!< code 47 */
double dimtm; /*!< code 48 */
double dimtxt; /*!< code 140 */
double dimcen; /*!< code 141 */
double dimtsz; /*!< code 142 */
double dimaltf; /*!< code 143 */
double dimlfac; /*!< code 144 */
double dimtvp; /*!< code 145 */
double dimtfac; /*!< code 146 */
double dimgap; /*!< code 147 */
double dimaltrnd; /*!< code 148 V2000+ */
int dimtol; /*!< code 71 */
int dimlim; /*!< code 72 */
int dimtih; /*!< code 73 */
int dimtoh; /*!< code 74 */
int dimse1; /*!< code 75 */
int dimse2; /*!< code 76 */
int dimtad; /*!< code 77 */
int dimzin; /*!< code 78 */
int dimazin; /*!< code 79 V2000+ */
int dimalt; /*!< code 170 */
int dimaltd; /*!< code 171 */
int dimtofl; /*!< code 172 */
int dimsah; /*!< code 173 */
int dimtix; /*!< code 174 */
int dimsoxd; /*!< code 175 */
int dimclrd; /*!< code 176 */
int dimclre; /*!< code 177 */
int dimclrt; /*!< code 178 */
int dimadec; /*!< code 179 V2000+ */
int dimunit; /*!< code 270 R13+ (obsolete 2000+, use dimlunit & dimfrac) */
int dimdec; /*!< code 271 R13+ */
int dimtdec; /*!< code 272 R13+ */
int dimaltu; /*!< code 273 R13+ */
int dimalttd; /*!< code 274 R13+ */
int dimaunit; /*!< code 275 R13+ */
int dimfrac; /*!< code 276 V2000+ */
int dimlunit; /*!< code 277 V2000+ */
int dimdsep; /*!< code 278 V2000+ */
int dimtmove; /*!< code 279 V2000+ */
int dimjust; /*!< code 280 R13+ */
int dimsd1; /*!< code 281 R13+ */
int dimsd2; /*!< code 282 R13+ */
int dimtolj; /*!< code 283 R13+ */
int dimtzin; /*!< code 284 R13+ */
int dimaltz; /*!< code 285 R13+ */
int dimaltttz; /*!< code 286 R13+ */
int dimfit; /*!< code 287 R13+ (obsolete 2000+, use dimatfit & dimtmove)*/
int dimupt; /*!< code 288 R13+ */
int dimatfit; /*!< code 289 V2000+ */
UTF8STRING dimtxsty; /*!< code 340 R13+ */
UTF8STRING dimldrblk; /*!< code 341 V2000+ */
int dimlwd; /*!< code 371 V2000+ */
int dimlwe; /*!< code 372 V2000+ */
};
// ! Class to handle line type entries
/*!
* Class to handle line type symbol table entries
* @author Rallaz
*/
/*TODO: handle complex lineType*/
class DRW_LType : public DRW_TableEntry
{
public:
DRW_LType() { reset(); }
void reset()
{
tType = DRW::LTYPE;
desc = "";
size = 0;
length = 0.0;
pathIdx = 0;
/* color = 256; // default BYLAYER (256)
* plotF = true; // default TRUE (plot yes)
* lWeight = -1; // default BYLAYER (-1)*/
// align = 65; //always 65
}
void parseCode( int code, dxfReader* reader );
void update();
public:
UTF8STRING desc; /*!< descriptive string, code 3 */
// int align; /*!< align code, always 65 ('A') code 72 */
int size; /*!< element number, code 73 */
double length; /*!< total length of pattern, code 40 */
// int haveShape; /*!< complex linetype type, code 74 */
std::vector<double> path; /*!< trace, point or space length sequence, code 49 */
private:
int pathIdx;
};
// ! Class to handle layer entries
/*!
* Class to handle layer symbol table entries
* @author Rallaz
*/
class DRW_Layer : public DRW_TableEntry
{
public:
DRW_Layer() { reset(); }
void reset()
{
tType = DRW::LAYER;
lineType = "CONTINUOUS";
color = 7; // default BYLAYER (256)
plotF = true; // default TRUE (plot yes)
lWeight = DRW_LW_Conv::widthDefault; // default BYDEFAULT (dxf -3, dwg 31)
color24 = -1; // default -1 not set
}
void parseCode( int code, dxfReader* reader );
public:
UTF8STRING lineType; /*!< line type, code 6 */
int color; /*!< layer color, code 62 */
int color24; /*!< 24-bit color, code 420 */
bool plotF; /*!< Plot flag, code 290 */
enum DRW_LW_Conv::lineWidth lWeight; /*!< layer lineweight, code 370 */
string handlePlotS; /*!< Hard-pointer ID/handle of plotstyle, code 390 */
string handlePlotM; /*!< Hard-pointer ID/handle of materialstyle, code 347 */
};
// ! Class to handle text style entries
/*!
* Class to handle text style symbol table entries
* @author Rallaz
*/
class DRW_Textstyle : public DRW_TableEntry
{
public:
DRW_Textstyle() { reset(); }
void reset()
{
tType = DRW::STYLE;
height = oblique = 0.0;
width = lastHeight = 1.0;
font = "txt";
genFlag = 0; // 2= X mirror, 4= Y mirror
fontFamily = 0;
}
void parseCode( int code, dxfReader* reader );
public:
double height; /*!< Fixed text height (0 not set), code 40 */
double width; /*!< Width factor, code 41 */
double oblique; /*!< Oblique angle, code 50 */
int genFlag; /*!< Text generation flags, code 71 */
double lastHeight; /*!< Last height used, code 42 */
UTF8STRING font; /*!< primary font file name, code 3 */
UTF8STRING bigFont; /*!< bigfont file name or blank if none, code 4 */
int fontFamily; /*!< ttf font family, italic and bold flags, code 1071 */
};
// ! Class to handle vport entries
/*!
* Class to handle vport symbol table entries
* @author Rallaz
*/
class DRW_Vport : public DRW_TableEntry
{
public:
DRW_Vport() { reset(); }
void reset()
{
UpperRight.x = UpperRight.y = 1.0;
snapSpacing.x = snapSpacing.y = 10.0;
gridSpacing = snapSpacing;
center.x = 0.651828;
center.y = -0.16;
viewDir.z = 1;
height = 5.13732;
ratio = 2.4426877;
lensHeight = 50;
frontClip = backClip = snapAngle = twistAngle = 0.0;
viewMode = snap = grid = snapStyle = snapIsopair = 0;
fastZoom = 1;
circleZoom = 100;
ucsIcon = 3;
gridBehavior = 7;
}
void parseCode( int code, dxfReader* reader );
public:
DRW_Coord lowerLeft; /*!< Lower left corner, code 10 & 20 */
DRW_Coord UpperRight; /*!< Upper right corner, code 11 & 21 */
DRW_Coord center; /*!< center point in WCS, code 12 & 22 */
DRW_Coord snapBase; /*!< snap base point in DCS, code 13 & 23 */
DRW_Coord snapSpacing; /*!< snap Spacing, code 14 & 24 */
DRW_Coord gridSpacing; /*!< grid Spacing, code 15 & 25 */
DRW_Coord viewDir; /*!< view direction from target point, code 16, 26 & 36 */
DRW_Coord viewTarget; /*!< view target point, code 17, 27 & 37 */
double height; /*!< view height, code 40 */
double ratio; /*!< viewport aspect ratio, code 41 */
double lensHeight; /*!< lens height, code 42 */
double frontClip; /*!< front clipping plane, code 43 */
double backClip; /*!< back clipping plane, code 44 */
double snapAngle; /*!< snap rotation angle, code 50 */
double twistAngle; /*!< view twist angle, code 51 */
int viewMode; /*!< view mode, code 71 */
int circleZoom; /*!< circle zoom percent, code 72 */
int fastZoom; /*!< fast zoom setting, code 73 */
int ucsIcon; /*!< UCSICON setting, code 74 */
int snap; /*!< snap on/off, code 75 */
int grid; /*!< grid on/off, code 76 */
int snapStyle; /*!< snap style, code 77 */
int snapIsopair; /*!< snap isopair, code 78 */
int gridBehavior; /*!< grid behavior, code 60, undocummented */
/** code 60, bit coded possible value are
* bit 1 (1) show out of limits
* bit 2 (2) adaptive grid
* bit 3 (4) allow subdivision
* bit 4 (8) follow dinamic SCP
**/
};
// ! Class to handle imagedef entries
/*!
* Class to handle image definitions object entries
* @author Rallaz
*/
class DRW_ImageDef
{
public:
DRW_ImageDef()
{
version = 0;
}
void parseCode( int code, dxfReader* reader );
public:
string handle; /*!< entity identifier, code 5 */
UTF8STRING name; /*!< File name of image, code 1 */
int version; /*!< class version, code 90, 0=R14 version */
double u; /*!< image size in pixels U value, code 10 */
double v; /*!< image size in pixels V value, code 20 */
double up; /*!< default size of one pixel U value, code 11 */
double vp; /*!< default size of one pixel V value, code 12 really is 21*/
int loaded; /*!< image is loaded flag, code 280, 0=unloaded, 1=loaded */
int resolution; /*!< resolution units, code 281, 0=no, 2=centimeters, 5=inch */
std::map<string, string> reactors;
};
// ! Class to handle header entries
/*!
* Class to handle layer symbol table entries
* @author Rallaz
*/
class DRW_Header
{
public:
DRW_Header()
{
}
~DRW_Header()
{
vars.clear();
}
void parseCode( int code, dxfReader* reader );
void write( dxfWriter* writer, DRW::Version ver );
void addComment( string c );
string getComments() const { return comments; }
private:
bool getDouble( string key, double* varDouble );
bool getInt( string key, int* varInt );
bool getStr( string key, string* varStr );
bool getCoord( string key, DRW_Coord* varStr );
public:
std::map<string, DRW_Variant*> vars;
private:
string comments;
string name;
DRW_Variant* curr;
int version; // to use on read
};
namespace DRW {
// Extended color palette:
// The first entry is only for direct indexing starting with [1]
// Color 1 is red (1,0,0)
const unsigned char dxfColors[][3] =
{
{ 0, 0, 0 }, // unused
{ 255, 0, 0 }, // 1 red
{ 255, 255, 0 }, // 2 yellow
{ 0, 255, 0 }, // 3 green
{ 0, 255, 255 }, // 4 cyan
{ 0, 0, 255 }, // 5 blue
{ 255, 0, 255 }, // 6 magenta
{ 0, 0, 0 }, // 7 black or white
{ 128, 128, 128 }, // 8 50% gray
{ 192, 192, 192 }, // 9 75% gray
{ 255, 0, 0 }, // 10
{ 255, 127, 127 },
{ 204, 0, 0 },
{ 204, 102, 102 },
{ 153, 0, 0 },
{ 153, 76, 76 }, // 15
{ 127, 0, 0 },
{ 127, 63, 63 },
{ 76, 0, 0 },
{ 76, 38, 38 },
{ 255, 63, 0 }, // 20
{ 255, 159, 127 },
{ 204, 51, 0 },
{ 204, 127, 102 },
{ 153, 38, 0 },
{ 153, 95, 76 }, // 25
{ 127, 31, 0 },
{ 127, 79, 63 },
{ 76, 19, 0 },
{ 76, 47, 38 },
{ 255, 127, 0 }, // 30
{ 255, 191, 127 },
{ 204, 102, 0 },
{ 204, 153, 102 },
{ 153, 76, 0 },
{ 153, 114, 76 }, // 35
{ 127, 63, 0 },
{ 127, 95, 63 },
{ 76, 38, 0 },
{ 76, 57, 38 },
{ 255, 191, 0 }, // 40
{ 255, 223, 127 },
{ 204, 153, 0 },
{ 204, 178, 102 },
{ 153, 114, 0 },
{ 153, 133, 76 }, // 45
{ 127, 95, 0 },
{ 127, 111, 63 },
{ 76, 57, 0 },
{ 76, 66, 38 },
{ 255, 255, 0 }, // 50
{ 255, 255, 127 },
{ 204, 204, 0 },
{ 204, 204, 102 },
{ 153, 153, 0 },
{ 153, 153, 76 }, // 55
{ 127, 127, 0 },
{ 127, 127, 63 },
{ 76, 76, 0 },
{ 76, 76, 38 },
{ 191, 255, 0 }, // 60
{ 223, 255, 127 },
{ 153, 204, 0 },
{ 178, 204, 102 },
{ 114, 153, 0 },
{ 133, 153, 76 }, // 65
{ 95, 127, 0 },
{ 111, 127, 63 },
{ 57, 76, 0 },
{ 66, 76, 38 },
{ 127, 255, 0 }, // 70
{ 191, 255, 127 },
{ 102, 204, 0 },
{ 153, 204, 102 },
{ 76, 153, 0 },
{ 114, 153, 76 }, // 75
{ 63, 127, 0 },
{ 95, 127, 63 },
{ 38, 76, 0 },
{ 57, 76, 38 },
{ 63, 255, 0 }, // 80
{ 159, 255, 127 },
{ 51, 204, 0 },
{ 127, 204, 102 },
{ 38, 153, 0 },
{ 95, 153, 76 }, // 85
{ 31, 127, 0 },
{ 79, 127, 63 },
{ 19, 76, 0 },
{ 47, 76, 38 },
{ 0, 255, 0 }, // 90
{ 127, 255, 127 },
{ 0, 204, 0 },
{ 102, 204, 102 },
{ 0, 153, 0 },
{ 76, 153, 76 }, // 95
{ 0, 127, 0 },
{ 63, 127, 63 },
{ 0, 76, 0 },
{ 38, 76, 38 },
{ 0, 255, 63 }, // 100
{ 127, 255, 159 },
{ 0, 204, 51 },
{ 102, 204, 127 },
{ 0, 153, 38 },
{ 76, 153, 95 }, // 105
{ 0, 127, 31 },
{ 63, 127, 79 },
{ 0, 76, 19 },
{ 38, 76, 47 },
{ 0, 255, 127 }, // 110
{ 127, 255, 191 },
{ 0, 204, 102 },
{ 102, 204, 153 },
{ 0, 153, 76 },
{ 76, 153, 114 }, // 115
{ 0, 127, 63 },
{ 63, 127, 95 },
{ 0, 76, 38 },
{ 38, 76, 57 },
{ 0, 255, 191 }, // 120
{ 127, 255, 223 },
{ 0, 204, 153 },
{ 102, 204, 178 },
{ 0, 153, 114 },
{ 76, 153, 133 }, // 125
{ 0, 127, 95 },
{ 63, 127, 111 },
{ 0, 76, 57 },
{ 38, 76, 66 },
{ 0, 255, 255 }, // 130
{ 127, 255, 255 },
{ 0, 204, 204 },
{ 102, 204, 204 },
{ 0, 153, 153 },
{ 76, 153, 153 }, // 135
{ 0, 127, 127 },
{ 63, 127, 127 },
{ 0, 76, 76 },
{ 38, 76, 76 },
{ 0, 191, 255 }, // 140
{ 127, 223, 255 },
{ 0, 153, 204 },
{ 102, 178, 204 },
{ 0, 114, 153 },
{ 76, 133, 153 }, // 145
{ 0, 95, 127 },
{ 63, 111, 127 },
{ 0, 57, 76 },
{ 38, 66, 76 },
{ 0, 127, 255 }, // 150
{ 127, 191, 255 },
{ 0, 102, 204 },
{ 102, 153, 204 },
{ 0, 76, 153 },
{ 76, 114, 153 }, // 155
{ 0, 63, 127 },
{ 63, 95, 127 },
{ 0, 38, 76 },
{ 38, 57, 76 },
{ 0, 66, 255 }, // 160
{ 127, 159, 255 },
{ 0, 51, 204 },
{ 102, 127, 204 },
{ 0, 38, 153 },
{ 76, 95, 153 }, // 165
{ 0, 31, 127 },
{ 63, 79, 127 },
{ 0, 19, 76 },
{ 38, 47, 76 },
{ 0, 0, 255 }, // 170
{ 127, 127, 255 },
{ 0, 0, 204 },
{ 102, 102, 204 },
{ 0, 0, 153 },
{ 76, 76, 153 }, // 175
{ 0, 0, 127 },
{ 63, 63, 127 },
{ 0, 0, 76 },
{ 38, 38, 76 },
{ 63, 0, 255 }, // 180
{ 159, 127, 255 },
{ 50, 0, 204 },
{ 127, 102, 204 },
{ 38, 0, 153 },
{ 95, 76, 153 }, // 185
{ 31, 0, 127 },
{ 79, 63, 127 },
{ 19, 0, 76 },
{ 47, 38, 76 },
{ 127, 0, 255 }, // 190
{ 191, 127, 255 },
{ 102, 0, 204 },
{ 153, 102, 204 },
{ 76, 0, 153 },
{ 114, 76, 153 }, // 195
{ 63, 0, 127 },
{ 95, 63, 127 },
{ 38, 0, 76 },
{ 57, 38, 76 },
{ 191, 0, 255 }, // 200
{ 223, 127, 255 },
{ 153, 0, 204 },
{ 178, 102, 204 },
{ 114, 0, 153 },
{ 133, 76, 153 }, // 205
{ 95, 0, 127 },
{ 111, 63, 127 },
{ 57, 0, 76 },
{ 66, 38, 76 },
{ 255, 0, 255 }, // 210
{ 255, 127, 255 },
{ 204, 0, 204 },
{ 204, 102, 204 },
{ 153, 0, 153 },
{ 153, 76, 153 }, // 215
{ 127, 0, 127 },
{ 127, 63, 127 },
{ 76, 0, 76 },
{ 76, 38, 76 },
{ 255, 0, 191 }, // 220
{ 255, 127, 223 },
{ 204, 0, 153 },
{ 204, 102, 178 },
{ 153, 0, 114 },
{ 153, 76, 133 }, // 225
{ 127, 0, 95 },
{ 127, 63, 11 },
{ 76, 0, 57 },
{ 76, 38, 66 },
{ 255, 0, 127 }, // 230
{ 255, 127, 191 },
{ 204, 0, 102 },
{ 204, 102, 153 },
{ 153, 0, 76 },
{ 153, 76, 114 }, // 235
{ 127, 0, 63 },
{ 127, 63, 95 },
{ 76, 0, 38 },
{ 76, 38, 57 },
{ 255, 0, 63 }, // 240
{ 255, 127, 159 },
{ 204, 0, 51 },
{ 204, 102, 127 },
{ 153, 0, 38 },
{ 153, 76, 95 }, // 245
{ 127, 0, 31 },
{ 127, 63, 79 },
{ 76, 0, 19 },
{ 76, 38, 47 },
{ 51, 51, 51 }, // 250
{ 91, 91, 91 },
{ 132, 132, 132 },
{ 173, 173, 173 },
{ 214, 214, 214 },
{ 255, 255, 255 } // 255
};
}
#endif
// EOF

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,498 @@
#include "drw_textcodec.h"
#include <sstream>
#include <iomanip>
#include <algorithm>
#include "../drw_base.h"
#include "drw_cptables.h"
#include "drw_cptable932.h"
#include "drw_cptable936.h"
#include "drw_cptable949.h"
#include "drw_cptable950.h"
DRW_TextCodec::DRW_TextCodec() {
version = DRW::AC1021;
conv = new DRW_Converter(NULL, 0);
}
DRW_TextCodec::~DRW_TextCodec() {
delete conv;
}
void DRW_TextCodec::setVersion(std::string *v){
std::string versionStr = *v;
if (versionStr == "AC1009" || versionStr == "AC1006") {
version = DRW::AC1009;
cp = "ANSI_1252";
setCodePage(&cp);
} else if (versionStr == "AC1012" || versionStr == "AC1014"
|| versionStr == "AC1015" || versionStr == "AC1018") {
version = DRW::AC1015;
if (cp.empty()) { //codepage not set, initialize
cp = "ANSI_1252";
setCodePage(&cp);
}
} else {
version = DRW::AC1021;
cp = "ANSI_1252";
}
}
void DRW_TextCodec::setCodePage(std::string *c){
cp = correctCodePage(*c);
delete conv;
if (version == DRW::AC1009 || version == DRW::AC1015) {
if (cp == "ANSI_874")
conv = new DRW_ConvTable(DRW_Table874, CPLENGHTCOMMON);
else if (cp == "ANSI_932")
conv = new DRW_Conv932Table(DRW_Table932, DRW_LeadTable932,
DRW_DoubleTable932, CPLENGHT932);
else if (cp == "ANSI_936")
conv = new DRW_ConvDBCSTable(DRW_Table936, DRW_LeadTable936,
DRW_DoubleTable936, CPLENGHT936);
else if (cp == "ANSI_949")
conv = new DRW_ConvDBCSTable(DRW_Table949, DRW_LeadTable949,
DRW_DoubleTable949, CPLENGHT949);
else if (cp == "ANSI_950")
conv = new DRW_ConvDBCSTable(DRW_Table950, DRW_LeadTable950,
DRW_DoubleTable950, CPLENGHT950);
else if (cp == "ANSI_1250")
conv = new DRW_ConvTable(DRW_Table1250, CPLENGHTCOMMON);
else if (cp == "ANSI_1251")
conv = new DRW_ConvTable(DRW_Table1251, CPLENGHTCOMMON);
else if (cp == "ANSI_1253")
conv = new DRW_ConvTable(DRW_Table1253, CPLENGHTCOMMON);
else if (cp == "ANSI_1254")
conv = new DRW_ConvTable(DRW_Table1254, CPLENGHTCOMMON);
else if (cp == "ANSI_1255")
conv = new DRW_ConvTable(DRW_Table1255, CPLENGHTCOMMON);
else if (cp == "ANSI_1256")
conv = new DRW_ConvTable(DRW_Table1256, CPLENGHTCOMMON);
else if (cp == "ANSI_1257")
conv = new DRW_ConvTable(DRW_Table1257, CPLENGHTCOMMON);
else if (cp == "ANSI_1258")
conv = new DRW_ConvTable(DRW_Table1258, CPLENGHTCOMMON);
else if (cp == "UTF-8") { //DXF older than 2007 are write in win codepages
cp = "ANSI_1252";
conv = new DRW_Converter(NULL, 0);
} else
conv = new DRW_ConvTable(DRW_Table1252, CPLENGHTCOMMON);
} else {
conv = new DRW_Converter(NULL, 0);
}
}
std::string DRW_TextCodec::toUtf8(std::string s) {
return conv->toUtf8(&s);
}
std::string DRW_TextCodec::fromUtf8(std::string s) {
return conv->fromUtf8(&s);
}
std::string DRW_Converter::toUtf8(std::string *s) {
std::string result;
int j = 0;
unsigned int i= 0;
for (i=0; i < s->length(); i++) {
unsigned char c = s->at(i);
if (c < 0x80) { //ascii check for /U+????
if (c == '\\' && i+6 < s->length() && s->at(i+1) == 'U' && s->at(i+2) == '+') {
result += s->substr(j,i-j);
result += encodeText(s->substr(i,7));
i +=6;
j = i+1;
}
} else if (c < 0xE0 ) {//2 bits
i++;
} else if (c < 0xF0 ) {//3 bits
i +=2;
} else if (c < 0xF8 ) {//4 bits
i +=3;
}
}
result += s->substr(j);
return result;
}
std::string DRW_ConvTable::fromUtf8(std::string *s) {
std::string result;
bool notFound;
int code;
int j = 0;
for (unsigned int i=0; i < s->length(); i++) {
unsigned char c = s->at(i);
if (c > 0x7F) { //need to decode
result += s->substr(j,i-j);
std::string part1 = s->substr(i,4);
int l;
code = decodeNum(part1, &l);
j = i+l;
i = j - 1;
notFound = true;
for (int k=0; k<cpLenght; k++){
if(table[k] == code) {
result += CPOFFSET + k; //translate from table
notFound = false;
break;
}
}
if (notFound)
result += decodeText(code);
}
}
result += s->substr(j);
return result;
}
std::string DRW_ConvTable::toUtf8(std::string *s) {
std::string res;
string::iterator it;
for ( it=s->begin() ; it < s->end(); it++ ) {
unsigned char c = *it;
if (c < 0x80) {
//check for \U+ encoded text
if (c == '\\') {
if (it+6 < s->end() && *(it+1) == 'U' && *(it+2) == '+') {
res += encodeText(std::string(it, it+7));
it +=6;
} else {
res +=c; //no \U+ encoded text write
}
} else
res +=c; //c!='\' ascii char write
} else {//end c < 0x80
res += encodeNum(table[c-0x80]); //translate from table
}
} //end for
return res;
}
std::string DRW_Converter::encodeText(std::string stmp){
int code;
#if defined(__APPLE__)
int Succeeded = sscanf (&( stmp.substr(3,4)[0]), "%x", &code );
if ( !Succeeded || Succeeded == EOF )
code = 0;
#else
std::istringstream sd(stmp.substr(3,4));
sd >> std::hex >> code;
#endif
return encodeNum(code);
}
std::string DRW_Converter::decodeText(int c){
std::string res = "\\U+";
std::string num;
#if defined(__APPLE__)
std::string str(16, '\0');
snprintf (&(str[0]), 16, "%04X", c );
num = str;
#else
std::stringstream ss;
ss << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << c;
ss >> num;
#endif
res += num;
return res;
}
std::string DRW_Converter::encodeNum(int c){
unsigned char ret[5];
if (c < 128) { // 0-7F US-ASCII 7 bits
ret[0] = c;
ret[1] = 0;
} else if (c < 0x800) { //80-07FF 2 bytes
ret[0] = 0xC0 | (c >> 6);
ret[1] = 0x80 | (c & 0x3f);
ret[2] = 0;
} else if (c< 0x10000) { //800-FFFF 3 bytes
ret[0] = 0xe0 | (c >> 12);
ret[1] = 0x80 | ((c >> 6) & 0x3f);
ret[2] = 0x80 | (c & 0x3f);
ret[3] = 0;
} else { //10000-10FFFF 4 bytes
ret[0] = 0xf0 | (c >> 18);
ret[1] = 0x80 | ((c >> 12) & 0x3f);
ret[2] = 0x80 | ((c >> 6) & 0x3f);
ret[3] = 0x80 | (c & 0x3f);
ret[4] = 0;
}
return std::string((char*)ret);
}
/** 's' is a string with at least 4 bytes lenght
** returned 'b' is byte lenght of encoded char: 2,3 or 4
**/
int DRW_Converter::decodeNum(std::string s, int *b){
int code= 0;
unsigned char c = s.at(0);
if ( (c& 0xE0) == 0xC0) { //2 bytes
code = ( c&0x1F)<<6;
code = (s.at(1) &0x3F) | code;
*b = 2;
} else if ( (c& 0xF0) == 0xE0) { //3 bytes
code = ( c&0x0F)<<12;
code = ((s.at(1) &0x3F)<<6) | code;
code = (s.at(2) &0x3F) | code;
*b = 3;
} else if ( (c& 0xF8) == 0xF0) { //4 bytes
code = ( c&0x07)<<18;
code = ((s.at(1) &0x3F)<<12) | code;
code = ((s.at(2) &0x3F)<<6) | code;
code = (s.at(3) &0x3F) | code;
*b = 4;
}
return code;
}
std::string DRW_ConvDBCSTable::fromUtf8(std::string *s) {
std::string result;
bool notFound;
int code;
int j = 0;
for (unsigned int i=0; i < s->length(); i++) {
unsigned char c = s->at(i);
if (c > 0x7F) { //need to decode
result += s->substr(j,i-j);
std::string part1 = s->substr(i,4);
int l;
code = decodeNum(part1, &l);
j = i+l;
i = j - 1;
notFound = true;
for (int k=0; k<cpLenght; k++){
if(doubleTable[k][1] == code) {
int data = doubleTable[k][0];
char d[3];
d[0] = data >> 8;
d[1] = data & 0xFF;
d[2]= '\0';
result += d; //translate from table
notFound = false;
break;
}
}
if (notFound)
result += decodeText(code);
} //direct conversion
}
result += s->substr(j);
return result;
}
std::string DRW_ConvDBCSTable::toUtf8(std::string *s) {
std::string res;
string::iterator it;
for ( it=s->begin() ; it < s->end(); it++ ) {
bool notFound = true;
unsigned char c = *it;
if (c < 0x80) {
notFound = false;
//check for \U+ encoded text
if (c == '\\') {
if (it+6 < s->end() && *(it+1) == 'U' && *(it+2) == '+') {
res += encodeText(std::string(it, it+7));
it +=6;
} else {
res +=c; //no \U+ encoded text write
}
} else
res +=c; //c!='\' ascii char write
} else if(c == 0x80 ){//1 byte table
notFound = false;
res += encodeNum(0x20AC);//euro sign
} else {//2 bytes
++it;
int code = (c << 8) | (unsigned char )(*it);
int sta = leadTable[c-0x81];
int end = leadTable[c-0x80];
for (int k=sta; k<end; k++){
if(doubleTable[k][0] == code) {
res += encodeNum(doubleTable[k][1]); //translate from table
notFound = false;
break;
}
}
}
//not found
if (notFound) res += encodeNum(NOTFOUND936);
} //end for
return res;
}
std::string DRW_Conv932Table::fromUtf8(std::string *s) {
std::string result;
bool notFound;
int code;
int j = 0;
for (unsigned int i=0; i < s->length(); i++) {
unsigned char c = s->at(i);
if (c > 0x7F) { //need to decode
result += s->substr(j,i-j);
std::string part1 = s->substr(i,4);
int l;
code = decodeNum(part1, &l);
j = i+l;
i = j - 1;
notFound = true;
// 1 byte table
if (code > 0xff60 && code < 0xFFA0) {
result += code - CPOFFSET932; //translate from table
notFound = false;
}
if (notFound && ( code<0xF8 || (code>0x390 && code<0x542) ||
(code>0x200F && code<0x9FA1) || code>0xF928 )) {
for (int k=0; k<cpLenght; k++){
if(doubleTable[k][1] == code) {
int data = doubleTable[k][0];
char d[3];
d[0] = data >> 8;
d[1] = data & 0xFF;
d[2]= '\0';
result += d; //translate from table
notFound = false;
break;
}
}
}
if (notFound)
result += decodeText(code);
} //direct conversion
}
result += s->substr(j);
return result;
}
std::string DRW_Conv932Table::toUtf8(std::string *s) {
std::string res;
string::iterator it;
for ( it=s->begin() ; it < s->end(); it++ ) {
bool notFound = true;
unsigned char c = *it;
if (c < 0x80) {
notFound = false;
//check for \U+ encoded text
if (c == '\\') {
if (it+6 < s->end() && *(it+1) == 'U' && *(it+2) == '+') {
res += encodeText(std::string(it, it+7));
it +=6;
} else {
res +=c; //no \U+ encoded text write
}
} else
res +=c; //c!='\' ascii char write
} else if(c > 0xA0 && c < 0xE0 ){//1 byte table
notFound = false;
res += encodeNum(c + CPOFFSET932); //translate from table
} else {//2 bytes
++it;
int code = (c << 8) | (unsigned char )(*it);
int sta;
int end=0;
if (c > 0x80 && c < 0xA0) {
sta = DRW_LeadTable932[c-0x81];
end = DRW_LeadTable932[c-0x80];
} else if (c > 0xDF && c < 0xFD){
sta = DRW_LeadTable932[c-0xC1];
end = DRW_LeadTable932[c-0xC0];
}
if (end > 0) {
for (int k=sta; k<end; k++){
if(DRW_DoubleTable932[k][0] == code) {
res += encodeNum(DRW_DoubleTable932[k][1]); //translate from table
notFound = false;
break;
}
}
}
}
//not found
if (notFound) res += encodeNum(NOTFOUND932);
} //end for
return res;
}
std::string DRW_TextCodec::correctCodePage(const std::string& s) {
//stringstream cause crash in OS/X, bug#3597944
std::string cp=s;
transform(cp.begin(), cp.end(), cp.begin(), toupper);
//Latin/Thai
if (cp=="ANSI_874" || cp=="CP874" || cp=="ISO8859-11" || cp=="TIS-620") {
return "ANSI_874";
//Central Europe and Eastern Europe
} else if (cp=="ANSI_1250" || cp=="CP1250" || cp=="ISO8859-2") {
return "ANSI_1250";
//Cyrillic script
} else if (cp=="ANSI_1251" || cp=="CP1251" || cp=="ISO8859-5" || cp=="KOI8-R" ||
cp=="KOI8-U" || cp=="IBM 866") {
return "ANSI_1251";
//Western Europe
} else if (cp=="ANSI_1252" || cp=="CP1252" || cp=="LATIN1" || cp=="ISO-8859-1" ||
cp=="CP819" || cp=="CSISO" || cp=="IBM819" || cp=="ISO_8859-1" || cp=="APPLE ROMAN" ||
cp=="ISO8859-1" || cp=="ISO8859-15" || cp=="ISO-IR-100" || cp=="L1" || cp=="IBM 850") {
return "ANSI_1252";
//Greek
} else if (cp=="ANSI_1253" || cp=="CP1253" || cp=="iso8859-7") {
return "ANSI_1253";
//Turkish
} else if (cp=="ANSI_1254" || cp=="CP1254" || cp=="iso8859-9" || cp=="iso8859-3") {
return "ANSI_1254";
//Hebrew
} else if (cp=="ANSI_1255" || cp=="CP1255" || cp=="iso8859-8") {
return "ANSI_1255";
//Arabic
} else if (cp=="ANSI_1256" || cp=="CP1256" || cp=="ISO8859-6") {
return "ANSI_1256";
//Baltic
} else if (cp=="ANSI_1257" || cp=="CP1257" || cp=="ISO8859-4" || cp=="ISO8859-10" || cp=="ISO8859-13") {
return "ANSI_1257";
//Vietnamese
} else if (cp=="ANSI_1258" || cp=="CP1258") {
return "ANSI_1258";
//Japanese
} else if (cp=="ANSI_932" || cp=="SHIFT-JIS" || cp=="SHIFT_JIS" || cp=="CSSHIFTJIS" ||
cp=="CSWINDOWS31J" || cp=="MS_KANJI" || cp=="X-MS-CP932" || cp=="X-SJIS" ||
cp=="EUCJP" || cp=="EUC-JP" || cp=="CSEUCPKDFMTJAPANESE" || cp=="X-EUC" ||
cp=="X-EUC-JP" || cp=="JIS7") {
return "ANSI_932";
//Chinese PRC GBK (XGB) simplified
} else if (cp=="ANSI_936" || cp=="GBK" || cp=="GB2312" || cp=="CHINESE" || cp=="CN-GB" ||
cp=="CSGB2312" || cp=="CSGB231280" || cp=="CSISO58BG231280" ||
cp=="GB_2312-80" || cp=="GB231280" || cp=="GB2312-80" || cp=="GBK" ||
cp=="ISO-IR-58" || cp=="GB18030") {
return "ANSI_936";
//Korean
} else if (cp=="ANSI_949" || cp=="EUCKR") {
return "ANSI_949";
//Chinese Big5 (Taiwan, Hong Kong SAR)
} else if (cp=="ANSI_950" || cp=="BIG5" || cp=="CN-BIG5" || cp=="CSBIG5" ||
cp=="X-X-BIG5" || cp=="BIG5-HKSCS") {
return "ANSI_950";
//celtic
/* } else if (cp=="ISO8859-14") {
return "ISO8859-14";
} else if (cp=="TSCII") {
return "TSCII"; //tamil
} else if (cp=="UTF16") {
return "UTF16"; */
} else if (cp=="UTF-8" || cp=="UTF8" || cp=="UTF88-BIT") {
return "UTF-8";
}
return "ANSI_1252";
}

View File

@ -0,0 +1,84 @@
#ifndef DRW_TEXTCODEC_H
#define DRW_TEXTCODEC_H
#include <string>
class DRW_Converter;
class DRW_TextCodec
{
public:
DRW_TextCodec();
~DRW_TextCodec();
std::string fromUtf8(std::string s);
std::string toUtf8(std::string s);
int getVersion(){return version;}
void setVersion(std::string *v);
void setVersion(int v){version = v;}
void setCodePage(std::string *c);
void setCodePage(std::string c){setCodePage(&c);}
std::string getCodePage(){return cp;}
private:
std::string correctCodePage(const std::string& s);
private:
int version;
std::string cp;
DRW_Converter *conv;
};
class DRW_Converter
{
public:
DRW_Converter(const int *t, int l){table = t;
cpLenght = l;}
virtual ~DRW_Converter(){}
virtual std::string fromUtf8(std::string *s) {return *s;}
virtual std::string toUtf8(std::string *s);
std::string encodeText(std::string stmp);
std::string decodeText(int c);
std::string encodeNum(int c);
int decodeNum(std::string s, int *b);
const int *table;
int cpLenght;
};
class DRW_ConvTable : public DRW_Converter {
public:
DRW_ConvTable(const int *t, int l):DRW_Converter(t, l) {}
virtual std::string fromUtf8(std::string *s);
virtual std::string toUtf8(std::string *s);
};
class DRW_ConvDBCSTable : public DRW_Converter {
public:
DRW_ConvDBCSTable(const int *t, const int *lt, const int dt[][2], int l):DRW_Converter(t, l) {
leadTable = lt;
doubleTable = dt;
}
virtual std::string fromUtf8(std::string *s);
virtual std::string toUtf8(std::string *s);
private:
const int *leadTable;
const int (*doubleTable)[2];
};
class DRW_Conv932Table : public DRW_Converter {
public:
DRW_Conv932Table(const int *t, const int *lt, const int dt[][2], int l):DRW_Converter(t, l) {
leadTable = lt;
doubleTable = dt;
}
virtual std::string fromUtf8(std::string *s);
virtual std::string toUtf8(std::string *s);
private:
const int *leadTable;
const int (*doubleTable)[2];
};
#endif // DRW_TEXTCODEC_H

View File

@ -0,0 +1,263 @@
/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011 Rallaz, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/
#include <stdlib.h>
#include <fstream>
#include <string>
#include <sstream>
#include "dxfreader.h"
#include "drw_textcodec.h"
#ifdef DRW_DBG
#include <iostream> //for debug
#define DBG(a) std::cerr << a
#else
#define DBG(a)
#endif
bool dxfReader::readRec(int *codeData, bool skip) {
// std::string text;
int code;
#ifdef DRW_DBG
count = count+2; //DBG
/* if (count > 10250)
DBG("line 10256");*/
#endif
if (!readCode(&code))
return false;
*codeData = code;
if (code < 10)
readString();
else if (code < 60)
readDouble();
else if (code < 80)
readInt();
else if (code > 89 && code < 100) //TODO this is an int 32b
readInt32();
else if (code == 100 || code == 102 || code == 105)
readString();
else if (code > 109 && code < 150) //skip not used at the v2012
readDouble();
else if (code > 159 && code < 170) //skip not used at the v2012
readInt64();
else if (code < 180)
readInt();
else if (code > 209 && code < 240) //skip not used at the v2012
readDouble();
else if (code > 269 && code < 290) //skip not used at the v2012
readInt();
else if (code < 300) //TODO this is a boolean indicator, int in Binary?
readBool();
else if (code < 370)
readString();
else if (code < 390)
readInt();
else if (code < 400)
readString();
else if (code < 410)
readInt();
else if (code < 420)
readString();
else if (code < 430) //TODO this is an int 32b
readInt32();
else if (code < 440)
readString();
else if (code < 450) //TODO this is an int 32b
readInt32();
else if (code < 460) //TODO this is long??
readInt();
else if (code < 470) //TODO this is a floating point double precision??
readDouble();
else if (code < 481)
readString();
else if (code > 998 && code < 1009) //skip not used at the v2012
readString();
else if (code < 1060) //TODO this is a floating point double precision??
readDouble();
else if (code < 1071)
readInt();
else if (code == 1071) //TODO this is an int 32b
readInt32();
else if (skip)
//skip safely this dxf entry ( ok for ascii dxf)
readString();
else
//break in binary files because the conduct is unpredictable
return false;
return (filestr->good());
}
int dxfReader::getHandleString(){
int res;
#if defined(__APPLE__)
int Succeeded = sscanf ( strData.c_str(), "%x", &res );
if ( !Succeeded || Succeeded == EOF )
res = 0;
#else
std::istringstream Convert(strData);
if ( !(Convert >> std::hex >>res) )
res = 0;
#endif
return res;
}
bool dxfReaderBinary::readCode(int *code) {
unsigned short *int16p;
char buffer[2];
filestr->read(buffer,2);
int16p = (unsigned short *) buffer;
//exist a 32bits int (code 90) with 2 bytes???
if ((*code == 90) && (*int16p>2000)){
DBG(*code); DBG(" de 16bits\n");
filestr->seekg(-4, std::ios_base::cur);
filestr->read(buffer,2);
int16p = (unsigned short *) buffer;
}
*code = *int16p;
DBG(*code); DBG("\n");
return (filestr->good());
}
bool dxfReaderBinary::readString() {
std::getline(*filestr, strData, '\0');
DBG(strData); DBG("\n");
return (filestr->good());
}
bool dxfReaderBinary::readString(std::string *text) {
std::getline(*filestr, *text, '\0');
DBG(*text); DBG("\n");
return (filestr->good());
}
bool dxfReaderBinary::readInt() {
char buffer[2];
filestr->read(buffer,2);
intData = (int)((buffer[1] << 8) | buffer[0]);
DBG(intData); DBG("\n");
return (filestr->good());
}
bool dxfReaderBinary::readInt32() {
unsigned int *int32p;
char buffer[4];
filestr->read(buffer,4);
int32p = (unsigned int *) buffer;
intData = *int32p;
DBG(intData); DBG("\n");
return (filestr->good());
}
bool dxfReaderBinary::readInt64() {
unsigned long long int *int64p; //64 bits integer pointer
char buffer[8];
filestr->read(buffer,8);
int64p = (unsigned long long int *) buffer;
int64 = *int64p;
DBG(int64); DBG(" int64\n");
return (filestr->good());
}
bool dxfReaderBinary::readDouble() {
double *result;
char buffer[8];
filestr->read(buffer,8);
result = (double *) buffer;
doubleData = *result;
DBG(doubleData); DBG("\n");
return (filestr->good());
}
//saved as int or add a bool member??
bool dxfReaderBinary::readBool() {
char buffer[1];
filestr->read(buffer,1);
intData = (int)(buffer[0]);
DBG(intData); DBG("\n");
return (filestr->good());
}
bool dxfReaderAscii::readCode(int *code) {
std::string text;
std::getline(*filestr, text);
*code = atoi(text.c_str());
DBG(*code); DBG("\n");
return (filestr->good());
}
bool dxfReaderAscii::readString(std::string *text) {
std::getline(*filestr, *text);
if (!text->empty() && text->at(text->size()-1) == '\r')
text->erase(text->size()-1);
return (filestr->good());
}
bool dxfReaderAscii::readString() {
std::getline(*filestr, strData);
if (!strData.empty() && strData.at(strData.size()-1) == '\r')
strData.erase(strData.size()-1);
DBG(strData); DBG("\n");
return (filestr->good());
}
bool dxfReaderAscii::readInt() {
std::string text;
if (readString(&text)){
intData = atoi(text.c_str());
DBG(intData); DBG("\n");
return true;
} else
return false;
}
bool dxfReaderAscii::readInt32() {
return readInt();
}
bool dxfReaderAscii::readInt64() {
return readInt();
}
bool dxfReaderAscii::readDouble() {
std::string text;
if (readString(&text)){
#if defined(__APPLE__)
int succeeded=sscanf( & (text[0]), "%lg", &doubleData);
if(succeeded != 1) {
DBG("dxfReaderAscii::readDouble(): reading double error: ");
DBG(text);
DBG('\n');
}
#else
std::istringstream sd(text);
sd >> doubleData;
DBG(doubleData); DBG('\n');
#endif
return true;
} else
return false;
}
//saved as int or add a bool member??
bool dxfReaderAscii::readBool() {
std::string text;
if (readString(&text)){
intData = atoi(text.c_str());
DBG(intData); DBG("\n");
return true;
} else
return false;
}

View File

@ -0,0 +1,89 @@
/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011 Rallaz, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/
#ifndef DXFREADER_H
#define DXFREADER_H
#include "drw_textcodec.h"
class dxfReader {
public:
dxfReader(std::ifstream *stream){
filestr = stream;
#ifdef DRW_DBG
count =0;
#endif
}
virtual ~dxfReader(){}
virtual bool readCode(int *code) = 0; //return true if sucesful (not EOF)
virtual bool readString(std::string *text) = 0;
virtual bool readString() = 0;
bool readRec(int *code, bool skip);
virtual bool readInt() = 0;
virtual bool readInt32() = 0;
virtual bool readInt64() = 0;
virtual bool readDouble() = 0;
virtual bool readBool() = 0;
std::string getString() {return strData;}
int getHandleString();//Convert hex string to int
std::string toUtf8String(std::string t) {return decoder.toUtf8(t);}
std::string getUtf8String() {return decoder.toUtf8(strData);}
double getDouble() {return doubleData;}
int getInt32() {return intData;}
unsigned long long int getInt64() {return int64;}
bool getBool() { return (intData==0) ? false : true;}
int getVersion(){return decoder.getVersion();}
void setVersion(std::string *v){decoder.setVersion(v);}
void setCodePage(std::string *c){decoder.setCodePage(c);}
std::string getCodePage(){ return decoder.getCodePage();}
#ifdef DRW_DBG
int count;//DBG
#endif
protected:
std::ifstream *filestr;
std::string strData;
double doubleData;
signed short intData; //16 bits integer
unsigned long long int int64; //64 bits integer
private:
DRW_TextCodec decoder;
};
class dxfReaderBinary : public dxfReader {
public:
dxfReaderBinary(std::ifstream *stream):dxfReader(stream){ }
virtual ~dxfReaderBinary() {}
virtual bool readCode(int *code);
virtual bool readString(std::string *text);
virtual bool readString();
virtual bool readInt();
virtual bool readInt32();
virtual bool readInt64();
virtual bool readDouble();
virtual bool readBool();
};
class dxfReaderAscii : public dxfReader {
public:
dxfReaderAscii(std::ifstream *stream):dxfReader(stream){ }
virtual ~dxfReaderAscii(){}
virtual bool readCode(int *code);
virtual bool readString(std::string *text);
virtual bool readString();
virtual bool readInt();
virtual bool readDouble();
virtual bool readInt32();
virtual bool readInt64();
virtual bool readBool();
};
#endif // DXFREADER_H

View File

@ -0,0 +1,281 @@
/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011 Rallaz, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/
#include <stdlib.h>
#include <fstream>
#include <string>
#include <algorithm>
#include "dxfwriter.h"
#ifdef DRW_DBG
#include <iostream> //for debug
#define DBG(a) std::cerr << a
#else
#define DBG(a)
#endif
//RLZ TODO change std::endl to x0D x0A (13 10)
/*bool dxfWriter::readRec(int *codeData, bool skip) {
// std::string text;
int code;
#ifdef DRW_DBG
count = count+2; //DBG
#endif
if (!readCode(&code))
return false;
*codeData = code;
if (code < 10)
readString();
else if (code < 60)
readDouble();
else if (code < 80)
readInt();
else if (code > 89 && code < 100) //TODO this is an int 32b
readInt32();
else if (code == 100 || code == 102 || code == 105)
readString();
else if (code > 109 && code < 150) //skip not used at the v2012
readDouble();
else if (code > 159 && code < 170) //skip not used at the v2012
readInt64();
else if (code < 180)
readInt();
else if (code > 209 && code < 240) //skip not used at the v2012
readDouble();
else if (code > 269 && code < 290) //skip not used at the v2012
readInt();
else if (code < 300) //TODO this is a boolean indicator, int in Binary?
readBool();
else if (code < 370)
readString();
else if (code < 390)
readInt();
else if (code < 400)
readString();
else if (code < 410)
readInt();
else if (code < 420)
readString();
else if (code < 430) //TODO this is an int 32b
readInt32();
else if (code < 440)
readString();
else if (code < 450) //TODO this is an int 32b
readInt32();
else if (code < 460) //TODO this is long??
readInt();
else if (code < 470) //TODO this is a floating point double precision??
readDouble();
else if (code < 481)
readString();
else if (code > 998 && code < 1009) //skip not used at the v2012
readString();
else if (code < 1060) //TODO this is a floating point double precision??
readDouble();
else if (code < 1071)
readInt();
else if (code == 1071) //TODO this is an int 32b
readInt32();
else if (skip)
//skip safely this dxf entry ( ok for ascii dxf)
readString();
else
//break in binary files because the conduct is unpredictable
return false;
return (filestr->good());
}*/
bool dxfWriter::writeUtf8String(int code, std::string text) {
std::string t = encoder.fromUtf8(text);
return writeString(code, t);
}
bool dxfWriter::writeUtf8Caps(int code, std::string text) {
std::string strname = text;
std::transform(strname.begin(), strname.end(), strname.begin(),::toupper);
std::string t = encoder.fromUtf8(strname);
return writeString(code, t);
}
bool dxfWriterBinary::writeString(int code, std::string text) {
char bufcode[2];
bufcode[0] =code & 0xFF;
bufcode[1] =code >> 8;
filestr->write(bufcode, 2);
*filestr << text << '\0';
return (filestr->good());
}
/*bool dxfWriterBinary::readCode(int *code) {
unsigned short *int16p;
char buffer[2];
filestr->read(buffer,2);
int16p = (unsigned short *) buffer;
//exist a 32bits int (code 90) with 2 bytes???
if ((*code == 90) && (*int16p>2000)){
DBG(*code); DBG(" de 16bits\n");
filestr->seekg(-4, std::ios_base::cur);
filestr->read(buffer,2);
int16p = (unsigned short *) buffer;
}
*code = *int16p;
DBG(*code); DBG("\n");
return (filestr->good());
}*/
/*bool dxfWriterBinary::readString() {
std::getline(*filestr, strData, '\0');
DBG(strData); DBG("\n");
return (filestr->good());
}*/
/*bool dxfWriterBinary::readString(std::string *text) {
std::getline(*filestr, *text, '\0');
DBG(*text); DBG("\n");
return (filestr->good());
}*/
bool dxfWriterBinary::writeInt16(int code, int data) {
char bufcode[2];
char buffer[2];
bufcode[0] =code & 0xFF;
bufcode[1] =code >> 8;
buffer[0] =data & 0xFF;
buffer[1] =data >> 8;
filestr->write(bufcode, 2);
filestr->write(buffer, 2);
return (filestr->good());
}
bool dxfWriterBinary::writeInt32(int code, int data) {
char buffer[4];
buffer[0] =code & 0xFF;
buffer[1] =code >> 8;
filestr->write(buffer, 2);
buffer[0] =data & 0xFF;
buffer[1] =data >> 8;
buffer[2] =data >> 16;
buffer[3] =data >> 24;
filestr->write(buffer, 4);
return (filestr->good());
}
bool dxfWriterBinary::writeInt64(int code, unsigned long long int data) {
char buffer[8];
buffer[0] =code & 0xFF;
buffer[1] =code >> 8;
filestr->write(buffer, 2);
buffer[0] =data & 0xFF;
buffer[1] =data >> 8;
buffer[2] =data >> 16;
buffer[3] =data >> 24;
buffer[4] =data >> 32;
buffer[5] =data >> 40;
buffer[6] =data >> 48;
buffer[7] =data >> 56;
filestr->write(buffer, 8);
return (filestr->good());
}
bool dxfWriterBinary::writeDouble(int code, double data) {
char bufcode[2];
char buffer[8];
bufcode[0] =code & 0xFF;
bufcode[1] =code >> 8;
filestr->write(bufcode, 2);
unsigned char *val;
val = (unsigned char *) &data;
for (int i=0; i<8; i++) {
buffer[i] =val[i];
}
filestr->write(buffer, 8);
return (filestr->good());
}
//saved as int or add a bool member??
bool dxfWriterBinary::writeBool(int code, bool data) {
char buffer[1];
char bufcode[2];
bufcode[0] =code & 0xFF;
bufcode[1] =code >> 8;
filestr->write(bufcode, 2);
buffer[0] = data;
filestr->write(buffer, 1);
return (filestr->good());
}
bool dxfWriterAscii::writeString(int code, std::string text) {
*filestr << code << std::endl << text << std::endl ;
/* std::getline(*filestr, strData, '\0');
DBG(strData); DBG("\n");*/
return (filestr->good());
}
/*bool dxfWriterAscii::readCode(int *code) {
std::string text;
std::getline(*filestr, text);
*code = atoi(text.c_str());
DBG(*code); DBG("\n");
return (filestr->good());
}*/
/*bool dxfWriterAscii::readString(std::string *text) {
std::getline(*filestr, *text);
if (text->at(text->size()-1) == '\r')
text->erase(text->size()-1);
return (filestr->good());
}*/
/*bool dxfWriterAscii::readString() {
std::getline(*filestr, strData);
if (strData.at(strData.size()-1) == '\r')
strData.erase(strData.size()-1);
DBG(strData); DBG("\n");
return (filestr->good());
}*/
bool dxfWriterAscii::writeInt16(int code, int data) {
// *filestr << code << "\r\n" << data << "\r\n";
*filestr << code << std::endl << data << std::endl;
return (filestr->good());
}
bool dxfWriterAscii::writeInt32(int code, int data) {
return writeInt16(code, data);
}
bool dxfWriterAscii::writeInt64(int code, unsigned long long int data) {
*filestr << code << std::endl << data << std::endl;
return (filestr->good());
}
bool dxfWriterAscii::writeDouble(int code, double data) {
std::streamsize prec = filestr->precision();
filestr->precision(12);
*filestr << code << std::endl << data << std::endl;
filestr->precision(prec);
return (filestr->good());
}
//saved as int or add a bool member??
bool dxfWriterAscii::writeBool(int code, bool data) {
*filestr << code << std::endl << data << std::endl;
return (filestr->good());
}

View File

@ -0,0 +1,64 @@
/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011 Rallaz, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/
#ifndef DXFWRITER_H
#define DXFWRITER_H
#include "drw_textcodec.h"
class dxfWriter {
public:
dxfWriter(std::ofstream *stream){filestr = stream; /*count =0;*/}
virtual ~dxfWriter(){}
virtual bool writeString(int code, std::string text) = 0;
bool writeUtf8String(int code, std::string text);
bool writeUtf8Caps(int code, std::string text);
std::string fromUtf8String(std::string t) {return encoder.fromUtf8(t);}
virtual bool writeInt16(int code, int data) = 0;
virtual bool writeInt32(int code, int data) = 0;
virtual bool writeInt64(int code, unsigned long long int data) = 0;
virtual bool writeDouble(int code, double data) = 0;
virtual bool writeBool(int code, bool data) = 0;
void setVersion(std::string *v){encoder.setVersion(v);}
void setCodePage(std::string *c){encoder.setCodePage(c);}
std::string getCodePage(){return encoder.getCodePage();}
protected:
std::ofstream *filestr;
private:
DRW_TextCodec encoder;
};
class dxfWriterBinary : public dxfWriter {
public:
dxfWriterBinary(std::ofstream *stream):dxfWriter(stream){ }
virtual ~dxfWriterBinary() {}
virtual bool writeString(int code, std::string text);
virtual bool writeInt16(int code, int data);
virtual bool writeInt32(int code, int data);
virtual bool writeInt64(int code, unsigned long long int data);
virtual bool writeDouble(int code, double data);
virtual bool writeBool(int code, bool data);
};
class dxfWriterAscii : public dxfWriter {
public:
dxfWriterAscii(std::ofstream *stream):dxfWriter(stream){ }
virtual ~dxfWriterAscii(){}
virtual bool writeString(int code, std::string text);
virtual bool writeInt16(int code, int data);
virtual bool writeInt32(int code, int data);
virtual bool writeInt64(int code, unsigned long long int data);
virtual bool writeDouble(int code, double data);
virtual bool writeBool(int code, bool data);
};
#endif // DXFWRITER_H

3818
lib_dxf/libdxfrw.cpp Normal file

File diff suppressed because it is too large Load Diff

143
lib_dxf/libdxfrw.h Normal file
View File

@ -0,0 +1,143 @@
/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011 Rallaz, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/
#ifndef LIBDXFRW_H
#define LIBDXFRW_H
#include <string>
#include "drw_entities.h"
#include "drw_objects.h"
#include "drw_interface.h"
class dxfReader;
class dxfWriter;
class dxfRW
{
public:
dxfRW( const char* name );
~dxfRW();
// / reads the file specified in constructor
/*!
* An interface must be provided. It is used by the class to signal various
* components being added.
* @param interface_ the interface to use
* @param ext should the extrusion be applied to convert in 2D?
* @return true for success
*/
bool read( DRW_Interface* interface_, bool ext );
void setBinary( bool b ) { binary = b; }
bool write( DRW_Interface* interface_, DRW::Version ver, bool bin );
bool writeLineType( DRW_LType* ent );
bool writeLayer( DRW_Layer* ent );
bool writeDimstyle( DRW_Dimstyle* ent );
bool writeTextstyle( DRW_Textstyle* ent );
bool writeVport( DRW_Vport* ent );
bool writePoint( DRW_Point* ent );
bool writeLine( DRW_Line* ent );
bool writeRay( DRW_Ray* ent );
bool writeXline( DRW_Xline* ent );
bool writeCircle( DRW_Circle* ent );
bool writeArc( DRW_Arc* ent );
bool writeEllipse( DRW_Ellipse* ent );
bool writeTrace( DRW_Trace* ent );
bool writeSolid( DRW_Solid* ent );
bool write3dface( DRW_3Dface* ent );
bool writeLWPolyline( DRW_LWPolyline* ent );
bool writePolyline( DRW_Polyline* ent );
bool writeSpline( DRW_Spline* ent );
bool writeBlockRecord( std::string name );
bool writeBlock( DRW_Block* ent );
bool writeInsert( DRW_Insert* ent );
bool writeMText( DRW_MText* ent );
bool writeText( DRW_Text* ent );
bool writeHatch( DRW_Hatch* ent );
bool writeViewport( DRW_Viewport* ent );
DRW_ImageDef* writeImage( DRW_Image* ent, std::string name );
bool writeLeader( DRW_Leader* ent );
bool writeDimension( DRW_Dimension* ent );
void setEllipseParts( int parts ) { elParts = parts; } /*!< set parts munber when convert ellipse to polyline */
private:
// / used by read() to parse the content of the file
bool processDxf();
bool processHeader();
bool processTables();
bool processBlocks();
bool processBlock();
bool processEntities( bool isblock );
bool processObjects();
bool processLType();
bool processLayer();
bool processDimStyle();
bool processTextStyle();
bool processVports();
bool processPoint();
bool processLine();
bool processRay();
bool processXline();
bool processCircle();
bool processArc();
bool processEllipse();
bool processTrace();
bool processSolid();
bool processInsert();
bool processLWPolyline();
bool processPolyline();
bool processVertex( DRW_Polyline* pl );
bool processText();
bool processMText();
bool processHatch();
bool processSpline();
bool process3dface();
bool processViewport();
bool processImage();
bool processImageDef();
bool processDimension();
bool processLeader();
// bool writeHeader();
bool writeEntity( DRW_Entity* ent );
bool writeTables();
bool writeBlocks();
bool writeObjects();
std::string toHexStr( int n );
private:
DRW::Version version;
std::string fileName;
std::string codePage;
bool binary;
dxfReader* reader;
dxfWriter* writer;
DRW_Interface* iface;
DRW_Header header;
// int section;
string nextentity;
int entCount;
bool wlayer0;
bool dimstyleStd;
bool applyExt;
bool writingBlock;
int elParts; /*!< parts munber when convert ellipse to polyline */
std::map<std::string, int> blockMap;
std::vector<DRW_ImageDef*> imageDef; /*!< imageDef list */
int currHandle;
};
#endif // LIBDXFRW_H

View File

@ -26,6 +26,8 @@ include_directories(
../common
../polygon
../common/dialogs
../lib_dxf
./import_dxf
${INC_AFTER}
)
@ -114,6 +116,11 @@ set( PCBNEW_DIALOGS
dialogs/dialog_footprint_wizard_list.cpp
)
set( PCBNEW_IMPORT_DXF
import_dxf/dialog_dxf_import.cpp
import_dxf/dxf2brd_items.cpp
)
set( PCBNEW_AUTOROUTER_SRCS
autorouter/automove.cpp
autorouter/autoplac.cpp
@ -145,6 +152,7 @@ set( PCBNEW_CLASS_SRCS
cross-probing.cpp
deltrack.cpp
${PCBNEW_DIALOGS}
${PCBNEW_IMPORT_DXF}
dragsegm.cpp
drc.cpp
drc_clearance_test_functions.cpp
@ -347,6 +355,7 @@ if( KICAD_SCRIPTING_MODULES )
pcbcommon
common
pcad2kicadpcb
lib_dxf
${GITHUB_PLUGIN_LIBRARIES}
polygon
bitmaps
@ -515,6 +524,7 @@ target_link_libraries( pcbnew
pcad2kicadpcb
polygon
bitmaps
lib_dxf
${GITHUB_PLUGIN_LIBRARIES}
${wxWidgets_LIBRARIES}
${OPENGL_LIBRARIES}

View File

@ -51,10 +51,9 @@
#include <class_pcb_text.h>
#include <modview_frame.h>
#include <class_pcb_layer_box_selector.h>
#include <dialog_drc.h>
#include <dialog_global_edit_tracks_and_vias.h>
#include <invoke_pcb_dialog.h>
// Handles the selection of command events.
void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
@ -1185,6 +1184,11 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
ArchiveModulesOnBoard( wxEmptyString, false );
break;
case ID_GEN_IMPORT_DXF_FILE:
InvokeDXFDialogImport( this );
m_canvas->Refresh();
break;
default:
wxString msg;
msg.Printf( wxT( "PCB_EDIT_FRAME::Process_Special_Functions() unknown event id %d" ),

View File

@ -0,0 +1,29 @@
#include <dxf2brd_items.h>
#include <wxPcbStruct.h>
#include <convert_from_iu.h>
bool InvokeDXFDialogImport( PCB_EDIT_FRAME* aCaller )
{
wxFileDialog dlg( aCaller,
wxT( "Open File" ),
wxEmptyString, wxEmptyString,
wxT( "dxf Files (*.dxf)|*.dxf|*.DXF" ),
wxFD_OPEN|wxFD_FILE_MUST_EXIST );
dlg.ShowModal();
wxString fileName = dlg.GetPath();
if( !fileName.IsEmpty() )
{
BOARD * brd = aCaller->GetBoard();
DXF2BRD_CONVERTER dxf_importer;
// Set coordinates offset for import (offset is given in mm)
double offsetY = - aCaller->GetPageSizeIU().y * MM_PER_IU;
dxf_importer.SetOffset( 0.0, offsetY );
dxf_importer.SetBrdLayer( DRAW_N );
dxf_importer.ImportDxfFile( fileName, brd );
}
return true;
}

View File

@ -0,0 +1,557 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2013 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
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
// The DXF reader lib (libdxfrw) comes from LibreCAD project, a 2D CAD program
// libdxfrw can be found on http://sourceforge.net/projects/libdxfrw/
// or (latest sources) on
// https://github.com/LibreCAD/LibreCAD/tree/master/libraries/libdxfrw/src
//
// There is no doc to use it, but have a look to
// https://github.com/LibreCAD/LibreCAD/blob/master/librecad/src/lib/filters/rs_filterdxf.cpp
// and https://github.com/LibreCAD/LibreCAD/blob/master/librecad/src/lib/filters/rs_filterdxf.h
// Each time a dxf entity is read, a "call back" fuction is called
// like void DXF2BRD_CONVERTER::addLine( const DRW_Line& data ) when a line is read.
// this function just add the BOARD entity from dxf parameters (start and end point ...)
#include "libdxfrw.h"
#include "dxf2brd_items.h"
#include <wx/arrstr.h>
#include <wx/regex.h>
#include <trigo.h>
#include <class_board.h>
#include <class_drawsegment.h>
#include <class_pcb_text.h>
DXF2BRD_CONVERTER::DXF2BRD_CONVERTER() : DRW_Interface()
{
m_xOffset = 0.0; // X coord offset for conversion (in mm)
m_yOffset = 0.0; // Y coord offset for conversion (in mm)
m_Dfx2mm = 1.0; // The scale factor to convert DXF units to mm
m_dxf = NULL;
m_brd = NULL;
m_version = 0;
m_defaultThickness = 0.1;
m_brdLayer = DRAW_N;
}
DXF2BRD_CONVERTER::~DXF2BRD_CONVERTER()
{
}
// coordinate conversions from dxf to internal units
int DXF2BRD_CONVERTER::mapX( double aDxfCoordX )
{
return Millimeter2iu( m_xOffset + (aDxfCoordX * m_Dfx2mm) );
}
int DXF2BRD_CONVERTER::mapY( double aDxfCoordY )
{
return Millimeter2iu( -m_yOffset - (aDxfCoordY * m_Dfx2mm) );
}
int DXF2BRD_CONVERTER::mapDim( double aDxfValue )
{
return Millimeter2iu( aDxfValue * m_Dfx2mm );
}
/**
* Implementation of the method used for communicate
* with this filter.
*
* @param aFile = the full filename.
* @param aLayersList = where to store the list of layer names
*/
bool DXF2BRD_CONVERTER::ImportDxfFile( const wxString& aFile, BOARD* aBoard )
{
m_brd = aBoard;
m_dxf = new dxfRW( aFile.ToUTF8() );
bool success = m_dxf->read( this, true );
if( success==false )
{
return false;
}
delete m_dxf;
m_dxf = NULL;
return true;
}
/**
* Implementation of the method which handles layers.
*/
void DXF2BRD_CONVERTER::addLayer( const DRW_Layer& data )
{
#if 0
wxString name = wxString::FromUTF8( data.name.c_str() );
wxLogMessage( name );
#endif
}
/*
* Import line entities.
*/
void DXF2BRD_CONVERTER::addLine( const DRW_Line& data )
{
DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd );
segm->SetLayer( m_brdLayer );
wxPoint start( mapX( data.basePoint.x ), mapY( data.basePoint.y ) );
segm->SetStart( start );
wxPoint end( mapX( data.secPoint.x ), mapY( data.secPoint.y ) );
segm->SetEnd( end );
segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness
: data.thickness ) );
m_brd->Add( segm );
}
/*
* Import Circle entities.
*/
void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& data )
{
DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd );
segm->SetLayer( m_brdLayer );
segm->SetShape( S_CIRCLE );
wxPoint center( mapX( data.basePoint.x ), mapY( data.basePoint.y ) );
segm->SetPosition( center );
wxPoint circle_start( mapX( data.basePoint.x + data.radious ),
mapY( data.basePoint.y ) );
segm->SetEnd( circle_start );
segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness
: data.thickness ) );
m_brd->Add( segm );
}
/*
* Import Arc entities.
*/
void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data )
{
DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd );
segm->SetLayer( m_brdLayer );
segm->SetShape( S_ARC );
// Init arc centre:
wxPoint center( mapX( data.basePoint.x ), mapY( data.basePoint.y ) );
segm->SetPosition( center );
// Init arc start point
double arcStartx = data.radious;
double arcStarty = 0;
RotatePoint( &arcStartx, &arcStarty, -RAD2DECIDEG( data.staangle ) );
wxPoint arcStart( mapX( arcStartx + data.basePoint.x ),
mapY( arcStarty + data.basePoint.y ) );
segm->SetEnd( arcStart );
// calculate arc angle (arcs are CCW, and should be < 0 in Pcbnew)
double angle = -RAD2DECIDEG( data.endangle - data.staangle );
if( angle > 0.0 )
angle -= 3600.0;
segm->SetAngle( angle );
segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness
: data.thickness ) );
m_brd->Add( segm );
}
/**
* Import texts (TEXT).
*/
void DXF2BRD_CONVERTER::addText(const DRW_Text& data)
{
TEXTE_PCB* pcb_text = new TEXTE_PCB( m_brd );
pcb_text->SetLayer( m_brdLayer );
wxPoint refPoint( mapX(data.basePoint.x), mapY(data.basePoint.y) );
wxPoint secPoint( mapX(data.secPoint.x), mapY(data.secPoint.y) );
if (data.alignV !=0 || data.alignH !=0 ||data.alignH ==DRW_Text::HMiddle)
{
if (data.alignH !=DRW_Text::HAligned && data.alignH !=DRW_Text::HFit)
{
wxPoint tmp = secPoint;
secPoint = refPoint;
refPoint = tmp;
}
}
switch( data.alignV )
{
case DRW_Text::VBaseLine: // Top
pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
break;
case DRW_Text::VBottom:
pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
break;
case DRW_Text::VMiddle:
pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
break;
case DRW_Text::VTop:
pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
break;
}
switch( data.alignH )
{
case DRW_Text::HLeft:
pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
break;
case DRW_Text::HCenter:
pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
break;
case DRW_Text::HRight:
pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
break;
case DRW_Text::HAligned:
// no equivalent options in text pcb.
pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
break;
case DRW_Text::HMiddle:
// no equivalent options in text pcb.
pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
break;
case DRW_Text::HFit:
// no equivalent options in text pcb.
pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
break;
}
#if 0
wxString sty = wxString::FromUTF8(data.style.c_str());
sty=sty.ToLower();
if (data.textgen==2)
{
// Text dir = left to right;
} else if (data.textgen==4)
{
/ Text dir = top to bottom;
} else
{
}
#endif
wxString text = toNativeString( wxString::FromUTF8( data.text.c_str() ) );
pcb_text->SetTextPosition( refPoint );
pcb_text->SetOrientation( data.angle * 10 );
// The 0.8 factor gives a better height/width ratio with our font
pcb_text->SetWidth( mapDim( data.height * 0.8 ) );
pcb_text->SetHeight( mapDim( data.height ) );
pcb_text->SetThickness( mapDim( data.thickness == 0 ? m_defaultThickness
: data.thickness ) );
pcb_text->SetText( text );
m_brd->Add( pcb_text );
}
/**
* Import multi line texts (MTEXT).
*/
void DXF2BRD_CONVERTER::addMText( const DRW_MText& data )
{
wxString text = toNativeString( wxString::FromUTF8( data.text.c_str() ) );
wxString attrib, tmp;
/* Some texts start by '\' and have formating chars (font name, font option...)
* ending with ';'
* Here are some mtext formatting codes:
* Format code Purpose
* \0...\o Turns overline on and off
* \L...\l Turns underline on and off
* \~ Inserts a nonbreaking space
\\ Inserts a backslash
\\\{...\} Inserts an opening and closing brace
\\ \File name; Changes to the specified font file
\\ \Hvalue; Changes to the text height specified in drawing units
\\ \Hvaluex; Changes the text height to a multiple of the current text height
\\ \S...^...; Stacks the subsequent text at the \, #, or ^ symbol
\\ \Tvalue; Adjusts the space between characters, from.75 to 4 times
\\ \Qangle; Changes obliquing angle
\\ \Wvalue; Changes width factor to produce wide text
\\ \A Sets the alignment value; valid values: 0, 1, 2 (bottom, center, top) while( text.StartsWith( wxT("\\") ) )
*/
while( text.StartsWith( wxT( "\\" ) ) )
{
attrib << text.BeforeFirst( ';' );
tmp = text.AfterFirst( ';' );
text = tmp;
}
TEXTE_PCB* pcb_text = new TEXTE_PCB( m_brd );
pcb_text->SetLayer( m_brdLayer );
wxPoint textpos( mapX( data.basePoint.x ), mapY( data.basePoint.y ) );
pcb_text->SetTextPosition( textpos );
pcb_text->SetOrientation( data.angle * 10 );
// The 0.8 factor gives a better height/width ratio with our font
pcb_text->SetWidth( mapDim( data.height * 0.8 ) );
pcb_text->SetHeight( mapDim( data.height ) );
pcb_text->SetThickness( mapDim( data.thickness == 0 ? m_defaultThickness
: data.thickness ) );
pcb_text->SetText( text );
// Initialize text justifications:
if( data.textgen <= 3 )
{
pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
}
else if( data.textgen <= 6 )
{
pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
}
else
{
pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
}
if( data.textgen % 3 == 1 )
{
pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
}
else if( data.textgen % 3 == 2 )
{
pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
}
else
{
pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
}
#if 0 // These setting have no mening in Pcbnew
if( data.alignH==1 )
{
// Text is left to right;
}
else if( data.alignH == 3 )
{
// Text is top to bottom;
}
else
{
// use ByStyle;
}
if( data.alignV==1 )
{
// use AtLeast;
}
else
{
// useExact;
}
#endif
m_brd->Add( pcb_text );
}
/**
* Sets the header variables from the DXF file.
*/
void DXF2BRD_CONVERTER::addHeader( const DRW_Header* data )
{
std::map<std::string, DRW_Variant*>::const_iterator it;
for( it = data->vars.begin(); it != data->vars.end(); it++ )
{
std::string key = ( (*it).first ).c_str();
if( key == "$DWGCODEPAGE" )
{
DRW_Variant* var = (*it).second;
m_codePage = ( *var->content.s );
}
}
}
/**
* Converts a native unicode string into a DXF encoded string.
*
* DXF endoding includes the following special sequences:
* - %%%c for a diameter sign
* - %%%d for a degree sign
* - %%%p for a plus/minus sign
*/
wxString DXF2BRD_CONVERTER::toDxfString( const wxString& str )
{
wxString res;
int j = 0;
for( unsigned i = 0; i<str.length(); ++i )
{
int c = str[i];
if( c>175 || c<11 )
{
res.append( str.Mid( j, i - j ) );
j = i;
switch( c )
{
case 0x0A:
res += wxT("\\P");
break;
// diameter:
#ifdef __WINDOWS_
// windows, as always, is special.
case 0x00D8:
#else
case 0x2205:
#endif
res += wxT("%%C");
break;
// degree:
case 0x00B0:
res += wxT("%%D");
break;
// plus/minus
case 0x00B1:
res += wxT("%%P");
break;
default:
j--;
break;
}
j++;
}
}
res.append( str.Mid( j ) );
return res;
}
/**
* Converts a DXF encoded string into a native Unicode string.
*/
wxString DXF2BRD_CONVERTER::toNativeString( const wxString& data )
{
wxString res;
// Ignore font tags:
int j = 0;
for( unsigned i = 0; i<data.length(); ++i )
{
if( data[ i ] == 0x7B ) // is '{' ?
{
if( data[ i + 1 ] == 0x5c && data[ i + 2 ] == 0x66 ) // is "\f" ?
{
// found font tag, append parsed part
res.append( data.Mid( j, i - j ) );
// skip to ';'
for( unsigned k = i + 3; k < data.length(); ++k )
{
if( data[ k ] == 0x3B )
{
i = j = ++k;
break;
}
}
// add to '}'
for( unsigned k = i; k<data.length(); ++k )
{
if( data[ k ] == 0x7D )
{
res.append( data.Mid( i, k - i ) );
i = j = ++k;
break;
}
}
}
}
}
res.append( data.Mid( j ) );
#if 1
wxRegEx regexp;
// Line feed:
regexp.Compile( wxT( "\\\\P" ) );
regexp.Replace( &res, wxT( "\n" ) );
// Space:
regexp.Compile( wxT( "\\\\~" ) );
regexp.Replace( &res, wxT( " " ) );
// diameter:
regexp.Compile( wxT( "%%[cC]" ) );
#ifdef __WINDOWS__
// windows, as always, is special.
regexp.Replace( &res, wxChar( 0xD8 ) );
#else
// Empty_set, diameter is 0x2300
regexp.Replace( &res, wxChar( 0x2205 ) );
#endif
// degree:
regexp.Compile( wxT( "%%[dD]" ) );
regexp.Replace( &res, wxChar( 0x00B0 ) );
// plus/minus
regexp.Compile( wxT( "%%[pP]" ) );
regexp.Replace( &res, wxChar( 0x00B1 ) );
#endif
return res;
}
void DXF2BRD_CONVERTER::addTextStyle( const DRW_Textstyle& data )
{
// TODO
}

View File

@ -0,0 +1,155 @@
/****************************************************************************
**
** This file comes from the LibreCAD project, a 2D CAD program
**
** Copyright (C) 2011 Rallaz, rallazz@gmail.com
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License as published by the Free Software
** Foundation either version 2 of the License, or (at your option)
** any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
**
**********************************************************************/
#ifndef FILTERDXFRW_H
#define FILTERDXFRW_H
#include "drw_interface.h"
#include "wx/wx.h"
class dxfRW;
class BOARD;
/**
* This format filter class can import and export DXF files.
* It depends on the dxflib library.
*
* @author Rallaz
*/
class DXF2BRD_CONVERTER : public DRW_Interface
{
private:
BOARD * m_brd;
double m_xOffset; // X coord offset for conversion (in mm)
double m_yOffset; // Y coord offset for conversion (in mm)
double m_defaultThickness; // default line thickness for conversion (in dxf units)
double m_Dfx2mm; // The scale factor to convert DXF units to mm
int m_brdLayer; // The board layer to place imported dfx items
int m_version;
std::string m_codePage;
dxfRW* m_dxf;
public:
DXF2BRD_CONVERTER();
~DXF2BRD_CONVERTER();
/**
* Set the coordinate offset between the importede dxf items
* and Pcbnew.
* because dxf files have the Y axis from bottom to top;
* aOffsetX = 0, and aOffsetY = - vertical page size to import a full page
* @param aOffsetX = the X offset in mm
* @param aOffsetY = the Y offset in mm
*/
void SetOffset( double aOffsetX, double aOffsetY )
{
m_xOffset =aOffsetX;
m_yOffset =aOffsetY;
}
/**
* Set the layer number to import dxf items.
* the layer should be a techicanl layer, not a copper layer
*/
void SetBrdLayer( int aBrdLayer ) { m_brdLayer = aBrdLayer; }
bool ImportDxfFile( const wxString& aFile, BOARD * aBoard );
private:
// coordinate conversions from dxf to internal units
int mapX( double aDxfCoordX );
int mapY( double aDxfCoordY );
int mapDim( double aDxfValue );
// Methods from DRW_CreationInterface:
// They are "call back" fonctions, called when the corresponding object
// is read in dxf file
// Depending of the application, they can do something or not
virtual void addHeader( const DRW_Header* data );
virtual void addLType( const DRW_LType& data ){}
virtual void addLayer( const DRW_Layer& data );
virtual void addDimStyle( const DRW_Dimstyle& data ){}
virtual void addBlock(const DRW_Block& data ){}
virtual void endBlock(){}
virtual void addPoint(const DRW_Point& data ){}
virtual void addLine(const DRW_Line& data);
virtual void addRay(const DRW_Ray& data ){}
virtual void addXline(const DRW_Xline& data ){}
virtual void addCircle(const DRW_Circle& data );
virtual void addArc(const DRW_Arc& data );
virtual void addEllipse(const DRW_Ellipse& data ){}
virtual void addLWPolyline(const DRW_LWPolyline& data ){}
virtual void addText(const DRW_Text& data );
virtual void addPolyline(const DRW_Polyline& data ){}
virtual void addSpline(const DRW_Spline* data ){}
virtual void addKnot(const DRW_Entity&) {}
virtual void addInsert(const DRW_Insert& data ){}
virtual void addTrace(const DRW_Trace& data ){}
virtual void addSolid(const DRW_Solid& data ){}
virtual void addMText(const DRW_MText& data);
virtual void addDimAlign(const DRW_DimAligned *data ){}
virtual void addDimLinear(const DRW_DimLinear *data ){}
virtual void addDimRadial(const DRW_DimRadial *data ){}
virtual void addDimDiametric(const DRW_DimDiametric *data ){}
virtual void addDimAngular(const DRW_DimAngular *data ){}
virtual void addDimAngular3P(const DRW_DimAngular3p *data ){}
virtual void addDimOrdinate(const DRW_DimOrdinate *data ){}
virtual void addLeader(const DRW_Leader *data ){}
virtual void addHatch(const DRW_Hatch* data ){}
virtual void addImage(const DRW_Image* data ){}
virtual void linkImage(const DRW_ImageDef* data ){}
virtual void add3dFace(const DRW_3Dface& data ){}
virtual void addComment(const char*){}
virtual void addVport(const DRW_Vport& data) {}
virtual void addTextStyle(const DRW_Textstyle& data);
virtual void addViewport(const DRW_Viewport& data) {}
virtual void setBlock(const int handle) {}
static wxString toDxfString(const wxString& str);
static wxString toNativeString(const wxString& data);
// These functions are not used in Kicad.
// But because they are virtual pure in DRW_Interface, they should be defined
virtual void writeTextstyles() {}
virtual void writeVports() {}
virtual void writeHeader(DRW_Header& data) {}
virtual void writeEntities() {}
virtual void writeLTypes() {}
virtual void writeLayers() {}
virtual void writeBlockRecords() {}
virtual void writeBlocks() {}
virtual void writeDimstyles() {}
void writeLine();
void writeMtext();
};
#endif // FILTERDXFRW_H

View File

@ -1,6 +1,8 @@
/**
* @file invoke_pcb_dialog.h
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
/* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2013 KiCad Developers, see change_log.txt for contributors.
@ -75,5 +77,14 @@ int InvokePcbLibTableEditor( wxTopLevelWindow* aCaller, FP_LIB_TABLE* aGlobal, F
void InvokePluginOptionsEditor( wxTopLevelWindow* aCaller,
const wxString& aNickname, const wxString& aOptions, wxString* aResult );
/**
* Function InvokePcbLibTableEditor
* shows the modal DIALOG_FP_LIB_TABLE for purposes of editing two lib tables.
*
* @param aCaller is the wxTopLevelWindow which is invoking the dialog.
* @return true if the ilport was made.
*/
bool InvokeDXFDialogImport( PCB_EDIT_FRAME* aCaller );
#endif // INVOKE_A_DIALOG_H_

View File

@ -174,6 +174,11 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
_( "Import a routed \"Specctra Session\" (*.ses) file" ),
KiBitmap( import_xpm ) );
AddMenuItem( submenuImport, ID_GEN_IMPORT_DXF_FILE,
_( "&DXF File" ),
_( "Import a 2D Drawing DXF file to Pcbnew on the Drawings layer" ),
KiBitmap( import_xpm ) );
AddMenuItem( filesMenu, submenuImport,
ID_GEN_IMPORT_FILE, _( "&Import" ),
_( "Import files" ), KiBitmap( import_xpm ) );

View File

@ -105,6 +105,7 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_MENU( ID_GEN_IMPORT_SPECCTRA_SESSION,PCB_EDIT_FRAME::ImportSpecctraSession )
EVT_MENU( ID_GEN_IMPORT_SPECCTRA_DESIGN, PCB_EDIT_FRAME::ImportSpecctraDesign )
EVT_MENU( ID_GEN_IMPORT_DXF_FILE, PCB_EDIT_FRAME::Process_Special_Functions )
EVT_MENU( ID_MENU_ARCHIVE_NEW_MODULES, PCB_EDIT_FRAME::Process_Special_Functions )
EVT_MENU( ID_MENU_ARCHIVE_ALL_MODULES, PCB_EDIT_FRAME::Process_Special_Functions )

View File

@ -252,6 +252,7 @@ enum pcbnew_ids
ID_GEN_EXPORT_FILE_MODULE_REPORT,
ID_GEN_IMPORT_SPECCTRA_SESSION,
ID_GEN_IMPORT_SPECCTRA_DESIGN,
ID_GEN_IMPORT_DXF_FILE,
ID_TOOLBARH_PCB_MODE_MODULE,
ID_TOOLBARH_PCB_MODE_TRACKS,