/**************************************************************************** ** ** This file is part of the LibreCAD project, a 2D CAD program ** ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl) ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved. ** ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file gpl-2.0.txt included in the ** packaging of this file. ** ** 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 ** ** This copyright notice MUST APPEAR in all copies of the script! ** **********************************************************************/ #ifndef DL_WRITER_H #define DL_WRITER_H #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #if defined(__OS2__)||defined(__EMX__)||defined(_WIN32) #define strcasecmp(s,t) stricmp(s,t) #endif #include #include #include "dl_attributes.h" #include "dl_codes.h" /** * Defines interface for writing low level DXF constructs to * a file. Implementation is defined in derived classes that write * to binary or ASCII files. * * Implements functions that write higher level constructs in terms of * the low level ones. * * @todo Add error checking for string/entry length. */ class DL_Writer { public: /** * @para version DXF version. Defaults to VER_2002. */ DL_Writer(DL_Codes::version version) : m_handle(0x30) { this->version = version; modelSpaceHandle = 0; paperSpaceHandle = 0; paperSpace0Handle = 0; } virtual ~DL_Writer() {} ; /** Generic section for section 'name'. * *
     *   0
     *  SECTION
     *   2
     *  name
     * 
*/ void section(const char* name) const { dxfString(0, "SECTION"); dxfString(2, name); } /** * Section HEADER * *
     *   0
     *  SECTION
     *   2
     *  HEADER
     * 
*/ void sectionHeader() const { section("HEADER"); } /** * Section TABLES * *
     *   0
     *  SECTION
     *   2
     *  TABLES
     * 
*/ void sectionTables() const { section("TABLES"); } /** * Section BLOCKS * *
     *   0
     *  SECTION
     *   2
     *  BLOCKS
     * 
*/ void sectionBlocks() const { section("BLOCKS"); } /** * Section ENTITIES * *
     *   0
     *  SECTION
     *   2
     *  ENTITIES
     * 
*/ void sectionEntities() const { section("ENTITIES"); } /** * Section CLASSES * *
     *   0
     *  SECTION
     *   2
     *  CLASSES
     * 
*/ void sectionClasses() const { section("CLASSES"); } /** * Section OBJECTS * *
     *   0
     *  SECTION
     *   2
     *  OBJECTS
     * 
*/ void sectionObjects() const { section("OBJECTS"); } /** * End of a section. * *
     *   0
     *  ENDSEC
     * 
*/ void sectionEnd() const { dxfString(0, "ENDSEC"); } /** * Generic table for table 'name' with 'num' entries: * *
     *   0
     *  TABLE
     *   2
     *  name
     *  70
     *   num
     * 
*/ void table(const char* name, int num, int handle) const { dxfString(0, "TABLE"); dxfString(2, name); if (version>=VER_2000) { dxfHex(5, handle); dxfString(100, "AcDbSymbolTable"); } dxfInt(70, num); } /** Table for layers. * * @param num Number of layers in total. * *
     *   0
     *  TABLE
     *   2
     *  LAYER
     *   70
     *      num
     * 
*/ void tableLayers(int num) const { table("LAYER", num, 2); } /** Table for line types. * * @param num Number of line types in total. * *
     *   0
     *  TABLE
     *   2
     *  LTYPE
     *   70
     *      num
     * 
*/ void tableLineTypes(int num) const { //lineTypeHandle = 5; table("LTYPE", num, 5); } /** Table for application id. * * @param num Number of registered applications in total. * *
     *   0
     *  TABLE
     *   2
     *  APPID
     *   70
     *      num
     * 
*/ void tableAppid(int num) const { table("APPID", num, 9); } /** * End of a table. * *
     *   0
     *  ENDTAB
     * 
*/ void tableEnd() const { dxfString(0, "ENDTAB"); } /** * End of the DXF file. * *
     *   0
     *  EOF
     * 
*/ void dxfEOF() const { dxfString(0, "EOF"); } /** * Comment. * *
     *  999
     *  text
     * 
*/ void comment(const char* text) const { dxfString(999, text); } /** * Entity. * *
     *   0
     *  entTypeName
     * 
* * @return Unique handle or 0. */ void entity(const char* entTypeName) const { dxfString(0, entTypeName); if (version>=VER_2000) { handle(); } } /** * Attributes of an entity. * *
     *   8
     *  layer
     *  62
     *  color
     *  39
     *  width
     *   6
     *  linetype
     * 
*/ void entityAttributes(const DL_Attributes& attrib) const { // layer name: dxfString(8, attrib.getLayer()); // R12 doesn't accept BYLAYER values. The value has to be missing // in that case. if (version>=VER_2000 || attrib.getColor()!=256) { dxfInt(62, attrib.getColor()); } if (version>=VER_2000) { dxfInt(370, attrib.getWidth()); } if (version>=VER_2000 || strcasecmp(attrib.getLineType().c_str(), "BYLAYER")) { dxfString(6, attrib.getLineType()); } } /** * Subclass. */ void subClass(const char* sub) const { dxfString(100, sub); } /** * Layer (must be in the TABLES section LAYER). * *
     *   0
     *  LAYER
     * 
*/ void tableLayerEntry(unsigned long int h=0) const { dxfString(0, "LAYER"); if (version>=VER_2000) { if (h==0) { handle(); } else { dxfHex(5, h); } dxfString(100, "AcDbSymbolTableRecord"); dxfString(100, "AcDbLayerTableRecord"); } } /** * Line type (must be in the TABLES section LTYPE). * *
     *   0
     *  LTYPE
     * 
*/ void tableLineTypeEntry(unsigned long int h=0) const { dxfString(0, "LTYPE"); if (version>=VER_2000) { if (h==0) { handle(); } else { dxfHex(5, h); } //dxfHex(330, 0x5); dxfString(100, "AcDbSymbolTableRecord"); dxfString(100, "AcDbLinetypeTableRecord"); } } /** * Appid (must be in the TABLES section APPID). * *
     *   0
     *  APPID
     * 
*/ void tableAppidEntry(unsigned long int h=0) const { dxfString(0, "APPID"); if (version>=VER_2000) { if (h==0) { handle(); } else { dxfHex(5, h); } //dxfHex(330, 0x9); dxfString(100, "AcDbSymbolTableRecord"); dxfString(100, "AcDbRegAppTableRecord"); } } /** * Block (must be in the section BLOCKS). * *
     *   0
     *  BLOCK
     * 
*/ void sectionBlockEntry(unsigned long int h=0) const { dxfString(0, "BLOCK"); if (version>=VER_2000) { if (h==0) { handle(); } else { dxfHex(5, h); } //dxfHex(330, blockHandle); dxfString(100, "AcDbEntity"); if (h==0x1C) { dxfInt(67, 1); } dxfString(8, "0"); // TODO: Layer for block dxfString(100, "AcDbBlockBegin"); } } /** * End of Block (must be in the section BLOCKS). * *
     *   0
     *  ENDBLK
     * 
*/ void sectionBlockEntryEnd(unsigned long int h=0) const { dxfString(0, "ENDBLK"); if (version>=VER_2000) { if (h==0) { handle(); } else { dxfHex(5, h); } //dxfHex(330, blockHandle); dxfString(100, "AcDbEntity"); if (h==0x1D) { dxfInt(67, 1); } dxfString(8, "0"); // TODO: Layer for block dxfString(100, "AcDbBlockEnd"); } } void color(int col=256) const { dxfInt(62, col); } void lineType(const char *lt) const { dxfString(6, lt); } void lineTypeScale(double scale) const { dxfReal(48, scale); } void lineWeight(int lw) const { dxfInt(370, lw); } void coord(int gc, double x, double y, double z=0) const { dxfReal(gc, x); dxfReal(gc+10, y); dxfReal(gc+20, z); } void coordTriplet(int gc, const double* value) const { if (value) { dxfReal(gc, *value++); dxfReal(gc+10, *value++); dxfReal(gc+20, *value++); } } void resetHandle() const { m_handle = 1; } /** * Writes a unique handle and returns it. */ unsigned long handle(int gc=5) const { // handle has to be hex dxfHex(gc, m_handle); return m_handle++; } /** * @return Next handle that will be written. */ unsigned long getNextHandle() const { return m_handle; } /** * Increases handle, so that the handle returned remains available. */ unsigned long incHandle() const { return m_handle++; } /** * Sets the handle of the model space. Entities refer to * this handle. */ void setModelSpaceHandle(unsigned long h) { modelSpaceHandle = h; } unsigned long getModelSpaceHandle() { return modelSpaceHandle; } /** * Sets the handle of the paper space. Some special blocks refer to * this handle. */ void setPaperSpaceHandle(unsigned long h) { paperSpaceHandle = h; } unsigned long getPaperSpaceHandle() { return paperSpaceHandle; } /** * Sets the handle of the paper space 0. Some special blocks refer to * this handle. */ void setPaperSpace0Handle(unsigned long h) { paperSpace0Handle = h; } unsigned long getPaperSpace0Handle() { return paperSpace0Handle; } /** * Must be overwritten by the implementing class to write a * real value to the file. * * @param gc Group code. * @param value The real value. */ virtual void dxfReal(int gc, double value) const = 0; /** * Must be overwritten by the implementing class to write an * int value to the file. * * @param gc Group code. * @param value The int value. */ virtual void dxfInt(int gc, int value) const = 0; /** * Must be overwritten by the implementing class to write an * int value (hex) to the file. * * @param gc Group code. * @param value The int value. */ virtual void dxfHex(int gc, int value) const = 0; /** * Must be overwritten by the implementing class to write a * string to the file. * * @param gc Group code. * @param value The string. */ virtual void dxfString(int gc, const char* value) const = 0; /** * Must be overwritten by the implementing class to write a * string to the file. * * @param gc Group code. * @param value The string. */ virtual void dxfString(int gc, const string& value) const = 0; protected: mutable unsigned long m_handle; mutable unsigned long modelSpaceHandle; mutable unsigned long paperSpaceHandle; mutable unsigned long paperSpace0Handle; /** * DXF version to be created. */ DL_Codes::version version; private: }; #endif