702 lines
13 KiB
C++
702 lines
13 KiB
C++
/****************************************************************************
|
|
** 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 <strings.h>
|
|
#endif
|
|
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
|
|
#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'.
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* SECTION
|
|
* 2
|
|
* name
|
|
* </pre>
|
|
*/
|
|
void section( const char* name ) const
|
|
{
|
|
dxfString( 0, "SECTION" );
|
|
dxfString( 2, name );
|
|
}
|
|
|
|
/**
|
|
* Section HEADER
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* SECTION
|
|
* 2
|
|
* HEADER
|
|
* </pre>
|
|
*/
|
|
void sectionHeader() const
|
|
{
|
|
section( "HEADER" );
|
|
}
|
|
|
|
/**
|
|
* Section TABLES
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* SECTION
|
|
* 2
|
|
* TABLES
|
|
* </pre>
|
|
*/
|
|
void sectionTables() const
|
|
{
|
|
section( "TABLES" );
|
|
}
|
|
|
|
/**
|
|
* Section BLOCKS
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* SECTION
|
|
* 2
|
|
* BLOCKS
|
|
* </pre>
|
|
*/
|
|
void sectionBlocks() const
|
|
{
|
|
section( "BLOCKS" );
|
|
}
|
|
|
|
/**
|
|
* Section ENTITIES
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* SECTION
|
|
* 2
|
|
* ENTITIES
|
|
* </pre>
|
|
*/
|
|
void sectionEntities() const
|
|
{
|
|
section( "ENTITIES" );
|
|
}
|
|
|
|
/**
|
|
* Section CLASSES
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* SECTION
|
|
* 2
|
|
* CLASSES
|
|
* </pre>
|
|
*/
|
|
void sectionClasses() const
|
|
{
|
|
section( "CLASSES" );
|
|
}
|
|
|
|
/**
|
|
* Section OBJECTS
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* SECTION
|
|
* 2
|
|
* OBJECTS
|
|
* </pre>
|
|
*/
|
|
void sectionObjects() const
|
|
{
|
|
section( "OBJECTS" );
|
|
}
|
|
|
|
/**
|
|
* End of a section.
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* ENDSEC
|
|
* </pre>
|
|
*/
|
|
void sectionEnd() const
|
|
{
|
|
dxfString( 0, "ENDSEC" );
|
|
}
|
|
|
|
/**
|
|
* Generic table for table 'name' with 'num' entries:
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* TABLE
|
|
* 2
|
|
* name
|
|
* 70
|
|
* num
|
|
* </pre>
|
|
*/
|
|
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.
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* TABLE
|
|
* 2
|
|
* LAYER
|
|
* 70
|
|
* num
|
|
* </pre>
|
|
*/
|
|
void tableLayers( int num ) const
|
|
{
|
|
table( "LAYER", num, 2 );
|
|
}
|
|
|
|
/** Table for line types.
|
|
*
|
|
* @param num Number of line types in total.
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* TABLE
|
|
* 2
|
|
* LTYPE
|
|
* 70
|
|
* num
|
|
* </pre>
|
|
*/
|
|
void tableLinetypes( int num ) const
|
|
{
|
|
// linetypeHandle = 5;
|
|
table( "LTYPE", num, 5 );
|
|
}
|
|
|
|
/** Table for application id.
|
|
*
|
|
* @param num Number of registered applications in total.
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* TABLE
|
|
* 2
|
|
* APPID
|
|
* 70
|
|
* num
|
|
* </pre>
|
|
*/
|
|
void tableAppid( int num ) const
|
|
{
|
|
table( "APPID", num, 9 );
|
|
}
|
|
|
|
/** Table for text style.
|
|
*
|
|
* @param num Number of text styles.
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* TABLE
|
|
* 2
|
|
* STYLE
|
|
* 70
|
|
* num
|
|
* </pre>
|
|
*/
|
|
void tableStyle( int num ) const
|
|
{
|
|
table( "STYLE", num, 3 );
|
|
}
|
|
|
|
/**
|
|
* End of a table.
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* ENDTAB
|
|
* </pre>
|
|
*/
|
|
void tableEnd() const
|
|
{
|
|
dxfString( 0, "ENDTAB" );
|
|
}
|
|
|
|
/**
|
|
* End of the DXF file.
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* EOF
|
|
* </pre>
|
|
*/
|
|
void dxfEOF() const
|
|
{
|
|
dxfString( 0, "EOF" );
|
|
}
|
|
|
|
/**
|
|
* Comment.
|
|
*
|
|
* <pre>
|
|
* 999
|
|
* text
|
|
* </pre>
|
|
*/
|
|
void comment( const char* text ) const
|
|
{
|
|
dxfString( 999, text );
|
|
}
|
|
|
|
/**
|
|
* Entity.
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* entTypeName
|
|
* </pre>
|
|
*
|
|
* @return Unique handle or 0.
|
|
*/
|
|
void entity( const char* entTypeName ) const
|
|
{
|
|
dxfString( 0, entTypeName );
|
|
|
|
if( version>=DL_VERSION_2000 )
|
|
{
|
|
handle();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Attributes of an entity.
|
|
*
|
|
* <pre>
|
|
* 8
|
|
* layer
|
|
* 62
|
|
* color
|
|
* 39
|
|
* width
|
|
* 6
|
|
* linetype
|
|
* </pre>
|
|
*/
|
|
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).
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* LAYER
|
|
* </pre>
|
|
*/
|
|
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).
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* LTYPE
|
|
* </pre>
|
|
*/
|
|
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).
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* APPID
|
|
* </pre>
|
|
*/
|
|
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).
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* BLOCK
|
|
* </pre>
|
|
*/
|
|
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).
|
|
*
|
|
* <pre>
|
|
* 0
|
|
* ENDBLK
|
|
* </pre>
|
|
*/
|
|
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
|