/**************************************************************************** ** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. ** Copyright (C) 2001 Robert J. Campbell Jr. ** ** This file is part of the dxflib project. ** ** This file is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** Licensees holding valid dxflib Professional Edition licenses may use ** this file in accordance with the dxflib Commercial License ** Agreement provided with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.ribbonsoft.com for further details. ** ** Contact info@ribbonsoft.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef DL_WRITER_H #define DL_WRITER_H #include "dl_global.h" #ifndef _WIN32 #include #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 DXFLIB_EXPORT DL_Writer { public: /** * @param version DXF version. Defaults to DL_VERSION_2002. */ DL_Writer( DL_Codes::version aversion ) : m_handle( 0x30 ) { version = aversion; 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 h = 0 ) const { dxfString( 0, "TABLE" ); dxfString( 2, name ); if( version>=DL_VERSION_2000 ) { if( h==0 ) { handle(); } else { dxfHex( 5, h ); } 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 ); } /** Table for text style. * * @param num Number of text styles. * *
     *   0
     *  TABLE
     *   2
     *  STYLE
     *   70
     *      num
     * 
*/ void tableStyle( int num ) const { table( "STYLE", num, 3 ); } /** * 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>=DL_VERSION_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>=DL_VERSION_2000 || attrib.getColor()!=256 ) { dxfInt( 62, attrib.getColor() ); } if( version>=DL_VERSION_2000 && attrib.getColor24()!=-1 ) { dxfInt( 420, attrib.getColor24() ); } if( version>=DL_VERSION_2000 ) { dxfInt( 370, attrib.getWidth() ); } if( version>=DL_VERSION_2000 ) { dxfReal( 48, attrib.getLinetypeScale() ); } std::string linetype = attrib.getLinetype(); std::transform( linetype.begin(), linetype.end(), linetype.begin(), ::toupper ); if( version>=DL_VERSION_2000 || linetype=="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>=DL_VERSION_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>=DL_VERSION_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>=DL_VERSION_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>=DL_VERSION_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>=DL_VERSION_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; } /** * 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; /** * Can be overwritten by the implementing class to write a * bool value to the file. * * @param gc Group code. * @param value The bool value. */ virtual void dxfBool( int gc, bool value ) const { dxfInt( gc, (int) value ); } /** * 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 std::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