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