valentina_old/src/libs/vdxf/dxflib/dl_writer.h

732 lines
14 KiB
C
Raw Normal View History

2015-09-07 16:39:04 +02:00
/****************************************************************************
** 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
#if defined(Q_CC_MSVC)
#if (_MSC_VER > 1000)
#pragma once
#endif // _MSC_VER > 1000
#endif // Q_CC_MSVC
2015-09-07 16:39:04 +02:00
#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.
*/
2015-10-12 13:52:48 +02:00
explicit DL_Writer(DL_Codes::version version)
: m_handle(0x30), modelSpaceHandle(0), paperSpaceHandle(0), paperSpace0Handle(0), version(version)
2015-09-07 16:39:04 +02:00
{
}
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, static_cast<int>(h));
2015-09-07 16:39:04 +02:00
}
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, static_cast<int>(h));
2015-09-07 16:39:04 +02:00
}
//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, static_cast<int>(h));
2015-09-07 16:39:04 +02:00
}
//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, static_cast<int>(h));
2015-09-07 16:39:04 +02:00
}
//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, static_cast<int>(h));
2015-09-07 16:39:04 +02:00
}
//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, static_cast<int>(m_handle));
2015-09-07 16:39:04 +02:00
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.
*/
2015-10-12 13:52:48 +02:00
// cppcheck-suppress functionConst
2015-09-07 16:39:04 +02:00
void setModelSpaceHandle(unsigned long h)
{
modelSpaceHandle = h;
}
2015-10-12 13:52:48 +02:00
unsigned long getModelSpaceHandle() const
2015-09-07 16:39:04 +02:00
{
return modelSpaceHandle;
}
/**
* Sets the handle of the paper space. Some special blocks refer to
* this handle.
*/
2015-10-12 13:52:48 +02:00
// cppcheck-suppress functionConst
2015-09-07 16:39:04 +02:00
void setPaperSpaceHandle(unsigned long h)
{
paperSpaceHandle = h;
}
2015-10-12 13:52:48 +02:00
unsigned long getPaperSpaceHandle() const
2015-09-07 16:39:04 +02:00
{
return paperSpaceHandle;
}
/**
* Sets the handle of the paper space 0. Some special blocks refer to
* this handle.
*/
2015-10-12 13:52:48 +02:00
// cppcheck-suppress functionConst
2015-09-07 16:39:04 +02:00
void setPaperSpace0Handle(unsigned long h)
{
paperSpace0Handle = h;
}
2015-10-12 13:52:48 +02:00
unsigned long getPaperSpace0Handle() const
2015-09-07 16:39:04 +02:00
{
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;
/**
* 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, static_cast<int>(value));
2015-09-07 16:39:04 +02:00
}
/**
* 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