]> Shamusworld >> Repos - architektonas/blob - dxflib/src/dl_writer.h
Refactored CAD tool bars to use predefined actions.
[architektonas] / dxflib / src / dl_writer.h
1 /****************************************************************************
2 ** $Id: dl_writer.h 2398 2005-06-06 18:12:14Z andrew $
3 **
4 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
5 ** Copyright (C) 2001 Robert J. Campbell Jr.
6 **
7 ** This file is part of the dxflib project.
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file LICENSE.GPL included in the
12 ** packaging of this file.
13 **
14 ** Licensees holding valid dxflib Professional Edition licenses may use 
15 ** this file in accordance with the dxflib Commercial License
16 ** Agreement provided with the Software.
17 **
18 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
19 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 **
21 ** See http://www.ribbonsoft.com for further details.
22 **
23 ** Contact info@ribbonsoft.com if any conditions of this licensing are
24 ** not clear to you.
25 **
26 **********************************************************************/
27
28 #ifndef DL_WRITER_H
29 #define DL_WRITER_H
30
31 #if _MSC_VER > 1000
32 #pragma once
33 #endif // _MSC_VER > 1000
34
35 #if defined(__OS2__)||defined(__EMX__)||defined(_WIN32)
36 #define strcasecmp(s,t) stricmp(s,t)
37 #endif
38
39 #include <iostream>
40 #include <string.h>
41
42 #include "dl_attributes.h"
43 #include "dl_codes.h"
44
45
46
47 /**
48  * Defines interface for writing low level DXF constructs to
49  * a file. Implementation is defined in derived classes that write
50  * to binary or ASCII files.
51  * 
52  * Implements functions that write higher level constructs in terms of
53  * the low level ones.
54  *
55  * @todo Add error checking for string/entry length.
56  */
57 class DL_Writer {
58 public:
59     /**
60      * @para version DXF version. Defaults to VER_2002.
61      */
62     DL_Writer(DL_Codes::version version) : m_handle(0x30) {
63         this->version = version;
64         modelSpaceHandle = 0;
65         paperSpaceHandle = 0;
66         paperSpace0Handle = 0;
67     }
68
69     virtual ~DL_Writer() {}
70     ;
71
72     /** Generic section for section 'name'.
73      *
74      * <pre>
75      *   0
76      *  SECTION
77      *   2
78      *  name
79      * </pre>
80      */
81     void section(const char* name) const {
82         dxfString(0, "SECTION");
83         dxfString(2, name);
84     }
85
86     /**
87      * Section HEADER
88      *
89      * <pre>
90      *   0
91      *  SECTION
92      *   2
93      *  HEADER
94      * </pre>
95      */
96     void sectionHeader() const {
97         section("HEADER");
98     }
99
100     /**
101      * Section TABLES
102      *
103      * <pre>
104      *   0
105      *  SECTION
106      *   2
107      *  TABLES
108      * </pre>
109      */
110     void sectionTables() const {
111         section("TABLES");
112     }
113
114     /**
115      * Section BLOCKS
116      *
117      * <pre>
118      *   0
119      *  SECTION
120      *   2
121      *  BLOCKS
122      * </pre>
123      */
124     void sectionBlocks() const {
125         section("BLOCKS");
126     }
127
128     /**
129      * Section ENTITIES
130      *
131      * <pre>
132      *   0
133      *  SECTION
134      *   2
135      *  ENTITIES
136      * </pre>
137      */
138     void sectionEntities() const {
139         section("ENTITIES");
140     }
141
142     /**
143      * Section CLASSES
144      *
145      * <pre>
146      *   0
147      *  SECTION
148      *   2
149      *  CLASSES
150      * </pre>
151      */
152     void sectionClasses() const {
153         section("CLASSES");
154     }
155
156     /**
157      * Section OBJECTS
158      *
159      * <pre>
160      *   0
161      *  SECTION
162      *   2
163      *  OBJECTS
164      * </pre>
165      */
166     void sectionObjects() const {
167         section("OBJECTS");
168     }
169
170     /**
171      * End of a section.
172      *
173      * <pre>
174      *   0
175      *  ENDSEC
176      * </pre>
177      */
178     void sectionEnd() const {
179         dxfString(0, "ENDSEC");
180     }
181
182     /**
183      * Generic table for table 'name' with 'num' entries:
184      *
185      * <pre>
186      *   0
187      *  TABLE
188      *   2
189      *  name
190      *  70
191      *   num
192      * </pre>
193      */
194     void table(const char* name, int num, int handle) const {
195         dxfString(0, "TABLE");
196         dxfString(2, name);
197         if (version>=VER_2000) {
198             dxfHex(5, handle);
199             dxfString(100, "AcDbSymbolTable");
200         }
201         dxfInt(70, num);
202     }
203
204     /** Table for layers.
205      *
206      * @param num Number of layers in total.
207      *
208      * <pre>
209      *   0
210      *  TABLE
211      *   2
212      *  LAYER
213      *   70
214      *      num
215      * </pre>
216      */
217     void tableLayers(int num) const {
218         table("LAYER", num, 2);
219     }
220
221     /** Table for line types.
222      *
223      * @param num Number of line types in total.
224      *
225      * <pre>
226      *   0
227      *  TABLE
228      *   2
229      *  LTYPE
230      *   70
231      *      num
232      * </pre>
233      */
234     void tableLineTypes(int num) const {
235         //lineTypeHandle = 5;
236         table("LTYPE", num, 5);
237     }
238
239     /** Table for application id.
240      *
241      * @param num Number of registered applications in total.
242      *
243      * <pre>
244      *   0
245      *  TABLE
246      *   2
247      *  APPID
248      *   70
249      *      num
250      * </pre>
251      */
252     void tableAppid(int num) const {
253         table("APPID", num, 9);
254     }
255
256     /**
257      * End of a table.
258      *
259      * <pre>
260      *   0
261      *  ENDTAB
262      * </pre>
263      */
264     void tableEnd() const {
265         dxfString(0, "ENDTAB");
266     }
267
268     /**
269      * End of the DXF file.
270      *
271      * <pre>
272      *   0
273      *  EOF
274      * </pre>
275      */
276     void dxfEOF() const {
277         dxfString(0, "EOF");
278     }
279
280     /**
281      * Comment.
282      *
283      * <pre>
284      *  999
285      *  text
286      * </pre>
287      */
288     void comment(const char* text) const {
289         dxfString(999, text);
290     }
291
292     /**
293      * Entity.
294      *
295      * <pre>
296      *   0
297      *  entTypeName
298      * </pre>
299          *
300          * @return Unique handle or 0.
301      */
302     void entity(const char* entTypeName) const {
303         dxfString(0, entTypeName);
304         if (version>=VER_2000) {
305             handle();
306         }
307     }
308
309     /**
310      * Attributes of an entity.
311      *
312      * <pre>
313      *   8
314      *  layer
315      *  62
316      *  color
317      *  39
318      *  width
319      *   6
320      *  linetype
321      * </pre>
322      */
323     void entityAttributes(const DL_Attributes& attrib) const {
324         
325                 // layer name:
326         dxfString(8, attrib.getLayer());
327                 
328                 // R12 doesn't accept BYLAYER values. The value has to be missing
329                 //   in that case.
330         if (version>=VER_2000 || 
331                         attrib.getColor()!=256) {
332                 dxfInt(62, attrib.getColor());
333                 }
334         if (version>=VER_2000) {
335             dxfInt(370, attrib.getWidth());
336         }
337         if (version>=VER_2000 || 
338                         strcasecmp(attrib.getLineType().c_str(), "BYLAYER")) {
339                 dxfString(6, attrib.getLineType());
340                 }
341     }
342
343     /**
344      * Subclass.
345      */
346     void subClass(const char* sub) const {
347         dxfString(100, sub);
348     }
349
350     /**
351      * Layer (must be in the TABLES section LAYER).
352      *
353      * <pre>
354      *   0
355      *  LAYER
356      * </pre>
357      */
358     void tableLayerEntry(unsigned long int h=0)  const {
359         dxfString(0, "LAYER");
360         if (version>=VER_2000) {
361             if (h==0) {
362                 handle();
363             } else {
364                 dxfHex(5, h);
365             }
366             dxfString(100, "AcDbSymbolTableRecord");
367             dxfString(100, "AcDbLayerTableRecord");
368         }
369     }
370
371     /**
372      * Line type (must be in the TABLES section LTYPE).
373      *
374      * <pre>
375      *   0
376      *  LTYPE
377      * </pre>
378      */
379     void tableLineTypeEntry(unsigned long int h=0)  const {
380         dxfString(0, "LTYPE");
381         if (version>=VER_2000) {
382             if (h==0) {
383                 handle();
384             } else {
385                 dxfHex(5, h);
386             }
387             //dxfHex(330, 0x5);
388             dxfString(100, "AcDbSymbolTableRecord");
389             dxfString(100, "AcDbLinetypeTableRecord");
390         }
391     }
392
393     /**
394      * Appid (must be in the TABLES section APPID).
395      *
396      * <pre>
397      *   0
398      *  APPID
399      * </pre>
400      */
401     void tableAppidEntry(unsigned long int h=0)  const {
402         dxfString(0, "APPID");
403         if (version>=VER_2000) {
404             if (h==0) {
405                 handle();
406             } else {
407                 dxfHex(5, h);
408             }
409             //dxfHex(330, 0x9);
410             dxfString(100, "AcDbSymbolTableRecord");
411             dxfString(100, "AcDbRegAppTableRecord");
412         }
413     }
414
415     /**
416      * Block (must be in the section BLOCKS).
417      *
418      * <pre>
419      *   0
420      *  BLOCK
421      * </pre>
422      */
423     void sectionBlockEntry(unsigned long int h=0)  const {
424         dxfString(0, "BLOCK");
425         if (version>=VER_2000) {
426             if (h==0) {
427                 handle();
428             } else {
429                 dxfHex(5, h);
430             }
431             //dxfHex(330, blockHandle);
432             dxfString(100, "AcDbEntity");
433             if (h==0x1C) {
434                 dxfInt(67, 1);
435             }
436             dxfString(8, "0");                 // TODO: Layer for block
437             dxfString(100, "AcDbBlockBegin");
438         }
439     }
440
441     /**
442      * End of Block (must be in the section BLOCKS).
443      *
444      * <pre>
445      *   0
446      *  ENDBLK
447      * </pre>
448      */
449     void sectionBlockEntryEnd(unsigned long int h=0)  const {
450         dxfString(0, "ENDBLK");
451         if (version>=VER_2000) {
452             if (h==0) {
453                 handle();
454             } else {
455                 dxfHex(5, h);
456             }
457             //dxfHex(330, blockHandle);
458             dxfString(100, "AcDbEntity");
459             if (h==0x1D) {
460                 dxfInt(67, 1);
461             }
462             dxfString(8, "0");                 // TODO: Layer for block
463             dxfString(100, "AcDbBlockEnd");
464         }
465     }
466
467     void color(int col=256) const {
468         dxfInt(62, col);
469     }
470     void lineType(const char *lt) const {
471         dxfString(6, lt);
472     }
473     void lineTypeScale(double scale) const {
474         dxfReal(48, scale);
475     }
476     void lineWeight(int lw) const {
477         dxfInt(370, lw);
478     }
479
480     void coord(int gc, double x, double y, double z=0) const {
481         dxfReal(gc, x);
482         dxfReal(gc+10, y);
483         dxfReal(gc+20, z);
484     }
485
486     void coordTriplet(int gc, const double* value) const {
487         if (value) {
488             dxfReal(gc, *value++);
489             dxfReal(gc+10, *value++);
490             dxfReal(gc+20, *value++);
491         }
492     }
493
494     void resetHandle() const {
495         m_handle = 1;
496     }
497
498     /**
499      * Writes a unique handle and returns it.
500      */
501     unsigned long handle(int gc=5) const {
502         // handle has to be hex
503         dxfHex(gc, m_handle);
504         return m_handle++;
505     }
506
507     /**
508      * @return Next handle that will be written.
509      */
510     unsigned long getNextHandle() const {
511         return m_handle;
512     }
513         
514     /**
515      * Increases handle, so that the handle returned remains available.
516      */
517     unsigned long incHandle() const {
518         return m_handle++;
519     }
520
521     /**
522      * Sets the handle of the model space. Entities refer to 
523      * this handle.
524      */
525     void setModelSpaceHandle(unsigned long h) {
526         modelSpaceHandle = h;
527     }
528
529     unsigned long getModelSpaceHandle() {
530         return modelSpaceHandle;
531     }
532
533     /**
534      * Sets the handle of the paper space. Some special blocks refer to 
535      * this handle.
536      */
537     void setPaperSpaceHandle(unsigned long h) {
538         paperSpaceHandle = h;
539     }
540
541     unsigned long getPaperSpaceHandle() {
542         return paperSpaceHandle;
543     }
544
545     /**
546      * Sets the handle of the paper space 0. Some special blocks refer to 
547      * this handle.
548      */
549     void setPaperSpace0Handle(unsigned long h) {
550         paperSpace0Handle = h;
551     }
552
553     unsigned long getPaperSpace0Handle() {
554         return paperSpace0Handle;
555     }
556
557     /**
558      * Must be overwritten by the implementing class to write a
559      * real value to the file.
560      *
561      * @param gc Group code.
562      * @param value The real value.
563      */
564     virtual void dxfReal(int gc, double value) const = 0;
565
566     /**
567      * Must be overwritten by the implementing class to write an
568      * int value to the file.
569      *
570      * @param gc Group code.
571      * @param value The int value.
572      */
573     virtual void dxfInt(int gc, int value) const = 0;
574
575     /**
576      * Must be overwritten by the implementing class to write an
577      * int value (hex) to the file.
578      *
579      * @param gc Group code.
580      * @param value The int value.
581      */
582     virtual void dxfHex(int gc, int value) const = 0;
583
584     /**
585      * Must be overwritten by the implementing class to write a
586      * string to the file.
587      *
588      * @param gc Group code.
589      * @param value The string.
590      */
591     virtual void dxfString(int gc, const char* value) const = 0;
592
593     /**
594      * Must be overwritten by the implementing class to write a
595      * string to the file.
596      *
597      * @param gc Group code.
598      * @param value The string.
599      */
600     virtual void dxfString(int gc, const string& value) const = 0;
601
602 protected:
603     mutable unsigned long m_handle;
604     mutable unsigned long modelSpaceHandle;
605     mutable unsigned long paperSpaceHandle;
606     mutable unsigned long paperSpace0Handle;
607
608     /**
609      * DXF version to be created.
610      */
611     DL_Codes::version version;
612 private:
613 };
614
615 #endif