LibreCAD / libraries /jwwlib /src /dl_jww-copy.cpp
AbdulElahGwaith's picture
Upload folder using huggingface_hub
a5ffdcd verified
/****************************************************************************
** $Id: dl_jww-copy.cpp,v 1.1.1.2 2010/02/08 11:58:29 zeronemo2007 Exp $
**
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
**
** This file is part of the dxflib project.
**
** 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 LICENSE.GPL included in the
** packaging of this file.
**
** 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.
**
**********************************************************************/
#include "dl_jww.h"
#include <algorithm>
#include <string>
#include <cstdio>
#include <cassert>
#include <cmath>
#include "dl_attributes.h"
#include "dl_codes.h"
#include "dl_creationinterface.h"
#include "dl_writer_ascii.h"
/**
* Default constructor.
*/
DL_Jww::DL_Jww() {
styleHandleStd = 0;
version = VER_2000;
vertices = NULL;
maxVertices = 0;
vertexIndex = 0;
knots = NULL;
maxKnots = 0;
knotIndex = 0;
controlPoints = NULL;
maxControlPoints = 0;
controlPointIndex = 0;
leaderVertices = NULL;
maxLeaderVertices = 0;
leaderVertexIndex = 0;
hatchLoops = NULL;
maxHatchLoops = 0;
hatchLoopIndex = -1;
hatchEdges = NULL;
maxHatchEdges = NULL;
hatchEdgeIndex = NULL;
dropEdges = false;
//bulge = 0.0;
}
/**
* Destructor.
*/
DL_Jww::~DL_Jww() {
if (vertices!=NULL) {
delete[] vertices;
}
if (knots!=NULL) {
delete[] knots;
}
if (controlPoints!=NULL) {
delete[] controlPoints;
}
if (leaderVertices!=NULL) {
delete[] leaderVertices;
}
if (hatchLoops!=NULL) {
delete[] hatchLoops;
}
if (hatchEdges!=NULL) {
for (int i=0; i<maxHatchLoops; ++i) {
if (hatchEdges[i]!=NULL) {
delete[] hatchEdges[i];
}
}
delete[] hatchEdges;
}
if (maxHatchEdges!=NULL) {
delete[] maxHatchEdges;
}
if (hatchEdgeIndex!=NULL) {
delete[] hatchEdgeIndex;
}
}
/**
* @brief Reads the given file and calls the appropriate functions in
* the given creation interface for every entity found in the file.
*
* @param file Input
* Path and name of file to read
* @param creationInterface
* Pointer to the class which takes care of the entities in the file.
*
* @retval true If \p file could be opened.
* @retval false If \p file could not be opened.
*/
bool DL_Jww::in(const string& file, DL_CreationInterface* creationInterface) {
FILE *fp;
firstCall = true;
currentEntity = DL_UNKNOWN;
int errorCounter = 0;
fp = fopen(file.c_str(), "rt");
if (fp) {
while (readDxfGroups(fp, creationInterface, &errorCounter)) {}
fclose(fp);
if (errorCounter>0) {
std::cerr << "DXF Filter: There have been " << errorCounter <<
" errors. The drawing might be incomplete / incorrect.\n";
}
return true;
}
return false;
}
/**
* Reads a DXF file from an existing stream.
*
* @param stream The string stream.
* @param creationInterface
* Pointer to the class which takes care of the entities in the file.
*
* @retval true If \p file could be opened.
* @retval false If \p file could not be opened.
*/
#ifndef __GCC2x__
bool DL_Jww::in(std::stringstream& stream,
DL_CreationInterface* creationInterface) {
int errorCounter = 0;
if (stream.good()) {
firstCall=true;
currentEntity = DL_UNKNOWN;
while (readDxfGroups(stream, creationInterface, &errorCounter)) {}
if (errorCounter>0) {
std::cerr << "DXF Filter: There have been " << errorCounter <<
" errors. The drawing might be incomplete / incorrect.\n";
}
return true;
}
return false;
}
#endif
/**
* @brief Reads a group couplet from a DXF file. Calls another function
* to process it.
*
* A group couplet consists of two lines that represent a single
* piece of data. An integer constant on the first line indicates
* the type of data. The value is on the next line.\n
*
* This function reads a couplet, determines the type of data, and
* passes the value to the the appropriate handler function of
* \p creationInterface.\n
*
* \p fp is advanced so that the next call to \p readDXFGroups() reads
* the next couplet in the file.
*
* @param fp Handle of input file
* @param creationInterface Handle of class which processes entities
* in the file
*
* @retval true If EOF not reached.
* @retval false If EOF reached.
*/
bool DL_Jww::readDxfGroups(FILE *fp, DL_CreationInterface* creationInterface,
int* errorCounter) {
bool ok = true;
static int line = 1;
// Read one group of the DXF file and chop the lines:
if (DL_Jww::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, fp) &&
DL_Jww::getChoppedLine(groupValue, DL_DXF_MAXLINE, fp) ) {
groupCode = (unsigned int)stringToInt(groupCodeTmp, &ok);
if (ok) {
//std::cerr << groupCode << "\n";
//std::cerr << groupValue << "\n";
line+=2;
processDXFGroup(creationInterface, groupCode, groupValue);
} else {
std::cerr << "DXF read error: Line: " << line << "\n";
if (errorCounter!=NULL) {
(*errorCounter)++;
}
// try to fix:
std::cerr << "DXF read error: trying to fix..\n";
// drop a line to sync:
DL_Jww::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, fp);
}
}
return !feof(fp);
}
/**
* Same as above but for stringstreams.
*/
#ifndef __GCC2x__
bool DL_Jww::readDxfGroups(std::stringstream& stream,
DL_CreationInterface* creationInterface,
int* errorCounter) {
bool ok = true;
static int line = 1;
// Read one group of the DXF file and chop the lines:
if (DL_Jww::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, stream) &&
DL_Jww::getChoppedLine(groupValue, DL_DXF_MAXLINE, stream) ) {
groupCode = (unsigned int)stringToInt(groupCodeTmp, &ok);
if (ok) {
//std::cout << groupCode << "\n";
//std::cout << groupValue << "\n";
line+=2;
processDXFGroup(creationInterface, groupCode, groupValue);
} else {
std::cerr << "DXF read error: Line: " << line << "\n";
if (errorCounter!=NULL) {
(*errorCounter)++;
}
// try to fix:
std::cerr << "DXF read error: trying to fix..\n";
// drop a line to sync:
DL_Jww::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, stream);
}
}
return !stream.eof();
}
#endif
/**
* @brief Reads line from file & strips whitespace at start and newline
* at end.
*
* @param s Output\n
* Pointer to character array that chopped line will be returned in.
* @param size Size of \p s. (Including space for NULL.)
* @param fp Input\n
* Handle of input file.
*
* @retval true if line could be read
* @retval false if \p fp is already at end of file
*
* @todo Change function to use safer FreeBSD strl* functions
* @todo Is it a problem if line is blank (i.e., newline only)?
* Then, when function returns, (s==NULL).
*/
bool DL_Jww::getChoppedLine(char *s, unsigned int size, FILE *fp) {
if (!feof(fp)) {
// The whole line in the file. Includes space for NULL.
char* wholeLine = new char[size];
// Only the useful part of the line
char* line;
line = fgets(wholeLine, size, fp);
if (line!=NULL && line[0] != '\0') { // Evaluates to fgets() retval
// line == wholeLine at this point.
// Both guaranteed to be NULL terminated.
// Strip leading whitespace and trailing CR/LF.
stripWhiteSpace(&line);
strncpy(s, line, size);
s[size] = '\0';
// s should always be NULL terminated, because:
assert(size > strlen(line));
}
delete[] wholeLine; // Done with wholeLine
return true;
} else {
s[0] = '\0';
return false;
}
}
/**
* Same as above but for stringstreams.
*/
#ifndef __GCC2x__
bool DL_Jww::getChoppedLine(char *s, unsigned int size,
std::stringstream& stream) {
if (!stream.eof()) {
// Only the useful part of the line
stream.getline(s, size);
stripWhiteSpace(&s);
assert(size > strlen(s));
return true;
} else {
s[0] = '\0';
return false;
}
}
#endif
/**
* @brief Strips leading whitespace and trailing Carriage Return (CR)
* and Line Feed (LF) from NULL terminated string.
*
* @param s Input and output.
* NULL terminates string.
*
* @retval true if \p s is non-NULL
* @retval false if \p s is NULL
*/
bool DL_Jww::stripWhiteSpace(char** s) {
// last non-NULL char:
int lastChar = strlen(*s) - 1;
//std::cout << "lastChar: " << lastChar << "\n";
// Is last character CR or LF?
while ( (lastChar >= 0) &&
(((*s)[lastChar] == 10) || ((*s)[lastChar] == 13) ||
((*s)[lastChar] == ' ' || ((*s)[lastChar] == '\t'))) ) {
(*s)[lastChar] = '\0';
lastChar--;
}
// Skip whitespace, excluding \n, at beginning of line
while ((*s)[0]==' ' || (*s)[0]=='\t') {
++(*s);
}
return ((*s) ? true : false);
}
/**
* Processes a group (pair of group code and value).
*
* @param creationInterface Handle to class that creates entities and
* other CAD data from DXF group codes
*
* @param groupCode Constant indicating the data type of the group.
* @param groupValue The data value.
*
* @retval true if done processing current entity and new entity begun
* @retval false if not done processing current entity
*/
bool DL_Jww::processDXFGroup(DL_CreationInterface* creationInterface,
int groupCode, const char *groupValue) {
//std::cout << "DL_Jww::processDXFGroup: " << groupCode << ": "
//<< groupValue << "\n";
// Init on first call
if (firstCall) {
for (int i=0; i<DL_DXF_MAXGROUPCODE; ++i) {
values[i][0] = '\0';
}
settingValue[0] = '\0';
firstCall=false;
}
// Indicates comment or dxflib version:
if (groupCode==999) {
//std::cout << "999: " << groupValue << "\n";
if (groupValue!=NULL) {
if (!strncmp(groupValue, "dxflib", 6)) {
//std::cout << "dxflib version found" << "\n";
libVersion = getLibVersion(&groupValue[7]);
}
}
}
// Indicates start of new entity or var
else if (groupCode==0 || groupCode==9) {
// If new entity is encountered, the last one must be complete
// prepare attributes which can be used for most entities:
char name[DL_DXF_MAXLINE+1];
if ((values[8])[0]!='\0') {
strcpy(name, values[8]);
}
// defaults to layer '0':
else {
strcpy(name, "0");
}
int width;
// Compatibillity with qcad1:
if ((values[39])[0]!='\0' &&
(values[370])[0]=='\0') {
width = toInt(values[39], -1);
}
// since autocad 2002:
else if ((values[370])[0]!='\0') {
width = toInt(values[370], -1);
}
// default to BYLAYER:
else {
width = -1;
}
int color;
color = toInt(values[62], 256);
char linetype[DL_DXF_MAXLINE+1];
strcpy(linetype, toString(values[6], "BYLAYER"));
attrib = DL_Attributes(values[8], // layer
color, // color
width, // width
linetype); // linetype
creationInterface->setAttributes(attrib);
creationInterface->setExtrusion(toReal(values[210], 0.0),
toReal(values[220], 0.0),
toReal(values[230], 1.0),
toReal(values[30], 0.0));
// Add the last entity via creationInterface
switch (currentEntity) {
case DL_SETTING:
addSetting(creationInterface);
break;
case DL_LAYER:
addLayer(creationInterface);
break;
case DL_BLOCK:
addBlock(creationInterface);
break;
case DL_ENDBLK:
endBlock(creationInterface);
break;
case DL_ENTITY_POINT:
addPoint(creationInterface);
break;
case DL_ENTITY_LINE:
addLine(creationInterface);
break;
case DL_ENTITY_POLYLINE:
//bulge = toReal(values[42]);
// fall through
case DL_ENTITY_LWPOLYLINE:
addPolyline(creationInterface);
break;
case DL_ENTITY_VERTEX:
addVertex(creationInterface);
break;
case DL_ENTITY_SPLINE:
addSpline(creationInterface);
break;
case DL_ENTITY_ARC:
addArc(creationInterface);
break;
case DL_ENTITY_CIRCLE:
addCircle(creationInterface);
break;
case DL_ENTITY_ELLIPSE:
addEllipse(creationInterface);
break;
case DL_ENTITY_INSERT:
addInsert(creationInterface);
break;
case DL_ENTITY_MTEXT:
addMText(creationInterface);
break;
case DL_ENTITY_TEXT:
addText(creationInterface);
break;
case DL_ENTITY_ATTRIB:
addAttrib(creationInterface);
break;
case DL_ENTITY_DIMENSION: {
int type = (toInt(values[70], 0)&0x07);
switch (type) {
case 0:
addDimLinear(creationInterface);
break;
case 1:
addDimAligned(creationInterface);
break;
case 2:
addDimAngular(creationInterface);
break;
case 3:
addDimDiametric(creationInterface);
break;
case 4:
addDimRadial(creationInterface);
break;
case 5:
addDimAngular3P(creationInterface);
break;
default:
break;
}
}
break;
case DL_ENTITY_LEADER:
addLeader(creationInterface);
break;
case DL_ENTITY_HATCH:
addHatch(creationInterface);
break;
case DL_ENTITY_IMAGE:
addImage(creationInterface);
break;
case DL_ENTITY_IMAGEDEF:
addImageDef(creationInterface);
break;
case DL_ENTITY_TRACE:
addTrace(creationInterface);
break;
case DL_ENTITY_SOLID:
addSolid(creationInterface);
break;
case DL_ENTITY_SEQEND:
endSequence(creationInterface);
break;
default:
break;
}
// reset all values (they are not persistent and only this
// way we can detect default values for unstored settings)
for (int i=0; i<DL_DXF_MAXGROUPCODE; ++i) {
values[i][0] = '\0';
}
settingValue[0] = '\0';
settingKey[0] = '\0';
// Last DXF entity or setting has been handled
// Now determine what the next entity or setting type is
int prevEntity = currentEntity;
// Read DXF settings:
if (groupValue[0]=='$') {
currentEntity = DL_SETTING;
strncpy(settingKey, groupValue, DL_DXF_MAXLINE);
settingKey[DL_DXF_MAXLINE] = '\0';
}
// Read Layers:
else if (!strcmp(groupValue, "LAYER")) {
currentEntity = DL_LAYER;
}
// Read Blocks:
else if (!strcmp(groupValue, "BLOCK")) {
currentEntity = DL_BLOCK;
} else if (!strcmp(groupValue, "ENDBLK")) {
currentEntity = DL_ENDBLK;
}
// Read entities:
else if (!strcmp(groupValue, "POINT")) {
currentEntity = DL_ENTITY_POINT;
} else if (!strcmp(groupValue, "LINE")) {
currentEntity = DL_ENTITY_LINE;
} else if (!strcmp(groupValue, "POLYLINE")) {
currentEntity = DL_ENTITY_POLYLINE;
} else if (!strcmp(groupValue, "LWPOLYLINE")) {
currentEntity = DL_ENTITY_LWPOLYLINE;
} else if (!strcmp(groupValue, "VERTEX")) {
currentEntity = DL_ENTITY_VERTEX;
} else if (!strcmp(groupValue, "SPLINE")) {
currentEntity = DL_ENTITY_SPLINE;
} else if (!strcmp(groupValue, "ARC")) {
currentEntity = DL_ENTITY_ARC;
} else if (!strcmp(groupValue, "ELLIPSE")) {
currentEntity = DL_ENTITY_ELLIPSE;
} else if (!strcmp(groupValue, "CIRCLE")) {
currentEntity = DL_ENTITY_CIRCLE;
} else if (!strcmp(groupValue, "INSERT")) {
currentEntity = DL_ENTITY_INSERT;
} else if (!strcmp(groupValue, "TEXT")) {
currentEntity = DL_ENTITY_TEXT;
} else if (!strcmp(groupValue, "MTEXT")) {
currentEntity = DL_ENTITY_MTEXT;
} else if (!strcmp(groupValue, "ATTRIB")) {
currentEntity = DL_ENTITY_ATTRIB;
} else if (!strcmp(groupValue, "DIMENSION")) {
currentEntity = DL_ENTITY_DIMENSION;
} else if (!strcmp(groupValue, "LEADER")) {
currentEntity = DL_ENTITY_LEADER;
} else if (!strcmp(groupValue, "HATCH")) {
currentEntity = DL_ENTITY_HATCH;
} else if (!strcmp(groupValue, "IMAGE")) {
currentEntity = DL_ENTITY_IMAGE;
} else if (!strcmp(groupValue, "IMAGEDEF")) {
currentEntity = DL_ENTITY_IMAGEDEF;
} else if (!strcmp(groupValue, "TRACE")) {
currentEntity = DL_ENTITY_TRACE;
} else if (!strcmp(groupValue, "SOLID")) {
currentEntity = DL_ENTITY_SOLID;
} else if (!strcmp(groupValue, "SEQEND")) {
currentEntity = DL_ENTITY_SEQEND;
} else {
currentEntity = DL_UNKNOWN;
}
// end of old style POLYLINE entity
if (prevEntity==DL_ENTITY_VERTEX && currentEntity!=DL_ENTITY_VERTEX) {
endEntity(creationInterface);
}
return true;
} else {
// Group code does not indicate start of new entity or setting,
// so this group must be continuation of data for the current
// one.
if (groupCode<DL_DXF_MAXGROUPCODE) {
bool handled = false;
switch (currentEntity) {
case DL_ENTITY_MTEXT:
handled = handleMTextData(creationInterface);
break;
case DL_ENTITY_LWPOLYLINE:
handled = handleLWPolylineData(creationInterface);
break;
case DL_ENTITY_SPLINE:
handled = handleSplineData(creationInterface);
break;
case DL_ENTITY_LEADER:
handled = handleLeaderData(creationInterface);
break;
case DL_ENTITY_HATCH:
handled = handleHatchData(creationInterface);
break;
default:
break;
}
if (!handled) {
// Normal group / value pair:
strncpy(values[groupCode], groupValue, DL_DXF_MAXLINE);
values[groupCode][DL_DXF_MAXLINE] = '\0';
}
}
return false;
}
return false;
}
/**
* Adds a variable from the DXF file.
*/
void DL_Jww::addSetting(DL_CreationInterface* creationInterface) {
int c = -1;
for (int i=0; i<=380; ++i) {
if (values[i][0]!='\0') {
c = i;
break;
}
}
// string
if (c>=0 && c<=9) {
creationInterface->setVariableString(settingKey,
values[c], c);
}
// vector
else if (c>=10 && c<=39) {
if (c==10) {
creationInterface->setVariableVector(
settingKey,
toReal(values[c]),
toReal(values[c+10]),
toReal(values[c+20]),
c);
}
}
// double
else if (c>=40 && c<=59) {
creationInterface->setVariableDouble(settingKey,
toReal(values[c]),
c);
}
// int
else if (c>=60 && c<=99) {
creationInterface->setVariableInt(settingKey,
toInt(values[c]),
c);
}
// misc
else if (c>=0) {
creationInterface->setVariableString(settingKey,
values[c],
c);
}
}
/**
* Adds a layer that was read from the file via the creation interface.
*/
void DL_Jww::addLayer(DL_CreationInterface* creationInterface) {
// correct some impossible attributes for layers:
attrib = creationInterface->getAttributes();
if (attrib.getColor()==256 || attrib.getColor()==0) {
attrib.setColor(7);
}
if (attrib.getWidth()<0) {
attrib.setWidth(1);
}
if (!strcasecmp(attrib.getLineType().c_str(), "BYLAYER") ||
!strcasecmp(attrib.getLineType().c_str(), "BYBLOCK")) {
attrib.setLineType("CONTINUOUS");
}
// add layer
creationInterface->addLayer(DL_LayerData(values[2],
toInt(values[70])));
}
/**
* Adds a block that was read from the file via the creation interface.
*/
void DL_Jww::addBlock(DL_CreationInterface* creationInterface) {
DL_BlockData d(
// Name:
values[2],
// flags:
toInt(values[70]),
// base point:
toReal(values[10]),
toReal(values[20]),
toReal(values[30]));
creationInterface->addBlock(d);
}
/**
* Ends a block that was read from the file via the creation interface.
*/
void DL_Jww::endBlock(DL_CreationInterface* creationInterface) {
creationInterface->endBlock();
}
/**
* Adds a point entity that was read from the file via the creation interface.
*/
void DL_Jww::addPoint(DL_CreationInterface* creationInterface) {
DL_PointData d(toReal(values[10]),
toReal(values[20]),
toReal(values[30]));
creationInterface->addPoint(d);
}
/**
* Adds a line entity that was read from the file via the creation interface.
*/
void DL_Jww::addLine(DL_CreationInterface* creationInterface) {
DL_LineData d(toReal(values[10]),
toReal(values[20]),
toReal(values[30]),
toReal(values[11]),
toReal(values[21]),
toReal(values[31]));
creationInterface->addLine(d);
}
/**
* Adds a polyline entity that was read from the file via the creation interface.
*/
void DL_Jww::addPolyline(DL_CreationInterface* creationInterface) {
DL_PolylineData pd(maxVertices, toInt(values[71], 0), toInt(values[72], 0), toInt(values[70], 0));
creationInterface->addPolyline(pd);
if (currentEntity==DL_ENTITY_LWPOLYLINE) {
for (int i=0; i<maxVertices; i++) {
DL_VertexData d(vertices[i*4],
vertices[i*4+1],
vertices[i*4+2],
vertices[i*4+3]);
creationInterface->addVertex(d);
}
creationInterface->endEntity();
}
}
/**
* Adds a polyline vertex entity that was read from the file
* via the creation interface.
*/
void DL_Jww::addVertex(DL_CreationInterface* creationInterface) {
DL_VertexData d(toReal(values[10]),
toReal(values[20]),
toReal(values[30]),
//bulge);
toReal(values[42]));
//bulge = toReal(values[42]);
creationInterface->addVertex(d);
}
/**
* Adds a spline entity that was read from the file via the creation interface.
*/
void DL_Jww::addSpline(DL_CreationInterface* creationInterface) {
DL_SplineData sd(toInt(values[71], 3), toInt(values[72], 0),
toInt(values[73], 0), toInt(values[70], 4));
creationInterface->addSpline(sd);
for (int i=0; i<maxControlPoints; i++) {
DL_ControlPointData d(controlPoints[i*3],
controlPoints[i*3+1],
controlPoints[i*3+2]);
creationInterface->addControlPoint(d);
}
}
/**
* Adds a knot to the previously added spline.
*/
/*
void DL_Jww::addKnot(DL_CreationInterface* creationInterface) {
std::cout << "DL_Jww::addKnot\n";
}
*/
/**
* Adds a control point to the previously added spline.
*/
/*
void DL_Jww::addControlPoint(DL_CreationInterface* creationInterface) {
std::cout << "DL_Jww::addControlPoint\n";
}
*/
/**
* Adds an arc entity that was read from the file via the creation interface.
*/
void DL_Jww::addArc(DL_CreationInterface* creationInterface) {
DL_ArcData d(toReal(values[10]),
toReal(values[20]),
toReal(values[30]),
toReal(values[40]),
toReal(values[50]),
toReal(values[51]));
creationInterface->addArc(d);
}
/**
* Adds a circle entity that was read from the file via the creation interface.
*/
void DL_Jww::addCircle(DL_CreationInterface* creationInterface) {
DL_CircleData d(toReal(values[10]),
toReal(values[20]),
toReal(values[30]),
toReal(values[40]));
creationInterface->addCircle(d);
}
/**
* Adds an ellipse entity that was read from the file via the creation interface.
*/
void DL_Jww::addEllipse(DL_CreationInterface* creationInterface) {
DL_EllipseData d(toReal(values[10]),
toReal(values[20]),
toReal(values[30]),
toReal(values[11]),
toReal(values[21]),
toReal(values[31]),
toReal(values[40], 1.0),
toReal(values[41], 0.0),
toReal(values[42], 2*M_PI));
creationInterface->addEllipse(d);
}
/**
* Adds an insert entity that was read from the file via the creation interface.
*/
void DL_Jww::addInsert(DL_CreationInterface* creationInterface) {
DL_InsertData d(values[2],
// insertion point
toReal(values[10], 0.0),
toReal(values[20], 0.0),
toReal(values[30], 0.0),
// scale:
toReal(values[41], 1.0),
toReal(values[42], 1.0),
toReal(values[43], 1.0),
// angle:
toReal(values[50], 0.0),
// cols / rows:
toInt(values[70], 1),
toInt(values[71], 1),
// spacing:
toReal(values[44], 0.0),
toReal(values[45], 0.0));
creationInterface->addInsert(d);
}
/**
* Adds a trace entity (4 edge closed polyline) that was read from the file via the creation interface.
*
* @author AHM
*/
void DL_Jww::addTrace(DL_CreationInterface* creationInterface) {
DL_TraceData td;
for (int k = 0; k < 4; k++) {
td.x[k] = toReal(values[10 + k]);
td.y[k] = toReal(values[20 + k]);
td.z[k] = toReal(values[30 + k]);
}
creationInterface->addTrace(td);
}
/**
* Adds a solid entity (filled trace) that was read from the file via the creation interface.
*
* @author AHM
*/
void DL_Jww::addSolid(DL_CreationInterface* creationInterface) {
DL_SolidData sd;
for (int k = 0; k < 4; k++) {
sd.x[k] = toReal(values[10 + k]);
sd.y[k] = toReal(values[20 + k]);
sd.z[k] = toReal(values[30 + k]);
}
creationInterface->addSolid(sd);
}
/**
* Adds an MText entity that was read from the file via the creation interface.
*/
void DL_Jww::addMText(DL_CreationInterface* creationInterface) {
double angle = 0.0;
if (values[50][0]!='\0') {
if (libVersion<=0x02000200) {
// wrong but compatible with dxflib <=2.0.2.0:
angle = toReal(values[50], 0.0);
} else {
angle = (toReal(values[50], 0.0)*2*M_PI)/360.0;
}
} else if (values[11][0]!='\0' && values[21][0]!='\0') {
double x = toReal(values[11], 0.0);
double y = toReal(values[21], 0.0);
if (fabs(x)<1.0e-6) {
if (y>0.0) {
angle = M_PI/2.0;
} else {
angle = M_PI/2.0*3.0;
}
} else {
angle = atan(y/x);
}
}
DL_MTextData d(
// insertion point
toReal(values[10], 0.0),
toReal(values[20], 0.0),
toReal(values[30], 0.0),
// height
toReal(values[40], 2.5),
// width
toReal(values[41], 100.0),
// attachment point
toInt(values[71], 1),
// drawing direction
toInt(values[72], 1),
// line spacing style
toInt(values[73], 1),
// line spacing factor
toReal(values[44], 1.0),
// text
values[1],
// style
values[7],
// angle
angle);
creationInterface->addMText(d);
}
/**
* Handles additional MText data.
*/
bool DL_Jww::handleMTextData(DL_CreationInterface* creationInterface) {
// Special handling of text chunks for MTEXT entities:
if (groupCode==3) {
creationInterface->addMTextChunk(groupValue);
return true;
}
return false;
}
/**
* Handles additional polyline data.
*/
bool DL_Jww::handleLWPolylineData(DL_CreationInterface* /*creationInterface*/) {
// Allocate LWPolyline vertices (group code 90):
if (groupCode==90) {
maxVertices = toInt(groupValue);
if (maxVertices>0) {
if (vertices!=NULL) {
delete[] vertices;
}
vertices = new double[4*maxVertices];
for (int i=0; i<maxVertices; ++i) {
vertices[i*4] = 0.0;
vertices[i*4+1] = 0.0;
vertices[i*4+2] = 0.0;
vertices[i*4+3] = 0.0;
}
}
vertexIndex=-1;
return true;
}
// Compute LWPolylines vertices (group codes 10/20/30/42):
else if (groupCode==10 || groupCode==20 ||
groupCode==30 || groupCode==42) {
if (vertexIndex<maxVertices-1 && groupCode==10) {
vertexIndex++;
}
if (groupCode<=30) {
if (vertexIndex>=0 && vertexIndex<maxVertices) {
vertices[4*vertexIndex + (groupCode/10-1)]
= toReal(groupValue);
}
} else if (groupCode==42 && vertexIndex<maxVertices) {
vertices[4*vertexIndex + 3] = toReal(groupValue);
}
return true;
}
return false;
}
/**
* Handles additional spline data.
*/
bool DL_Jww::handleSplineData(DL_CreationInterface* /*creationInterface*/) {
// Allocate Spline knots (group code 72):
if (groupCode==72) {
maxKnots = toInt(groupValue);
if (maxKnots>0) {
if (knots!=NULL) {
delete[] knots;
}
knots = new double[maxKnots];
for (int i=0; i<maxKnots; ++i) {
knots[i] = 0.0;
}
}
knotIndex=-1;
return true;
}
// Allocate Spline control points (group code 73):
else if (groupCode==73) {
maxControlPoints = toInt(groupValue);
if (maxControlPoints>0) {
if (controlPoints!=NULL) {
delete[] controlPoints;
}
controlPoints = new double[3*maxControlPoints];
for (int i=0; i<maxControlPoints; ++i) {
controlPoints[i*3] = 0.0;
controlPoints[i*3+1] = 0.0;
controlPoints[i*3+2] = 0.0;
}
}
controlPointIndex=-1;
return true;
}
// Compute spline knot vertices (group code 40):
else if (groupCode==40) {
if (knotIndex<maxKnots-1) {
knotIndex++;
knots[knotIndex] = toReal(groupValue);
}
return true;
}
// Compute spline control points (group codes 10/20/30):
else if (groupCode==10 || groupCode==20 ||
groupCode==30) {
if (controlPointIndex<maxControlPoints-1 && groupCode==10) {
controlPointIndex++;
}
if (controlPointIndex>=0 && controlPointIndex<maxControlPoints) {
controlPoints[3*controlPointIndex + (groupCode/10-1)]
= toReal(groupValue);
}
return true;
}
return false;
}
/**
* Handles additional leader data.
*/
bool DL_Jww::handleLeaderData(DL_CreationInterface* /*creationInterface*/) {
// Allocate Leader vertices (group code 76):
if (groupCode==76) {
maxLeaderVertices = toInt(groupValue);
if (maxLeaderVertices>0) {
if (leaderVertices!=NULL) {
delete[] leaderVertices;
}
leaderVertices = new double[3*maxLeaderVertices];
for (int i=0; i<maxLeaderVertices; ++i) {
leaderVertices[i*3] = 0.0;
leaderVertices[i*3+1] = 0.0;
leaderVertices[i*3+2] = 0.0;
}
}
leaderVertexIndex=-1;
return true;
}
// Compute Leader vertices (group codes 10/20/30):
else if (groupCode==10 || groupCode==20 || groupCode==30) {
if (leaderVertexIndex<maxLeaderVertices-1 && groupCode==10) {
leaderVertexIndex++;
}
if (groupCode<=30) {
if (leaderVertexIndex>=0 &&
leaderVertexIndex<maxLeaderVertices) {
leaderVertices[3*leaderVertexIndex + (groupCode/10-1)]
= toReal(groupValue);
}
}
return true;
}
return false;
}
/**
* Handles additional hatch data.
*/
bool DL_Jww::handleHatchData(DL_CreationInterface* /*creationInterface*/) {
static int firstPolylineStatus = 0;
// Allocate hatch loops (group code 91):
if (groupCode==91 && toInt(groupValue)>0) {
//std::cout << "allocating " << toInt(groupValue) << " loops\n";
if (hatchLoops!=NULL) {
delete[] hatchLoops;
hatchLoops = NULL;
}
if (maxHatchEdges!=NULL) {
delete[] maxHatchEdges;
maxHatchEdges = NULL;
}
if (hatchEdgeIndex!=NULL) {
delete[] hatchEdgeIndex;
hatchEdgeIndex = NULL;
}
if (hatchEdges!=NULL) {
for (int i=0; i<maxHatchLoops; ++i) {
delete[] hatchEdges[i];
}
delete[] hatchEdges;
hatchEdges = NULL;
}
maxHatchLoops = toInt(groupValue);
//std::cout << "maxHatchLoops: " << maxHatchLoops << "\n";
if (maxHatchLoops>0) {
hatchLoops = new DL_HatchLoopData[maxHatchLoops];
maxHatchEdges = new int[maxHatchLoops];
hatchEdgeIndex = new int[maxHatchLoops];
hatchEdges = new DL_HatchEdgeData*[maxHatchLoops];
//std::cout << "new hatchEdges[" << maxHatchLoops << "]\n";
for (int i=0; i<maxHatchLoops; ++i) {
hatchEdges[i] = NULL;
//std::cout << "hatchEdges[" << i << "] = NULL\n";
maxHatchEdges[i] = 0;
}
hatchLoopIndex = -1;
dropEdges = false;
}
//std::cout << "done\n";
return true;
}
// Allocate hatch edges, group code 93
if (groupCode==93 && toInt(groupValue)>0) {
if (hatchLoopIndex<maxHatchLoops-1 && hatchLoops!=NULL &&
maxHatchEdges!=NULL && hatchEdgeIndex!=NULL &&
hatchEdges!=NULL) {
//std::cout << " allocating " << toInt(groupValue) << " edges\n";
dropEdges = false;
hatchLoopIndex++;
hatchLoops[hatchLoopIndex]
= DL_HatchLoopData(toInt(groupValue));
maxHatchEdges[hatchLoopIndex] = toInt(groupValue);
hatchEdgeIndex[hatchLoopIndex] = -1;
hatchEdges[hatchLoopIndex]
= new DL_HatchEdgeData[toInt(groupValue)];
//std::cout << "hatchEdges[" << hatchLoopIndex << "] = new "
// << toInt(groupValue) << "\n";
firstPolylineStatus = 0;
} else {
//std::cout << "dropping " << toInt(groupValue) << " edges\n";
dropEdges = true;
}
//std::cout << "done\n";
return true;
}
// Init hatch edge for non-polyline boundary (group code 72)
if (hatchEdges!=NULL &&
hatchEdgeIndex!=NULL &&
maxHatchEdges!=NULL &&
hatchLoopIndex>=0 &&
hatchLoopIndex<maxHatchLoops &&
hatchEdgeIndex[hatchLoopIndex] <
maxHatchEdges[hatchLoopIndex] &&
(atoi(values[92])&2)==0 && // not a polyline
groupCode==72 &&
!dropEdges) {
//std::cout << "Init hatch edge for non-polyline boundary\n";
//std::cout << "hatchLoopIndex: " << hatchLoopIndex << "\n";
//std::cout << "maxHatchLoops: " << maxHatchLoops << "\n";
hatchEdgeIndex[hatchLoopIndex]++;
//std::cout << " init edge: type: "
//<< toInt(groupValue)
//<< " index: " << hatchEdgeIndex[hatchLoopIndex] << "\n";
hatchEdges[hatchLoopIndex][hatchEdgeIndex[hatchLoopIndex]]
.type = toInt(groupValue);
hatchEdges[hatchLoopIndex][hatchEdgeIndex[hatchLoopIndex]]
.defined = false;
//std::cout << "done\n";
return true;
}
// Handle hatch edges for non-polyline boundaries
// (group codes 10, 20, 11, 21, 40, 50, 51, 73)
if (!dropEdges &&
hatchEdges!=NULL &&
hatchEdgeIndex!=NULL &&
hatchLoopIndex>=0 &&
hatchLoopIndex<maxHatchLoops &&
hatchEdges[hatchLoopIndex]!=NULL &&
hatchEdgeIndex[hatchLoopIndex]>=0 &&
hatchEdgeIndex[hatchLoopIndex] <
maxHatchEdges[hatchLoopIndex] &&
((atoi(values[92])&2)==0) && // not a polyline
(groupCode==10 || groupCode==20 ||
groupCode==11 || groupCode==21 ||
groupCode==40 || groupCode==50 ||
groupCode==51 || groupCode==73)) {
//std::cout << "Handle hatch edge for non-polyline boundary\n";
//std::cout << " found edge data: " << groupCode << "\n";
//std::cout << " value: " << toReal(groupValue) << "\n";
// can crash:
//std::cout << " defined: "
// << (int)hatchEdges[hatchLoopIndex]
// [hatchEdgeIndex[hatchLoopIndex]].defined << "\n";
//std::cout << "92 flag: '" << values[92] << "'\n";
//std::cout << "92 flag (int): '" << atoi(values[92]) << "'\n";
if (hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].defined==false) {
if (hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].type==1) {
switch (groupCode) {
case 10:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].x1
= toReal(groupValue);
break;
case 20:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].y1
= toReal(groupValue);
break;
case 11:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].x2
= toReal(groupValue);
break;
case 21:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].y2
= toReal(groupValue);
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].defined = true;
break;
default:
break;
}
}
if (hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].type==2) {
switch (groupCode) {
case 10:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].cx
= toReal(groupValue);
break;
case 20:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].cy
= toReal(groupValue);
break;
case 40:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].radius
= toReal(groupValue);
break;
case 50:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].angle1
= toReal(groupValue)/360.0*2*M_PI;
break;
case 51:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].angle2
= toReal(groupValue)/360.0*2*M_PI;
break;
case 73:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].ccw
= (bool)toInt(groupValue);
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].defined = true;
break;
default:
break;
}
}
}
return true;
}
/*
// 2003/12/31: polyline hatches can be extremely slow and are rarely used
//
// Handle hatch edges for polyline boundaries
// (group codes 10, 20, 42)
if (!dropEdges &&
hatchEdges!=NULL &&
hatchEdgeIndex!=NULL &&
hatchLoopIndex>=0 &&
hatchLoopIndex<maxHatchLoops &&
hatchEdges[hatchLoopIndex]!=NULL &&
//hatchEdgeIndex[hatchLoopIndex]>=0 &&
hatchEdgeIndex[hatchLoopIndex] <
maxHatchEdges[hatchLoopIndex] &&
((atoi(values[92])&2)==2)) { // a polyline
if (groupCode==10 || groupCode==20 ||
groupCode==42) {
std::cout << " found polyline edge data: " << groupCode << "\n";
std::cout << " value: " << toReal(groupValue) << "\n";
static double lastX = 0.0;
static double lastY = 0.0;
static double lastB = 0.0;
if (firstPolylineStatus<2) {
switch (groupCode) {
case 10:
firstPolylineStatus++;
if (firstPolylineStatus==1) {
lastX = toReal(groupValue);
std::cout << " firstX: " << lastX << "\n";
}
break;
case 20:
lastY = toReal(groupValue);
std::cout << " firstY: " << lastY << "\n";
break;
case 42:
lastB = toReal(groupValue);
break;
default:
break;
}
if (firstPolylineStatus!=2) {
return true;
}
}
switch (groupCode) {
case 10:
hatchEdgeIndex[hatchLoopIndex]++;
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].type = 1;
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].x1
= lastX;
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].x2
= lastX = toReal(groupValue);
std::cout << " X: " << lastX << "\n";
break;
case 20:
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].y1
= lastY;
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].y2
= lastY = toReal(groupValue);
std::cout << " Y: " << lastY << "\n";
break;
/ *
case 42: {
// convert to arc:
double x1 = hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].x1;
double y1 = hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].y1;
double x2 = hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].x2;
double y2 = hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].y2;
double bulge = toReal(groupValue);
bool reversed = (bulge<0.0);
double alpha = atan(bulge)*4.0;
double radius;
double cx;
double cy;
double a1;
double a2;
double mx = (x2+x1)/2.0;
double my = (y2+y1)/2.0;
double dist = sqrt(pow(x2-x1,2) + pow(y2-y1,2)) / 2.0;
// alpha can't be 0.0 at this point
radius = fabs(dist / sin(alpha/2.0));
double wu = fabs(pow(radius, 2.0) - pow(dist, 2.0));
double h = sqrt(wu);
double angle = acos((x2-x1) / dist);
if (bulge>0.0) {
angle+=M_PI/2.0;
} else {
angle-=M_PI/2.0;
}
if (fabs(alpha)>M_PI) {
h*=-1.0;
}
cx = mx + cos(angle) * h;
cy = my + sin(angle) * h;
a1 = hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].type = 2;
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].ccw = (toReal(groupValue)>0.0);
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].cx = cx;
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].cy = cy;
hatchEdges[hatchLoopIndex]
[hatchEdgeIndex[hatchLoopIndex]].radius = radius;
} break;
* /
default:
break;
}
} else {
// end polyline boundary
dropEdges = true;
}
return true;
}
*/
return false;
}
/**
* Adds an text entity that was read from the file via the creation interface.
*/
void DL_Jww::addText(DL_CreationInterface* creationInterface) {
DL_TextData d(
// insertion point
toReal(values[10], 0.0),
toReal(values[20], 0.0),
toReal(values[30], 0.0),
// alignment point
toReal(values[11], 0.0),
toReal(values[21], 0.0),
toReal(values[31], 0.0),
// height
toReal(values[40], 2.5),
// x scale
toReal(values[41], 1.0),
// generation flags
toInt(values[71], 0),
// h just
toInt(values[72], 0),
// v just
toInt(values[73], 0),
// text
values[1],
// style
values[7],
// angle
(toReal(values[50], 0.0)*2*M_PI)/360.0);
creationInterface->addText(d);
}
/**
* Adds an attrib entity that was read from the file via the creation interface.
* @todo add attrib instead of normal text
*/
void DL_Jww::addAttrib(DL_CreationInterface* creationInterface) {
DL_TextData d(
// insertion point
toReal(values[10], 0.0),
toReal(values[20], 0.0),
toReal(values[30], 0.0),
// alignment point
toReal(values[11], 0.0),
toReal(values[21], 0.0),
toReal(values[31], 0.0),
// height
toReal(values[40], 2.5),
// x scale
toReal(values[41], 1.0),
// generation flags
toInt(values[71], 0),
// h just
toInt(values[72], 0),
// v just
toInt(values[74], 0),
// text
values[1],
// style
values[7],
// angle
(toReal(values[50], 0.0)*2*M_PI)/360.0);
creationInterface->addText(d);
}
/**
* @return dimension data from current values.
*/
DL_DimensionData DL_Jww::getDimData() {
// generic dimension data:
return DL_DimensionData(
// def point
toReal(values[10], 0.0),
toReal(values[20], 0.0),
toReal(values[30], 0.0),
// text middle point
toReal(values[11], 0.0),
toReal(values[21], 0.0),
toReal(values[31], 0.0),
// type
toInt(values[70], 0),
// attachment point
toInt(values[71], 5),
// line sp. style
toInt(values[72], 1),
// line sp. factor
toReal(values[41], 1.0),
// text
values[1],
// style
values[3],
// angle
toReal(values[53], 0.0));
}
/**
* Adds a linear dimension entity that was read from the file via the creation interface.
*/
void DL_Jww::addDimLinear(DL_CreationInterface* creationInterface) {
DL_DimensionData d = getDimData();
// horizontal / vertical / rotated dimension:
DL_DimLinearData dl(
// definition point 1
toReal(values[13], 0.0),
toReal(values[23], 0.0),
toReal(values[33], 0.0),
// definition point 2
toReal(values[14], 0.0),
toReal(values[24], 0.0),
toReal(values[34], 0.0),
// angle
toReal(values[50], 0.0),
// oblique
toReal(values[52], 0.0));
creationInterface->addDimLinear(d, dl);
}
/**
* Adds an aligned dimension entity that was read from the file via the creation interface.
*/
void DL_Jww::addDimAligned(DL_CreationInterface* creationInterface) {
DL_DimensionData d = getDimData();
// aligned dimension:
DL_DimAlignedData da(
// extension point 1
toReal(values[13], 0.0),
toReal(values[23], 0.0),
toReal(values[33], 0.0),
// extension point 2
toReal(values[14], 0.0),
toReal(values[24], 0.0),
toReal(values[34], 0.0));
creationInterface->addDimAlign(d, da);
}
/**
* Adds a radial dimension entity that was read from the file via the creation interface.
*/
void DL_Jww::addDimRadial(DL_CreationInterface* creationInterface) {
DL_DimensionData d = getDimData();
DL_DimRadialData dr(
// definition point
toReal(values[15], 0.0),
toReal(values[25], 0.0),
toReal(values[35], 0.0),
// leader length:
toReal(values[40], 0.0));
creationInterface->addDimRadial(d, dr);
}
/**
* Adds a diametric dimension entity that was read from the file via the creation interface.
*/
void DL_Jww::addDimDiametric(DL_CreationInterface* creationInterface) {
DL_DimensionData d = getDimData();
// diametric dimension:
DL_DimDiametricData dr(
// definition point
toReal(values[15], 0.0),
toReal(values[25], 0.0),
toReal(values[35], 0.0),
// leader length:
toReal(values[40], 0.0));
creationInterface->addDimDiametric(d, dr);
}
/**
* Adds an angular dimension entity that was read from the file via the creation interface.
*/
void DL_Jww::addDimAngular(DL_CreationInterface* creationInterface) {
DL_DimensionData d = getDimData();
// angular dimension:
DL_DimAngularData da(
// definition point 1
toReal(values[13], 0.0),
toReal(values[23], 0.0),
toReal(values[33], 0.0),
// definition point 2
toReal(values[14], 0.0),
toReal(values[24], 0.0),
toReal(values[34], 0.0),
// definition point 3
toReal(values[15], 0.0),
toReal(values[25], 0.0),
toReal(values[35], 0.0),
// definition point 4
toReal(values[16], 0.0),
toReal(values[26], 0.0),
toReal(values[36], 0.0));
creationInterface->addDimAngular(d, da);
}
/**
* Adds an angular dimension entity that was read from the file via the creation interface.
*/
void DL_Jww::addDimAngular3P(DL_CreationInterface* creationInterface) {
DL_DimensionData d = getDimData();
// angular dimension (3P):
DL_DimAngular3PData da(
// definition point 1
toReal(values[13], 0.0),
toReal(values[23], 0.0),
toReal(values[33], 0.0),
// definition point 2
toReal(values[14], 0.0),
toReal(values[24], 0.0),
toReal(values[34], 0.0),
// definition point 3
toReal(values[15], 0.0),
toReal(values[25], 0.0),
toReal(values[35], 0.0));
creationInterface->addDimAngular3P(d, da);
}
/**
* Adds a leader entity that was read from the file via the creation interface.
*/
void DL_Jww::addLeader(DL_CreationInterface* creationInterface) {
// leader (arrow)
DL_LeaderData le(
// arrow head flag
toInt(values[71], 1),
// leader path type
toInt(values[72], 0),
// Leader creation flag
toInt(values[73], 3),
// Hookline direction flag
toInt(values[74], 1),
// Hookline flag
toInt(values[75], 0),
// Text annotation height
toReal(values[40], 1.0),
// Text annotation width
toReal(values[41], 1.0),
// Number of vertices in leader
toInt(values[76], 0)
);
creationInterface->addLeader(le);
for (int i=0; i<maxLeaderVertices; i++) {
DL_LeaderVertexData d(leaderVertices[i*3],
leaderVertices[i*3+1],
leaderVertices[i*3+2]);
creationInterface->addLeaderVertex(d);
}
}
/**
* Adds a hatch entity that was read from the file via the creation interface.
*/
void DL_Jww::addHatch(DL_CreationInterface* creationInterface) {
DL_HatchData hd(toInt(values[91], 1),
toInt(values[70], 0),
toReal(values[41], 1.0),
toReal(values[52], 0.0),
values[2]);
creationInterface->addHatch(hd);
for (int l=0; l<maxHatchLoops; l++) {
DL_HatchLoopData ld(maxHatchEdges[l]);
creationInterface->addHatchLoop(ld);
for (int b=0; b<maxHatchEdges[l]; b++) {
creationInterface->addHatchEdge(hatchEdges[l][b]);
}
}
creationInterface->endEntity();
currentEntity = DL_UNKNOWN;
}
/**
* Adds an image entity that was read from the file via the creation interface.
*/
void DL_Jww::addImage(DL_CreationInterface* creationInterface) {
DL_ImageData id(// pass ref insead of name we don't have yet
values[340],
// ins point:
toReal(values[10], 0.0),
toReal(values[20], 0.0),
toReal(values[30], 0.0),
// u vector:
toReal(values[11], 1.0),
toReal(values[21], 0.0),
toReal(values[31], 0.0),
// v vector:
toReal(values[12], 0.0),
toReal(values[22], 1.0),
toReal(values[32], 0.0),
// image size (pixel):
toInt(values[13], 1),
toInt(values[23], 1),
// brightness, contrast, fade
toInt(values[281], 50),
toInt(values[282], 50),
toInt(values[283], 0));
creationInterface->addImage(id);
creationInterface->endEntity();
currentEntity = DL_UNKNOWN;
}
/**
* Adds an image definition that was read from the file via the creation interface.
*/
void DL_Jww::addImageDef(DL_CreationInterface* creationInterface) {
DL_ImageDefData id(// handle
values[5],
values[1]);
creationInterface->linkImage(id);
creationInterface->endEntity();
currentEntity = DL_UNKNOWN;
}
/**
* Ends some special entities like hatches or old style polylines.
*/
void DL_Jww::endEntity(DL_CreationInterface* creationInterface) {
creationInterface->endEntity();
}
/**
* Ends a sequence and notifies the creation interface.
*/
void DL_Jww::endSequence(DL_CreationInterface* creationInterface) {
creationInterface->endSequence();
}
/**
* Converts the given string into an int.
* ok is set to false if there was an error.
*/
int DL_Jww::stringToInt(const char* s, bool* ok) {
if (ok!=NULL) {
// check string:
*ok = true;
int i=0;
bool dot = false;
do {
if (s[i]=='\0') {
break;
} else if (s[i]=='.') {
if (dot==true) {
//std::cerr << "two dots\n";
*ok = false;
} else {
dot = true;
}
} else if (s[i]<'0' || s[i]>'9') {
//std::cerr << "NaN: '" << s[i] << "'\n";
*ok = false;
}
i++;
} while(s[i]!='\0' && *ok==true);
}
return atoi(s);
}
/**
* @brief Opens the given file for writing and returns a pointer
* to the dxf writer. This pointer needs to be passed on to other
* writing functions.
*
* @param file Full path of the file to open.
*
* @return Pointer to an ascii dxf writer object.
*/
DL_WriterA* DL_Jww::out(const char* file, DL_Codes::version version) {
char* f = new char[strlen(file)+1];
strcpy(f, file);
this->version = version;
DL_WriterA* dw = new DL_WriterA(f, version);
if (dw->openFailed()) {
delete dw;
return NULL;
} else {
return dw;
}
}
/**
* @brief Writes a DXF header to the file currently opened
* by the given DXF writer object.
*/
void DL_Jww::writeHeader(DL_WriterA& dw) {
dw.comment("dxflib " DL_VERSION);
dw.sectionHeader();
dw.dxfString(9, "$ACADVER");
switch (version) {
case DL_Codes::AC1009:
dw.dxfString(1, "AC1009");
break;
case DL_Codes::AC1012:
dw.dxfString(1, "AC1012");
break;
case DL_Codes::AC1014:
dw.dxfString(1, "AC1014");
break;
case DL_Codes::AC1015:
dw.dxfString(1, "AC1015");
break;
}
// Newer version require that (otherwise a*cad crashes..)
if (version==VER_2000) {
dw.dxfString(9, "$HANDSEED");
dw.dxfHex(5, 0xFFFF);
}
//dw.sectionEnd();
}
/**
* Writes a point entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writePoint(DL_WriterA& dw,
const DL_PointData& data,
const DL_Attributes& attrib) {
dw.entity("POINT");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbPoint");
}
dw.entityAttributes(attrib);
dw.coord(POINT_COORD_CODE, data.x, data.y);
}
/**
* Writes a line entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeLine(DL_WriterA& dw,
const DL_LineData& data,
const DL_Attributes& attrib) {
dw.entity("LINE");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbLine");
}
dw.entityAttributes(attrib);
dw.coord(LINE_START_CODE, data.x1, data.y1);
dw.coord(LINE_END_CODE, data.x2, data.y2);
}
/**
* Writes a polyline entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
* @see writeVertex
*/
void DL_Jww::writePolyline(DL_WriterA& dw,
const DL_PolylineData& data,
const DL_Attributes& attrib) {
if (version==VER_2000) {
dw.entity("LWPOLYLINE");
dw.entityAttributes(attrib);
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbPolyline");
dw.dxfInt(90, (int)data.number);
dw.dxfInt(70, data.flags);
} else {
dw.entity("POLYLINE");
dw.entityAttributes(attrib);
polylineLayer = attrib.getLayer();
dw.dxfInt(66, 1);
dw.dxfInt(70, data.flags);
dw.coord(VERTEX_COORD_CODE, 0.0, 0.0);
}
}
/**
* Writes a single vertex of a polyline to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeVertex(DL_WriterA& dw,
const DL_VertexData& data) {
if (version==VER_2000) {
dw.dxfReal(10, data.x);
dw.dxfReal(20, data.y);
if (fabs(data.bulge)>1.0e-10) {
dw.dxfReal(42, data.bulge);
}
} else {
dw.entity("VERTEX");
//dw.entityAttributes(attrib);
dw.dxfString(8, polylineLayer);
dw.coord(VERTEX_COORD_CODE, data.x, data.y);
if (fabs(data.bulge)>1.0e-10) {
dw.dxfReal(42, data.bulge);
}
}
}
/**
* Writes the polyline end. Only needed for DXF R12.
*/
void DL_Jww::writePolylineEnd(DL_WriterA& dw) {
if (version==VER_2000) {
} else {
dw.entity("SEQEND");
}
}
/**
* Writes a spline entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
* @see writeControlPoint
*/
void DL_Jww::writeSpline(DL_WriterA& dw,
const DL_SplineData& data,
const DL_Attributes& attrib) {
dw.entity("SPLINE");
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbSpline");
}
dw.dxfInt(70, data.flags);
dw.dxfInt(71, data.degree);
dw.dxfInt(72, data.nKnots); // number of knots
dw.dxfInt(73, data.nControl); // number of control points
dw.dxfInt(74, 0); // number of fit points
}
/**
* Writes a single control point of a spline to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeControlPoint(DL_WriterA& dw,
const DL_ControlPointData& data) {
dw.dxfReal(10, data.x);
dw.dxfReal(20, data.y);
dw.dxfReal(30, data.z);
}
/**
* Writes a single knot of a spline to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeKnot(DL_WriterA& dw,
const DL_KnotData& data) {
dw.dxfReal(40, data.k);
}
/**
* Writes a circle entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeCircle(DL_WriterA& dw,
const DL_CircleData& data,
const DL_Attributes& attrib) {
dw.entity("CIRCLE");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbCircle");
}
dw.entityAttributes(attrib);
dw.coord(10, data.cx, data.cy);
dw.dxfReal(40, data.radius);
}
/**
* Writes an arc entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeArc(DL_WriterA& dw,
const DL_ArcData& data,
const DL_Attributes& attrib) {
dw.entity("ARC");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
}
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbCircle");
}
dw.coord(10, data.cx, data.cy);
dw.dxfReal(40, data.radius);
if (version==VER_2000) {
dw.dxfString(100, "AcDbArc");
}
dw.dxfReal(50, data.angle1);
dw.dxfReal(51, data.angle2);
}
/**
* Writes an ellipse entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeEllipse(DL_WriterA& dw,
const DL_EllipseData& data,
const DL_Attributes& attrib) {
if (version>VER_R12) {
dw.entity("ELLIPSE");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbEllipse");
}
dw.entityAttributes(attrib);
dw.coord(10, data.cx, data.cy);
dw.coord(11, data.mx, data.my);
dw.dxfReal(40, data.ratio);
dw.dxfReal(41, data.angle1);
dw.dxfReal(42, data.angle2);
}
}
/**
* Writes an insert to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeInsert(DL_WriterA& dw,
const DL_InsertData& data,
const DL_Attributes& attrib) {
if (data.name.empty()) {
std::cerr << "DL_Jww::writeInsert: "
<< "Block name must not be empty\n";
return;
}
dw.entity("INSERT");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbBlockReference");
}
dw.entityAttributes(attrib);
dw.dxfString(2, data.name);
dw.dxfReal(10, data.ipx);
dw.dxfReal(20, data.ipy);
dw.dxfReal(30, 0.0);
if (data.sx!=1.0 || data.sy!=1.0) {
dw.dxfReal(41, data.sx);
dw.dxfReal(42, data.sy);
dw.dxfReal(43, 1.0);
}
if (data.angle!=0.0) {
dw.dxfReal(50, data.angle);
}
if (data.cols!=1 || data.rows!=1) {
dw.dxfInt(70, data.cols);
dw.dxfInt(71, data.rows);
}
if (data.colSp!=0.0 || data.rowSp!=0.0) {
dw.dxfReal(44, data.colSp);
dw.dxfReal(45, data.rowSp);
}
}
/**
* Writes a multi text entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeMText(DL_WriterA& dw,
const DL_MTextData& data,
const DL_Attributes& attrib) {
dw.entity("MTEXT");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbMText");
}
dw.entityAttributes(attrib);
dw.dxfReal(10, data.ipx);
dw.dxfReal(20, data.ipy);
dw.dxfReal(30, 0.0);
dw.dxfReal(40, data.height);
dw.dxfReal(41, data.width);
dw.dxfInt(71, data.attachmentPoint);
dw.dxfInt(72, data.drawingDirection);
// Creare text chunks of 250 characters each:
int length = data.text.length();
char chunk[251];
int i;
for (i=250; i<length; i+=250) {
strncpy(chunk, &data.text.c_str()[i-250], 250);
chunk[250]='\0';
dw.dxfString(3, chunk);
}
strncpy(chunk, &data.text.c_str()[i-250], 250);
chunk[250]='\0';
dw.dxfString(1, chunk);
dw.dxfString(7, data.style);
// since dxflib 2.0.2.1: degrees not rad (error in autodesk dxf doc)
dw.dxfReal(50, data.angle/(2.0*M_PI)*360.0);
dw.dxfInt(73, data.lineSpacingStyle);
dw.dxfReal(44, data.lineSpacingFactor);
}
/**
* Writes a text entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeText(DL_WriterA& dw,
const DL_TextData& data,
const DL_Attributes& attrib) {
dw.entity("TEXT");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbText");
}
dw.entityAttributes(attrib);
dw.dxfReal(10, data.ipx);
dw.dxfReal(20, data.ipy);
dw.dxfReal(30, 0.0);
dw.dxfReal(40, data.height);
dw.dxfString(1, data.text);
dw.dxfReal(50, data.angle/(2*M_PI)*360.0);
dw.dxfReal(41, data.xScaleFactor);
dw.dxfString(7, data.style);
dw.dxfInt(71, data.textGenerationFlags);
dw.dxfInt(72, data.hJustification);
dw.dxfReal(11, data.apx);
dw.dxfReal(21, data.apy);
dw.dxfReal(31, 0.0);
dw.dxfInt(73, data.vJustification);
}
/**
* Writes an aligned dimension entity to the file.
*
* @param dw DXF writer
* @param data Generic dimension data for from the file
* @param data Specific aligned dimension data from the file
* @param attrib Attributes
*/
void DL_Jww::writeDimAligned(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimAlignedData& edata,
const DL_Attributes& attrib) {
dw.entity("DIMENSION");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
}
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbDimension");
}
dw.dxfReal(10, data.dpx);
dw.dxfReal(20, data.dpy);
dw.dxfReal(30, 0.0);
dw.dxfReal(11, data.mpx);
dw.dxfReal(21, data.mpy);
dw.dxfReal(31, 0.0);
dw.dxfInt(70, 1);
if (version>VER_R12) {
dw.dxfInt(71, data.attachmentPoint);
dw.dxfInt(72, data.lineSpacingStyle); // opt
dw.dxfReal(41, data.lineSpacingFactor); // opt
}
dw.dxfReal(42, data.angle);
dw.dxfString(1, data.text); // opt
//dw.dxfString(3, data.style);
dw.dxfString(3, "Standard");
if (version==VER_2000) {
dw.dxfString(100, "AcDbAlignedDimension");
}
dw.dxfReal(13, edata.epx1);
dw.dxfReal(23, edata.epy1);
dw.dxfReal(33, 0.0);
dw.dxfReal(14, edata.epx2);
dw.dxfReal(24, edata.epy2);
dw.dxfReal(34, 0.0);
}
/**
* Writes a linear dimension entity to the file.
*
* @param dw DXF writer
* @param data Generic dimension data for from the file
* @param data Specific linear dimension data from the file
* @param attrib Attributes
*/
void DL_Jww::writeDimLinear(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimLinearData& edata,
const DL_Attributes& attrib) {
dw.entity("DIMENSION");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
}
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbDimension");
}
dw.dxfReal(10, data.dpx);
dw.dxfReal(20, data.dpy);
dw.dxfReal(30, 0.0);
dw.dxfReal(11, data.mpx);
dw.dxfReal(21, data.mpy);
dw.dxfReal(31, 0.0);
dw.dxfInt(70, 0);
if (version>VER_R12) {
dw.dxfInt(71, data.attachmentPoint);
dw.dxfInt(72, data.lineSpacingStyle); // opt
dw.dxfReal(41, data.lineSpacingFactor); // opt
}
dw.dxfReal(42, data.angle);
dw.dxfString(1, data.text); // opt
//dw.dxfString(3, data.style);
dw.dxfString(3, "Standard");
if (version==VER_2000) {
dw.dxfString(100, "AcDbAlignedDimension");
}
dw.dxfReal(13, edata.dpx1);
dw.dxfReal(23, edata.dpy1);
dw.dxfReal(33, 0.0);
dw.dxfReal(14, edata.dpx2);
dw.dxfReal(24, edata.dpy2);
dw.dxfReal(34, 0.0);
dw.dxfReal(50, edata.angle/(2.0*M_PI)*360.0);
if (version==VER_2000) {
dw.dxfString(100, "AcDbRotatedDimension");
/*
dw.dxfString(1001, "ACAD");
dw.dxfString(1000, "DSTYLE");
dw.dxfString(1002, "{");
dw.dxfInt(1070, 340);
dw.dxfInt(1005, 11);
dw.dxfString(1002, "}");
*/
}
}
/**
* Writes a radial dimension entity to the file.
*
* @param dw DXF writer
* @param data Generic dimension data for from the file
* @param data Specific radial dimension data from the file
* @param attrib Attributes
*/
void DL_Jww::writeDimRadial(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimRadialData& edata,
const DL_Attributes& attrib) {
dw.entity("DIMENSION");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
}
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbDimension");
}
dw.dxfReal(10, data.dpx);
dw.dxfReal(20, data.dpy);
dw.dxfReal(30, 0.0);
dw.dxfReal(11, data.mpx);
dw.dxfReal(21, data.mpy);
dw.dxfReal(31, 0.0);
dw.dxfInt(70, 4);
if (version>VER_R12) {
dw.dxfInt(71, data.attachmentPoint);
dw.dxfInt(72, data.lineSpacingStyle); // opt
dw.dxfReal(41, data.lineSpacingFactor); // opt
}
dw.dxfReal(42, data.angle);
dw.dxfString(1, data.text); // opt
//dw.dxfString(3, data.style);
dw.dxfString(3, "Standard");
if (version==VER_2000) {
dw.dxfString(100, "AcDbRadialDimension");
}
dw.dxfReal(15, edata.dpx);
dw.dxfReal(25, edata.dpy);
dw.dxfReal(35, 0.0);
dw.dxfReal(40, edata.leader);
}
/**
* Writes a diametric dimension entity to the file.
*
* @param dw DXF writer
* @param data Generic dimension data for from the file
* @param data Specific diametric dimension data from the file
* @param attrib Attributes
*/
void DL_Jww::writeDimDiametric(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimDiametricData& edata,
const DL_Attributes& attrib) {
dw.entity("DIMENSION");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
}
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbDimension");
}
dw.dxfReal(10, data.dpx);
dw.dxfReal(20, data.dpy);
dw.dxfReal(30, 0.0);
dw.dxfReal(11, data.mpx);
dw.dxfReal(21, data.mpy);
dw.dxfReal(31, 0.0);
dw.dxfInt(70, 3);
if (version>VER_R12) {
dw.dxfInt(71, data.attachmentPoint);
dw.dxfInt(72, data.lineSpacingStyle); // opt
dw.dxfReal(41, data.lineSpacingFactor); // opt
}
dw.dxfReal(42, data.angle);
dw.dxfString(1, data.text); // opt
//dw.dxfString(3, data.style);
dw.dxfString(3, "Standard");
if (version==VER_2000) {
dw.dxfString(100, "AcDbDiametricDimension");
}
dw.dxfReal(15, edata.dpx);
dw.dxfReal(25, edata.dpy);
dw.dxfReal(35, 0.0);
dw.dxfReal(40, edata.leader);
}
/**
* Writes an angular dimension entity to the file.
*
* @param dw DXF writer
* @param data Generic dimension data for from the file
* @param data Specific angular dimension data from the file
* @param attrib Attributes
*/
void DL_Jww::writeDimAngular(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimAngularData& edata,
const DL_Attributes& attrib) {
dw.entity("DIMENSION");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
}
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbDimension");
}
dw.dxfReal(10, data.dpx);
dw.dxfReal(20, data.dpy);
dw.dxfReal(30, 0.0);
dw.dxfReal(11, data.mpx);
dw.dxfReal(21, data.mpy);
dw.dxfReal(31, 0.0);
dw.dxfInt(70, 2);
if (version>VER_R12) {
dw.dxfInt(71, data.attachmentPoint);
dw.dxfInt(72, data.lineSpacingStyle); // opt
dw.dxfReal(41, data.lineSpacingFactor); // opt
}
dw.dxfReal(42, data.angle);
dw.dxfString(1, data.text); // opt
//dw.dxfString(3, data.style);
dw.dxfString(3, "Standard");
if (version==VER_2000) {
dw.dxfString(100, "AcDb2LineAngularDimension");
}
dw.dxfReal(13, edata.dpx1);
dw.dxfReal(23, edata.dpy1);
dw.dxfReal(33, 0.0);
dw.dxfReal(14, edata.dpx2);
dw.dxfReal(24, edata.dpy2);
dw.dxfReal(34, 0.0);
dw.dxfReal(15, edata.dpx3);
dw.dxfReal(25, edata.dpy3);
dw.dxfReal(35, 0.0);
dw.dxfReal(16, edata.dpx4);
dw.dxfReal(26, edata.dpy4);
dw.dxfReal(36, 0.0);
}
/**
* Writes an angular dimension entity (3 points version) to the file.
*
* @param dw DXF writer
* @param data Generic dimension data for from the file
* @param data Specific angular dimension data from the file
* @param attrib Attributes
*/
void DL_Jww::writeDimAngular3P(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimAngular3PData& edata,
const DL_Attributes& attrib) {
dw.entity("DIMENSION");
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
}
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbDimension");
}
dw.dxfReal(10, data.dpx);
dw.dxfReal(20, data.dpy);
dw.dxfReal(30, 0.0);
dw.dxfReal(11, data.mpx);
dw.dxfReal(21, data.mpy);
dw.dxfReal(31, 0.0);
dw.dxfInt(70, 5);
if (version>VER_R12) {
dw.dxfInt(71, data.attachmentPoint);
dw.dxfInt(72, data.lineSpacingStyle); // opt
dw.dxfReal(41, data.lineSpacingFactor); // opt
}
dw.dxfReal(42, data.angle);
dw.dxfString(1, data.text); // opt
//dw.dxfString(3, data.style);
dw.dxfString(3, "Standard");
if (version==VER_2000) {
dw.dxfString(100, "AcDb3PointAngularDimension");
}
dw.dxfReal(13, edata.dpx1);
dw.dxfReal(23, edata.dpy1);
dw.dxfReal(33, 0.0);
dw.dxfReal(14, edata.dpx2);
dw.dxfReal(24, edata.dpy2);
dw.dxfReal(34, 0.0);
dw.dxfReal(15, edata.dpx3);
dw.dxfReal(25, edata.dpy3);
dw.dxfReal(35, 0.0);
}
/**
* Writes a leader entity to the file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
* @see writeVertex
*/
void DL_Jww::writeLeader(DL_WriterA& dw,
const DL_LeaderData& data,
const DL_Attributes& attrib) {
if (version>VER_R12) {
dw.entity("LEADER");
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbLeader");
}
dw.dxfString(3, "Standard");
dw.dxfInt(71, data.arrowHeadFlag);
dw.dxfInt(72, data.leaderPathType);
dw.dxfInt(73, data.leaderCreationFlag);
dw.dxfInt(74, data.hooklineDirectionFlag);
dw.dxfInt(75, data.hooklineFlag);
dw.dxfReal(40, data.textAnnotationHeight);
dw.dxfReal(41, data.textAnnotationWidth);
dw.dxfInt(76, data.number);
}
}
/**
* Writes a single vertex of a leader to the file.
*
* @param dw DXF writer
* @param data Entity data
*/
void DL_Jww::writeLeaderVertex(DL_WriterA& dw,
const DL_LeaderVertexData& data) {
if (version>VER_R12) {
dw.dxfReal(10, data.x);
dw.dxfReal(20, data.y);
}
}
/**
* Writes the beginning of a hatch entity to the file.
* This must be followed by one or more writeHatchLoop()
* calls and a writeHatch2() call.
*
* @param dw DXF writer
* @param data Entity data.
* @param attrib Attributes
*/
void DL_Jww::writeHatch1(DL_WriterA& dw,
const DL_HatchData& data,
const DL_Attributes& attrib) {
dw.entity("HATCH");
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbHatch");
}
dw.dxfReal(10, 0.0); // elevation
dw.dxfReal(20, 0.0);
dw.dxfReal(30, 0.0);
dw.dxfReal(210, 0.0); // extrusion dir.
dw.dxfReal(220, 0.0);
dw.dxfReal(230, 1.0);
if (data.solid==false) {
dw.dxfString(2, data.pattern);
} else {
dw.dxfString(2, "SOLID");
}
dw.dxfInt(70, (int)data.solid);
dw.dxfInt(71, 0); // associative
dw.dxfInt(91, data.numLoops);
}
/**
* Writes the end of a hatch entity to the file.
*
* @param dw DXF writer
* @param data Entity data.
* @param attrib Attributes
*/
void DL_Jww::writeHatch2(DL_WriterA& dw,
const DL_HatchData& data,
const DL_Attributes& /*attrib*/) {
dw.dxfInt(75, 0); // odd parity
dw.dxfInt(76, 1); // pattern type
if (data.solid==false) {
dw.dxfReal(52, data.angle);
dw.dxfReal(41, data.scale);
dw.dxfInt(77, 0); // not double
//dw.dxfInt(78, 0);
dw.dxfInt(78, 1);
dw.dxfReal(53, 45.0);
dw.dxfReal(43, 0.0);
dw.dxfReal(44, 0.0);
dw.dxfReal(45, -0.0883883476483184);
dw.dxfReal(46, 0.0883883476483185);
dw.dxfInt(79, 0);
}
dw.dxfInt(98, 0);
}
/**
* Writes the beginning of a hatch loop to the file. This
* must happen after writing the beginning of a hatch entity.
*
* @param dw DXF writer
* @param data Entity data.
* @param attrib Attributes
*/
void DL_Jww::writeHatchLoop1(DL_WriterA& dw,
const DL_HatchLoopData& data) {
dw.dxfInt(92, 1);
dw.dxfInt(93, data.numEdges);
//dw.dxfInt(97, 0);
}
/**
* Writes the end of a hatch loop to the file.
*
* @param dw DXF writer
* @param data Entity data.
* @param attrib Attributes
*/
void DL_Jww::writeHatchLoop2(DL_WriterA& dw,
const DL_HatchLoopData& /*data*/) {
dw.dxfInt(97, 0);
}
/**
* Writes the beginning of a hatch entity to the file.
*
* @param dw DXF writer
* @param data Entity data.
* @param attrib Attributes
*/
void DL_Jww::writeHatchEdge(DL_WriterA& dw,
const DL_HatchEdgeData& data) {
dw.dxfInt(72, data.type);
switch (data.type) {
case 1:
dw.dxfReal(10, data.x1);
dw.dxfReal(20, data.y1);
dw.dxfReal(11, data.x2);
dw.dxfReal(21, data.y2);
break;
case 2:
dw.dxfReal(10, data.cx);
dw.dxfReal(20, data.cy);
dw.dxfReal(40, data.radius);
dw.dxfReal(50, data.angle1/(2*M_PI)*360.0);
dw.dxfReal(51, data.angle2/(2*M_PI)*360.0);
dw.dxfInt(73, (int)(data.ccw));
break;
default:
break;
}
}
/**
* Writes an image entity.
*
* @return IMAGEDEF handle. Needed for the IMAGEDEF counterpart.
*/
int DL_Jww::writeImage(DL_WriterA& dw,
const DL_ImageData& data,
const DL_Attributes& attrib) {
/*if (data.file.empty()) {
std::cerr << "DL_Jww::writeImage: "
<< "Image file must not be empty\n";
return;
}*/
dw.entity("IMAGE");
dw.entityAttributes(attrib);
if (version==VER_2000) {
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbRasterImage");
dw.dxfInt(90, 0);
}
// insertion point
dw.dxfReal(10, data.ipx);
dw.dxfReal(20, data.ipy);
dw.dxfReal(30, 0.0);
// vector along bottom side (1 pixel long)
dw.dxfReal(11, data.ux);
dw.dxfReal(21, data.uy);
dw.dxfReal(31, 0.0);
// vector along left side (1 pixel long)
dw.dxfReal(12, data.vx);
dw.dxfReal(22, data.vy);
dw.dxfReal(32, 0.0);
// image size in pixel
dw.dxfReal(13, data.width);
dw.dxfReal(23, data.height);
// handle of IMAGEDEF object
int handle = dw.incHandle();
dw.dxfHex(340, handle);
// flags
dw.dxfInt(70, 15);
// clipping:
dw.dxfInt(280, 0);
// brightness, contrast, fade
dw.dxfInt(281, data.brightness);
dw.dxfInt(282, data.contrast);
dw.dxfInt(283, data.fade);
return handle;
}
/**
* Writes an image definiition entity.
*/
void DL_Jww::writeImageDef(DL_WriterA& dw,
int handle,
const DL_ImageData& data) {
/*if (data.file.empty()) {
std::cerr << "DL_Jww::writeImage: "
<< "Image file must not be empty\n";
return;
}*/
dw.dxfString(0, "IMAGEDEF");
if (version==VER_2000) {
dw.dxfHex(5, handle);
}
if (version==VER_2000) {
dw.dxfString(100, "AcDbRasterImageDef");
dw.dxfInt(90, 0);
}
// file name:
dw.dxfString(1, data.ref);
// image size in pixel
dw.dxfReal(10, data.width);
dw.dxfReal(20, data.height);
dw.dxfReal(11, 1.0);
dw.dxfReal(21, 1.0);
// loaded:
dw.dxfInt(280, 1);
// units:
dw.dxfInt(281, 0);
}
/**
* Writes a layer to the file. Layers are stored in the
* tables section of a DXF file.
*
* @param dw DXF writer
* @param data Entity data from the file
* @param attrib Attributes
*/
void DL_Jww::writeLayer(DL_WriterA& dw,
const DL_LayerData& data,
const DL_Attributes& attrib) {
if (data.name.empty()) {
std::cerr << "DL_Jww::writeLayer: "
<< "Layer name must not be empty\n";
return;
}
int color = attrib.getColor();
if (color<=0 || color>=256) {
std::cerr << "Layer color cannot be " << color << ". Changed to 7.\n";
color = 7;
}
if (data.name == "0") {
dw.tableLayerEntry(0x10);
} else {
dw.tableLayerEntry();
}
dw.dxfString(2, data.name);
dw.dxfInt(70, data.flags);
dw.dxfInt(62, color);
dw.dxfString(6, (attrib.getLineType().length()==0 ?
string("CONTINUOUS") : attrib.getLineType()));
if (version>=VER_2000) {
// layer defpoints cannot be plotted
std::string lstr = data.name;
std::transform(lstr.begin(), lstr.end(), lstr.begin(), tolower);
if (lstr=="defpoints") {
dw.dxfInt(290, 0);
}
}
if (version>=VER_2000 && attrib.getWidth()!=-1) {
dw.dxfInt(370, attrib.getWidth());
}
if (version>=VER_2000) {
dw.dxfHex(390, 0xF);
}
}
/**
* Writes a line type to the file. Line types are stored in the
* tables section of a DXF file.
*/
void DL_Jww::writeLineType(DL_WriterA& dw,
const DL_LineTypeData& data) {
//const char* description,
//int elements,
//double patternLength) {
if (data.name.empty()) {
std::cerr << "DL_Jww::writeLineType: "
<< "Line type name must not be empty\n";
return;
}
// ignore BYLAYER, BYBLOCK for R12
if (version<VER_2000) {
if (!strcasecmp(data.name.c_str(), "BYBLOCK") ||
!strcasecmp(data.name.c_str(), "BYLAYER")) {
return;
}
}
// write id (not for R12)
if (!strcasecmp(data.name.c_str(), "BYBLOCK")) {
dw.tableLineTypeEntry(0x14);
} else if (!strcasecmp(data.name.c_str(), "BYLAYER")) {
dw.tableLineTypeEntry(0x15);
} else if (!strcasecmp(data.name.c_str(), "CONTINUOUS")) {
dw.tableLineTypeEntry(0x16);
} else {
dw.tableLineTypeEntry();
}
dw.dxfString(2, data.name);
//if (version>=VER_2000) {
dw.dxfInt(70, data.flags);
//}
if (!strcasecmp(data.name.c_str(), "BYBLOCK")) {
dw.dxfString(3, "");
dw.dxfInt(72, 65);
dw.dxfInt(73, 0);
dw.dxfReal(40, 0.0);
} else if (!strcasecmp(data.name.c_str(), "BYLAYER")) {
dw.dxfString(3, "");
dw.dxfInt(72, 65);
dw.dxfInt(73, 0);
dw.dxfReal(40, 0.0);
} else if (!strcasecmp(data.name.c_str(), "CONTINUOUS")) {
dw.dxfString(3, "Solid line");
dw.dxfInt(72, 65);
dw.dxfInt(73, 0);
dw.dxfReal(40, 0.0);
} else if (!strcasecmp(data.name.c_str(), "ACAD_ISO02W100")) {
dw.dxfString(3, "ISO Dashed __ __ __ __ __ __ __ __ __ __ _");
dw.dxfInt(72, 65);
dw.dxfInt(73, 2);
dw.dxfReal(40, 15.0);
dw.dxfReal(49, 12.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "ACAD_ISO03W100")) {
dw.dxfString(3, "ISO Dashed with Distance __ __ __ _");
dw.dxfInt(72, 65);
dw.dxfInt(73, 2);
dw.dxfReal(40, 30.0);
dw.dxfReal(49, 12.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -18.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "ACAD_ISO04W100")) {
dw.dxfString(3, "ISO Long Dashed Dotted ____ . ____ . __");
dw.dxfInt(72, 65);
dw.dxfInt(73, 4);
dw.dxfReal(40, 30.0);
dw.dxfReal(49, 24.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "ACAD_ISO05W100")) {
dw.dxfString(3, "ISO Long Dashed Double Dotted ____ .. __");
dw.dxfInt(72, 65);
dw.dxfInt(73, 6);
dw.dxfReal(40, 33.0);
dw.dxfReal(49, 24.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "BORDER")) {
dw.dxfString(3, "Border __ __ . __ __ . __ __ . __ __ . __ __ .");
dw.dxfInt(72, 65);
dw.dxfInt(73, 6);
dw.dxfReal(40, 44.45);
dw.dxfReal(49, 12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "BORDER2")) {
dw.dxfString(3, "Border (.5x) __.__.__.__.__.__.__.__.__.__.__.");
dw.dxfInt(72, 65);
dw.dxfInt(73, 6);
dw.dxfReal(40, 22.225);
dw.dxfReal(49, 6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "BORDERX2")) {
dw.dxfString(3, "Border (2x) ____ ____ . ____ ____ . ___");
dw.dxfInt(72, 65);
dw.dxfInt(73, 6);
dw.dxfReal(40, 88.9);
dw.dxfReal(49, 25.4);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 25.4);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "CENTER")) {
dw.dxfString(3, "Center ____ _ ____ _ ____ _ ____ _ ____ _ ____");
dw.dxfInt(72, 65);
dw.dxfInt(73, 4);
dw.dxfReal(40, 50.8);
dw.dxfReal(49, 31.75);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "CENTER2")) {
dw.dxfString(3, "Center (.5x) ___ _ ___ _ ___ _ ___ _ ___ _ ___");
dw.dxfInt(72, 65);
dw.dxfInt(73, 4);
dw.dxfReal(40, 28.575);
dw.dxfReal(49, 19.05);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "CENTERX2")) {
dw.dxfString(3, "Center (2x) ________ __ ________ __ _____");
dw.dxfInt(72, 65);
dw.dxfInt(73, 4);
dw.dxfReal(40, 101.6);
dw.dxfReal(49, 63.5);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DASHDOT")) {
dw.dxfString(3, "Dash dot __ . __ . __ . __ . __ . __ . __ . __");
dw.dxfInt(72, 65);
dw.dxfInt(73, 4);
dw.dxfReal(40, 25.4);
dw.dxfReal(49, 12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DASHDOT2")) {
dw.dxfString(3, "Dash dot (.5x) _._._._._._._._._._._._._._._.");
dw.dxfInt(72, 65);
dw.dxfInt(73, 4);
dw.dxfReal(40, 12.7);
dw.dxfReal(49, 6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DASHDOTX2")) {
dw.dxfString(3, "Dash dot (2x) ____ . ____ . ____ . ___");
dw.dxfInt(72, 65);
dw.dxfInt(73, 4);
dw.dxfReal(40, 50.8);
dw.dxfReal(49, 25.4);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DASHED")) {
dw.dxfString(3, "Dashed __ __ __ __ __ __ __ __ __ __ __ __ __ _");
dw.dxfInt(72, 65);
dw.dxfInt(73, 2);
dw.dxfReal(40, 19.05);
dw.dxfReal(49, 12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DASHED2")) {
dw.dxfString(3, "Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _");
dw.dxfInt(72, 65);
dw.dxfInt(73, 2);
dw.dxfReal(40, 9.525);
dw.dxfReal(49, 6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DASHEDX2")) {
dw.dxfString(3, "Dashed (2x) ____ ____ ____ ____ ____ ___");
dw.dxfInt(72, 65);
dw.dxfInt(73, 2);
dw.dxfReal(40, 38.1);
dw.dxfReal(49, 25.4);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DIVIDE")) {
dw.dxfString(3, "Divide ____ . . ____ . . ____ . . ____ . . ____");
dw.dxfInt(72, 65);
dw.dxfInt(73, 6);
dw.dxfReal(40, 31.75);
dw.dxfReal(49, 12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DIVIDE2")) {
dw.dxfString(3, "Divide (.5x) __..__..__..__..__..__..__..__.._");
dw.dxfInt(72, 65);
dw.dxfInt(73, 6);
dw.dxfReal(40, 15.875);
dw.dxfReal(49, 6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DIVIDEX2")) {
dw.dxfString(3, "Divide (2x) ________ . . ________ . . _");
dw.dxfInt(72, 65);
dw.dxfInt(73, 6);
dw.dxfReal(40, 63.5);
dw.dxfReal(49, 25.4);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DOT")) {
dw.dxfString(3, "Dot . . . . . . . . . . . . . . . . . . . . . .");
dw.dxfInt(72, 65);
dw.dxfInt(73, 2);
dw.dxfReal(40, 6.35);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -6.35);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DOT2")) {
dw.dxfString(3, "Dot (.5x) .....................................");
dw.dxfInt(72, 65);
dw.dxfInt(73, 2);
dw.dxfReal(40, 3.175);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -3.175);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else if (!strcasecmp(data.name.c_str(), "DOTX2")) {
dw.dxfString(3, "Dot (2x) . . . . . . . . . . . . .");
dw.dxfInt(72, 65);
dw.dxfInt(73, 2);
dw.dxfReal(40, 12.7);
dw.dxfReal(49, 0.0);
if (version>=VER_R13)
dw.dxfInt(74, 0);
dw.dxfReal(49, -12.7);
if (version>=VER_R13)
dw.dxfInt(74, 0);
} else {
std::cerr << "dxflib warning: DL_Jww::writeLineType: Unknown Line Type\n";
}
}
/**
* Writes the APPID section to the DXF file.
*
* @param name Application name
*/
void DL_Jww::writeAppid(DL_WriterA& dw, const string& name) {
if (name.empty()) {
std::cerr << "DL_Jww::writeAppid: "
<< "Application name must not be empty\n";
return;
}
if (!strcasecmp(name.c_str(), "ACAD")) {
dw.tableAppidEntry(0x12);
} else {
dw.tableAppidEntry();
}
dw.dxfString(2, name);
dw.dxfInt(70, 0);
}
/**
* Writes a block's definition (no entities) to the DXF file.
*/
void DL_Jww::writeBlock(DL_WriterA& dw, const DL_BlockData& data) {
if (data.name.empty()) {
std::cerr << "DL_Jww::writeBlock: "
<< "Block name must not be empty\n";
return;
}
//bool paperSpace = !strcasecmp(name, "*paper_space");
//!strcasecmp(name, "*paper_space0");
if (!strcasecmp(data.name.c_str(), "*paper_space")) {
dw.sectionBlockEntry(0x1C);
} else if (!strcasecmp(data.name.c_str(), "*model_space")) {
dw.sectionBlockEntry(0x20);
} else if (!strcasecmp(data.name.c_str(), "*paper_space0")) {
dw.sectionBlockEntry(0x24);
} else {
dw.sectionBlockEntry();
}
dw.dxfString(2, data.name);
dw.dxfInt(70, 0);
dw.coord(10, data.bpx, data.bpy);
dw.dxfString(3, data.name);
dw.dxfString(1, "");
}
/**
* Writes a block end.
*
* @param name Block name
*/
void DL_Jww::writeEndBlock(DL_WriterA& dw, const string& name) {
if (!strcasecmp(name.c_str(), "*paper_space")) {
dw.sectionBlockEntryEnd(0x1D);
} else if (!strcasecmp(name.c_str(), "*model_space")) {
dw.sectionBlockEntryEnd(0x21);
} else if (!strcasecmp(name.c_str(), "*paper_space0")) {
dw.sectionBlockEntryEnd(0x25);
} else {
dw.sectionBlockEntryEnd();
}
}
/**
* Writes a viewport section. This section is needed in VER_R13.
* Note that this method currently only writes a faked VPORT section
* to make the file readable by Aut*cad.
*/
void DL_Jww::writeVPort(DL_WriterA& dw) {
dw.dxfString(0, "TABLE");
dw.dxfString(2, "VPORT");
if (version==VER_2000) {
dw.dxfHex(5, 0x8);
}
//dw.dxfHex(330, 0);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTable");
}
dw.dxfInt(70, 1);
dw.dxfString(0, "VPORT");
//dw.dxfHex(5, 0x2F);
if (version==VER_2000) {
dw.handle();
}
//dw.dxfHex(330, 8);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTableRecord");
dw.dxfString(100, "AcDbViewportTableRecord");
}
dw.dxfString( 2, "*Active");
dw.dxfInt( 70, 0);
dw.dxfReal( 10, 0.0);
dw.dxfReal( 20, 0.0);
dw.dxfReal( 11, 1.0);
dw.dxfReal( 21, 1.0);
dw.dxfReal( 12, 286.3055555555555);
dw.dxfReal( 22, 148.5);
dw.dxfReal( 13, 0.0);
dw.dxfReal( 23, 0.0);
dw.dxfReal( 14, 10.0);
dw.dxfReal( 24, 10.0);
dw.dxfReal( 15, 10.0);
dw.dxfReal( 25, 10.0);
dw.dxfReal( 16, 0.0);
dw.dxfReal( 26, 0.0);
dw.dxfReal( 36, 1.0);
dw.dxfReal( 17, 0.0);
dw.dxfReal( 27, 0.0);
dw.dxfReal( 37, 0.0);
dw.dxfReal( 40, 297.0);
dw.dxfReal( 41, 1.92798353909465);
dw.dxfReal( 42, 50.0);
dw.dxfReal( 43, 0.0);
dw.dxfReal( 44, 0.0);
dw.dxfReal( 50, 0.0);
dw.dxfReal( 51, 0.0);
dw.dxfInt( 71, 0);
dw.dxfInt( 72, 100);
dw.dxfInt( 73, 1);
dw.dxfInt( 74, 3);
dw.dxfInt( 75, 1);
dw.dxfInt( 76, 1);
dw.dxfInt( 77, 0);
dw.dxfInt( 78, 0);
if (version==VER_2000) {
dw.dxfInt(281, 0);
dw.dxfInt( 65, 1);
dw.dxfReal(110, 0.0);
dw.dxfReal(120, 0.0);
dw.dxfReal(130, 0.0);
dw.dxfReal(111, 1.0);
dw.dxfReal(121, 0.0);
dw.dxfReal(131, 0.0);
dw.dxfReal(112, 0.0);
dw.dxfReal(122, 1.0);
dw.dxfReal(132, 0.0);
dw.dxfInt( 79, 0);
dw.dxfReal(146, 0.0);
}
dw.dxfString( 0, "ENDTAB");
}
/**
* Writes a style section. This section is needed in VER_R13.
* Note that this method currently only writes a faked STYLE section
* to make the file readable by Aut*cad.
*/
void DL_Jww::writeStyle(DL_WriterA& dw) {
dw.dxfString( 0, "TABLE");
dw.dxfString( 2, "STYLE");
if (version==VER_2000) {
dw.dxfHex(5, 3);
}
//dw.dxfHex(330, 0);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTable");
}
dw.dxfInt( 70, 1);
dw.dxfString( 0, "STYLE");
if (version==VER_2000) {
dw.dxfHex(5, 0x11);
}
//styleHandleStd = dw.handle();
//dw.dxfHex(330, 3);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTableRecord");
dw.dxfString(100, "AcDbTextStyleTableRecord");
}
dw.dxfString( 2, "Standard");
dw.dxfInt( 70, 0);
dw.dxfReal( 40, 0.0);
dw.dxfReal( 41, 0.75);
dw.dxfReal( 50, 0.0);
dw.dxfInt( 71, 0);
dw.dxfReal( 42, 2.5);
dw.dxfString( 3, "txt");
dw.dxfString( 4, "");
dw.dxfString( 0, "ENDTAB");
}
/**
* Writes a view section. This section is needed in VER_R13.
* Note that this method currently only writes a faked VIEW section
* to make the file readable by Aut*cad.
*/
void DL_Jww::writeView(DL_WriterA& dw) {
dw.dxfString( 0, "TABLE");
dw.dxfString( 2, "VIEW");
if (version==VER_2000) {
dw.dxfHex(5, 6);
}
//dw.dxfHex(330, 0);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTable");
}
dw.dxfInt( 70, 0);
dw.dxfString( 0, "ENDTAB");
}
/**
* Writes a ucs section. This section is needed in VER_R13.
* Note that this method currently only writes a faked UCS section
* to make the file readable by Aut*cad.
*/
void DL_Jww::writeUcs(DL_WriterA& dw) {
dw.dxfString( 0, "TABLE");
dw.dxfString( 2, "UCS");
if (version==VER_2000) {
dw.dxfHex(5, 7);
}
//dw.dxfHex(330, 0);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTable");
}
dw.dxfInt( 70, 0);
dw.dxfString( 0, "ENDTAB");
}
/**
* Writes a dimstyle section. This section is needed in VER_R13.
* Note that this method currently only writes a faked DIMSTYLE section
* to make the file readable by Aut*cad.
*/
void DL_Jww::writeDimStyle(DL_WriterA& dw,
double dimasz, double dimexe, double dimexo,
double dimgap, double dimtxt) {
dw.dxfString( 0, "TABLE");
dw.dxfString( 2, "DIMSTYLE");
if (version==VER_2000) {
dw.dxfHex(5, 0xA);
dw.dxfString(100, "AcDbSymbolTable");
}
dw.dxfInt( 70, 1);
if (version==VER_2000) {
dw.dxfString(100, "AcDbDimStyleTable");
dw.dxfInt( 71, 0);
}
dw.dxfString( 0, "DIMSTYLE");
if (version==VER_2000) {
dw.dxfHex(105, 0x27);
}
//dw.handle(105);
//dw.dxfHex(330, 0xA);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTableRecord");
dw.dxfString(100, "AcDbDimStyleTableRecord");
}
dw.dxfString( 2, "Standard");
if (version==VER_R12) {
dw.dxfString( 3, "");
dw.dxfString( 4, "");
dw.dxfString( 5, "");
dw.dxfString( 6, "");
dw.dxfString( 7, "");
dw.dxfReal( 40, 1.0);
}
dw.dxfReal( 41, dimasz);
dw.dxfReal( 42, dimexo);
dw.dxfReal( 43, 3.75);
dw.dxfReal( 44, dimexe);
if (version==VER_R12) {
dw.dxfReal( 45, 0.0);
dw.dxfReal( 46, 0.0);
dw.dxfReal( 47, 0.0);
dw.dxfReal( 48, 0.0);
}
dw.dxfInt( 70, 0);
if (version==VER_R12) {
dw.dxfInt( 71, 0);
dw.dxfInt( 72, 0);
}
dw.dxfInt( 73, 0);
dw.dxfInt( 74, 0);
if (version==VER_R12) {
dw.dxfInt( 75, 0);
dw.dxfInt( 76, 0);
}
dw.dxfInt( 77, 1);
dw.dxfInt( 78, 8);
dw.dxfReal(140, dimtxt);
dw.dxfReal(141, 2.5);
if (version==VER_R12) {
dw.dxfReal(142, 0.0);
}
dw.dxfReal(143, 0.03937007874016);
if (version==VER_R12) {
dw.dxfReal(144, 1.0);
dw.dxfReal(145, 0.0);
dw.dxfReal(146, 1.0);
}
dw.dxfReal(147, dimgap);
if (version==VER_R12) {
dw.dxfInt(170, 0);
}
dw.dxfInt(171, 3);
dw.dxfInt(172, 1);
if (version==VER_R12) {
dw.dxfInt(173, 0);
dw.dxfInt(174, 0);
dw.dxfInt(175, 0);
dw.dxfInt(176, 0);
dw.dxfInt(177, 0);
dw.dxfInt(178, 0);
}
if (version==VER_2000) {
dw.dxfInt(271, 2);
dw.dxfInt(272, 2);
dw.dxfInt(274, 3);
dw.dxfInt(278, 44);
dw.dxfInt(283, 0);
dw.dxfInt(284, 8);
//dw.dxfHex(340, styleHandleStd);
dw.dxfHex(340, 0x11);
}
// * /
dw.dxfString( 0, "ENDTAB");
}
/**
* Writes a blockrecord section. This section is needed in VER_R13.
* Note that this method currently only writes a faked BLOCKRECORD section
* to make the file readable by Aut*cad.
*/
void DL_Jww::writeBlockRecord(DL_WriterA& dw) {
dw.dxfString( 0, "TABLE");
dw.dxfString( 2, "BLOCK_RECORD");
if (version==VER_2000) {
dw.dxfHex(5, 1);
}
//dw.dxfHex(330, 0);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTable");
}
dw.dxfInt( 70, 1);
dw.dxfString( 0, "BLOCK_RECORD");
if (version==VER_2000) {
dw.dxfHex(5, 0x1F);
}
//int msh = dw.handle();
//dw.setModelSpaceHandle(msh);
//dw.dxfHex(330, 1);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTableRecord");
dw.dxfString(100, "AcDbBlockTableRecord");
}
dw.dxfString( 2, "*Model_Space");
dw.dxfHex(340, 0x22);
dw.dxfString( 0, "BLOCK_RECORD");
if (version==VER_2000) {
dw.dxfHex(5, 0x1B);
}
//int psh = dw.handle();
//dw.setPaperSpaceHandle(psh);
//dw.dxfHex(330, 1);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTableRecord");
dw.dxfString(100, "AcDbBlockTableRecord");
}
dw.dxfString( 2, "*Paper_Space");
dw.dxfHex(340, 0x1E);
dw.dxfString( 0, "BLOCK_RECORD");
if (version==VER_2000) {
dw.dxfHex(5, 0x23);
}
//int ps0h = dw.handle();
//dw.setPaperSpace0Handle(ps0h);
//dw.dxfHex(330, 1);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTableRecord");
dw.dxfString(100, "AcDbBlockTableRecord");
}
dw.dxfString( 2, "*Paper_Space0");
dw.dxfHex(340, 0x26);
//dw.dxfString( 0, "ENDTAB");
}
/**
* Writes a single block record with the given name.
*/
void DL_Jww::writeBlockRecord(DL_WriterA& dw, const string& name) {
dw.dxfString( 0, "BLOCK_RECORD");
if (version==VER_2000) {
dw.handle();
}
//dw->dxfHex(330, 1);
if (version==VER_2000) {
dw.dxfString(100, "AcDbSymbolTableRecord");
dw.dxfString(100, "AcDbBlockTableRecord");
}
dw.dxfString( 2, name);
dw.dxfHex(340, 0);
}
/**
* Writes a objects section. This section is needed in VER_R13.
* Note that this method currently only writes a faked OBJECTS section
* to make the file readable by Aut*cad.
*/
void DL_Jww::writeObjects(DL_WriterA& dw) {
//int dicId, dicId2, dicId3, dicId4, dicId5;
//int dicId5;
dw.dxfString( 0, "SECTION");
dw.dxfString( 2, "OBJECTS");
dw.dxfString( 0, "DICTIONARY");
dw.dxfHex(5, 0xC); // C
//dw.dxfHex(330, 0);
dw.dxfString(100, "AcDbDictionary");
dw.dxfInt(280, 0);
dw.dxfInt(281, 1);
dw.dxfString( 3, "ACAD_GROUP");
//dw.dxfHex(350, dw.getNextHandle()); // D
dw.dxfHex(350, 0xD); // D
dw.dxfString( 3, "ACAD_LAYOUT");
dw.dxfHex(350, 0x1A);
//dw.dxfHex(350, dw.getNextHandle()+0); // 1A
dw.dxfString( 3, "ACAD_MLINESTYLE");
dw.dxfHex(350, 0x17);
//dw.dxfHex(350, dw.getNextHandle()+1); // 17
dw.dxfString( 3, "ACAD_PLOTSETTINGS");
dw.dxfHex(350, 0x19);
//dw.dxfHex(350, dw.getNextHandle()+2); // 19
dw.dxfString( 3, "ACAD_PLOTSTYLENAME");
dw.dxfHex(350, 0xE);
//dw.dxfHex(350, dw.getNextHandle()+3); // E
dw.dxfString( 3, "AcDbVariableDictionary");
dw.dxfHex(350, dw.getNextHandle()); // 2C
dw.dxfString( 0, "DICTIONARY");
dw.dxfHex(5, 0xD);
//dw.handle(); // D
//dw.dxfHex(330, 0xC);
dw.dxfString(100, "AcDbDictionary");
dw.dxfInt(280, 0);
dw.dxfInt(281, 1);
dw.dxfString( 0, "ACDBDICTIONARYWDFLT");
dw.dxfHex(5, 0xE);
//dicId4 = dw.handle(); // E
//dw.dxfHex(330, 0xC); // C
dw.dxfString(100, "AcDbDictionary");
dw.dxfInt(281, 1);
dw.dxfString( 3, "Normal");
dw.dxfHex(350, 0xF);
//dw.dxfHex(350, dw.getNextHandle()+5); // F
dw.dxfString(100, "AcDbDictionaryWithDefault");
dw.dxfHex(340, 0xF);
//dw.dxfHex(340, dw.getNextHandle()+5); // F
dw.dxfString( 0, "ACDBPLACEHOLDER");
dw.dxfHex(5, 0xF);
//dw.handle(); // F
//dw.dxfHex(330, dicId4); // E
dw.dxfString( 0, "DICTIONARY");
//dicId3 = dw.handle(); // 17
dw.dxfHex(5, 0x17);
//dw.dxfHex(330, 0xC); // C
dw.dxfString(100, "AcDbDictionary");
dw.dxfInt(280, 0);
dw.dxfInt(281, 1);
dw.dxfString( 3, "Standard");
dw.dxfHex(350, 0x18);
//dw.dxfHex(350, dw.getNextHandle()+5); // 18
dw.dxfString( 0, "MLINESTYLE");
dw.dxfHex(5, 0x18);
//dw.handle(); // 18
//dw.dxfHex(330, dicId3); // 17
dw.dxfString(100, "AcDbMlineStyle");
dw.dxfString( 2, "STANDARD");
dw.dxfInt( 70, 0);
dw.dxfString( 3, "");
dw.dxfInt( 62, 256);
dw.dxfReal( 51, 90.0);
dw.dxfReal( 52, 90.0);
dw.dxfInt( 71, 2);
dw.dxfReal( 49, 0.5);
dw.dxfInt( 62, 256);
dw.dxfString( 6, "BYLAYER");
dw.dxfReal( 49, -0.5);
dw.dxfInt( 62, 256);
dw.dxfString( 6, "BYLAYER");
dw.dxfString( 0, "DICTIONARY");
dw.dxfHex(5, 0x19);
//dw.handle(); // 17
//dw.dxfHex(330, 0xC); // C
dw.dxfString(100, "AcDbDictionary");
dw.dxfInt(280, 0);
dw.dxfInt(281, 1);
dw.dxfString( 0, "DICTIONARY");
//dicId2 = dw.handle(); // 1A
dw.dxfHex(5, 0x1A);
//dw.dxfHex(330, 0xC);
dw.dxfString(100, "AcDbDictionary");
dw.dxfInt(281, 1);
dw.dxfString( 3, "Layout1");
dw.dxfHex(350, 0x1E);
//dw.dxfHex(350, dw.getNextHandle()+2); // 1E
dw.dxfString( 3, "Layout2");
dw.dxfHex(350, 0x26);
//dw.dxfHex(350, dw.getNextHandle()+4); // 26
dw.dxfString( 3, "Model");
dw.dxfHex(350, 0x22);
//dw.dxfHex(350, dw.getNextHandle()+5); // 22
dw.dxfString( 0, "LAYOUT");
dw.dxfHex(5, 0x1E);
//dw.handle(); // 1E
//dw.dxfHex(330, dicId2); // 1A
dw.dxfString(100, "AcDbPlotSettings");
dw.dxfString( 1, "");
dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
dw.dxfString( 4, "");
dw.dxfString( 6, "");
dw.dxfReal( 40, 0.0);
dw.dxfReal( 41, 0.0);
dw.dxfReal( 42, 0.0);
dw.dxfReal( 43, 0.0);
dw.dxfReal( 44, 0.0);
dw.dxfReal( 45, 0.0);
dw.dxfReal( 46, 0.0);
dw.dxfReal( 47, 0.0);
dw.dxfReal( 48, 0.0);
dw.dxfReal( 49, 0.0);
dw.dxfReal(140, 0.0);
dw.dxfReal(141, 0.0);
dw.dxfReal(142, 1.0);
dw.dxfReal(143, 1.0);
dw.dxfInt( 70, 688);
dw.dxfInt( 72, 0);
dw.dxfInt( 73, 0);
dw.dxfInt( 74, 5);
dw.dxfString( 7, "");
dw.dxfInt( 75, 16);
dw.dxfReal(147, 1.0);
dw.dxfReal(148, 0.0);
dw.dxfReal(149, 0.0);
dw.dxfString(100, "AcDbLayout");
dw.dxfString( 1, "Layout1");
dw.dxfInt( 70, 1);
dw.dxfInt( 71, 1);
dw.dxfReal( 10, 0.0);
dw.dxfReal( 20, 0.0);
dw.dxfReal( 11, 420.0);
dw.dxfReal( 21, 297.0);
dw.dxfReal( 12, 0.0);
dw.dxfReal( 22, 0.0);
dw.dxfReal( 32, 0.0);
dw.dxfReal( 14, 1.000000000000000E+20);
dw.dxfReal( 24, 1.000000000000000E+20);
dw.dxfReal( 34, 1.000000000000000E+20);
dw.dxfReal( 15, -1.000000000000000E+20);
dw.dxfReal( 25, -1.000000000000000E+20);
dw.dxfReal( 35, -1.000000000000000E+20);
dw.dxfReal(146, 0.0);
dw.dxfReal( 13, 0.0);
dw.dxfReal( 23, 0.0);
dw.dxfReal( 33, 0.0);
dw.dxfReal( 16, 1.0);
dw.dxfReal( 26, 0.0);
dw.dxfReal( 36, 0.0);
dw.dxfReal( 17, 0.0);
dw.dxfReal( 27, 1.0);
dw.dxfReal( 37, 0.0);
dw.dxfInt( 76, 0);
//dw.dxfHex(330, dw.getPaperSpaceHandle()); // 1B
dw.dxfHex(330, 0x1B);
dw.dxfString( 0, "LAYOUT");
dw.dxfHex(5, 0x22);
//dw.handle(); // 22
//dw.dxfHex(330, dicId2); // 1A
dw.dxfString(100, "AcDbPlotSettings");
dw.dxfString( 1, "");
dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
dw.dxfString( 4, "");
dw.dxfString( 6, "");
dw.dxfReal( 40, 0.0);
dw.dxfReal( 41, 0.0);
dw.dxfReal( 42, 0.0);
dw.dxfReal( 43, 0.0);
dw.dxfReal( 44, 0.0);
dw.dxfReal( 45, 0.0);
dw.dxfReal( 46, 0.0);
dw.dxfReal( 47, 0.0);
dw.dxfReal( 48, 0.0);
dw.dxfReal( 49, 0.0);
dw.dxfReal(140, 0.0);
dw.dxfReal(141, 0.0);
dw.dxfReal(142, 1.0);
dw.dxfReal(143, 1.0);
dw.dxfInt( 70, 1712);
dw.dxfInt( 72, 0);
dw.dxfInt( 73, 0);
dw.dxfInt( 74, 0);
dw.dxfString( 7, "");
dw.dxfInt( 75, 0);
dw.dxfReal(147, 1.0);
dw.dxfReal(148, 0.0);
dw.dxfReal(149, 0.0);
dw.dxfString(100, "AcDbLayout");
dw.dxfString( 1, "Model");
dw.dxfInt( 70, 1);
dw.dxfInt( 71, 0);
dw.dxfReal( 10, 0.0);
dw.dxfReal( 20, 0.0);
dw.dxfReal( 11, 12.0);
dw.dxfReal( 21, 9.0);
dw.dxfReal( 12, 0.0);
dw.dxfReal( 22, 0.0);
dw.dxfReal( 32, 0.0);
dw.dxfReal( 14, 0.0);
dw.dxfReal( 24, 0.0);
dw.dxfReal( 34, 0.0);
dw.dxfReal( 15, 0.0);
dw.dxfReal( 25, 0.0);
dw.dxfReal( 35, 0.0);
dw.dxfReal(146, 0.0);
dw.dxfReal( 13, 0.0);
dw.dxfReal( 23, 0.0);
dw.dxfReal( 33, 0.0);
dw.dxfReal( 16, 1.0);
dw.dxfReal( 26, 0.0);
dw.dxfReal( 36, 0.0);
dw.dxfReal( 17, 0.0);
dw.dxfReal( 27, 1.0);
dw.dxfReal( 37, 0.0);
dw.dxfInt( 76, 0);
//dw.dxfHex(330, dw.getModelSpaceHandle()); // 1F
dw.dxfHex(330, 0x1F);
dw.dxfString( 0, "LAYOUT");
//dw.handle(); // 26
dw.dxfHex(5, 0x26);
//dw.dxfHex(330, dicId2); // 1A
dw.dxfString(100, "AcDbPlotSettings");
dw.dxfString( 1, "");
dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
dw.dxfString( 4, "");
dw.dxfString( 6, "");
dw.dxfReal( 40, 0.0);
dw.dxfReal( 41, 0.0);
dw.dxfReal( 42, 0.0);
dw.dxfReal( 43, 0.0);
dw.dxfReal( 44, 0.0);
dw.dxfReal( 45, 0.0);
dw.dxfReal( 46, 0.0);
dw.dxfReal( 47, 0.0);
dw.dxfReal( 48, 0.0);
dw.dxfReal( 49, 0.0);
dw.dxfReal(140, 0.0);
dw.dxfReal(141, 0.0);
dw.dxfReal(142, 1.0);
dw.dxfReal(143, 1.0);
dw.dxfInt( 70, 688);
dw.dxfInt( 72, 0);
dw.dxfInt( 73, 0);
dw.dxfInt( 74, 5);
dw.dxfString( 7, "");
dw.dxfInt( 75, 16);
dw.dxfReal(147, 1.0);
dw.dxfReal(148, 0.0);
dw.dxfReal(149, 0.0);
dw.dxfString(100, "AcDbLayout");
dw.dxfString( 1, "Layout2");
dw.dxfInt( 70, 1);
dw.dxfInt( 71, 2);
dw.dxfReal( 10, 0.0);
dw.dxfReal( 20, 0.0);
dw.dxfReal( 11, 12.0);
dw.dxfReal( 21, 9.0);
dw.dxfReal( 12, 0.0);
dw.dxfReal( 22, 0.0);
dw.dxfReal( 32, 0.0);
dw.dxfReal( 14, 0.0);
dw.dxfReal( 24, 0.0);
dw.dxfReal( 34, 0.0);
dw.dxfReal( 15, 0.0);
dw.dxfReal( 25, 0.0);
dw.dxfReal( 35, 0.0);
dw.dxfReal(146, 0.0);
dw.dxfReal( 13, 0.0);
dw.dxfReal( 23, 0.0);
dw.dxfReal( 33, 0.0);
dw.dxfReal( 16, 1.0);
dw.dxfReal( 26, 0.0);
dw.dxfReal( 36, 0.0);
dw.dxfReal( 17, 0.0);
dw.dxfReal( 27, 1.0);
dw.dxfReal( 37, 0.0);
dw.dxfInt( 76, 0);
//dw.dxfHex(330, dw.getPaperSpace0Handle()); // 23
dw.dxfHex(330, 0x23);
dw.dxfString( 0, "DICTIONARY");
//dw.dxfHex(5, 0x2C);
//dicId5 =
dw.handle(); // 2C
//dw.dxfHex(330, 0xC); // C
dw.dxfString(100, "AcDbDictionary");
dw.dxfInt(281, 1);
dw.dxfString( 3, "DIMASSOC");
//dw.dxfHex(350, 0x2F);
dw.dxfHex(350, dw.getNextHandle()+1); // 2E
dw.dxfString( 3, "HIDETEXT");
//dw.dxfHex(350, 0x2E);
dw.dxfHex(350, dw.getNextHandle()); // 2D
dw.dxfString( 0, "DICTIONARYVAR");
//dw.dxfHex(5, 0x2E);
dw.handle(); // 2E
//dw.dxfHex(330, dicId5); // 2C
dw.dxfString(100, "DictionaryVariables");
dw.dxfInt(280, 0);
dw.dxfInt( 1, 2);
dw.dxfString( 0, "DICTIONARYVAR");
//dw.dxfHex(5, 0x2D);
dw.handle(); // 2D
//dw.dxfHex(330, dicId5); // 2C
dw.dxfString(100, "DictionaryVariables");
dw.dxfInt(280, 0);
dw.dxfInt( 1, 1);
}
/**
* Writes the end of the objects section. This section is needed in VER_R13.
* Note that this method currently only writes a faked OBJECTS section
* to make the file readable by Aut*cad.
*/
void DL_Jww::writeObjectsEnd(DL_WriterA& dw) {
dw.dxfString( 0, "ENDSEC");
}
/**
* Checks if the given variable is known by the given DXF version.
*/
bool DL_Jww::checkVariable(const char* var, DL_Codes::version version) {
if (version>=VER_2000) {
return true;
} else if (version==VER_R12) {
// these are all the variables recognized by dxf r12:
if (!strcmp(var, "$ACADVER")) {
return true;
}
if (!strcmp(var, "$ACADVER")) {
return true;
}
if (!strcmp(var, "$ANGBASE")) {
return true;
}
if (!strcmp(var, "$ANGDIR")) {
return true;
}
if (!strcmp(var, "$ATTDIA")) {
return true;
}
if (!strcmp(var, "$ATTMODE")) {
return true;
}
if (!strcmp(var, "$ATTREQ")) {
return true;
}
if (!strcmp(var, "$AUNITS")) {
return true;
}
if (!strcmp(var, "$AUPREC")) {
return true;
}
if (!strcmp(var, "$AXISMODE")) {
return true;
}
if (!strcmp(var, "$AXISUNIT")) {
return true;
}
if (!strcmp(var, "$BLIPMODE")) {
return true;
}
if (!strcmp(var, "$CECOLOR")) {
return true;
}
if (!strcmp(var, "$CELTYPE")) {
return true;
}
if (!strcmp(var, "$CHAMFERA")) {
return true;
}
if (!strcmp(var, "$CHAMFERB")) {
return true;
}
if (!strcmp(var, "$CLAYER")) {
return true;
}
if (!strcmp(var, "$COORDS")) {
return true;
}
if (!strcmp(var, "$DIMALT")) {
return true;
}
if (!strcmp(var, "$DIMALTD")) {
return true;
}
if (!strcmp(var, "$DIMALTF")) {
return true;
}
if (!strcmp(var, "$DIMAPOST")) {
return true;
}
if (!strcmp(var, "$DIMASO")) {
return true;
}
if (!strcmp(var, "$DIMASZ")) {
return true;
}
if (!strcmp(var, "$DIMBLK")) {
return true;
}
if (!strcmp(var, "$DIMBLK1")) {
return true;
}
if (!strcmp(var, "$DIMBLK2")) {
return true;
}
if (!strcmp(var, "$DIMCEN")) {
return true;
}
if (!strcmp(var, "$DIMCLRD")) {
return true;
}
if (!strcmp(var, "$DIMCLRE")) {
return true;
}
if (!strcmp(var, "$DIMCLRT")) {
return true;
}
if (!strcmp(var, "$DIMDLE")) {
return true;
}
if (!strcmp(var, "$DIMDLI")) {
return true;
}
if (!strcmp(var, "$DIMEXE")) {
return true;
}
if (!strcmp(var, "$DIMEXO")) {
return true;
}
if (!strcmp(var, "$DIMGAP")) {
return true;
}
if (!strcmp(var, "$DIMLFAC")) {
return true;
}
if (!strcmp(var, "$DIMLIM")) {
return true;
}
if (!strcmp(var, "$DIMPOST")) {
return true;
}
if (!strcmp(var, "$DIMRND")) {
return true;
}
if (!strcmp(var, "$DIMSAH")) {
return true;
}
if (!strcmp(var, "$DIMSCALE")) {
return true;
}
if (!strcmp(var, "$DIMSE1")) {
return true;
}
if (!strcmp(var, "$DIMSE2")) {
return true;
}
if (!strcmp(var, "$DIMSHO")) {
return true;
}
if (!strcmp(var, "$DIMSOXD")) {
return true;
}
if (!strcmp(var, "$DIMSTYLE")) {
return true;
}
if (!strcmp(var, "$DIMTAD")) {
return true;
}
if (!strcmp(var, "$DIMTFAC")) {
return true;
}
if (!strcmp(var, "$DIMTIH")) {
return true;
}
if (!strcmp(var, "$DIMTIX")) {
return true;
}
if (!strcmp(var, "$DIMTM")) {
return true;
}
if (!strcmp(var, "$DIMTOFL")) {
return true;
}
if (!strcmp(var, "$DIMTOH")) {
return true;
}
if (!strcmp(var, "$DIMTOL")) {
return true;
}
if (!strcmp(var, "$DIMTP")) {
return true;
}
if (!strcmp(var, "$DIMTSZ")) {
return true;
}
if (!strcmp(var, "$DIMTVP")) {
return true;
}
if (!strcmp(var, "$DIMTXT")) {
return true;
}
if (!strcmp(var, "$DIMZIN")) {
return true;
}
if (!strcmp(var, "$DWGCODEPAGE")) {
return true;
}
if (!strcmp(var, "$DRAGMODE")) {
return true;
}
if (!strcmp(var, "$ELEVATION")) {
return true;
}
if (!strcmp(var, "$EXTMAX")) {
return true;
}
if (!strcmp(var, "$EXTMIN")) {
return true;
}
if (!strcmp(var, "$FILLETRAD")) {
return true;
}
if (!strcmp(var, "$FILLMODE")) {
return true;
}
if (!strcmp(var, "$HANDLING")) {
return true;
}
if (!strcmp(var, "$HANDSEED")) {
return true;
}
if (!strcmp(var, "$INSBASE")) {
return true;
}
if (!strcmp(var, "$LIMCHECK")) {
return true;
}
if (!strcmp(var, "$LIMMAX")) {
return true;
}
if (!strcmp(var, "$LIMMIN")) {
return true;
}
if (!strcmp(var, "$LTSCALE")) {
return true;
}
if (!strcmp(var, "$LUNITS")) {
return true;
}
if (!strcmp(var, "$LUPREC")) {
return true;
}
if (!strcmp(var, "$MAXACTVP")) {
return true;
}
if (!strcmp(var, "$MENU")) {
return true;
}
if (!strcmp(var, "$MIRRTEXT")) {
return true;
}
if (!strcmp(var, "$ORTHOMODE")) {
return true;
}
if (!strcmp(var, "$OSMODE")) {
return true;
}
if (!strcmp(var, "$PDMODE")) {
return true;
}
if (!strcmp(var, "$PDSIZE")) {
return true;
}
if (!strcmp(var, "$PELEVATION")) {
return true;
}
if (!strcmp(var, "$PEXTMAX")) {
return true;
}
if (!strcmp(var, "$PEXTMIN")) {
return true;
}
if (!strcmp(var, "$PLIMCHECK")) {
return true;
}
if (!strcmp(var, "$PLIMMAX")) {
return true;
}
if (!strcmp(var, "$PLIMMIN")) {
return true;
}
if (!strcmp(var, "$PLINEGEN")) {
return true;
}
if (!strcmp(var, "$PLINEWID")) {
return true;
}
if (!strcmp(var, "$PSLTSCALE")) {
return true;
}
if (!strcmp(var, "$PUCSNAME")) {
return true;
}
if (!strcmp(var, "$PUCSORG")) {
return true;
}
if (!strcmp(var, "$PUCSXDIR")) {
return true;
}
if (!strcmp(var, "$PUCSYDIR")) {
return true;
}
if (!strcmp(var, "$QTEXTMODE")) {
return true;
}
if (!strcmp(var, "$REGENMODE")) {
return true;
}
if (!strcmp(var, "$SHADEDGE")) {
return true;
}
if (!strcmp(var, "$SHADEDIF")) {
return true;
}
if (!strcmp(var, "$SKETCHINC")) {
return true;
}
if (!strcmp(var, "$SKPOLY")) {
return true;
}
if (!strcmp(var, "$SPLFRAME")) {
return true;
}
if (!strcmp(var, "$SPLINESEGS")) {
return true;
}
if (!strcmp(var, "$SPLINETYPE")) {
return true;
}
if (!strcmp(var, "$SURFTAB1")) {
return true;
}
if (!strcmp(var, "$SURFTAB2")) {
return true;
}
if (!strcmp(var, "$SURFTYPE")) {
return true;
}
if (!strcmp(var, "$SURFU")) {
return true;
}
if (!strcmp(var, "$SURFV")) {
return true;
}
if (!strcmp(var, "$TDCREATE")) {
return true;
}
if (!strcmp(var, "$TDINDWG")) {
return true;
}
if (!strcmp(var, "$TDUPDATE")) {
return true;
}
if (!strcmp(var, "$TDUSRTIMER")) {
return true;
}
if (!strcmp(var, "$TEXTSIZE")) {
return true;
}
if (!strcmp(var, "$TEXTSTYLE")) {
return true;
}
if (!strcmp(var, "$THICKNESS")) {
return true;
}
if (!strcmp(var, "$TILEMODE")) {
return true;
}
if (!strcmp(var, "$TRACEWID")) {
return true;
}
if (!strcmp(var, "$UCSNAME")) {
return true;
}
if (!strcmp(var, "$UCSORG")) {
return true;
}
if (!strcmp(var, "$UCSXDIR")) {
return true;
}
if (!strcmp(var, "$UCSYDIR")) {
return true;
}
if (!strcmp(var, "$UNITMODE")) {
return true;
}
if (!strcmp(var, "$USERI1")) {
return true;
}
if (!strcmp(var, "$USERR1")) {
return true;
}
if (!strcmp(var, "$USRTIMER")) {
return true;
}
if (!strcmp(var, "$VISRETAIN")) {
return true;
}
if (!strcmp(var, "$WORLDVIEW")) {
return true;
}
if (!strcmp(var, "$FASTZOOM")) {
return true;
}
if (!strcmp(var, "$GRIDMODE")) {
return true;
}
if (!strcmp(var, "$GRIDUNIT")) {
return true;
}
if (!strcmp(var, "$SNAPANG")) {
return true;
}
if (!strcmp(var, "$SNAPBASE")) {
return true;
}
if (!strcmp(var, "$SNAPISOPAIR")) {
return true;
}
if (!strcmp(var, "$SNAPMODE")) {
return true;
}
if (!strcmp(var, "$SNAPSTYLE")) {
return true;
}
if (!strcmp(var, "$SNAPUNIT")) {
return true;
}
if (!strcmp(var, "$VIEWCTR")) {
return true;
}
if (!strcmp(var, "$VIEWDIR")) {
return true;
}
if (!strcmp(var, "$VIEWSIZE")) {
return true;
}
return false;
}
return false;
}
/**
* @returns the library version as int (4 bytes, each byte one version number).
* e.g. if str = "2.0.2.0" getLibVersion returns 0x02000200
*/
int DL_Jww::getLibVersion(const char* str) {
int d[4];
int idx = 0;
char v[4][5];
int ret = 0;
for (unsigned int i=0; i<strlen(str) && idx<3; ++i) {
if (str[i]=='.') {
d[idx] = i;
idx++;
}
}
if (idx==3) {
d[3] = strlen(str);
strncpy(v[0], str, d[0]);
v[0][d[0]] = '\0';
//std::cout << "v[0]: " << atoi(v[0]) << "\n";
strncpy(v[1], &str[d[0]+1], d[1]-d[0]-1);
v[1][d[1]-d[0]-1] = '\0';
//std::cout << "v[1]: " << atoi(v[1]) << "\n";
strncpy(v[2], &str[d[1]+1], d[2]-d[1]-1);
v[2][d[2]-d[1]-1] = '\0';
//std::cout << "v[2]: " << atoi(v[2]) << "\n";
strncpy(v[3], &str[d[2]+1], d[3]-d[2]-1);
v[3][d[3]-d[2]-1] = '\0';
//std::cout << "v[3]: " << atoi(v[3]) << "\n";
ret = (atoi(v[0])<<(3*8)) +
(atoi(v[1])<<(2*8)) +
(atoi(v[2])<<(1*8)) +
(atoi(v[3])<<(0*8));
return ret;
} else {
std::cerr << "DL_Jww::getLibVersion: invalid version number: " << str << "\n";
return 0;
}
}
/**
* Some test routines.
*/
void DL_Jww::test() {
char* buf1;
char* buf2;
char* buf3;
char* buf4;
char* buf5;
char* buf6;
buf1 = new char[10];
buf2 = new char[10];
buf3 = new char[10];
buf4 = new char[10];
buf5 = new char[10];
buf6 = new char[10];
strcpy(buf1, " 10\n");
strcpy(buf2, "10");
strcpy(buf3, "10\n");
strcpy(buf4, " 10 \n");
strcpy(buf5, " 10 \r");
strcpy(buf6, "\t10 \n");
std::cout << "1 buf1: '" << buf1 << "'\n";
stripWhiteSpace(&buf1);
std::cout << "2 buf1: '" << buf1 << "'\n";
//assert(!strcmp(buf1, "10"));
std::cout << "1 buf2: '" << buf2 << "'\n";
stripWhiteSpace(&buf2);
std::cout << "2 buf2: '" << buf2 << "'\n";
std::cout << "1 buf3: '" << buf3 << "'\n";
stripWhiteSpace(&buf3);
std::cout << "2 buf3: '" << buf3 << "'\n";
std::cout << "1 buf4: '" << buf4 << "'\n";
stripWhiteSpace(&buf4);
std::cout << "2 buf4: '" << buf4 << "'\n";
std::cout << "1 buf5: '" << buf5 << "'\n";
stripWhiteSpace(&buf5);
std::cout << "2 buf5: '" << buf5 << "'\n";
std::cout << "1 buf6: '" << buf6 << "'\n";
stripWhiteSpace(&buf6);
std::cout << "2 buf6: '" << buf6 << "'\n";
}