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