Resolved issue #443. Not valid dxf file.

- libdxf updated to version 3.12.2.0.
- Fixed wrong pen width.
- Fixed drawPath() method. Drawing subpaths.
(grafted from f587dae3fa6cd75f987f54aa282caf73225da8fe)

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2016-02-09 17:19:07 +02:00
parent fb6e3b29ff
commit 863b62cd6e
9 changed files with 189 additions and 82 deletions

View File

@ -6,6 +6,7 @@
- [#325] Check pattern for inverse compatibility.
# Version 0.4.2
- [#443] Not valid dxf file. libdxf updated to version 3.12.2.0. Fixed drawing subpaths.
- Fixed combobox width in Dialog "Tool True Dart point".
- [#441] Broken reference incrementation for tool "True Dart point".
- [#439] Widen Formula Dialog.

View File

@ -101,6 +101,7 @@ public:
*/
enum version
{
AC1009_MIN, // R12, minimalistic
AC1009, // R12
AC1012,
AC1014,

View File

@ -172,13 +172,16 @@ bool DL_Dxf::in(std::stringstream& stream,
*/
bool DL_Dxf::readDxfGroups(FILE *fp, DL_CreationInterface* creationInterface)
{
static int line = 1;
// Read one group of the DXF file and strip the lines:
if (DL_Dxf::getStrippedLine(groupCodeTmp, DL_DXF_MAXLINE, fp) &&
DL_Dxf::getStrippedLine(groupValue, DL_DXF_MAXLINE, fp) )
DL_Dxf::getStrippedLine(groupValue, DL_DXF_MAXLINE, fp, false) )
{
groupCode = static_cast<quint32>(toInt(groupCodeTmp));
creationInterface->processCodeValuePair(groupCode, groupValue);
line+=2;
processDXFGroup(creationInterface, static_cast<int>(groupCode), groupValue);
}
@ -193,12 +196,16 @@ bool DL_Dxf::readDxfGroups(FILE *fp, DL_CreationInterface* creationInterface)
bool DL_Dxf::readDxfGroups(std::stringstream& stream,
DL_CreationInterface* creationInterface)
{
static int line = 1;
// Read one group of the DXF file and chop the lines:
if (DL_Dxf::getStrippedLine(groupCodeTmp, DL_DXF_MAXLINE, stream) &&
DL_Dxf::getStrippedLine(groupValue, DL_DXF_MAXLINE, stream) )
DL_Dxf::getStrippedLine(groupValue, DL_DXF_MAXLINE, stream, false) )
{
groupCode = static_cast<quint32>(toInt(groupCodeTmp));
line+=2;
processDXFGroup(creationInterface, static_cast<int>(groupCode), groupValue);
}
return !stream.eof();
@ -223,7 +230,7 @@ bool DL_Dxf::readDxfGroups(std::stringstream& stream,
* @todo Is it a problem if line is blank (i.e., newline only)?
* Then, when function returns, (s==NULL).
*/
bool DL_Dxf::getStrippedLine(std::string& s, quint32 size, FILE *fp)
bool DL_Dxf::getStrippedLine(std::string& s, quint32 size, FILE *fp, bool stripSpace)
{
if (!feof(fp))
{
@ -240,7 +247,7 @@ bool DL_Dxf::getStrippedLine(std::string& s, quint32 size, FILE *fp)
// Both guaranteed to be NULL terminated.
// Strip leading whitespace and trailing CR/LF.
stripWhiteSpace(&line);
stripWhiteSpace(&line, stripSpace);
s = line;
assert(size > s.length());
@ -263,7 +270,7 @@ bool DL_Dxf::getStrippedLine(std::string& s, quint32 size, FILE *fp)
* Same as above but for stringstreams.
*/
bool DL_Dxf::getStrippedLine(std::string &s, quint32 size,
std::stringstream& stream)
std::stringstream& stream, bool stripSpace)
{
if (!stream.eof())
@ -272,7 +279,7 @@ bool DL_Dxf::getStrippedLine(std::string &s, quint32 size,
char* line = new char[size+1];
char* oriLine = line;
stream.getline(line, static_cast<int>(size));
stripWhiteSpace(&line);
stripWhiteSpace(&line, stripSpace);
s = line;
assert(size > s.length());
delete[] oriLine;
@ -297,33 +304,30 @@ bool DL_Dxf::getStrippedLine(std::string &s, quint32 size,
* @retval true if \p s is non-NULL
* @retval false if \p s is NULL
*/
bool DL_Dxf::stripWhiteSpace(char** s)
bool DL_Dxf::stripWhiteSpace(char** s, bool stripSpace)
{
// No need to check if string is null
if (not (*s))
{
return false;
}
// last non-NULL char:
int lastChar = static_cast<int>(strlen(*s) - 1);
// Is last character CR or LF?
while ( (lastChar >= 0) &&
(((*s)[lastChar] == 10) || ((*s)[lastChar] == 13) ||
((*s)[lastChar] == ' ' || ((*s)[lastChar] == '\t'))) )
(stripSpace && ((*s)[lastChar] == ' ' || ((*s)[lastChar] == '\t')))) )
{
(*s)[lastChar] = '\0';
lastChar--;
}
// Skip whitespace, excluding \n, at beginning of line
while ((*s)[0]==' ' || (*s)[0]=='\t')
if (stripSpace)
{
++(*s);
while ((*s)[0]==' ' || (*s)[0]=='\t')
{
++(*s);
}
}
return true;
return ((*s) ? true : false);
}
@ -1475,9 +1479,9 @@ bool DL_Dxf::handleXRecordData(DL_CreationInterface* creationInterface)
// string:
if (groupCode<=9 ||
groupCode==100 || groupCode==102 || groupCode==105 ||
(groupCode>=300 && groupCode<=369) ||
(groupCode>=1000 && groupCode<=1009))
groupCode==100 || groupCode==102 || groupCode==105 ||
(groupCode>=300 && groupCode<=369) ||
(groupCode>=1000 && groupCode<=1009))
{
creationInterface->addXRecordString(static_cast<int>(groupCode), groupValue);
@ -1831,9 +1835,9 @@ void DL_Dxf::addText(DL_CreationInterface* creationInterface)
getRealValue(20, 0.0),
getRealValue(30, 0.0),
// alignment point
getRealValue(11, 0.0),
getRealValue(21, 0.0),
getRealValue(31, 0.0),
getRealValue(11, DL_NANDOUBLE),
getRealValue(21, DL_NANDOUBLE),
getRealValue(31, DL_NANDOUBLE),
// height
getRealValue(40, 2.5),
// x scale
@ -2244,7 +2248,7 @@ bool DL_Dxf::handleHatchData(DL_CreationInterface* creationInterface)
}
return true;
default:
return false;
break;
}
}
else
@ -2268,7 +2272,7 @@ bool DL_Dxf::handleHatchData(DL_CreationInterface* creationInterface)
hatchEdge.defined = true;
return true;
default:
return false;
break;
}
}
@ -2297,7 +2301,7 @@ bool DL_Dxf::handleHatchData(DL_CreationInterface* creationInterface)
hatchEdge.defined = true;
return true;
default:
return false;
break;
}
}
@ -2332,7 +2336,7 @@ bool DL_Dxf::handleHatchData(DL_CreationInterface* creationInterface)
hatchEdge.defined = true;
return true;
default:
return false;
break;
}
}
@ -2414,7 +2418,7 @@ bool DL_Dxf::handleHatchData(DL_CreationInterface* creationInterface)
hatchEdge.endTangentY = toReal(groupValue);
return true;
default:
return false;
break;
}
}
}
@ -2577,6 +2581,9 @@ void DL_Dxf::writeHeader(DL_WriterA& dw) const
break;
case DL_Codes::AC1015:
dw.dxfString(1, "AC1015");
break;
case DL_Codes::AC1009_MIN:
// minimalistic DXF version is unidentified in file:
break;
default:
break;
@ -3043,7 +3050,14 @@ void DL_Dxf::writeInsert(DL_WriterA& dw,
if (version==DL_VERSION_2000)
{
dw.dxfString(100, "AcDbEntity");
dw.dxfString(100, "AcDbBlockReference");
if (data.cols!=1 || data.rows!=1)
{
dw.dxfString(100, "AcDbMInsertBlock");
}
else
{
dw.dxfString(100, "AcDbBlockReference");
}
}
dw.entityAttributes(attrib);
dw.dxfString(2, data.name);
@ -3070,7 +3084,6 @@ void DL_Dxf::writeInsert(DL_WriterA& dw,
dw.dxfReal(44, data.colSp);
dw.dxfReal(45, data.rowSp);
}
}
@ -3218,7 +3231,9 @@ void DL_Dxf::writeDimStyleOverrides(DL_WriterA& dw,
dw.dxfString(1000, "DSTYLE");
dw.dxfString(1002, "{");
dw.dxfInt(1070, 144);
dw.dxfInt(1040, static_cast<int>(data.linearFactor));
dw.dxfReal(1040, data.linearFactor);
dw.dxfInt(1070,40);
dw.dxfReal(1040, data.dimScale);
dw.dxfString(1002, "}");
}
}
@ -3977,9 +3992,10 @@ int DL_Dxf::writeImage(DL_WriterA& dw,
const DL_Attributes& attrib)
{
/*if (data.file.empty()) {
/*if (data.file.empty())
{
std::cerr << "DL_Dxf::writeImage: "
<< "Image file must not be empty\n";
<< "Image file must not be empty\n";
return;
}*/
@ -4039,9 +4055,10 @@ void DL_Dxf::writeImageDef(DL_WriterA& dw,
const DL_ImageData& data) const
{
/*if (data.file.empty()) {
/*if (data.file.empty())
{
std::cerr << "DL_Dxf::writeImage: "
<< "Image file must not be empty\n";
<< "Image file must not be empty\n";
return;
}*/

View File

@ -27,6 +27,7 @@
#include "dl_global.h"
#include <limits>
#include <stdio.h>
#include <stdlib.h>
#include <string>
@ -50,15 +51,19 @@
#define M_PI 3.1415926535897932384626433832795
#endif
#ifndef DL_NANDOUBLE
#define DL_NANDOUBLE std::numeric_limits<double>::quiet_NaN()
#endif
class DL_CreationInterface;
class DL_WriterA;
#define DL_VERSION "3.7.5.0"
#define DL_VERSION "3.12.2.0"
#define DL_VERSION_MAJOR 3
#define DL_VERSION_MINOR 7
#define DL_VERSION_REV 5
#define DL_VERSION_MINOR 12
#define DL_VERSION_REV 2
#define DL_VERSION_BUILD 0
#define DL_UNKNOWN 0
@ -126,16 +131,16 @@ public:
bool readDxfGroups(FILE* fp,
DL_CreationInterface* creationInterface);
static bool getStrippedLine(std::string& s, quint32 size,
FILE* stream);
FILE* stream, bool stripSpace = true);
bool readDxfGroups(std::stringstream& stream,
DL_CreationInterface* creationInterface);
bool in(std::stringstream &stream,
DL_CreationInterface* creationInterface);
static bool getStrippedLine(std::string& s, quint32 size,
std::stringstream& stream);
std::stringstream& stream, bool stripSpace = true);
static bool stripWhiteSpace(char** s);
static bool stripWhiteSpace(char** s, bool stripSpaces = true);
bool processDXFGroup(DL_CreationInterface* creationInterface,
int groupCode, const std::string& groupValue);

