You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

553 lines
18 KiB

  1. /****************************************************************************
  2. ** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
  3. **
  4. ** This file is part of the dxflib project.
  5. **
  6. ** This file is free software; you can redistribute it and/or modify
  7. ** it under the terms of the GNU General Public License as published by
  8. ** the Free Software Foundation; either version 2 of the License, or
  9. ** (at your option) any later version.
  10. **
  11. ** Licensees holding valid dxflib Professional Edition licenses may use
  12. ** this file in accordance with the dxflib Commercial License
  13. ** Agreement provided with the Software.
  14. **
  15. ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  16. ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  17. **
  18. ** See http://www.ribbonsoft.com for further details.
  19. **
  20. ** Contact info@ribbonsoft.com if any conditions of this licensing are
  21. ** not clear to you.
  22. **
  23. **********************************************************************/
  24. #ifndef DL_DXF_H
  25. #define DL_DXF_H
  26. #include "dl_global.h"
  27. #include <limits>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string>
  31. #include <sstream>
  32. #include <map>
  33. #include "dl_attributes.h"
  34. #include "dl_codes.h"
  35. #include "dl_entities.h"
  36. #include "dl_writer_ascii.h"
  37. #ifdef _WIN32
  38. #undef M_PI
  39. #define M_PI 3.14159265358979323846
  40. #endif
  41. #ifndef M_PI
  42. #define M_PI 3.1415926535897932384626433832795
  43. #endif
  44. #ifndef DL_NANDOUBLE
  45. #define DL_NANDOUBLE std::numeric_limits<double>::quiet_NaN()
  46. #endif
  47. class DL_CreationInterface;
  48. class DL_WriterA;
  49. #define DL_VERSION "3.26.4.0"
  50. #define DL_VERSION_MAJOR 3
  51. #define DL_VERSION_MINOR 26
  52. #define DL_VERSION_REV 4
  53. #define DL_VERSION_BUILD 0
  54. #define DL_UNKNOWN 0
  55. #define DL_LAYER 10
  56. #define DL_BLOCK 11
  57. #define DL_ENDBLK 12
  58. #define DL_LINETYPE 13
  59. #define DL_STYLE 20
  60. #define DL_SETTING 50
  61. #define DL_ENTITY_POINT 100
  62. #define DL_ENTITY_LINE 101
  63. #define DL_ENTITY_POLYLINE 102
  64. #define DL_ENTITY_LWPOLYLINE 103
  65. #define DL_ENTITY_VERTEX 104
  66. #define DL_ENTITY_SPLINE 105
  67. #define DL_ENTITY_KNOT 106
  68. #define DL_ENTITY_CONTROLPOINT 107
  69. #define DL_ENTITY_ARC 108
  70. #define DL_ENTITY_CIRCLE 109
  71. #define DL_ENTITY_ELLIPSE 110
  72. #define DL_ENTITY_INSERT 111
  73. #define DL_ENTITY_TEXT 112
  74. #define DL_ENTITY_MTEXT 113
  75. #define DL_ENTITY_DIMENSION 114
  76. #define DL_ENTITY_LEADER 115
  77. #define DL_ENTITY_HATCH 116
  78. #define DL_ENTITY_ATTRIB 117
  79. #define DL_ENTITY_IMAGE 118
  80. #define DL_ENTITY_IMAGEDEF 119
  81. #define DL_ENTITY_TRACE 120
  82. #define DL_ENTITY_SOLID 121
  83. #define DL_ENTITY_3DFACE 122
  84. #define DL_ENTITY_XLINE 123
  85. #define DL_ENTITY_RAY 124
  86. #define DL_ENTITY_ARCALIGNEDTEXT 125
  87. #define DL_ENTITY_SEQEND 126
  88. #define DL_XRECORD 200
  89. #define DL_DICTIONARY 210
  90. /**
  91. * Reading and writing of DXF files.
  92. *
  93. * This class can read in a DXF file and calls methods from the
  94. * interface DL_EntityContainer to add the entities to the
  95. * contianer provided by the user of the library.
  96. *
  97. * It can also be used to write DXF files to a certain extent.
  98. *
  99. * When saving entities, special values for colors and linetypes
  100. * can be used:
  101. *
  102. * Special colors are 0 (=BYBLOCK) and 256 (=BYLAYER).
  103. * Special linetypes are "BYLAYER" and "BYBLOCK".
  104. *
  105. * @author Andrew Mustun
  106. */
  107. class DXFLIB_EXPORT DL_Dxf
  108. {
  109. public:
  110. DL_Dxf();
  111. ~DL_Dxf();
  112. bool in( FILE* fp, DL_CreationInterface* creationInterface );
  113. bool in( const std::string& file, DL_CreationInterface* creationInterface );
  114. bool readDxfGroups( FILE* fp, DL_CreationInterface* creationInterface );
  115. static bool getStrippedLine( std::string& s, unsigned int size,
  116. FILE* stream, bool stripSpace = true );
  117. bool readDxfGroups( std::istream& stream,
  118. DL_CreationInterface* creationInterface );
  119. bool in( std::istream& stream,
  120. DL_CreationInterface* creationInterface );
  121. static bool getStrippedLine( std::string& s, unsigned int size,
  122. std::istream& stream, bool stripSpace = true );
  123. static bool stripWhiteSpace( char** s, bool stripSpaces = true );
  124. bool processDXFGroup( DL_CreationInterface* creationInterface,
  125. int groupCode, const std::string& groupValue );
  126. void addSetting( DL_CreationInterface* creationInterface );
  127. void addLayer( DL_CreationInterface* creationInterface );
  128. void addLinetype( DL_CreationInterface* creationInterface );
  129. void addBlock( DL_CreationInterface* creationInterface );
  130. void endBlock( DL_CreationInterface* creationInterface );
  131. void addTextStyle( DL_CreationInterface* creationInterface );
  132. void addPoint( DL_CreationInterface* creationInterface );
  133. void addLine( DL_CreationInterface* creationInterface );
  134. void addXLine( DL_CreationInterface* creationInterface );
  135. void addRay( DL_CreationInterface* creationInterface );
  136. void addPolyline( DL_CreationInterface* creationInterface );
  137. void addVertex( DL_CreationInterface* creationInterface );
  138. void addSpline( DL_CreationInterface* creationInterface );
  139. void addArc( DL_CreationInterface* creationInterface );
  140. void addCircle( DL_CreationInterface* creationInterface );
  141. void addEllipse( DL_CreationInterface* creationInterface );
  142. void addInsert( DL_CreationInterface* creationInterface );
  143. void addTrace( DL_CreationInterface* creationInterface );
  144. void add3dFace( DL_CreationInterface* creationInterface );
  145. void addSolid( DL_CreationInterface* creationInterface );
  146. void addMText( DL_CreationInterface* creationInterface );
  147. void addText( DL_CreationInterface* creationInterface );
  148. void addArcAlignedText( DL_CreationInterface* creationInterface );
  149. void addAttribute( DL_CreationInterface* creationInterface );
  150. DL_DimensionData getDimData();
  151. void addDimLinear( DL_CreationInterface* creationInterface );
  152. void addDimAligned( DL_CreationInterface* creationInterface );
  153. void addDimRadial( DL_CreationInterface* creationInterface );
  154. void addDimDiametric( DL_CreationInterface* creationInterface );
  155. void addDimAngular( DL_CreationInterface* creationInterface );
  156. void addDimAngular3P( DL_CreationInterface* creationInterface );
  157. void addDimOrdinate( DL_CreationInterface* creationInterface );
  158. void addLeader( DL_CreationInterface* creationInterface );
  159. void addHatch( DL_CreationInterface* creationInterface );
  160. void addHatchLoop();
  161. void addHatchEdge();
  162. bool handleHatchData( DL_CreationInterface* creationInterface );
  163. void addImage( DL_CreationInterface* creationInterface );
  164. void addImageDef( DL_CreationInterface* creationInterface );
  165. void addComment( DL_CreationInterface* creationInterface, const std::string& comment );
  166. void addDictionary( DL_CreationInterface* creationInterface );
  167. void addDictionaryEntry( DL_CreationInterface* creationInterface );
  168. bool handleXRecordData( DL_CreationInterface* creationInterface );
  169. bool handleDictionaryData( DL_CreationInterface* creationInterface );
  170. bool handleXData( DL_CreationInterface* creationInterface );
  171. bool handleMTextData( DL_CreationInterface* creationInterface );
  172. bool handleLWPolylineData( DL_CreationInterface* creationInterface );
  173. bool handleSplineData( DL_CreationInterface* creationInterface );
  174. bool handleLeaderData( DL_CreationInterface* creationInterface );
  175. bool handleLinetypeData( DL_CreationInterface* creationInterface );
  176. void endEntity( DL_CreationInterface* creationInterface );
  177. void endSequence( DL_CreationInterface* creationInterface );
  178. // int stringToInt(const char* s, bool* ok=NULL);
  179. DL_WriterA* out( const char* file,
  180. DL_Codes::version version = DL_VERSION_2000 );
  181. void writeHeader( DL_WriterA& dw );
  182. void writePoint( DL_WriterA& dw,
  183. const DL_PointData& data,
  184. const DL_Attributes& attrib );
  185. void writeLine( DL_WriterA& dw,
  186. const DL_LineData& data,
  187. const DL_Attributes& attrib );
  188. void writeXLine( DL_WriterA& dw,
  189. const DL_XLineData& data,
  190. const DL_Attributes& attrib );
  191. void writeRay( DL_WriterA& dw,
  192. const DL_RayData& data,
  193. const DL_Attributes& attrib );
  194. void writePolyline( DL_WriterA& dw,
  195. const DL_PolylineData& data,
  196. const DL_Attributes& attrib );
  197. void writeVertex( DL_WriterA& dw,
  198. const DL_VertexData& data );
  199. void writePolylineEnd( DL_WriterA& dw );
  200. void writeSpline( DL_WriterA& dw,
  201. const DL_SplineData& data,
  202. const DL_Attributes& attrib );
  203. void writeControlPoint( DL_WriterA& dw,
  204. const DL_ControlPointData& data );
  205. void writeFitPoint( DL_WriterA& dw,
  206. const DL_FitPointData& data );
  207. void writeKnot( DL_WriterA& dw,
  208. const DL_KnotData& data );
  209. void writeCircle( DL_WriterA& dw,
  210. const DL_CircleData& data,
  211. const DL_Attributes& attrib );
  212. void writeArc( DL_WriterA& dw,
  213. const DL_ArcData& data,
  214. const DL_Attributes& attrib );
  215. void writeEllipse( DL_WriterA& dw,
  216. const DL_EllipseData& data,
  217. const DL_Attributes& attrib );
  218. void writeSolid( DL_WriterA& dw,
  219. const DL_SolidData& data,
  220. const DL_Attributes& attrib );
  221. void writeTrace( DL_WriterA& dw,
  222. const DL_TraceData& data,
  223. const DL_Attributes& attrib );
  224. void write3dFace( DL_WriterA& dw,
  225. const DL_3dFaceData& data,
  226. const DL_Attributes& attrib );
  227. void writeInsert( DL_WriterA& dw,
  228. const DL_InsertData& data,
  229. const DL_Attributes& attrib );
  230. void writeMText( DL_WriterA& dw,
  231. const DL_MTextData& data,
  232. const DL_Attributes& attrib );
  233. void writeText( DL_WriterA& dw,
  234. const DL_TextData& data,
  235. const DL_Attributes& attrib );
  236. void writeAttribute( DL_WriterA& dw,
  237. const DL_AttributeData& data,
  238. const DL_Attributes& attrib );
  239. void writeDimStyleOverrides( DL_WriterA& dw,
  240. const DL_DimensionData& data );
  241. void writeDimAligned( DL_WriterA& dw,
  242. const DL_DimensionData& data,
  243. const DL_DimAlignedData& edata,
  244. const DL_Attributes& attrib );
  245. void writeDimLinear( DL_WriterA& dw,
  246. const DL_DimensionData& data,
  247. const DL_DimLinearData& edata,
  248. const DL_Attributes& attrib );
  249. void writeDimRadial( DL_WriterA& dw,
  250. const DL_DimensionData& data,
  251. const DL_DimRadialData& edata,
  252. const DL_Attributes& attrib );
  253. void writeDimDiametric( DL_WriterA& dw,
  254. const DL_DimensionData& data,
  255. const DL_DimDiametricData& edata,
  256. const DL_Attributes& attrib );
  257. void writeDimAngular2L( DL_WriterA& dw,
  258. const DL_DimensionData& data,
  259. const DL_DimAngular2LData& edata,
  260. const DL_Attributes& attrib );
  261. void writeDimAngular3P( DL_WriterA& dw,
  262. const DL_DimensionData& data,
  263. const DL_DimAngular3PData& edata,
  264. const DL_Attributes& attrib );
  265. void writeDimOrdinate( DL_WriterA& dw,
  266. const DL_DimensionData& data,
  267. const DL_DimOrdinateData& edata,
  268. const DL_Attributes& attrib );
  269. void writeLeader( DL_WriterA& dw,
  270. const DL_LeaderData& data,
  271. const DL_Attributes& attrib );
  272. void writeLeaderVertex( DL_WriterA& dw,
  273. const DL_LeaderVertexData& data );
  274. void writeLeaderEnd( DL_WriterA& dw,
  275. const DL_LeaderData& data );
  276. void writeHatch1( DL_WriterA& dw,
  277. const DL_HatchData& data,
  278. const DL_Attributes& attrib );
  279. void writeHatch2( DL_WriterA& dw,
  280. const DL_HatchData& data,
  281. const DL_Attributes& attrib );
  282. void writeHatchLoop1( DL_WriterA& dw,
  283. const DL_HatchLoopData& data );
  284. void writeHatchLoop2( DL_WriterA& dw,
  285. const DL_HatchLoopData& data );
  286. void writeHatchEdge( DL_WriterA& dw,
  287. const DL_HatchEdgeData& data );
  288. unsigned int writeImage( DL_WriterA& dw,
  289. const DL_ImageData& data,
  290. const DL_Attributes& attrib );
  291. void writeImageDef( DL_WriterA& dw, int handle,
  292. const DL_ImageData& data );
  293. void writeLayer( DL_WriterA& dw,
  294. const DL_LayerData& data,
  295. const DL_Attributes& attrib );
  296. void writeLinetype( DL_WriterA& dw,
  297. const DL_LinetypeData& data );
  298. void writeAppid( DL_WriterA& dw, const std::string& name );
  299. void writeBlock( DL_WriterA& dw,
  300. const DL_BlockData& data );
  301. void writeEndBlock( DL_WriterA& dw, const std::string& name );
  302. void writeVPort( DL_WriterA& dw );
  303. void writeStyle( DL_WriterA& dw, const DL_StyleData& style );
  304. void writeView( DL_WriterA& dw );
  305. void writeUcs( DL_WriterA& dw );
  306. void writeDimStyle( DL_WriterA& dw,
  307. double dimasz, double dimexe, double dimexo,
  308. double dimgap, double dimtxt,
  309. int dimtad = 1, bool dimtih = false );
  310. void writeBlockRecord( DL_WriterA& dw );
  311. void writeBlockRecord( DL_WriterA& dw, const std::string& name );
  312. void writeObjects( DL_WriterA& dw, const std::string& appDictionaryName = "" );
  313. void writeAppDictionary( DL_WriterA& dw );
  314. unsigned int writeDictionaryEntry( DL_WriterA& dw, const std::string& name );
  315. void writeXRecord( DL_WriterA& dw, int handle, int value );
  316. void writeXRecord( DL_WriterA& dw, int handle, double value );
  317. void writeXRecord( DL_WriterA& dw, int handle, bool value );
  318. void writeXRecord( DL_WriterA& dw, int handle, const std::string& value );
  319. void writeObjectsEnd( DL_WriterA& dw );
  320. void writeComment( DL_WriterA& dw, const std::string& comment );
  321. /**
  322. * Converts the given string into a double or returns the given
  323. * default valud (def) if value is NULL or empty.
  324. */
  325. // static double toReal(const char* value, double def=0.0);
  326. /**
  327. * Converts the given string into an int or returns the given
  328. * default valud (def) if value is NULL or empty.
  329. */
  330. // static int toInt(const char* value, int def=0) {
  331. // if (value!=NULL && value[0] != '\0') {
  332. // return atoi(value);
  333. // }
  334. // return def;
  335. // }
  336. /**
  337. * Converts the given string into a string or returns the given
  338. * default valud (def) if value is NULL or empty.
  339. */
  340. // static const char* toString(const char* value, const char* def="") {
  341. // if (value!=NULL && value[0] != '\0') {
  342. // return value;
  343. // } else {
  344. // return def;
  345. // }
  346. // }
  347. static bool checkVariable( const char* var, DL_Codes::version version );
  348. DL_Codes::version getVersion()
  349. {
  350. return version;
  351. }
  352. int getLibVersion( const std::string& str );
  353. static void test();
  354. bool hasValue( int code )
  355. {
  356. return values.count( code )==1;
  357. }
  358. int getIntValue( int code, int def )
  359. {
  360. if( !hasValue( code ) )
  361. {
  362. return def;
  363. }
  364. return toInt( values[code] );
  365. }
  366. int toInt( const std::string& str )
  367. {
  368. char* p;
  369. return strtol( str.c_str(), &p, 10 );
  370. }
  371. int getInt16Value( int code, int def )
  372. {
  373. if( !hasValue( code ) )
  374. {
  375. return def;
  376. }
  377. return toInt16( values[code] );
  378. }
  379. int toInt16( const std::string& str )
  380. {
  381. char* p;
  382. return strtol( str.c_str(), &p, 16 );
  383. }
  384. bool toBool( const std::string& str )
  385. {
  386. char* p;
  387. return (bool) strtol( str.c_str(), &p, 10 );
  388. }
  389. std::string getStringValue( int code, const std::string& def )
  390. {
  391. if( !hasValue( code ) )
  392. {
  393. return def;
  394. }
  395. return values[code];
  396. }
  397. double getRealValue( int code, double def )
  398. {
  399. if( !hasValue( code ) )
  400. {
  401. return def;
  402. }
  403. return toReal( values[code] );
  404. }
  405. double toReal( const std::string& str )
  406. {
  407. double ret;
  408. // make sure the real value uses '.' not ',':
  409. std::string str2 = str;
  410. std::replace( str2.begin(), str2.end(), ',', '.' );
  411. // make sure c++ expects '.' not ',':
  412. std::istringstream istr( str2 );
  413. // istr.imbue(std::locale("C"));
  414. istr >> ret;
  415. return ret;
  416. }
  417. private:
  418. DL_Codes::version version;
  419. std::string polylineLayer;
  420. double* vertices;
  421. int maxVertices;
  422. int vertexIndex;
  423. double* knots;
  424. int maxKnots;
  425. int knotIndex;
  426. double* weights;
  427. int weightIndex;
  428. double* controlPoints;
  429. int maxControlPoints;
  430. int controlPointIndex;
  431. double* fitPoints;
  432. int maxFitPoints;
  433. int fitPointIndex;
  434. double* leaderVertices;
  435. int maxLeaderVertices;
  436. int leaderVertexIndex;
  437. bool firstHatchLoop;
  438. DL_HatchEdgeData hatchEdge;
  439. std::vector<std::vector<DL_HatchEdgeData> > hatchEdges;
  440. std::string xRecordHandle;
  441. bool xRecordValues;
  442. // Only the useful part of the group code
  443. std::string groupCodeTmp;
  444. // ...same as integer
  445. unsigned int groupCode;
  446. // Only the useful part of the group value
  447. std::string groupValue;
  448. // Current entity type
  449. int currentObjectType;
  450. // Value of the current setting
  451. char settingValue[DL_DXF_MAXLINE + 1];
  452. // Key of the current setting (e.g. "$ACADVER")
  453. std::string settingKey;
  454. // Stores the group codes
  455. std::map<int, std::string> values;
  456. // First call of this method. We initialize all group values in
  457. // the first call.
  458. bool firstCall;
  459. // Attributes of the current entity (layer, color, width, line type)
  460. DL_Attributes attrib;
  461. // library version. hex: 0x20003001 = 2.0.3.1
  462. int libVersion;
  463. // app specific dictionary handle:
  464. unsigned long appDictionaryHandle;
  465. // handle of standard text style, referenced by dimstyle:
  466. unsigned long styleHandleStd;
  467. };
  468. #endif
  469. // EOF