View File

@ -847,18 +847,6 @@ struct DXFLIB_EXPORT DL_TextData
virtual ~DL_TextData()
{}
DL_TextData(const DL_TextData &data)
:ipx(data.ipx), ipy(data.ipy), ipz(data.ipz),
apx(data.apx), apy(data.apy), apz(data.apz),
height(data.height), xScaleFactor(data.xScaleFactor),
textGenerationFlags(data.textGenerationFlags),
hJustification(data.hJustification),
vJustification(data.vJustification),
text(data.text),
style(data.style),
angle(data.angle)
{}
/*! X Coordinate of insertion point. */
double ipx;
/*! Y Coordinate of insertion point. */
@ -966,7 +954,8 @@ struct DXFLIB_EXPORT DL_DimensionData
const std::string& text,
const std::string& style,
double angle,
double linearFactor = 1.0) :
double linearFactor = 1.0,
double dimScale = 1.0) :
dpx(dpx), dpy(dpy), dpz(dpz),
mpx(mpx), mpy(mpy), mpz(mpz),
type(type),
@ -976,7 +965,8 @@ struct DXFLIB_EXPORT DL_DimensionData
text(text),
style(style),
angle(angle),
linearFactor(linearFactor)
linearFactor(linearFactor),
dimScale(dimScale)
{
}
@ -1050,6 +1040,10 @@ struct DXFLIB_EXPORT DL_DimensionData
* Linear factor style override.
*/
double linearFactor;
/**
* Dimension scale (dimscale) style override.
*/
double dimScale;
};

View File

@ -65,7 +65,12 @@ public:
}
/**
* @brief DL_Extrusion Constructor for DXF extrusion.
* Constructor for DXF extrusion.
*
* @param direction Vector of axis along which the entity shall be extruded
* this is also the Z axis of the Entity coordinate system
* @param elevation Distance of the entities XY plane from the origin of the
* world coordinate system
*/
DL_Extrusion(double dx, double dy, double dz, double elevation)
: direction(new double[3]), elevation(elevation)
@ -76,7 +81,7 @@ public:
/**
* @brief setDirection Sets the direction vector.
* Sets the direction vector.
*/
void setDirection(double dx, double dy, double dz)
{
@ -95,7 +100,12 @@ public:
return direction;
}
void getDirection(double dir[]) const
/**
* @return direction vector.
*/
void getDirection(double dir[]) const
{
dir[0]=direction[0];
dir[1]=direction[1];

View File

@ -64,8 +64,15 @@ bool DL_WriterA::openFailed() const
void DL_WriterA::dxfReal(int gc, double value) const
{
char str[256];
sprintf(str, "%.16lf", value);
if (version==DL_Codes::AC1009_MIN)
{
sprintf(str, "%.6lf", value);
}
else
{
sprintf(str, "%.16lf", value);
}
// fix for german locale:
strReplace(str, ',', '.');

View File

@ -41,17 +41,16 @@
/**
* Implements functions defined in DL_Writer for writing low
* level DXF constructs to an ASCII format DXF file.
*
* @para fname File name of the file to be created.
* @para version DXF version. Defaults to DL_VERSION_2002.
*
* @todo What if \c fname is NULL? Or \c fname can't be opened for
* another reason?
*/
class DXFLIB_EXPORT DL_WriterA : public DL_Writer
{
public:
/**
* @param fname fname File name of the file to be created.
* @param version version DXF version. Defaults to DL_VERSION_2002.
*
* @todo What if \c fname is NULL? Or \c fname can't be opened for
* another reason?
*/
explicit DL_WriterA(const char* fname, DL_Codes::version version=DL_VERSION_2000)
: DL_Writer(version), m_ofile(fname) {}
virtual ~DL_WriterA() {}

View File

@ -95,7 +95,7 @@ bool VDxfEngine::begin(QPaintDevice *pdev)
QByteArray fileNameArray = getFileName().toLocal8Bit();
dw = dxf->out(fileNameArray.data(), exportVersion);
if (dw==NULL)
if (dw==nullptr)
{
qWarning("VDxfEngine::begin(), can't open file");
return false;
@ -123,10 +123,37 @@ bool VDxfEngine::begin(QPaintDevice *pdev)
dw->sectionTables();
dxf->writeVPort(*dw);
dw->tableLinetypes(25);
dxf->writeLinetype(*dw, DL_LinetypeData("BYBLOCK", "BYBLOCK", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("BYLAYER", "BYLAYER", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("CONTINUOUS", "Continuous", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("ACAD_ISO02W100", "ACAD_ISO02W100", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("ACAD_ISO03W100", "ACAD_ISO03W100", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("ACAD_ISO04W100", "ACAD_ISO04W100", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("ACAD_ISO05W100", "ACAD_ISO05W100", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("BORDER", "BORDER", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("BORDER2", "BORDER2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("BORDERX2", "BORDERX2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("CENTER", "CENTER", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("CENTER2", "CENTER2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("CENTERX2", "CENTERX2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DASHDOT", "DASHDOT", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DASHDOT2", "DASHDOT2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DASHDOTX2", "DASHDOTX2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DASHED", "DASHED", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DASHED2", "DASHED2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DASHEDX2", "DASHEDX2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DIVIDE", "DIVIDE", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DIVIDE2", "DIVIDE2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DIVIDEX2", "DIVIDEX2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DOT", "DOT", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DOT2", "DOT2", 0, 0, 0.0));
dxf->writeLinetype(*dw, DL_LinetypeData("DOTX2", "DOTX2", 0, 0, 0.0));
dw->tableEnd();
int numberOfLayers = 1;
dw->tableLayers(numberOfLayers);
dxf->writeLayer(*dw,
DL_LayerData("0", 0),
DL_Attributes(
@ -135,7 +162,46 @@ bool VDxfEngine::begin(QPaintDevice *pdev)
100, // default width
"CONTINUOUS", // default line style
1.0)); // default line type scale
dw->tableEnd();
dw->tableStyle(1);
DL_StyleData style("Standard", 0, 0.0, 1.0, 0.0, 0, 2.5, "txt", "");
style.bold = false;
style.italic = false;
dxf->writeStyle(*dw, style);
dw->tableEnd();
dxf->writeView(*dw);
dxf->writeUcs(*dw);
dw->tableAppid(1);
dw->tableAppidEntry(0x12);
dw->dxfString(2, "ACAD");
dw->dxfInt(70, 0);
dw->tableEnd();
dxf->writeDimStyle(*dw, 1, 1, 1, 1, 1);
dxf->writeBlockRecord(*dw);
dxf->writeBlockRecord(*dw, "layout");
dw->tableEnd();
dw->sectionEnd();
dw->sectionBlocks();
dxf->writeBlock(*dw, DL_BlockData("*Model_Space", 0, 0.0, 0.0, 0.0));
dxf->writeEndBlock(*dw, "*Model_Space");
dxf->writeBlock(*dw, DL_BlockData("*Paper_Space", 0, 0.0, 0.0, 0.0));
dxf->writeEndBlock(*dw, "*Paper_Space");
dxf->writeBlock(*dw, DL_BlockData("*Paper_Space0", 0, 0.0, 0.0, 0.0));
dxf->writeEndBlock(*dw, "*Paper_Space0");
dxf->writeBlock(*dw, DL_BlockData("layout", 0, 0.0, 0.0, 0.0));
// ...
// write block entities e.g. with dxf->writeLine(), ..
// ...
dxf->writeEndBlock(*dw, "layout");
dw->sectionEnd();
dw->sectionEntities();
@ -146,6 +212,8 @@ bool VDxfEngine::begin(QPaintDevice *pdev)
bool VDxfEngine::end()
{
dw->sectionEnd();
dxf->writeObjects(*dw);
dxf->writeObjectsEnd(*dw);
dw->dxfEOF();
dw->close();
delete dw;
@ -172,14 +240,18 @@ void VDxfEngine::updateState(const QPaintEngineState &state)
//---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::drawPath(const QPainterPath &path)
{
QPolygonF polygon = path.toFillPolygon(matrix);
if (polygon.size() < 3)
{
return;
}
const QList<QPolygonF> subpaths = path.toSubpathPolygons(matrix);
for (int i=1; i < polygon.count(); i++)
for (int j=0; j < subpaths.size(); ++j)
{
const QPolygonF polygon = subpaths.at(j);
if (polygon.size() < 3)
{
return;
}
for (int i=1; i < polygon.count(); i++)
{
dxf->writeLine(
*dw,
DL_LineData(polygon.at(i-1).x(), // start point
@ -188,7 +260,8 @@ void VDxfEngine::drawPath(const QPainterPath &path)
polygon.at(i).x(), // end point
getSize().height() - polygon.at(i).y(),
0.0),
DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0));
DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0));
}
}
}
@ -208,7 +281,7 @@ void VDxfEngine::drawLines(const QLineF * lines, int lineCount)
p2.x(), // end point
getSize().height() - p2.y(),
0.0),
DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0));
DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0));
}
}
@ -236,7 +309,7 @@ void VDxfEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawM
p2.x(), // end point
getSize().height() - p2.y(),
0.0),
DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0));
DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0));
}
}
@ -281,7 +354,7 @@ void VDxfEngine::drawEllipse(const QRectF & rect)
ratio,
0,6.28 // startangle and endangle of ellipse in rad
),
DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0));
DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0));
}
//---------------------------------------------------------------------------------------------------------------------
@ -315,7 +388,7 @@ void VDxfEngine::drawTextItem(const QPointF & p, const QTextItem & textItem)
f.family().toUtf8().constData(), // font
-rotationAngle
),
DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0));
DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0));
}
//---------------------------------------------------------------------------------------------------------------------