summaryrefslogtreecommitdiffstats
path: root/vcl/source/filter/idxf
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--vcl/source/filter/idxf/dxf2mtf.cxx902
-rw-r--r--vcl/source/filter/idxf/dxf2mtf.hxx119
-rw-r--r--vcl/source/filter/idxf/dxfblkrd.cxx125
-rw-r--r--vcl/source/filter/idxf/dxfblkrd.hxx83
-rw-r--r--vcl/source/filter/idxf/dxfentrd.cxx848
-rw-r--r--vcl/source/filter/idxf/dxfentrd.hxx538
-rw-r--r--vcl/source/filter/idxf/dxfgrprd.cxx213
-rw-r--r--vcl/source/filter/idxf/dxfgrprd.hxx115
-rw-r--r--vcl/source/filter/idxf/dxfreprd.cxx480
-rw-r--r--vcl/source/filter/idxf/dxfreprd.hxx129
-rw-r--r--vcl/source/filter/idxf/dxftblrd.cxx381
-rw-r--r--vcl/source/filter/idxf/dxftblrd.hxx175
-rw-r--r--vcl/source/filter/idxf/dxfvec.cxx232
-rw-r--r--vcl/source/filter/idxf/dxfvec.hxx218
-rw-r--r--vcl/source/filter/idxf/idxf.cxx43
15 files changed, 4601 insertions, 0 deletions
diff --git a/vcl/source/filter/idxf/dxf2mtf.cxx b/vcl/source/filter/idxf/dxf2mtf.cxx
new file mode 100644
index 000000000..2b26abffd
--- /dev/null
+++ b/vcl/source/filter/idxf/dxf2mtf.cxx
@@ -0,0 +1,902 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <unotools/configmgr.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/virdev.hxx>
+#include <tools/poly.hxx>
+#include "dxf2mtf.hxx"
+
+#include <math.h>
+
+
+sal_uInt64 DXF2GDIMetaFile::CountEntities(const DXFEntities & rEntities)
+{
+ const DXFBasicEntity * pBE;
+ sal_uInt64 nRes;
+
+ nRes=0;
+ for (pBE=rEntities.pFirst; pBE!=nullptr; pBE=pBE->pSucc) nRes++;
+ return nRes;
+}
+
+Color DXF2GDIMetaFile::ConvertColor(sal_uInt8 nColor) const
+{
+ return Color(
+ pDXF->aPalette.GetRed( nColor ),
+ pDXF->aPalette.GetGreen( nColor ),
+ pDXF->aPalette.GetBlue( nColor ) );
+}
+
+tools::Long DXF2GDIMetaFile::GetEntityColor(const DXFBasicEntity & rE) const
+{
+ tools::Long nColor;
+
+ nColor=rE.nColor;
+ if (nColor==256) {
+ if (rE.m_sLayer.getLength() < 2) {
+ nColor=nParentLayerColor;
+ } else {
+ const DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.m_sLayer);
+ if (pLayer!=nullptr) nColor=pLayer->nColor;
+ else nColor=nParentLayerColor;
+ }
+ }
+ else if (nColor==0) nColor=nBlockColor;
+ return nColor;
+}
+
+DXFLineInfo DXF2GDIMetaFile::LTypeToDXFLineInfo(std::string_view rLineType) const
+{
+ const DXFLType * pLT;
+ DXFLineInfo aDXFLineInfo;
+
+ pLT = pDXF->aTables.SearchLType(rLineType);
+ if (pLT==nullptr || pLT->nDashCount == 0) {
+ aDXFLineInfo.eStyle = LineStyle::Solid;
+ }
+ else {
+ aDXFLineInfo.eStyle = LineStyle::Dash;
+ for (tools::Long i=0; i < (pLT->nDashCount); i++) {
+ const double x = pLT->fDash[i] * pDXF->getGlobalLineTypeScale();
+ if ( x >= 0.0 ) {
+ if ( aDXFLineInfo.nDotCount == 0 ) {
+ aDXFLineInfo.nDotCount ++;
+ aDXFLineInfo.fDotLen = x;
+ }
+ else if ( aDXFLineInfo.fDotLen == x ) {
+ aDXFLineInfo.nDotCount ++;
+ }
+ else if ( aDXFLineInfo.nDashCount == 0 ) {
+ aDXFLineInfo.nDashCount ++;
+ aDXFLineInfo.fDashLen = x;
+ }
+ else if ( aDXFLineInfo.fDashLen == x ) {
+ aDXFLineInfo.nDashCount ++;
+ }
+ else {
+ // It is impossible to be converted.
+ }
+ }
+ else {
+ if ( aDXFLineInfo.fDistance == 0 ) {
+ aDXFLineInfo.fDistance = -1 * x;
+ }
+ else {
+ // It is impossible to be converted.
+ }
+ }
+
+ }
+ }
+
+ return aDXFLineInfo;
+}
+
+DXFLineInfo DXF2GDIMetaFile::GetEntityDXFLineInfo(const DXFBasicEntity & rE)
+{
+ DXFLineInfo aDXFLineInfo;
+
+ aDXFLineInfo.eStyle = LineStyle::Solid;
+ aDXFLineInfo.nDashCount = 0;
+ aDXFLineInfo.fDashLen = 0;
+ aDXFLineInfo.nDotCount = 0;
+ aDXFLineInfo.fDotLen = 0;
+ aDXFLineInfo.fDistance = 0;
+
+ if (rE.m_sLineType == "BYLAYER") {
+ if (rE.m_sLayer.getLength() < 2) {
+ aDXFLineInfo=aParentLayerDXFLineInfo;
+ } else {
+ const DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.m_sLayer);
+ if (pLayer!=nullptr) {
+ aDXFLineInfo = LTypeToDXFLineInfo(pLayer->m_sLineType);
+ }
+ else aDXFLineInfo=aParentLayerDXFLineInfo;
+ }
+ }
+ else if (rE.m_sLineType == "BYBLOCK") {
+ aDXFLineInfo=aBlockDXFLineInfo;
+ }
+ else {
+ aDXFLineInfo = LTypeToDXFLineInfo(rE.m_sLineType);
+ }
+ return aDXFLineInfo;
+}
+
+
+bool DXF2GDIMetaFile::SetLineAttribute(const DXFBasicEntity & rE)
+{
+ tools::Long nColor;
+ Color aColor;
+
+ nColor=GetEntityColor(rE);
+ if (nColor<0) return false;
+ aColor=ConvertColor(static_cast<sal_uInt8>(nColor));
+
+ if (aActLineColor!=aColor) {
+ aActLineColor = aColor;
+ pVirDev->SetLineColor( aActLineColor );
+ }
+
+ if (aActFillColor!=COL_TRANSPARENT) {
+ aActFillColor = COL_TRANSPARENT;
+ pVirDev->SetFillColor(aActFillColor);
+ }
+ return true;
+}
+
+
+bool DXF2GDIMetaFile::SetAreaAttribute(const DXFBasicEntity & rE)
+{
+ tools::Long nColor;
+ Color aColor;
+
+ nColor=GetEntityColor(rE);
+ if (nColor<0) return false;
+ aColor=ConvertColor(static_cast<sal_uInt8>(nColor));
+
+ if (aActLineColor!=aColor) {
+ aActLineColor = aColor;
+ pVirDev->SetLineColor( aActLineColor );
+ }
+
+ if ( aActFillColor == COL_TRANSPARENT || aActFillColor != aColor) {
+ aActFillColor = aColor;
+ pVirDev->SetFillColor( aActFillColor );
+ }
+ return true;
+}
+
+
+bool DXF2GDIMetaFile::SetFontAttribute(const DXFBasicEntity & rE, short nAngle, sal_uInt16 nHeight)
+{
+ tools::Long nColor;
+ Color aColor;
+ vcl::Font aFont;
+
+ nAngle=-nAngle;
+ while (nAngle>=3600) nAngle-=3600;
+ while (nAngle<0) nAngle+=3600;
+
+ nColor=GetEntityColor(rE);
+ if (nColor<0) return false;
+ aColor=ConvertColor(static_cast<sal_uInt8>(nColor));
+
+ aFont.SetColor(aColor);
+ aFont.SetTransparent(true);
+ aFont.SetFamily(FAMILY_SWISS);
+ aFont.SetFontSize(Size(0,nHeight));
+ aFont.SetAlignment(ALIGN_BASELINE);
+ aFont.SetOrientation(Degree10(nAngle));
+ if (aActFont!=aFont) {
+ aActFont=aFont;
+ pVirDev->SetFont(aActFont);
+ }
+
+ return true;
+}
+
+
+void DXF2GDIMetaFile::DrawLineEntity(const DXFLineEntity & rE, const DXFTransform & rTransform)
+{
+ if (!SetLineAttribute(rE))
+ return;
+
+ Point aP0,aP1;
+ rTransform.Transform(rE.aP0,aP0);
+ rTransform.Transform(rE.aP1,aP1);
+
+ DXFLineInfo aDXFLineInfo=GetEntityDXFLineInfo(rE);
+ LineInfo aLineInfo;
+ aLineInfo = rTransform.Transform(aDXFLineInfo);
+
+ pVirDev->DrawLine(aP0,aP1,aLineInfo);
+ if (rE.fThickness!=0) {
+ Point aP2,aP3;
+ rTransform.Transform(rE.aP0+DXFVector(0,0,rE.fThickness),aP2);
+ rTransform.Transform(rE.aP1+DXFVector(0,0,rE.fThickness),aP3);
+ DrawLine(aP2,aP3);
+ DrawLine(aP0,aP2);
+ DrawLine(aP1,aP3);
+ }
+}
+
+
+void DXF2GDIMetaFile::DrawPointEntity(const DXFPointEntity & rE, const DXFTransform & rTransform)
+{
+
+ if (SetLineAttribute(rE)) {
+ Point aP0;
+ rTransform.Transform(rE.aP0,aP0);
+ if (rE.fThickness==0) pVirDev->DrawPixel(aP0);
+ else {
+ Point aP1;
+ rTransform.Transform(rE.aP0+DXFVector(0,0,rE.fThickness),aP1);
+ DrawLine(aP0,aP1);
+ }
+ }
+}
+
+
+void DXF2GDIMetaFile::DrawCircleEntity(const DXFCircleEntity & rE, const DXFTransform & rTransform)
+{
+ double frx,fry;
+ sal_uInt16 nPoints,i;
+ DXFVector aC;
+
+ if (!SetLineAttribute(rE)) return;
+ rTransform.Transform(rE.aP0,aC);
+ if (rE.fThickness==0 && rTransform.TransCircleToEllipse(rE.fRadius,frx,fry)) {
+ pVirDev->DrawEllipse(
+ tools::Rectangle(static_cast<tools::Long>(aC.fx-frx+0.5),static_cast<tools::Long>(aC.fy-fry+0.5),
+ static_cast<tools::Long>(aC.fx+frx+0.5),static_cast<tools::Long>(aC.fy+fry+0.5)));
+ }
+ else {
+ double fAng;
+ nPoints=OptPointsPerCircle;
+ tools::Polygon aPoly(nPoints);
+ for (i=0; i<nPoints; i++) {
+ fAng=2*M_PI/static_cast<double>(nPoints-1)*static_cast<double>(i);
+ rTransform.Transform(
+ rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),0),
+ aPoly[i]
+ );
+ }
+ pVirDev->DrawPolyLine(aPoly);
+ if (rE.fThickness!=0) {
+ tools::Polygon aPoly2(nPoints);
+ for (i=0; i<nPoints; i++) {
+ fAng=2*M_PI/static_cast<double>(nPoints-1)*static_cast<double>(i);
+ rTransform.Transform(
+ rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),rE.fThickness),
+ aPoly2[i]
+ );
+
+ }
+ pVirDev->DrawPolyLine(aPoly2);
+ for (i=0; i<nPoints-1; i++) DrawLine(aPoly[i],aPoly2[i]);
+ }
+ }
+}
+
+void DXF2GDIMetaFile::DrawLine(const Point& rA, const Point& rB)
+{
+ if (utl::ConfigManager::IsFuzzing())
+ return;
+ GDIMetaFile* pMetaFile = pVirDev->GetConnectMetaFile();
+ assert(pMetaFile);
+ //use AddAction instead of OutputDevice::DrawLine so that we can explicitly share
+ //the aDefaultLineInfo between the MetaLineActions to reduce memory use
+ pMetaFile->AddAction(new MetaLineAction(rA, rB, aDefaultLineInfo));
+}
+
+void DXF2GDIMetaFile::DrawArcEntity(const DXFArcEntity & rE, const DXFTransform & rTransform)
+{
+ double frx,fry;
+ sal_uInt16 nPoints,i;
+ DXFVector aC;
+
+ if (!SetLineAttribute(rE)) return;
+ double fA1=rE.fStart;
+ double fdA=rE.fEnd-fA1;
+ fdA = fmod(fdA, 360.0);
+ if (fdA<=0) fdA+=360.0;
+ rTransform.Transform(rE.aP0,aC);
+ if (rE.fThickness==0 && fdA>5.0 && rTransform.TransCircleToEllipse(rE.fRadius,frx,fry)) {
+ DXFVector aVS(cos(basegfx::deg2rad(fA1)),sin(basegfx::deg2rad(fA1)),0.0);
+ aVS*=rE.fRadius;
+ aVS+=rE.aP0;
+ DXFVector aVE(cos(basegfx::deg2rad(fA1+fdA)),sin(basegfx::deg2rad(fA1+fdA)),0.0);
+ aVE*=rE.fRadius;
+ aVE+=rE.aP0;
+ Point aPS,aPE;
+ if (rTransform.Mirror()) {
+ rTransform.Transform(aVS,aPS);
+ rTransform.Transform(aVE,aPE);
+ }
+ else {
+ rTransform.Transform(aVS,aPE);
+ rTransform.Transform(aVE,aPS);
+ }
+ pVirDev->DrawArc(
+ tools::Rectangle(static_cast<tools::Long>(aC.fx-frx+0.5),static_cast<tools::Long>(aC.fy-fry+0.5),
+ static_cast<tools::Long>(aC.fx+frx+0.5),static_cast<tools::Long>(aC.fy+fry+0.5)),
+ aPS,aPE
+ );
+ }
+ else {
+ double fAng;
+ nPoints=static_cast<sal_uInt16>(fdA/360.0*static_cast<double>(OptPointsPerCircle)+0.5);
+ if (nPoints<2) nPoints=2;
+ tools::Polygon aPoly(nPoints);
+ for (i=0; i<nPoints; i++) {
+ fAng=basegfx::deg2rad( fA1 + fdA/static_cast<double>(nPoints-1)*static_cast<double>(i) );
+ rTransform.Transform(
+ rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),0),
+ aPoly[i]
+ );
+ }
+ pVirDev->DrawPolyLine(aPoly);
+ if (rE.fThickness!=0) {
+ tools::Polygon aPoly2(nPoints);
+ for (i=0; i<nPoints; i++) {
+ fAng=basegfx::deg2rad( fA1 + fdA/static_cast<double>(nPoints-1)*static_cast<double>(i) );
+ rTransform.Transform(
+ rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),rE.fThickness),
+ aPoly2[i]
+ );
+ }
+ pVirDev->DrawPolyLine(aPoly2);
+ for (i=0; i<nPoints; i++)
+ DrawLine(aPoly[i], aPoly2[i]);
+ }
+ }
+}
+
+void DXF2GDIMetaFile::DrawTraceEntity(const DXFTraceEntity & rE, const DXFTransform & rTransform)
+{
+ if (!SetLineAttribute(rE))
+ return;
+
+ tools::Polygon aPoly(4);
+ rTransform.Transform(rE.aP0,aPoly[0]);
+ rTransform.Transform(rE.aP1,aPoly[1]);
+ rTransform.Transform(rE.aP3,aPoly[2]);
+ rTransform.Transform(rE.aP2,aPoly[3]);
+ pVirDev->DrawPolygon(aPoly);
+ if (rE.fThickness!=0) {
+ sal_uInt16 i;
+ tools::Polygon aPoly2(4);
+ DXFVector aVAdd(0,0,rE.fThickness);
+ rTransform.Transform(rE.aP0+aVAdd,aPoly2[0]);
+ rTransform.Transform(rE.aP1+aVAdd,aPoly2[1]);
+ rTransform.Transform(rE.aP3+aVAdd,aPoly2[2]);
+ rTransform.Transform(rE.aP2+aVAdd,aPoly2[3]);
+ pVirDev->DrawPolygon(aPoly2);
+ for (i=0; i<4; i++) DrawLine(aPoly[i],aPoly2[i]);
+ }
+}
+
+
+void DXF2GDIMetaFile::DrawSolidEntity(const DXFSolidEntity & rE, const DXFTransform & rTransform)
+{
+ if (!SetAreaAttribute(rE))
+ return;
+
+ sal_uInt16 nN;
+ if (rE.aP2==rE.aP3) nN=3; else nN=4;
+ tools::Polygon aPoly(nN);
+ rTransform.Transform(rE.aP0,aPoly[0]);
+ rTransform.Transform(rE.aP1,aPoly[1]);
+ rTransform.Transform(rE.aP3,aPoly[2]);
+ if (nN>3) rTransform.Transform(rE.aP2,aPoly[3]);
+ pVirDev->DrawPolygon(aPoly);
+ if (rE.fThickness==0) return;
+
+ tools::Polygon aPoly2(nN);
+ DXFVector aVAdd(0,0,rE.fThickness);
+ rTransform.Transform(rE.aP0+aVAdd,aPoly2[0]);
+ rTransform.Transform(rE.aP1+aVAdd,aPoly2[1]);
+ rTransform.Transform(rE.aP3+aVAdd,aPoly2[2]);
+ if (nN>3) rTransform.Transform(rE.aP2+aVAdd,aPoly2[3]);
+ pVirDev->DrawPolygon(aPoly2);
+ if (SetLineAttribute(rE)) {
+ sal_uInt16 i;
+ for (i=0; i<nN; i++) DrawLine(aPoly[i],aPoly2[i]);
+ }
+}
+
+
+void DXF2GDIMetaFile::DrawTextEntity(const DXFTextEntity & rE, const DXFTransform & rTransform)
+{
+ DXFVector aV;
+ double fA;
+ sal_uInt16 nHeight;
+ short nAng;
+ DXFTransform aT( DXFTransform(rE.fXScale,rE.fHeight,1.0,rE.fRotAngle,rE.aP0), rTransform );
+ aT.TransDir(DXFVector(0,1,0),aV);
+ nHeight=static_cast<sal_uInt16>(aV.Abs()+0.5);
+ fA=aT.CalcRotAngle();
+ nAng=static_cast<short>(fA*10.0+0.5);
+ aT.TransDir(DXFVector(1,0,0),aV);
+ if ( SetFontAttribute( rE,nAng, nHeight ) )
+ {
+ OUString const aUString(pDXF->ToOUString(rE.m_sText));
+ Point aPt;
+ aT.Transform( DXFVector( 0, 0, 0 ), aPt );
+ pVirDev->DrawText( aPt, aUString );
+ }
+}
+
+
+void DXF2GDIMetaFile::DrawInsertEntity(const DXFInsertEntity & rE, const DXFTransform & rTransform)
+{
+ const DXFBlock * pB;
+ pB=pDXF->aBlocks.Search(rE.m_sName);
+ if (pB==nullptr)
+ return;
+
+ DXFTransform aDXFTransform1(1.0,1.0,1.0,DXFVector(0.0,0.0,0.0)-pB->aBasePoint);
+ DXFTransform aDXFTransform2(rE.fXScale,rE.fYScale,rE.fZScale,rE.fRotAngle,rE.aP0);
+ DXFTransform aT(
+ DXFTransform( aDXFTransform1, aDXFTransform2 ),
+ rTransform
+ );
+ tools::Long nSavedBlockColor, nSavedParentLayerColor;
+ DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo;
+ nSavedBlockColor=nBlockColor;
+ nSavedParentLayerColor=nParentLayerColor;
+ aSavedBlockDXFLineInfo=aBlockDXFLineInfo;
+ aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo;
+ nBlockColor=GetEntityColor(rE);
+ aBlockDXFLineInfo=GetEntityDXFLineInfo(rE);
+ if (rE.m_sLayer.getLength() > 1) {
+ DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.m_sLayer);
+ if (pLayer!=nullptr) {
+ nParentLayerColor=pLayer->nColor;
+ aParentLayerDXFLineInfo = LTypeToDXFLineInfo(pLayer->m_sLineType);
+ }
+ }
+ DrawEntities(*pB,aT);
+ aBlockDXFLineInfo=aSavedBlockDXFLineInfo;
+ aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo;
+ nBlockColor=nSavedBlockColor;
+ nParentLayerColor=nSavedParentLayerColor;
+}
+
+
+void DXF2GDIMetaFile::DrawAttribEntity(const DXFAttribEntity & rE, const DXFTransform & rTransform)
+{
+ if ((rE.nAttrFlags&1)!=0)
+ return;
+
+ DXFVector aV;
+ double fA;
+ sal_uInt16 nHeight;
+ short nAng;
+ DXFTransform aT( DXFTransform( rE.fXScale, rE.fHeight, 1.0, rE.fRotAngle, rE.aP0 ), rTransform );
+ aT.TransDir(DXFVector(0,1,0),aV);
+ nHeight=static_cast<sal_uInt16>(aV.Abs()+0.5);
+ fA=aT.CalcRotAngle();
+ nAng=static_cast<short>(fA*10.0+0.5);
+ aT.TransDir(DXFVector(1,0,0),aV);
+ if (SetFontAttribute(rE,nAng,nHeight))
+ {
+ OUString const aUString(pDXF->ToOUString(rE.m_sText));
+ Point aPt;
+ aT.Transform( DXFVector( 0, 0, 0 ), aPt );
+ pVirDev->DrawText( aPt, aUString );
+ }
+}
+
+
+void DXF2GDIMetaFile::DrawPolyLineEntity(const DXFPolyLineEntity & rE, const DXFTransform & rTransform)
+{
+ sal_uInt16 i,nPolySize;
+ const DXFBasicEntity * pBE;
+
+ nPolySize=0;
+ pBE=rE.pSucc;
+ while (pBE!=nullptr && pBE->eType==DXF_VERTEX) {
+ nPolySize++;
+ pBE=pBE->pSucc;
+ }
+ if (nPolySize<2)
+ return;
+ tools::Polygon aPoly(nPolySize);
+ pBE=rE.pSucc;
+ for (i=0; i<nPolySize; i++) {
+ rTransform.Transform(static_cast<const DXFVertexEntity*>(pBE)->aP0,aPoly[i]);
+ pBE=pBE->pSucc;
+ }
+
+ if (!SetLineAttribute(rE))
+ return;
+
+ if ((rE.nFlags&1)!=0) pVirDev->DrawPolygon(aPoly);
+ else pVirDev->DrawPolyLine(aPoly);
+ if (rE.fThickness==0)
+ return;
+
+ tools::Polygon aPoly2(nPolySize);
+ pBE=rE.pSucc;
+ for (i=0; i<nPolySize; i++) {
+ rTransform.Transform(
+ (static_cast<const DXFVertexEntity*>(pBE)->aP0)+DXFVector(0,0,rE.fThickness),
+ aPoly2[i]
+ );
+ pBE=pBE->pSucc;
+ }
+ if ((rE.nFlags&1)!=0) pVirDev->DrawPolygon(aPoly2);
+ else pVirDev->DrawPolyLine(aPoly2);
+ for (i=0; i<nPolySize; i++) DrawLine(aPoly[i],aPoly2[i]);
+}
+
+void DXF2GDIMetaFile::DrawLWPolyLineEntity(const DXFLWPolyLineEntity & rE, const DXFTransform & rTransform )
+{
+ sal_Int32 nPolySize = rE.aP.size();
+ if (!nPolySize)
+ return;
+
+ tools::Polygon aPoly( static_cast<sal_uInt16>(nPolySize));
+ for (sal_Int32 i = 0; i < nPolySize; ++i)
+ {
+ rTransform.Transform( rE.aP[ static_cast<sal_uInt16>(i) ], aPoly[ static_cast<sal_uInt16>(i) ] );
+ }
+ if ( SetLineAttribute( rE ) )
+ {
+ if ( ( rE.nFlags & 1 ) != 0 )
+ pVirDev->DrawPolygon( aPoly );
+ else
+ pVirDev->DrawPolyLine( aPoly );
+ }
+}
+
+void DXF2GDIMetaFile::DrawHatchEntity(const DXFHatchEntity & rE, const DXFTransform & rTransform )
+{
+ if (rE.aBoundaryPathData.empty())
+ return;
+
+ SetAreaAttribute( rE );
+ tools::PolyPolygon aPolyPoly;
+ for (const DXFBoundaryPathData& rPathData : rE.aBoundaryPathData)
+ {
+ std::vector< Point > aPtAry;
+ if ( rPathData.bIsPolyLine )
+ {
+ for (const auto& a : rPathData.aP)
+ {
+ Point aPt;
+ rTransform.Transform(a, aPt);
+ aPtAry.push_back( aPt );
+ }
+ }
+ else
+ {
+ for ( auto& rEdge : rPathData.aEdges )
+ {
+ const DXFEdgeType* pEdge = rEdge.get();
+ switch( pEdge->nEdgeType )
+ {
+ case 1 :
+ {
+ Point aPt;
+ rTransform.Transform( static_cast<const DXFEdgeTypeLine*>(pEdge)->aStartPoint, aPt );
+ aPtAry.push_back( aPt );
+ rTransform.Transform( static_cast<const DXFEdgeTypeLine*>(pEdge)->aEndPoint, aPt );
+ aPtAry.push_back( aPt );
+ }
+ break;
+ case 2 :
+ case 3 :
+ case 4 :
+ break;
+ }
+ }
+ }
+ sal_uInt16 i, nSize = static_cast<sal_uInt16>(aPtAry.size());
+ if ( nSize )
+ {
+ tools::Polygon aPoly( nSize );
+ for ( i = 0; i < nSize; i++ )
+ aPoly[ i ] = aPtAry[ i ];
+ aPolyPoly.Insert( aPoly );
+ }
+ }
+ if ( aPolyPoly.Count() )
+ pVirDev->DrawPolyPolygon( aPolyPoly );
+}
+
+void DXF2GDIMetaFile::Draw3DFaceEntity(const DXF3DFaceEntity & rE, const DXFTransform & rTransform)
+{
+ sal_uInt16 nN,i;
+ if (!SetLineAttribute(rE))
+ return;
+
+ if (rE.aP2==rE.aP3) nN=3; else nN=4;
+ tools::Polygon aPoly(nN);
+ rTransform.Transform(rE.aP0,aPoly[0]);
+ rTransform.Transform(rE.aP1,aPoly[1]);
+ rTransform.Transform(rE.aP2,aPoly[2]);
+ if (nN>3) rTransform.Transform(rE.aP3,aPoly[3]);
+ if ((rE.nIEFlags&0x0f)==0) pVirDev->DrawPolygon(aPoly);
+ else {
+ for (i=0; i<nN; i++) {
+ if ( (rE.nIEFlags & (static_cast<tools::Long>(1)<<i)) == 0 ) {
+ DrawLine(aPoly[i],aPoly[(i+1)%nN]);
+ }
+ }
+ }
+}
+
+void DXF2GDIMetaFile::DrawDimensionEntity(const DXFDimensionEntity & rE, const DXFTransform & rTransform)
+{
+ const DXFBlock * pB;
+ pB=pDXF->aBlocks.Search(rE.m_sPseudoBlock);
+ if (pB==nullptr)
+ return;
+
+ DXFTransform aT(
+ DXFTransform(1.0,1.0,1.0,DXFVector(0.0,0.0,0.0)-pB->aBasePoint),
+ rTransform
+ );
+ tools::Long nSavedBlockColor, nSavedParentLayerColor;
+ DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo;
+ nSavedBlockColor=nBlockColor;
+ nSavedParentLayerColor=nParentLayerColor;
+ aSavedBlockDXFLineInfo=aBlockDXFLineInfo;
+ aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo;
+ nBlockColor=GetEntityColor(rE);
+ aBlockDXFLineInfo=GetEntityDXFLineInfo(rE);
+ if (rE.m_sLayer.getLength() > 1) {
+ DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.m_sLayer);
+ if (pLayer!=nullptr) {
+ nParentLayerColor=pLayer->nColor;
+ aParentLayerDXFLineInfo = LTypeToDXFLineInfo(pLayer->m_sLineType);
+ }
+ }
+ DrawEntities(*pB,aT);
+ aBlockDXFLineInfo=aSavedBlockDXFLineInfo;
+ aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo;
+ nBlockColor=nSavedBlockColor;
+ nParentLayerColor=nSavedParentLayerColor;
+}
+
+
+void DXF2GDIMetaFile::DrawEntities(const DXFEntities & rEntities,
+ const DXFTransform & rTransform)
+{
+ if (rEntities.mbBeingDrawn)
+ return;
+ rEntities.mbBeingDrawn = true;
+
+ DXFTransform aET;
+ const DXFTransform * pT;
+
+ const DXFBasicEntity * pE=rEntities.pFirst;
+
+ while (pE!=nullptr && bStatus) {
+ if (pE->nSpace==0) {
+ if (pE->aExtrusion.fz==1.0) {
+ pT=&rTransform;
+ }
+ else {
+ aET=DXFTransform(DXFTransform(pE->aExtrusion),rTransform);
+ pT=&aET;
+ }
+ switch (pE->eType) {
+ case DXF_LINE:
+ DrawLineEntity(static_cast<const DXFLineEntity&>(*pE),*pT);
+ break;
+ case DXF_POINT:
+ DrawPointEntity(static_cast<const DXFPointEntity&>(*pE),*pT);
+ break;
+ case DXF_CIRCLE:
+ DrawCircleEntity(static_cast<const DXFCircleEntity&>(*pE),*pT);
+ break;
+ case DXF_ARC:
+ DrawArcEntity(static_cast<const DXFArcEntity&>(*pE),*pT);
+ break;
+ case DXF_TRACE:
+ DrawTraceEntity(static_cast<const DXFTraceEntity&>(*pE),*pT);
+ break;
+ case DXF_SOLID:
+ DrawSolidEntity(static_cast<const DXFSolidEntity&>(*pE),*pT);
+ break;
+ case DXF_TEXT:
+ DrawTextEntity(static_cast<const DXFTextEntity&>(*pE),*pT);
+ break;
+ case DXF_INSERT:
+ DrawInsertEntity(static_cast<const DXFInsertEntity&>(*pE),*pT);
+ break;
+ case DXF_ATTRIB:
+ DrawAttribEntity(static_cast<const DXFAttribEntity&>(*pE),*pT);
+ break;
+ case DXF_POLYLINE:
+ DrawPolyLineEntity(static_cast<const DXFPolyLineEntity&>(*pE),*pT);
+ break;
+ case DXF_LWPOLYLINE :
+ DrawLWPolyLineEntity(static_cast<const DXFLWPolyLineEntity&>(*pE), *pT);
+ break;
+ case DXF_HATCH :
+ DrawHatchEntity(static_cast<const DXFHatchEntity&>(*pE), *pT);
+ break;
+ case DXF_3DFACE:
+ Draw3DFaceEntity(static_cast<const DXF3DFaceEntity&>(*pE),*pT);
+ break;
+ case DXF_DIMENSION:
+ DrawDimensionEntity(static_cast<const DXFDimensionEntity&>(*pE),*pT);
+ break;
+ default:
+ break; // four other values not handled -Wall
+ }
+ }
+ pE=pE->pSucc;
+ }
+
+ rEntities.mbBeingDrawn = false;
+}
+
+
+DXF2GDIMetaFile::DXF2GDIMetaFile()
+ : pVirDev(nullptr)
+ , pDXF(nullptr)
+ , bStatus(false)
+ , OptPointsPerCircle(0)
+ , nMinPercent(0)
+ , nMaxPercent(0)
+ , nLastPercent(0)
+ , nMainEntitiesCount(0)
+ , nBlockColor(0)
+ , nParentLayerColor(0)
+{
+}
+
+
+DXF2GDIMetaFile::~DXF2GDIMetaFile()
+{
+}
+
+
+bool DXF2GDIMetaFile::Convert(const DXFRepresentation & rDXF, GDIMetaFile & rMTF, sal_uInt16 nminpercent, sal_uInt16 nmaxpercent)
+{
+ double fWidth,fHeight,fScale(0.0);
+ DXFTransform aTransform;
+ Size aPrefSize;
+ const DXFLayer * pLayer;
+ const DXFVPort * pVPort;
+
+ pVirDev = VclPtr<VirtualDevice>::Create();
+ pDXF = &rDXF;
+ bStatus = true;
+
+ OptPointsPerCircle=50;
+
+ nMinPercent=nminpercent;
+ nMaxPercent=nmaxpercent;
+ nLastPercent=nMinPercent;
+ nMainEntitiesCount=CountEntities(pDXF->aEntities);
+
+ nBlockColor=7;
+ aBlockDXFLineInfo.eStyle = LineStyle::Solid;
+ aBlockDXFLineInfo.nDashCount = 0;
+ aBlockDXFLineInfo.fDashLen = 0;
+ aBlockDXFLineInfo.nDotCount = 0;
+ aBlockDXFLineInfo.fDotLen = 0;
+ aBlockDXFLineInfo.fDistance = 0;
+
+ pLayer=pDXF->aTables.SearchLayer("0");
+ if (pLayer!=nullptr) {
+ nParentLayerColor=pLayer->nColor & 0xff;
+ aParentLayerDXFLineInfo = LTypeToDXFLineInfo(pLayer->m_sLineType);
+ }
+ else {
+ nParentLayerColor=7;
+ aParentLayerDXFLineInfo.eStyle = LineStyle::Solid;
+ aParentLayerDXFLineInfo.nDashCount = 0;
+ aParentLayerDXFLineInfo.fDashLen = 0;
+ aParentLayerDXFLineInfo.nDotCount = 0;
+ aParentLayerDXFLineInfo.fDotLen = 0;
+ aParentLayerDXFLineInfo.fDistance = 0;
+ }
+
+ pVirDev->EnableOutput(false);
+ if (!utl::ConfigManager::IsFuzzing()) // for fuzzing don't bother recording the drawing
+ rMTF.Record(pVirDev);
+
+ aActLineColor = pVirDev->GetLineColor();
+ aActFillColor = pVirDev->GetFillColor();
+ aActFont = pVirDev->GetFont();
+
+ pVPort=pDXF->aTables.SearchVPort("*ACTIVE");
+ if (pVPort!=nullptr) {
+ if (pVPort->aDirection.fx==0 && pVPort->aDirection.fy==0)
+ pVPort=nullptr;
+ }
+
+ if (pVPort==nullptr) {
+ if (pDXF->aBoundingBox.bEmpty)
+ bStatus=false;
+ else {
+ fWidth=pDXF->aBoundingBox.fMaxX-pDXF->aBoundingBox.fMinX;
+ fHeight=pDXF->aBoundingBox.fMaxY-pDXF->aBoundingBox.fMinY;
+ if (fWidth<=0 || fHeight<=0) {
+ bStatus=false;
+ }
+ else {
+ if (fWidth>fHeight)
+ fScale=10000.0/fWidth;
+ else
+ fScale=10000.0/fHeight;
+ aTransform=DXFTransform(fScale,-fScale,fScale,
+ DXFVector(-pDXF->aBoundingBox.fMinX*fScale,
+ pDXF->aBoundingBox.fMaxY*fScale,
+ -pDXF->aBoundingBox.fMinZ*fScale));
+ }
+ aPrefSize.setWidth(static_cast<tools::Long>(fWidth*fScale+1.5) );
+ aPrefSize.setHeight(static_cast<tools::Long>(fHeight*fScale+1.5) );
+ }
+ }
+ else {
+ fHeight=pVPort->fHeight;
+ fWidth=fHeight*pVPort->fAspectRatio;
+ if (fWidth<=0 || fHeight<=0) {
+ bStatus=false;
+ } else {
+ if (fWidth>fHeight)
+ fScale=10000.0/fWidth;
+ else
+ fScale=10000.0/fHeight;
+ aTransform=DXFTransform(
+ DXFTransform(pVPort->aDirection,pVPort->aTarget),
+ DXFTransform(
+ DXFTransform(1.0,-1.0,1.0,DXFVector(fWidth/2-pVPort->fCenterX,fHeight/2+pVPort->fCenterY,0)),
+ DXFTransform(fScale,fScale,fScale,DXFVector(0,0,0))
+ )
+ );
+ }
+ aPrefSize.setWidth(static_cast<tools::Long>(fWidth*fScale+1.5) );
+ aPrefSize.setHeight(static_cast<tools::Long>(fHeight*fScale+1.5) );
+ }
+
+ if (bStatus)
+ DrawEntities(pDXF->aEntities,aTransform);
+
+ rMTF.Stop();
+
+ if ( bStatus )
+ {
+ rMTF.SetPrefSize( aPrefSize );
+ // simply set map mode to 1/100-mm (1/10-mm) if the graphic
+ // does not get not too small (<0.5cm)
+ if( ( aPrefSize.Width() < 500 ) && ( aPrefSize.Height() < 500 ) )
+ rMTF.SetPrefMapMode( MapMode( MapUnit::Map10thMM ) );
+ else
+ rMTF.SetPrefMapMode( MapMode( MapUnit::Map100thMM ) );
+ }
+
+ pVirDev.disposeAndClear();
+ return bStatus;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxf2mtf.hxx b/vcl/source/filter/idxf/dxf2mtf.hxx
new file mode 100644
index 000000000..d8a935b51
--- /dev/null
+++ b/vcl/source/filter/idxf/dxf2mtf.hxx
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXF2MTF_HXX
+#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXF2MTF_HXX
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include "dxfreprd.hxx"
+#include <vcl/font.hxx>
+#include <vcl/lineinfo.hxx>
+#include <vcl/vclptr.hxx>
+#include <vcl/virdev.hxx>
+
+class DXF2GDIMetaFile {
+private:
+
+ VclPtr<VirtualDevice> pVirDev;
+ const DXFRepresentation * pDXF;
+ bool bStatus;
+
+ sal_uInt16 OptPointsPerCircle;
+
+ sal_uInt16 nMinPercent;
+ sal_uInt16 nMaxPercent;
+ sal_uInt16 nLastPercent;
+ sal_uInt16 nMainEntitiesCount;
+
+ tools::Long nBlockColor;
+ DXFLineInfo aBlockDXFLineInfo;
+ tools::Long nParentLayerColor;
+ DXFLineInfo aParentLayerDXFLineInfo;
+ Color aActLineColor;
+ Color aActFillColor;
+ vcl::Font aActFont;
+ const LineInfo aDefaultLineInfo; // to share between lines to reduce memory
+
+ static sal_uInt64 CountEntities(const DXFEntities & rEntities);
+
+ Color ConvertColor(sal_uInt8 nColor) const;
+
+ tools::Long GetEntityColor(const DXFBasicEntity & rE) const;
+
+ DXFLineInfo LTypeToDXFLineInfo(std::string_view rLineType) const;
+
+ DXFLineInfo GetEntityDXFLineInfo(const DXFBasicEntity & rE);
+
+ bool SetLineAttribute(const DXFBasicEntity & rE);
+
+ bool SetAreaAttribute(const DXFBasicEntity & rE);
+
+ bool SetFontAttribute(const DXFBasicEntity & rE, short nAngle,
+ sal_uInt16 nHeight);
+
+ void DrawLineEntity(const DXFLineEntity & rE, const DXFTransform & rTransform);
+
+ void DrawPointEntity(const DXFPointEntity & rE, const DXFTransform & rTransform);
+
+ void DrawCircleEntity(const DXFCircleEntity & rE, const DXFTransform & rTransform);
+
+ void DrawArcEntity(const DXFArcEntity & rE, const DXFTransform & rTransform);
+
+ void DrawTraceEntity(const DXFTraceEntity & rE, const DXFTransform & rTransform);
+
+ void DrawSolidEntity(const DXFSolidEntity & rE, const DXFTransform & rTransform);
+
+ void DrawTextEntity(const DXFTextEntity & rE, const DXFTransform & rTransform);
+
+ void DrawInsertEntity(const DXFInsertEntity & rE, const DXFTransform & rTransform);
+
+ void DrawAttribEntity(const DXFAttribEntity & rE, const DXFTransform & rTransform);
+
+ void DrawPolyLineEntity(const DXFPolyLineEntity & rE, const DXFTransform & rTransform);
+
+ void Draw3DFaceEntity(const DXF3DFaceEntity & rE, const DXFTransform & rTransform);
+
+ void DrawDimensionEntity(const DXFDimensionEntity & rE, const DXFTransform & rTransform);
+
+ void DrawLWPolyLineEntity( const DXFLWPolyLineEntity & rE, const DXFTransform & rTransform );
+
+ void DrawHatchEntity( const DXFHatchEntity & rE, const DXFTransform & rTransform );
+
+ void DrawEntities(const DXFEntities & rEntities,
+ const DXFTransform & rTransform);
+
+ void DrawLine(const Point& rA, const Point& rB);
+
+public:
+
+ DXF2GDIMetaFile();
+ ~DXF2GDIMetaFile();
+
+ bool Convert( const DXFRepresentation & rDXF, GDIMetaFile & rMTF, sal_uInt16 nMinPercent, sal_uInt16 nMaxPercent);
+
+};
+
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfblkrd.cxx b/vcl/source/filter/idxf/dxfblkrd.cxx
new file mode 100644
index 000000000..b5a96b93e
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfblkrd.cxx
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include "dxfblkrd.hxx"
+
+
+//---------------- DXFBlock --------------------------------------------------
+
+
+DXFBlock::DXFBlock()
+ : pSucc(nullptr)
+ , nFlags(0)
+{
+}
+
+
+DXFBlock::~DXFBlock()
+{
+}
+
+
+void DXFBlock::Read(DXFGroupReader & rDGR)
+{
+ m_sName = "";
+ m_sAlsoName = "";
+ aBasePoint.fx=0.0;
+ aBasePoint.fy=0.0;
+ aBasePoint.fz=0.0;
+ nFlags=0;
+ m_sXRef = "";
+
+ while (rDGR.Read()!=0)
+ {
+ switch (rDGR.GetG())
+ {
+ case 2: m_sName = rDGR.GetS(); break;
+ case 3: m_sAlsoName = rDGR.GetS(); break;
+ case 70: nFlags=rDGR.GetI(); break;
+ case 10: aBasePoint.fx=rDGR.GetF(); break;
+ case 20: aBasePoint.fy=rDGR.GetF(); break;
+ case 30: aBasePoint.fz=rDGR.GetF(); break;
+ case 1: m_sXRef = rDGR.GetS(); break;
+ }
+ }
+ DXFEntities::Read(rDGR);
+}
+
+
+//---------------- DXFBlocks -------------------------------------------------
+
+
+DXFBlocks::DXFBlocks()
+{
+ pFirst=nullptr;
+}
+
+
+DXFBlocks::~DXFBlocks()
+{
+ Clear();
+}
+
+
+void DXFBlocks::Read(DXFGroupReader & rDGR)
+{
+ DXFBlock * pB, * * ppSucc;
+
+ ppSucc=&pFirst;
+ while (*ppSucc!=nullptr) ppSucc=&((*ppSucc)->pSucc);
+
+ for (;;) {
+ while (rDGR.GetG()!=0) rDGR.Read();
+ if (rDGR.GetS() == "ENDSEC" ||
+ rDGR.GetS() == "EOF") break;
+ if (rDGR.GetS() == "BLOCK") {
+ pB=new DXFBlock;
+ pB->Read(rDGR);
+ *ppSucc=pB;
+ ppSucc=&(pB->pSucc);
+ }
+ else rDGR.Read();
+ }
+}
+
+
+DXFBlock * DXFBlocks::Search(std::string_view rName) const
+{
+ DXFBlock * pB;
+ for (pB=pFirst; pB!=nullptr; pB=pB->pSucc) {
+ if (rName == pB->m_sName) break;
+ }
+ return pB;
+}
+
+
+void DXFBlocks::Clear()
+{
+ DXFBlock * ptmp;
+
+ while (pFirst!=nullptr) {
+ ptmp=pFirst;
+ pFirst=ptmp->pSucc;
+ delete ptmp;
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfblkrd.hxx b/vcl/source/filter/idxf/dxfblkrd.hxx
new file mode 100644
index 000000000..ca0a0e68a
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfblkrd.hxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFBLKRD_HXX
+#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFBLKRD_HXX
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include "dxfentrd.hxx"
+
+
+//---------------- A Block (= Set of Entities) --------------------------
+
+
+class DXFBlock : public DXFEntities {
+
+public:
+
+ DXFBlock * pSucc;
+ // pointer to the next block in the list DXFBlocks::pFirst
+
+ // properties of blocks; commented with group codes:
+ OString m_sName; // 2
+ OString m_sAlsoName; // 3
+ tools::Long nFlags; // 70
+ DXFVector aBasePoint; // 10,20,30
+ OString m_sXRef; // 1
+
+ DXFBlock();
+ ~DXFBlock();
+
+ void Read(DXFGroupReader & rDGR);
+ // reads the block (including entities) from a dxf file
+ // by rGDR until an ENDBLK, ENDSEC or EOF.
+};
+
+
+//---------------- A set of blocks -----------------------------------
+
+
+class DXFBlocks {
+
+ DXFBlock * pFirst;
+ // list of blocks, READ ONLY!
+
+public:
+
+ DXFBlocks();
+ ~DXFBlocks();
+
+ void Read(DXFGroupReader & rDGR);
+ // reads all block per rDGR until an ENDSEC or EOF.
+
+ DXFBlock * Search(std::string_view rName) const;
+ // looks for a block with the name, return NULL if not successful
+
+ void Clear();
+ // deletes all blocks
+
+};
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfentrd.cxx b/vcl/source/filter/idxf/dxfentrd.cxx
new file mode 100644
index 000000000..b4915c657
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfentrd.cxx
@@ -0,0 +1,848 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <o3tl/safeint.hxx>
+
+#include "dxfentrd.hxx"
+
+//--------------------------DXFBasicEntity--------------------------------------
+
+DXFBasicEntity::DXFBasicEntity(DXFEntityType eThisType)
+ : m_sLayer("0")
+ , m_sLineType("BYLAYER")
+{
+ eType=eThisType;
+ pSucc=nullptr;
+ fThickness=0;
+ nColor=256;
+ nSpace=0;
+ aExtrusion.fx=0.0;
+ aExtrusion.fy=0.0;
+ aExtrusion.fz=1.0;
+}
+
+void DXFBasicEntity::Read(DXFGroupReader & rDGR)
+{
+ while (rDGR.Read()!=0) EvaluateGroup(rDGR);
+}
+
+void DXFBasicEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG())
+ {
+ case 8: m_sLayer = rDGR.GetS(); break;
+ case 6: m_sLineType = rDGR.GetS(); break;
+ case 39: fThickness=rDGR.GetF(); break;
+ case 62: nColor=rDGR.GetI(); break;
+ case 67: nSpace=rDGR.GetI(); break;
+ case 210: aExtrusion.fx=rDGR.GetF(); break;
+ case 220: aExtrusion.fy=rDGR.GetF(); break;
+ case 230: aExtrusion.fz=rDGR.GetF(); break;
+ }
+}
+
+DXFBasicEntity::~DXFBasicEntity()
+{
+}
+
+//--------------------------DXFLineEntity---------------------------------------
+
+DXFLineEntity::DXFLineEntity() : DXFBasicEntity(DXF_LINE)
+{
+}
+
+void DXFLineEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 11: aP1.fx=rDGR.GetF(); break;
+ case 21: aP1.fy=rDGR.GetF(); break;
+ case 31: aP1.fz=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFPointEntity--------------------------------------
+
+DXFPointEntity::DXFPointEntity() : DXFBasicEntity(DXF_POINT)
+{
+}
+
+void DXFPointEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFCircleEntity-------------------------------------
+
+DXFCircleEntity::DXFCircleEntity() : DXFBasicEntity(DXF_CIRCLE)
+{
+ fRadius=1.0;
+}
+
+void DXFCircleEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 40: fRadius=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFArcEntity----------------------------------------
+
+DXFArcEntity::DXFArcEntity() : DXFBasicEntity(DXF_ARC)
+{
+ fRadius=1.0;
+ fStart=0;
+ fEnd=360.0;
+}
+
+void DXFArcEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 40: fRadius=rDGR.GetF(); break;
+ case 50: fStart=rDGR.GetF(); break;
+ case 51: fEnd=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFTraceEntity--------------------------------------
+
+DXFTraceEntity::DXFTraceEntity() : DXFBasicEntity(DXF_TRACE)
+{
+}
+
+void DXFTraceEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 11: aP1.fx=rDGR.GetF(); break;
+ case 21: aP1.fy=rDGR.GetF(); break;
+ case 31: aP1.fz=rDGR.GetF(); break;
+ case 12: aP2.fx=rDGR.GetF(); break;
+ case 22: aP2.fy=rDGR.GetF(); break;
+ case 32: aP2.fz=rDGR.GetF(); break;
+ case 13: aP3.fx=rDGR.GetF(); break;
+ case 23: aP3.fy=rDGR.GetF(); break;
+ case 33: aP3.fz=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFSolidEntity--------------------------------------
+
+DXFSolidEntity::DXFSolidEntity() : DXFBasicEntity(DXF_SOLID)
+{
+}
+
+void DXFSolidEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 11: aP1.fx=rDGR.GetF(); break;
+ case 21: aP1.fy=rDGR.GetF(); break;
+ case 31: aP1.fz=rDGR.GetF(); break;
+ case 12: aP2.fx=rDGR.GetF(); break;
+ case 22: aP2.fy=rDGR.GetF(); break;
+ case 32: aP2.fz=rDGR.GetF(); break;
+ case 13: aP3.fx=rDGR.GetF(); break;
+ case 23: aP3.fy=rDGR.GetF(); break;
+ case 33: aP3.fz=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFTextEntity---------------------------------------
+
+DXFTextEntity::DXFTextEntity()
+ : DXFBasicEntity(DXF_TEXT)
+ , m_sStyle("STANDARD")
+{
+ fHeight=1.0;
+ fRotAngle=0.0;
+ fXScale=1.0;
+ fOblAngle=0.0;
+ nGenFlags=0;
+ nHorzJust=0;
+ nVertJust=0;
+}
+
+void DXFTextEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 40: fHeight=rDGR.GetF(); break;
+ case 1: m_sText = rDGR.GetS(); break;
+ case 50: fRotAngle=rDGR.GetF(); break;
+ case 41: fXScale=rDGR.GetF(); break;
+ case 42: fOblAngle=rDGR.GetF(); break;
+ case 7: m_sStyle = rDGR.GetS(); break;
+ case 71: nGenFlags=rDGR.GetI(); break;
+ case 72: nHorzJust=rDGR.GetI(); break;
+ case 73: nVertJust=rDGR.GetI(); break;
+ case 11: aAlign.fx=rDGR.GetF(); break;
+ case 21: aAlign.fy=rDGR.GetF(); break;
+ case 31: aAlign.fz=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFShapeEntity--------------------------------------
+
+DXFShapeEntity::DXFShapeEntity() : DXFBasicEntity(DXF_SHAPE)
+{
+ fSize=1.0;
+ fRotAngle=0;
+ fXScale=1.0;
+ fOblAngle=0;
+}
+
+void DXFShapeEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 40: fSize=rDGR.GetF(); break;
+ case 2: m_sName = rDGR.GetS(); break;
+ case 50: fRotAngle=rDGR.GetF(); break;
+ case 41: fXScale=rDGR.GetF(); break;
+ case 51: fOblAngle=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFInsertEntity-------------------------------------
+
+DXFInsertEntity::DXFInsertEntity() : DXFBasicEntity(DXF_INSERT)
+{
+ nAttrFlag=0;
+ fXScale=1.0;
+ fYScale=1.0;
+ fZScale=1.0;
+ fRotAngle=0.0;
+ nColCount=1;
+ nRowCount=1;
+ fColSpace=0.0;
+ fRowSpace=0.0;
+}
+
+void DXFInsertEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 66: nAttrFlag=rDGR.GetI(); break;
+ case 2: m_sName = rDGR.GetS(); break;
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 41: fXScale=rDGR.GetF(); break;
+ case 42: fYScale=rDGR.GetF(); break;
+ case 43: fZScale=rDGR.GetF(); break;
+ case 50: fRotAngle=rDGR.GetF(); break;
+ case 70: nColCount=rDGR.GetI(); break;
+ case 71: nRowCount=rDGR.GetI(); break;
+ case 44: fColSpace=rDGR.GetF(); break;
+ case 45: fRowSpace=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFAttDefEntity-------------------------------------
+
+DXFAttDefEntity::DXFAttDefEntity()
+ : DXFBasicEntity(DXF_ATTDEF)
+ , m_sStyle("STANDARD")
+{
+ fHeight=1.0;
+ nAttrFlags=0;
+ nFieldLen=0;
+ fRotAngle=0.0;
+ fXScale=1.0;
+ fOblAngle=0.0;
+ nGenFlags=0;
+ nHorzJust=0;
+ nVertJust=0;
+}
+
+void DXFAttDefEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 40: fHeight=rDGR.GetF(); break;
+ case 1: m_sDefVal = rDGR.GetS(); break;
+ case 3: m_sPrompt = rDGR.GetS(); break;
+ case 2: m_sTagStr = rDGR.GetS(); break;
+ case 70: nAttrFlags=rDGR.GetI(); break;
+ case 73: nFieldLen=rDGR.GetI(); break;
+ case 50: fRotAngle=rDGR.GetF(); break;
+ case 41: fXScale=rDGR.GetF(); break;
+ case 51: fOblAngle=rDGR.GetF(); break;
+ case 7: m_sStyle = rDGR.GetS(); break;
+ case 71: nGenFlags=rDGR.GetI(); break;
+ case 72: nHorzJust=rDGR.GetI(); break;
+ case 74: nVertJust=rDGR.GetI(); break;
+ case 11: aAlign.fx=rDGR.GetF(); break;
+ case 21: aAlign.fy=rDGR.GetF(); break;
+ case 31: aAlign.fz=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFAttribEntity-------------------------------------
+
+DXFAttribEntity::DXFAttribEntity()
+ : DXFBasicEntity(DXF_ATTRIB)
+ , m_sStyle("STANDARD")
+{
+ fHeight=1.0;
+ nAttrFlags=0;
+ nFieldLen=0;
+ fRotAngle=0.0;
+ fXScale=1.0;
+ fOblAngle=0.0;
+ nGenFlags=0;
+ nHorzJust=0;
+ nVertJust=0;
+}
+
+void DXFAttribEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 40: fHeight=rDGR.GetF(); break;
+ case 1: m_sText = rDGR.GetS(); break;
+ case 2: m_sTagStr = rDGR.GetS(); break;
+ case 70: nAttrFlags=rDGR.GetI(); break;
+ case 73: nFieldLen=rDGR.GetI(); break;
+ case 50: fRotAngle=rDGR.GetF(); break;
+ case 41: fXScale=rDGR.GetF(); break;
+ case 51: fOblAngle=rDGR.GetF(); break;
+ case 7: m_sStyle = rDGR.GetS(); break;
+ case 71: nGenFlags=rDGR.GetI(); break;
+ case 72: nHorzJust=rDGR.GetI(); break;
+ case 74: nVertJust=rDGR.GetI(); break;
+ case 11: aAlign.fx=rDGR.GetF(); break;
+ case 21: aAlign.fy=rDGR.GetF(); break;
+ case 31: aAlign.fz=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFPolyLine-----------------------------------------
+
+DXFPolyLineEntity::DXFPolyLineEntity() : DXFBasicEntity(DXF_POLYLINE)
+{
+ nFlags=0;
+ fSWidth=0.0;
+ fEWidth=0.0;
+ nMeshMCount=0;
+ nMeshNCount=0;
+ nMDensity=0;
+ nNDensity=0;
+ nCSSType=0;
+}
+
+void DXFPolyLineEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 70: nFlags=rDGR.GetI(); break;
+ case 40: fSWidth=rDGR.GetF(); break;
+ case 41: fEWidth=rDGR.GetF(); break;
+ case 71: nMeshMCount=rDGR.GetI(); break;
+ case 72: nMeshNCount=rDGR.GetI(); break;
+ case 73: nMDensity=rDGR.GetI(); break;
+ case 74: nNDensity=rDGR.GetI(); break;
+ case 75: nCSSType=rDGR.GetI(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFLWPolyLine---------------------------------------
+
+DXFLWPolyLineEntity::DXFLWPolyLineEntity() :
+ DXFBasicEntity( DXF_LWPOLYLINE ),
+ nIndex( 0 ),
+ nCount( 0 ),
+ nFlags( 0 ),
+ fConstantWidth( 0.0 ),
+ fStartWidth( 0.0 ),
+ fEndWidth( 0.0 )
+{
+}
+
+void DXFLWPolyLineEntity::EvaluateGroup( DXFGroupReader & rDGR )
+{
+ switch ( rDGR.GetG() )
+ {
+ case 90 :
+ {
+ nCount = rDGR.GetI();
+ // limit alloc to max reasonable size based on remaining data in stream
+ if (nCount > 0 && o3tl::make_unsigned(nCount) <= rDGR.remainingSize())
+ aP.reserve(nCount);
+ else
+ nCount = 0;
+ }
+ break;
+ case 70: nFlags = rDGR.GetI(); break;
+ case 43: fConstantWidth = rDGR.GetF(); break;
+ case 40: fStartWidth = rDGR.GetF(); break;
+ case 41: fEndWidth = rDGR.GetF(); break;
+ case 10:
+ {
+ if (nIndex < nCount)
+ {
+ aP.resize(nIndex+1);
+ aP[nIndex].fx = rDGR.GetF();
+ }
+ }
+ break;
+ case 20:
+ {
+ if (nIndex < nCount)
+ {
+ aP.resize(nIndex+1);
+ aP[nIndex].fy = rDGR.GetF();
+ ++nIndex;
+ }
+ }
+ break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFHatchEntity-------------------------------------
+
+DXFEdgeTypeLine::DXFEdgeTypeLine() :
+ DXFEdgeType( 1 )
+{
+
+}
+
+bool DXFEdgeTypeLine::EvaluateGroup( DXFGroupReader & rDGR )
+{
+ bool bExecutingGroupCode = true;
+ switch ( rDGR.GetG() )
+ {
+ case 10 : aStartPoint.fx = rDGR.GetF(); break;
+ case 20 : aStartPoint.fy = rDGR.GetF(); break;
+ case 11 : aEndPoint.fx = rDGR.GetF(); break;
+ case 21 : aEndPoint.fy = rDGR.GetF(); break;
+ default : bExecutingGroupCode = false; break;
+ }
+ return bExecutingGroupCode;
+}
+
+DXFEdgeTypeCircularArc::DXFEdgeTypeCircularArc() :
+ DXFEdgeType( 2 ),
+ fRadius( 0.0 ),
+ fStartAngle( 0.0 ),
+ fEndAngle( 0.0 ),
+ nIsCounterClockwiseFlag( 0 )
+{
+}
+
+bool DXFEdgeTypeCircularArc::EvaluateGroup( DXFGroupReader & rDGR )
+{
+ bool bExecutingGroupCode = true;
+ switch ( rDGR.GetG() )
+ {
+ case 10 : aCenter.fx = rDGR.GetF(); break;
+ case 20 : aCenter.fy = rDGR.GetF(); break;
+ case 40 : fRadius = rDGR.GetF(); break;
+ case 50 : fStartAngle = rDGR.GetF(); break;
+ case 51 : fEndAngle = rDGR.GetF(); break;
+ case 73 : nIsCounterClockwiseFlag = rDGR.GetI(); break;
+ default : bExecutingGroupCode = false; break;
+ }
+ return bExecutingGroupCode;
+}
+
+DXFEdgeTypeEllipticalArc::DXFEdgeTypeEllipticalArc() :
+ DXFEdgeType( 3 ),
+ fLength( 0.0 ),
+ fStartAngle( 0.0 ),
+ fEndAngle( 0.0 ),
+ nIsCounterClockwiseFlag( 0 )
+{
+}
+
+bool DXFEdgeTypeEllipticalArc::EvaluateGroup( DXFGroupReader & rDGR )
+{
+ bool bExecutingGroupCode = true;
+ switch( rDGR.GetG() )
+ {
+ case 10 : aCenter.fx = rDGR.GetF(); break;
+ case 20 : aCenter.fy = rDGR.GetF(); break;
+ case 11 : aEndPoint.fx = rDGR.GetF(); break;
+ case 21 : aEndPoint.fy = rDGR.GetF(); break;
+ case 40 : fLength = rDGR.GetF(); break;
+ case 50 : fStartAngle = rDGR.GetF(); break;
+ case 51 : fEndAngle = rDGR.GetF(); break;
+ case 73 : nIsCounterClockwiseFlag = rDGR.GetI(); break;
+ default : bExecutingGroupCode = false; break;
+ }
+ return bExecutingGroupCode;
+}
+
+DXFEdgeTypeSpline::DXFEdgeTypeSpline() :
+ DXFEdgeType( 4 ),
+ nDegree( 0 ),
+ nRational( 0 ),
+ nPeriodic( 0 ),
+ nKnotCount( 0 ),
+ nControlCount( 0 )
+{
+}
+
+bool DXFEdgeTypeSpline::EvaluateGroup( DXFGroupReader & rDGR )
+{
+ bool bExecutingGroupCode = true;
+ switch ( rDGR.GetG() )
+ {
+ case 94 : nDegree = rDGR.GetI(); break;
+ case 73 : nRational = rDGR.GetI(); break;
+ case 74 : nPeriodic = rDGR.GetI(); break;
+ case 95 : nKnotCount = rDGR.GetI(); break;
+ case 96 : nControlCount = rDGR.GetI(); break;
+ default : bExecutingGroupCode = false; break;
+ }
+ return bExecutingGroupCode;
+}
+
+DXFBoundaryPathData::DXFBoundaryPathData() :
+ nPointCount( 0 ),
+ nFlags( 0 ),
+ nHasBulgeFlag( 0 ),
+ nIsClosedFlag( 0 ),
+ fBulge( 0.0 ),
+ nSourceBoundaryObjects( 0 ),
+ nEdgeCount( 0 ),
+ bIsPolyLine( true ),
+ nPointIndex( 0 )
+{
+}
+
+bool DXFBoundaryPathData::EvaluateGroup( DXFGroupReader & rDGR )
+{
+ bool bExecutingGroupCode = true;
+ if ( bIsPolyLine )
+ {
+ switch( rDGR.GetG() )
+ {
+ case 92 :
+ {
+ nFlags = rDGR.GetI();
+ if ( ( nFlags & 2 ) == 0 )
+ bIsPolyLine = false;
+ }
+ break;
+ case 93 :
+ {
+ nPointCount = rDGR.GetI();
+ // limit alloc to max reasonable size based on remaining data in stream
+ if (nPointCount > 0 && o3tl::make_unsigned(nPointCount) <= rDGR.remainingSize())
+ aP.reserve(nPointCount);
+ else
+ nPointCount = 0;
+ }
+ break;
+ case 72 : nHasBulgeFlag = rDGR.GetI(); break;
+ case 73 : nIsClosedFlag = rDGR.GetI(); break;
+ case 97 : nSourceBoundaryObjects = rDGR.GetI(); break;
+ case 42 : fBulge = rDGR.GetF(); break;
+ case 10:
+ {
+ if (nPointIndex < nPointCount)
+ {
+ aP.resize(nPointIndex+1);
+ aP[nPointIndex].fx = rDGR.GetF();
+ }
+ }
+ break;
+ case 20:
+ {
+ if (nPointIndex < nPointCount)
+ {
+ aP.resize(nPointIndex+1);
+ aP[nPointIndex].fy = rDGR.GetF();
+ ++nPointIndex;
+ }
+ }
+ break;
+
+ default : bExecutingGroupCode = false; break;
+ }
+ }
+ else
+ {
+ if ( rDGR.GetG() == 93 )
+ nEdgeCount = rDGR.GetI();
+ else if ( rDGR.GetG() == 72 )
+ {
+ sal_Int32 nEdgeType = rDGR.GetI();
+ switch( nEdgeType )
+ {
+ case 1 : aEdges.emplace_back( new DXFEdgeTypeLine() ); break;
+ case 2 : aEdges.emplace_back( new DXFEdgeTypeCircularArc() ); break;
+ case 3 : aEdges.emplace_back( new DXFEdgeTypeEllipticalArc() ); break;
+ case 4 : aEdges.emplace_back( new DXFEdgeTypeSpline() ); break;
+ }
+ }
+ else if ( !aEdges.empty() )
+ aEdges.back()->EvaluateGroup( rDGR );
+ else
+ bExecutingGroupCode = false;
+ }
+ return bExecutingGroupCode;
+}
+
+DXFHatchEntity::DXFHatchEntity() :
+ DXFBasicEntity( DXF_HATCH ),
+ bIsInBoundaryPathContext( false ),
+ nCurrentBoundaryPathIndex( -1 ),
+ nFlags( 0 ),
+ nAssociativityFlag( 0 ),
+ nMaxBoundaryPathCount( 0 ),
+ nHatchStyle( 0 ),
+ nHatchPatternType( 0 ),
+ fHatchPatternAngle( 0.0 ),
+ fHatchPatternScale( 1.0 ),
+ nHatchDoubleFlag( 0 ),
+ nHatchPatternDefinitionLines( 0 ),
+ fPixelSize( 1.0 ),
+ nNumberOfSeedPoints( 0 )
+{
+}
+
+void DXFHatchEntity::EvaluateGroup( DXFGroupReader & rDGR )
+{
+ switch ( rDGR.GetG() )
+ {
+// case 10 : aElevationPoint.fx = rDGR.GetF(); break;
+// case 20 : aElevationPoint.fy = rDGR.GetF(); break;
+// case 30 : aElevationPoint.fz = rDGR.GetF(); break;
+ case 70 : nFlags = rDGR.GetI(); break;
+ case 71 : nAssociativityFlag = rDGR.GetI(); break;
+ case 91 :
+ {
+ bIsInBoundaryPathContext = true;
+ nMaxBoundaryPathCount = rDGR.GetI();
+ // limit alloc to max reasonable size based on remaining data in stream
+ if (nMaxBoundaryPathCount > 0 && o3tl::make_unsigned(nMaxBoundaryPathCount) <= rDGR.remainingSize())
+ aBoundaryPathData.reserve(nMaxBoundaryPathCount);
+ else
+ nMaxBoundaryPathCount = 0;
+ }
+ break;
+ case 75 :
+ {
+ nHatchStyle = rDGR.GetI();
+ bIsInBoundaryPathContext = false;
+ }
+ break;
+ case 76 : nHatchPatternType = rDGR.GetI(); break;
+ case 52 : fHatchPatternAngle = rDGR.GetF(); break;
+ case 41 : fHatchPatternScale = rDGR.GetF(); break;
+ case 77 : nHatchDoubleFlag = rDGR.GetI(); break;
+ case 78 : nHatchPatternDefinitionLines = rDGR.GetI(); break;
+ case 47 : fPixelSize = rDGR.GetF(); break;
+ case 98 : nNumberOfSeedPoints = rDGR.GetI(); break;
+
+ case 92:
+ nCurrentBoundaryPathIndex++;
+ [[fallthrough]];
+ default:
+ {
+ bool bExecutingGroupCode = false;
+ if ( bIsInBoundaryPathContext )
+ {
+ if (nCurrentBoundaryPathIndex >= 0 && nCurrentBoundaryPathIndex < nMaxBoundaryPathCount)
+ {
+ aBoundaryPathData.resize(nCurrentBoundaryPathIndex + 1);
+ bExecutingGroupCode = aBoundaryPathData.back().EvaluateGroup(rDGR);
+ }
+ }
+ if ( !bExecutingGroupCode )
+ DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+ break;
+ }
+}
+
+//--------------------------DXFVertexEntity-------------------------------------
+
+DXFVertexEntity::DXFVertexEntity() : DXFBasicEntity(DXF_VERTEX)
+{
+ fSWidth=-1.0;
+ fEWidth=-1.0;
+ fBulge=0.0;
+ nFlags=0;
+ fCFTDir=0.0;
+
+}
+
+void DXFVertexEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 40: fSWidth=rDGR.GetF(); break;
+ case 41: fEWidth=rDGR.GetF(); break;
+ case 42: fBulge=rDGR.GetF(); break;
+ case 70: nFlags=rDGR.GetI(); break;
+ case 50: fCFTDir=rDGR.GetF(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//--------------------------DXFSeqEndEntity-------------------------------------
+
+DXFSeqEndEntity::DXFSeqEndEntity() : DXFBasicEntity(DXF_SEQEND)
+{
+}
+
+//--------------------------DXF3DFace-------------------------------------------
+
+DXF3DFaceEntity::DXF3DFaceEntity() : DXFBasicEntity(DXF_3DFACE)
+{
+ nIEFlags=0;
+}
+
+void DXF3DFaceEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 10: aP0.fx=rDGR.GetF(); break;
+ case 20: aP0.fy=rDGR.GetF(); break;
+ case 30: aP0.fz=rDGR.GetF(); break;
+ case 11: aP1.fx=rDGR.GetF(); break;
+ case 21: aP1.fy=rDGR.GetF(); break;
+ case 31: aP1.fz=rDGR.GetF(); break;
+ case 12: aP2.fx=rDGR.GetF(); break;
+ case 22: aP2.fy=rDGR.GetF(); break;
+ case 32: aP2.fz=rDGR.GetF(); break;
+ case 13: aP3.fx=rDGR.GetF(); break;
+ case 23: aP3.fy=rDGR.GetF(); break;
+ case 33: aP3.fz=rDGR.GetF(); break;
+ case 70: nIEFlags=rDGR.GetI(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+
+//--------------------------DXFDimensionEntity----------------------------------
+
+DXFDimensionEntity::DXFDimensionEntity() : DXFBasicEntity(DXF_DIMENSION)
+{
+}
+
+void DXFDimensionEntity::EvaluateGroup(DXFGroupReader & rDGR)
+{
+ switch (rDGR.GetG()) {
+ case 2: m_sPseudoBlock = rDGR.GetS(); break;
+ default: DXFBasicEntity::EvaluateGroup(rDGR);
+ }
+}
+
+//---------------------------- DXFEntities --------------------------------------
+
+void DXFEntities::Read(DXFGroupReader & rDGR)
+{
+ DXFBasicEntity * pE, * * ppSucc;
+
+ ppSucc=&pFirst;
+ while (*ppSucc!=nullptr) ppSucc=&((*ppSucc)->pSucc);
+
+ while (rDGR.GetG()!=0) rDGR.Read();
+
+ while (rDGR.GetS()!="ENDBLK" &&
+ rDGR.GetS()!="ENDSEC" &&
+ rDGR.GetS()!="EOF" )
+ {
+
+ if (rDGR.GetS() == "LINE" ) pE=new DXFLineEntity;
+ else if (rDGR.GetS() == "POINT" ) pE=new DXFPointEntity;
+ else if (rDGR.GetS() == "CIRCLE" ) pE=new DXFCircleEntity;
+ else if (rDGR.GetS() == "ARC" ) pE=new DXFArcEntity;
+ else if (rDGR.GetS() == "TRACE" ) pE=new DXFTraceEntity;
+ else if (rDGR.GetS() == "SOLID" ) pE=new DXFSolidEntity;
+ else if (rDGR.GetS() == "TEXT" ) pE=new DXFTextEntity;
+ else if (rDGR.GetS() == "SHAPE" ) pE=new DXFShapeEntity;
+ else if (rDGR.GetS() == "INSERT" ) pE=new DXFInsertEntity;
+ else if (rDGR.GetS() == "ATTDEF" ) pE=new DXFAttDefEntity;
+ else if (rDGR.GetS() == "ATTRIB" ) pE=new DXFAttribEntity;
+ else if (rDGR.GetS() == "POLYLINE" ) pE=new DXFPolyLineEntity;
+ else if (rDGR.GetS() == "LWPOLYLINE") pE=new DXFLWPolyLineEntity;
+ else if (rDGR.GetS() == "VERTEX" ) pE=new DXFVertexEntity;
+ else if (rDGR.GetS() == "SEQEND" ) pE=new DXFSeqEndEntity;
+ else if (rDGR.GetS() == "3DFACE" ) pE=new DXF3DFaceEntity;
+ else if (rDGR.GetS() == "DIMENSION" ) pE=new DXFDimensionEntity;
+ else if (rDGR.GetS() == "HATCH" ) pE=new DXFHatchEntity;
+ else
+ {
+ do {
+ rDGR.Read();
+ } while (rDGR.GetG()!=0);
+ continue;
+ }
+ *ppSucc=pE;
+ ppSucc=&(pE->pSucc);
+ pE->Read(rDGR);
+ }
+}
+
+void DXFEntities::Clear()
+{
+ DXFBasicEntity * ptmp;
+
+ while (pFirst!=nullptr) {
+ ptmp=pFirst;
+ pFirst=ptmp->pSucc;
+ delete ptmp;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfentrd.hxx b/vcl/source/filter/idxf/dxfentrd.hxx
new file mode 100644
index 000000000..85dbf7dd0
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfentrd.hxx
@@ -0,0 +1,538 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFENTRD_HXX
+#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFENTRD_HXX
+
+#include "dxfgrprd.hxx"
+#include "dxfvec.hxx"
+#include <tools/long.hxx>
+
+#include <memory>
+#include <vector>
+
+enum DXFEntityType {
+ DXF_LINE,
+ DXF_POINT,
+ DXF_CIRCLE,
+ DXF_ARC,
+ DXF_TRACE,
+ DXF_SOLID,
+ DXF_TEXT,
+ DXF_SHAPE,
+ DXF_INSERT,
+ DXF_ATTDEF,
+ DXF_ATTRIB,
+ DXF_POLYLINE,
+ DXF_VERTEX,
+ DXF_SEQEND,
+ DXF_3DFACE,
+ DXF_DIMENSION,
+ DXF_LWPOLYLINE,
+ DXF_HATCH
+};
+
+// base class of an entity
+
+class DXFBasicEntity {
+
+public:
+
+ DXFBasicEntity * pSucc;
+ // pointer to next entity (in the list of DXFEntities.pFirst)
+
+ DXFEntityType eType;
+ // entity kind (line or circle or what)
+
+ // properties that all entities have, each
+ // commented with group codes:
+ OString m_sLayer; // 8
+ OString m_sLineType; // 6
+ double fThickness; // 39
+ tools::Long nColor; // 62
+ tools::Long nSpace; // 67
+ DXFVector aExtrusion; // 210,220,230
+
+protected:
+
+ DXFBasicEntity(DXFEntityType eThisType);
+ // always initialize the constructors of entities with default values
+
+public:
+
+ virtual ~DXFBasicEntity();
+ void Read(DXFGroupReader & rDGR);
+ // Reads a parameter till the next 0-group
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR);
+ // This method will be called by Read() for every parameter (respectively
+ // for every group).
+ // As far as the group code of the entity is known, the corresponding
+ // parameter is fetched.
+
+};
+
+
+// the different kinds of entities
+
+class DXFLineEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+ DXFVector aP1; // 11,21,31
+
+ DXFLineEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFPointEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+
+ DXFPointEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFCircleEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+ double fRadius; // 40
+
+ DXFCircleEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFArcEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+ double fRadius; // 40
+ double fStart; // 50
+ double fEnd; // 51
+
+ DXFArcEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFTraceEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+ DXFVector aP1; // 11,21,31
+ DXFVector aP2; // 12,22,32
+ DXFVector aP3; // 13,23,33
+
+ DXFTraceEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFSolidEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+ DXFVector aP1; // 11,21,31
+ DXFVector aP2; // 12,22,32
+ DXFVector aP3; // 13,23,33
+
+ DXFSolidEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFTextEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+ double fHeight; // 40
+ OString m_sText; // 1
+ double fRotAngle; // 50
+ double fXScale; // 41
+ double fOblAngle; // 42
+ OString m_sStyle; // 7
+ tools::Long nGenFlags; // 71
+ tools::Long nHorzJust; // 72
+ tools::Long nVertJust; // 73
+ DXFVector aAlign; // 11,21,31
+
+ DXFTextEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFShapeEntity : public DXFBasicEntity {
+
+ DXFVector aP0; // 10,20,30
+ double fSize; // 40
+ OString m_sName; // 2
+ double fRotAngle; // 50
+ double fXScale; // 41
+ double fOblAngle; // 51
+
+public:
+
+ DXFShapeEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFInsertEntity : public DXFBasicEntity {
+
+public:
+
+ tools::Long nAttrFlag; // 66
+ OString m_sName; // 2
+ DXFVector aP0; // 10,20,30
+ double fXScale; // 41
+ double fYScale; // 42
+ double fZScale; // 43
+ double fRotAngle; // 50
+ tools::Long nColCount; // 70
+ tools::Long nRowCount; // 71
+ double fColSpace; // 44
+ double fRowSpace; // 45
+
+ DXFInsertEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFAttDefEntity : public DXFBasicEntity {
+
+ DXFVector aP0; // 10,20,30
+ double fHeight; // 40
+ OString m_sDefVal; // 1
+ OString m_sPrompt; // 3
+ OString m_sTagStr; // 2
+ tools::Long nAttrFlags; // 70
+ tools::Long nFieldLen; // 73
+ double fRotAngle; // 50
+ double fXScale; // 41
+ double fOblAngle; // 51
+ OString m_sStyle; // 7
+ tools::Long nGenFlags; // 71
+ tools::Long nHorzJust; // 72
+ tools::Long nVertJust; // 74
+ DXFVector aAlign; // 11,21,31
+
+public:
+
+ DXFAttDefEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFAttribEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+ double fHeight; // 40
+ OString m_sText; // 1
+ OString m_sTagStr; // 2
+ tools::Long nAttrFlags; // 70
+ tools::Long nFieldLen; // 73
+ double fRotAngle; // 50
+ double fXScale; // 41
+ double fOblAngle; // 51
+ OString m_sStyle; // 7
+ tools::Long nGenFlags; // 71
+ tools::Long nHorzJust; // 72
+ tools::Long nVertJust; // 74
+ DXFVector aAlign; // 11,21,31
+
+ DXFAttribEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFPolyLineEntity : public DXFBasicEntity {
+
+public:
+
+ tools::Long nFlags; // 70
+ double fSWidth; // 40
+ double fEWidth; // 41
+ tools::Long nMeshMCount; // 71
+ tools::Long nMeshNCount; // 72
+ tools::Long nMDensity; // 73
+ tools::Long nNDensity; // 74
+ tools::Long nCSSType; // 75
+
+ DXFPolyLineEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFLWPolyLineEntity : public DXFBasicEntity
+{
+ sal_Int32 nIndex;
+ sal_Int32 nCount; // 90
+
+ public:
+
+ sal_Int32 nFlags; // 70 1 = closed, 128 = plinegen
+ double fConstantWidth; // 43 (optional - default: 0, not used if fStartWidth and/or fEndWidth is used)
+ double fStartWidth; // 40
+ double fEndWidth; // 41
+
+ std::vector<DXFVector> aP;
+
+ DXFLWPolyLineEntity();
+
+ protected:
+
+ virtual void EvaluateGroup( DXFGroupReader & rDGR ) override;
+
+};
+
+struct DXFEdgeType
+{
+ sal_Int32 nEdgeType;
+
+ virtual ~DXFEdgeType(){};
+ virtual bool EvaluateGroup( DXFGroupReader & /*rDGR*/ ){ return true; };
+
+ protected:
+
+ DXFEdgeType( sal_Int32 EdgeType ):nEdgeType(EdgeType){};
+};
+
+struct DXFEdgeTypeLine : public DXFEdgeType
+{
+ DXFVector aStartPoint; // 10,20
+ DXFVector aEndPoint; // 11,21
+ DXFEdgeTypeLine();
+ virtual bool EvaluateGroup( DXFGroupReader & rDGR ) override;
+};
+
+struct DXFEdgeTypeCircularArc : public DXFEdgeType
+{
+ DXFVector aCenter; // 10,20
+ double fRadius; // 40
+ double fStartAngle; // 50
+ double fEndAngle; // 51
+ sal_Int32 nIsCounterClockwiseFlag; // 73
+ DXFEdgeTypeCircularArc();
+ virtual bool EvaluateGroup( DXFGroupReader & rDGR ) override;
+};
+
+struct DXFEdgeTypeEllipticalArc : public DXFEdgeType
+{
+ DXFVector aCenter; // 10,20
+ DXFVector aEndPoint; // 11,21
+ double fLength; // 40
+ double fStartAngle; // 50
+ double fEndAngle; // 51
+ sal_Int32 nIsCounterClockwiseFlag; // 73
+
+ DXFEdgeTypeEllipticalArc();
+ virtual bool EvaluateGroup( DXFGroupReader & rDGR ) override;
+};
+
+struct DXFEdgeTypeSpline : public DXFEdgeType
+{
+ sal_Int32 nDegree; // 94
+ sal_Int32 nRational; // 73
+ sal_Int32 nPeriodic; // 74
+ sal_Int32 nKnotCount; // 75
+ sal_Int32 nControlCount; // 76
+
+ DXFEdgeTypeSpline();
+ virtual bool EvaluateGroup( DXFGroupReader & rDGR ) override;
+};
+
+struct DXFBoundaryPathData
+{
+private:
+ sal_Int32 nPointCount; // 93
+public:
+ sal_Int32 nFlags; // 92
+ sal_Int32 nHasBulgeFlag; // 72
+ sal_Int32 nIsClosedFlag; // 73
+ double fBulge; // 42
+ sal_Int32 nSourceBoundaryObjects; // 97
+ sal_Int32 nEdgeCount; // 93
+
+ bool bIsPolyLine;
+ sal_Int32 nPointIndex;
+
+ std::vector<DXFVector> aP;
+ std::vector<std::unique_ptr<DXFEdgeType>> aEdges;
+
+ DXFBoundaryPathData();
+
+ bool EvaluateGroup( DXFGroupReader & rDGR );
+};
+
+class DXFHatchEntity : public DXFBasicEntity
+{
+ bool bIsInBoundaryPathContext;
+ sal_Int32 nCurrentBoundaryPathIndex;
+
+ public:
+
+ sal_Int32 nFlags; // 70 (solid fill = 1, pattern fill = 0)
+ sal_Int32 nAssociativityFlag; // 71 (associative = 1, non-associative = 0)
+ sal_Int32 nMaxBoundaryPathCount; // 91
+ sal_Int32 nHatchStyle; // 75 (odd parity = 0, outmost area = 1, entire area = 2 )
+ sal_Int32 nHatchPatternType; // 76 (user defined = 0, predefined = 1, custom = 2)
+ double fHatchPatternAngle; // 52 (pattern fill only)
+ double fHatchPatternScale; // 41 (pattern fill only:scale or spacing)
+ sal_Int32 nHatchDoubleFlag; // 77 (pattern fill only:double = 1, not double = 0)
+ sal_Int32 nHatchPatternDefinitionLines; // 78
+ double fPixelSize; // 47
+ sal_Int32 nNumberOfSeedPoints; // 98
+
+ std::vector<DXFBoundaryPathData> aBoundaryPathData;
+
+ DXFHatchEntity();
+
+ protected:
+
+ virtual void EvaluateGroup( DXFGroupReader & rDGR ) override;
+};
+
+class DXFVertexEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+ double fSWidth; // 40 (if <0.0, then one has DXFPolyLine::fSWidth)
+ double fEWidth; // 41 (if <0.0, then one has DXFPolyLine::fEWidth)
+ double fBulge; // 42
+ tools::Long nFlags; // 70
+ double fCFTDir; // 50
+
+ DXFVertexEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFSeqEndEntity : public DXFBasicEntity {
+
+public:
+
+ DXFSeqEndEntity();
+};
+
+class DXF3DFaceEntity : public DXFBasicEntity {
+
+public:
+
+ DXFVector aP0; // 10,20,30
+ DXFVector aP1; // 11,21,31
+ DXFVector aP2; // 12,22,32
+ DXFVector aP3; // 13,23,33
+ tools::Long nIEFlags; // 70
+
+ DXF3DFaceEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+class DXFDimensionEntity : public DXFBasicEntity {
+
+public:
+
+ OString m_sPseudoBlock; // 2
+
+ DXFDimensionEntity();
+
+protected:
+
+ virtual void EvaluateGroup(DXFGroupReader & rDGR) override;
+};
+
+
+// read and represent the set of entities
+class DXFEntities {
+
+public:
+
+ DXFEntities()
+ : pFirst(nullptr)
+ , mbBeingDrawn(false)
+ {
+ }
+
+ ~DXFEntities()
+ {
+ Clear();
+ }
+
+ DXFBasicEntity * pFirst; // list of entities, READ ONLY!
+ mutable bool mbBeingDrawn; // guard for loop in entity parsing
+
+ void Read(DXFGroupReader & rDGR);
+ // read entities by rGDR of a DXF file until a
+ // ENDBLK, ENDSEC or EOF (of group 0).
+ // (all unknown thing will be skipped)
+
+ void Clear();
+ // deletes all entities
+};
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfgrprd.cxx b/vcl/source/filter/idxf/dxfgrprd.cxx
new file mode 100644
index 000000000..48cdb3660
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfgrprd.cxx
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <stdlib.h>
+#include <rtl/strbuf.hxx>
+#include <tools/stream.hxx>
+#include <o3tl/string_view.hxx>
+#include "dxfgrprd.hxx"
+
+// we use an own ReadLine function, because Stream::ReadLine stops if
+// a 0-sign occurs; this function converts 0-signs to blanks and reads
+// a complete line until a cr/lf is found
+
+static OString DXFReadLine(SvStream& rIStm)
+{
+ char buf[256 + 1];
+ bool bEnd = false;
+ sal_uInt64 nOldFilePos = rIStm.Tell();
+ char c = 0;
+
+ OStringBuffer aBuf(512);
+
+ while( !bEnd && !rIStm.GetError() ) // !!! do not check for EOF
+ // !!! because we read blockwise
+ {
+ sal_uInt16 nLen = static_cast<sal_uInt16>(rIStm.ReadBytes(buf, sizeof(buf)-1));
+ if( !nLen )
+ {
+ if( aBuf.isEmpty() )
+ return OString();
+ else
+ break;
+ }
+
+ for( sal_uInt16 n = 0; n < nLen ; n++ )
+ {
+ c = buf[n];
+ if( c != '\n' && c != '\r' )
+ {
+ if( !c )
+ c = ' ';
+ aBuf.append(c);
+ }
+ else
+ {
+ bEnd = true;
+ break;
+ }
+ }
+ }
+
+ if( !bEnd && !rIStm.GetError() && !aBuf.isEmpty() )
+ bEnd = true;
+
+ nOldFilePos += aBuf.getLength();
+ if( rIStm.Tell() > nOldFilePos )
+ nOldFilePos++;
+ rIStm.Seek( nOldFilePos ); // seek because of BlockRead above!
+
+ if( bEnd && (c=='\r' || c=='\n')) // special treatment of DOS files
+ {
+ char cTemp(0);
+ rIStm.ReadBytes(&cTemp, 1);
+ if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
+ rIStm.Seek( nOldFilePos );
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
+static void DXFSkipLine(SvStream& rIStm)
+{
+ while (rIStm.good())
+ {
+ char buf[256 + 1];
+ sal_uInt16 nLen = static_cast<sal_uInt16>(rIStm.ReadBytes(buf, sizeof(buf) - 1));
+ for (sal_uInt16 n = 0; n < nLen; n++)
+ {
+ char c = buf[n];
+ if ((c == '\n') || (c == '\r'))
+ {
+ rIStm.SeekRel(n-nLen+1); // return stream to next to current position
+ char c1 = 0;
+ rIStm.ReadBytes(&c1, 1);
+ if (c1 == c || (c1 != '\n' && c1!= '\r'))
+ rIStm.SeekRel(-1);
+ return;
+ }
+ }
+ }
+}
+
+DXFGroupReader::DXFGroupReader(SvStream & rIStream)
+ : rIS(rIStream)
+ , bStatus(true)
+ , nLastG(0)
+ , I(0)
+{
+ rIS.Seek(0);
+}
+
+sal_uInt16 DXFGroupReader::Read()
+{
+ sal_uInt16 nG = 0;
+ if ( bStatus )
+ {
+ nG = static_cast<sal_uInt16>(ReadI());
+ if ( bStatus )
+ {
+ if (nG< 10) ReadS();
+ else if (nG< 60) F = ReadF();
+ else if (nG< 80) I = ReadI();
+ else if (nG< 90) DXFSkipLine(rIS);
+ else if (nG< 99) I = ReadI();
+ else if (nG==100) ReadS();
+ else if (nG==102) ReadS();
+ else if (nG==105) DXFSkipLine(rIS);
+ else if (nG< 140) DXFSkipLine(rIS);
+ else if (nG< 148) F = ReadF();
+ else if (nG< 170) DXFSkipLine(rIS);
+ else if (nG< 176) I = ReadI();
+ else if (nG< 180) DXFSkipLine(rIS); // ReadI();
+ else if (nG< 210) DXFSkipLine(rIS);
+ else if (nG< 240) F = ReadF();
+ else if (nG<=369) DXFSkipLine(rIS);
+ else if (nG< 999) DXFSkipLine(rIS);
+ else if (nG<1010) ReadS();
+ else if (nG<1060) F = ReadF();
+ else if (nG<1072) I = ReadI();
+ else bStatus = false;
+ }
+ }
+ if ( !bStatus )
+ {
+ nG = 0;
+ S = "EOF";
+ }
+ nLastG = nG;
+ return nG;
+}
+
+tools::Long DXFGroupReader::ReadI()
+{
+ OString s = DXFReadLine(rIS);
+ char *p=s.pData->buffer;
+ const char *end = s.pData->buffer + s.pData->length;
+
+ while((p != end) && (*p==0x20)) p++;
+
+ if ((p == end) || ((*p<'0' || *p>'9') && *p!='-')) {
+ bStatus=false;
+ return 0;
+ }
+
+ OStringBuffer aNumber;
+ if (*p == '-') {
+ aNumber.append(*p++);
+ }
+
+ while ((p != end) && *p >= '0' && *p <= '9') {
+ aNumber.append(*p++);
+ }
+
+ while ((p != end) && (*p==0x20)) p++;
+ if (p != end) {
+ bStatus=false;
+ return 0;
+ }
+
+ return o3tl::toInt32(aNumber);
+}
+
+double DXFGroupReader::ReadF()
+{
+ OString s = DXFReadLine(rIS);
+ char *p = s.pData->buffer;
+ const char *end = s.pData->buffer + s.pData->length;
+
+ while((p != end) && (*p==0x20)) p++;
+ if ((p == end) || ((*p<'0' || *p>'9') && *p!='.' && *p!='-')) {
+ bStatus=false;
+ return 0.0;
+ }
+ return atof(p);
+}
+
+void DXFGroupReader::ReadS()
+{
+ S = DXFReadLine(rIS);
+}
+
+sal_uInt64 DXFGroupReader::remainingSize() const
+{
+ return rIS.remainingSize();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfgrprd.hxx b/vcl/source/filter/idxf/dxfgrprd.hxx
new file mode 100644
index 000000000..4d20ae2bf
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfgrprd.hxx
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFGRPRD_HXX
+#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFGRPRD_HXX
+
+#include <rtl/string.hxx>
+#include <sal/types.h>
+#include <tools/long.hxx>
+
+class SvStream;
+
+class DXFGroupReader
+{
+public:
+ explicit DXFGroupReader( SvStream & rIStream );
+
+ bool GetStatus() const;
+
+ void SetError();
+
+ sal_uInt16 Read();
+ // Reads next group and returns the group code.
+ // In case of an error GetStatus() returns sal_False, group code will be set
+ // to 0 and SetS(0,"EOF") will be executed.
+ bool Read(sal_uInt16 nExpectedG) { return Read() == nExpectedG; }
+
+ sal_uInt16 GetG() const;
+ // Return the last group code (the one the last Read() did return).
+
+ tools::Long GetI() const;
+ // Returns the integer value of the group which was read earlier with Read().
+ // This read must have returned a group code for datatype Integer.
+ // If not 0 is returned
+
+ double GetF() const;
+ // Returns the floating point value of the group which was read earlier with Read().
+ // This read must have returned a group code for datatype Floatingpoint.
+ // If not 0 is returned
+
+ const OString& GetS() const;
+ // Returns the string of the group which was read earlier with Read().
+ // This read must have returned a group code for datatype String.
+ // If not NULL is returned
+
+ sal_uInt64 remainingSize() const;
+private:
+
+ tools::Long ReadI();
+ double ReadF();
+ void ReadS();
+
+ SvStream & rIS;
+ bool bStatus;
+ sal_uInt16 nLastG;
+
+ OString S;
+ union {
+ double F;
+ tools::Long I;
+ };
+};
+
+
+inline bool DXFGroupReader::GetStatus() const
+{
+ return bStatus;
+}
+
+
+inline void DXFGroupReader::SetError()
+{
+ bStatus=false;
+}
+
+inline sal_uInt16 DXFGroupReader::GetG() const
+{
+ return nLastG;
+}
+
+inline tools::Long DXFGroupReader::GetI() const
+{
+ return I;
+}
+
+inline double DXFGroupReader::GetF() const
+{
+ return F;
+}
+
+inline const OString& DXFGroupReader::GetS() const
+{
+ return S;
+}
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfreprd.cxx b/vcl/source/filter/idxf/dxfreprd.cxx
new file mode 100644
index 000000000..7124e296e
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfreprd.cxx
@@ -0,0 +1,480 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include "dxfreprd.hxx"
+#include <osl/nlsupport.h>
+#include <unotools/defaultencoding.hxx>
+#include <unotools/wincodepage.hxx>
+
+//------------------DXFBoundingBox--------------------------------------------
+
+
+void DXFBoundingBox::Union(const DXFVector & rVector)
+{
+ if (bEmpty) {
+ fMinX=rVector.fx;
+ fMinY=rVector.fy;
+ fMinZ=rVector.fz;
+ fMaxX=rVector.fx;
+ fMaxY=rVector.fy;
+ fMaxZ=rVector.fz;
+ bEmpty=false;
+ }
+ else {
+ if (fMinX>rVector.fx) fMinX=rVector.fx;
+ if (fMinY>rVector.fy) fMinY=rVector.fy;
+ if (fMinZ>rVector.fz) fMinZ=rVector.fz;
+ if (fMaxX<rVector.fx) fMaxX=rVector.fx;
+ if (fMaxY<rVector.fy) fMaxY=rVector.fy;
+ if (fMaxZ<rVector.fz) fMaxZ=rVector.fz;
+ }
+}
+
+
+//------------------DXFPalette------------------------------------------------
+
+
+DXFPalette::DXFPalette()
+{
+ short i,j,nHue,nNSat,nVal,nC[3],nmax,nmed,nmin;
+ sal_uInt8 nV;
+
+ // colors 0 - 9 (normal colors)
+ SetColor(0, 0x00, 0x00, 0x00); // actually never being used
+ SetColor(1, 0xff, 0x00, 0x00);
+ SetColor(2, 0xff, 0xff, 0x00);
+ SetColor(3, 0x00, 0xff, 0x00);
+ SetColor(4, 0x00, 0xff, 0xff);
+ SetColor(5, 0x00, 0x00, 0xff);
+ SetColor(6, 0xff, 0x00, 0xff);
+ SetColor(7, 0x0f, 0x0f, 0x0f); // actually white???
+ SetColor(8, 0x80, 0x80, 0x80);
+ SetColor(9, 0xc0, 0xc0, 0xc0);
+
+ // colors 10 - 249
+ // (Universal-Palette: 24 hues * 5 lightnesses * 2 saturations )
+ i=10;
+ for (nHue=0; nHue<24; nHue++) {
+ for (nVal=5; nVal>=1; nVal--) {
+ for (nNSat=0; nNSat<2; nNSat++) {
+ nmax=((nHue+3)>>3)%3;
+ j=nHue-(nmax<<3); if (j>4) j=j-24;
+ if (j>=0) {
+ nmed=(nmax+1)%3;
+ nmin=(nmax+2)%3;
+ }
+ else {
+ nmed=(nmax+2)%3;
+ nmin=(nmax+1)%3;
+ j=-j;
+ }
+ nC[nmin]=0;
+ nC[nmed]=255*j/4;
+ nC[nmax]=255;
+ if (nNSat!=0) {
+ for (j=0; j<3; j++) nC[j]=(nC[j]>>1)+128;
+ }
+ for (j=0; j<3; j++) nC[j]=nC[j]*nVal/5;
+ SetColor(static_cast<sal_uInt8>(i++),static_cast<sal_uInt8>(nC[0]),static_cast<sal_uInt8>(nC[1]),static_cast<sal_uInt8>(nC[2]));
+ }
+ }
+ }
+
+ // Farben 250 - 255 (shades of gray)
+ for (i=0; i<6; i++) {
+ nV=static_cast<sal_uInt8>(i*38+65);
+ SetColor(static_cast<sal_uInt8>(250+i),nV,nV,nV);
+ }
+}
+
+
+void DXFPalette::SetColor(sal_uInt8 nIndex, sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
+{
+ pRed[nIndex]=nRed;
+ pGreen[nIndex]=nGreen;
+ pBlue[nIndex]=nBlue;
+}
+
+
+//------------------DXFRepresentation-----------------------------------------
+
+
+DXFRepresentation::DXFRepresentation()
+ : mEnc(RTL_TEXTENCODING_DONTKNOW)
+ , mbInCalc(false)
+{
+ setGlobalLineTypeScale(1.0);
+}
+
+DXFRepresentation::~DXFRepresentation()
+{
+}
+
+rtl_TextEncoding DXFRepresentation::getTextEncoding() const
+{
+ return (isTextEncodingSet()) ?
+ mEnc :
+ osl_getTextEncodingFromLocale(nullptr); // Use default encoding if none specified
+}
+
+bool DXFRepresentation::Read( SvStream & rIStream )
+{
+ bool bRes;
+
+ aTables.Clear();
+ aBlocks.Clear();
+ aEntities.Clear();
+
+ DXFGroupReader DGR( rIStream );
+
+ DGR.Read();
+ while (DGR.GetG()!=0 || (DGR.GetS() != "EOF")) {
+ if (DGR.GetG()==0 && DGR.GetS() == "SECTION") {
+ if (DGR.Read()!=2) {
+ DGR.SetError();
+ break;
+ }
+ if (DGR.GetS() == "HEADER") ReadHeader(DGR);
+ else if (DGR.GetS() == "TABLES") aTables.Read(DGR);
+ else if (DGR.GetS() == "BLOCKS") aBlocks.Read(DGR);
+ else if (DGR.GetS() == "ENTITIES") aEntities.Read(DGR);
+ else DGR.Read();
+ }
+ else DGR.Read();
+ }
+
+ bRes=DGR.GetStatus();
+
+ if (bRes && aBoundingBox.bEmpty)
+ CalcBoundingBox(aEntities,aBoundingBox);
+
+ return bRes;
+}
+
+void DXFRepresentation::ReadHeader(DXFGroupReader & rDGR)
+{
+ while (rDGR.GetG()!=0 || (rDGR.GetS() != "EOF" && rDGR.GetS() != "ENDSEC") )
+ {
+ if (rDGR.GetG()==9) {
+ if (rDGR.GetS() == "$EXTMIN" ||
+ rDGR.GetS() == "$EXTMAX")
+ {
+ DXFVector aVector;
+ while (rDGR.Read()!=9 && rDGR.GetG()!=0) {
+ switch (rDGR.GetG()) {
+ case 10: aVector.fx = rDGR.GetF(); break;
+ case 20: aVector.fy = rDGR.GetF(); break;
+ case 30: aVector.fz = rDGR.GetF(); break;
+ }
+ }
+ aBoundingBox.Union(aVector);
+ }
+ else if (rDGR.GetS() == "$ACADVER")
+ {
+ if (!rDGR.Read(1))
+ continue;
+ // Versions of AutoCAD up to Release 12 (inclusive, AC1009)
+ // were DOS software and used OEM encoding for storing strings.
+ // Release 13 (AC1012) had both DOS and Windows variants.
+ // Its Windows variant, and later releases used ANSI encodings for
+ // strings (up to version 2006, which was the last one to do so).
+ // Later versions (2007+, AC1021+) use UTF-8 for that.
+ // Other (non-Autodesk) implementations may have used different
+ // encodings for storing to corresponding formats, but there's
+ // no way to know that.
+ // See http://autodesk.blogs.com/between_the_lines/autocad-release-history.html
+ if ((rDGR.GetS() <= std::string_view("AC1009")) || (rDGR.GetS() == "AC2.22") || (rDGR.GetS() == "AC2.21") || (rDGR.GetS() == "AC2.10") ||
+ (rDGR.GetS() == "AC1.50") || (rDGR.GetS() == "AC1.40") || (rDGR.GetS() == "AC1.2") || (rDGR.GetS() == "MC0.0"))
+ {
+ // Set OEM encoding for old DOS formats
+ // only if the encoding is not set yet
+ // e.g. by previous $DWGCODEPAGE
+ if (!isTextEncodingSet())
+ setTextEncoding(utl_getWinTextEncodingFromLangStr(
+ utl_getLocaleForGlobalDefaultEncoding(), true));
+ }
+ else if (rDGR.GetS() >= std::string_view("AC1021"))
+ setTextEncoding(RTL_TEXTENCODING_UTF8);
+ else
+ {
+ // Set ANSI encoding for old Windows formats
+ // only if the encoding is not set yet
+ // e.g. by previous $DWGCODEPAGE
+ if (!isTextEncodingSet())
+ setTextEncoding(utl_getWinTextEncodingFromLangStr(
+ utl_getLocaleForGlobalDefaultEncoding()));
+ }
+ }
+ else if (rDGR.GetS() == "$DWGCODEPAGE")
+ {
+ if (!rDGR.Read(3))
+ continue;
+
+ // If we already use UTF8, then don't update encoding anymore
+ if (mEnc == RTL_TEXTENCODING_UTF8)
+ continue;
+ // FIXME: we really need a whole table of
+ // $DWGCODEPAGE to encodings mappings
+ else if ( (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_932")) ||
+ (rDGR.GetS().equalsIgnoreAsciiCase("DOS932")) )
+ {
+ setTextEncoding(RTL_TEXTENCODING_MS_932);
+ }
+ else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_936"))
+ {
+ setTextEncoding(RTL_TEXTENCODING_MS_936);
+ }
+ else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_949"))
+ {
+ setTextEncoding(RTL_TEXTENCODING_MS_949);
+ }
+ else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_950"))
+ {
+ setTextEncoding(RTL_TEXTENCODING_MS_950);
+ }
+ else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_1251"))
+ {
+ setTextEncoding(RTL_TEXTENCODING_MS_1251);
+ }
+ }
+ else if (rDGR.GetS() == "$LTSCALE")
+ {
+ if (!rDGR.Read(40))
+ continue;
+ setGlobalLineTypeScale(getGlobalLineTypeScale() * rDGR.GetF());
+ }
+ else rDGR.Read();
+ }
+ else rDGR.Read();
+ }
+}
+
+void DXFRepresentation::CalcBoundingBox(const DXFEntities & rEntities,
+ DXFBoundingBox & rBox)
+{
+ if (mbInCalc)
+ return;
+ mbInCalc = true;
+
+ DXFBasicEntity * pBE=rEntities.pFirst;
+ while (pBE!=nullptr) {
+ switch (pBE->eType) {
+ case DXF_LINE: {
+ const DXFLineEntity * pE = static_cast<const DXFLineEntity*>(pBE);
+ rBox.Union(pE->aP0);
+ rBox.Union(pE->aP1);
+ break;
+ }
+ case DXF_POINT: {
+ const DXFPointEntity * pE = static_cast<const DXFPointEntity*>(pBE);
+ rBox.Union(pE->aP0);
+ break;
+ }
+ case DXF_CIRCLE: {
+ const DXFCircleEntity * pE = static_cast<const DXFCircleEntity*>(pBE);
+ DXFVector aP;
+ aP=pE->aP0;
+ aP.fx-=pE->fRadius;
+ aP.fy-=pE->fRadius;
+ rBox.Union(aP);
+ aP=pE->aP0;
+ aP.fx+=pE->fRadius;
+ aP.fy+=pE->fRadius;
+ rBox.Union(aP);
+ break;
+ }
+ case DXF_ARC: {
+ const DXFArcEntity * pE = static_cast<const DXFArcEntity*>(pBE);
+ DXFVector aP;
+ aP=pE->aP0;
+ aP.fx-=pE->fRadius;
+ aP.fy-=pE->fRadius;
+ rBox.Union(aP);
+ aP=pE->aP0;
+ aP.fx+=pE->fRadius;
+ aP.fy+=pE->fRadius;
+ rBox.Union(aP);
+ break;
+ }
+ case DXF_TRACE: {
+ const DXFTraceEntity * pE = static_cast<const DXFTraceEntity*>(pBE);
+ rBox.Union(pE->aP0);
+ rBox.Union(pE->aP1);
+ rBox.Union(pE->aP2);
+ rBox.Union(pE->aP3);
+ break;
+ }
+ case DXF_SOLID: {
+ const DXFSolidEntity * pE = static_cast<const DXFSolidEntity*>(pBE);
+ rBox.Union(pE->aP0);
+ rBox.Union(pE->aP1);
+ rBox.Union(pE->aP2);
+ rBox.Union(pE->aP3);
+ break;
+ }
+ case DXF_TEXT: {
+ //const DXFTextEntity * pE = (DXFTextEntity*)pBE;
+ //???
+ break;
+ }
+ case DXF_SHAPE: {
+ //const DXFShapeEntity * pE = (DXFShapeEntity*)pBE;
+ //???
+ break;
+ }
+ case DXF_INSERT: {
+ const DXFInsertEntity * pE = static_cast<const DXFInsertEntity*>(pBE);
+ DXFBlock * pB;
+ DXFBoundingBox aBox;
+ DXFVector aP;
+ pB=aBlocks.Search(pE->m_sName);
+ if (pB==nullptr) break;
+ CalcBoundingBox(*pB,aBox);
+ if (aBox.bEmpty) break;
+ aP.fx=(aBox.fMinX-pB->aBasePoint.fx)*pE->fXScale+pE->aP0.fx;
+ aP.fy=(aBox.fMinY-pB->aBasePoint.fy)*pE->fYScale+pE->aP0.fy;
+ aP.fz=(aBox.fMinZ-pB->aBasePoint.fz)*pE->fZScale+pE->aP0.fz;
+ rBox.Union(aP);
+ aP.fx=(aBox.fMaxX-pB->aBasePoint.fx)*pE->fXScale+pE->aP0.fx;
+ aP.fy=(aBox.fMaxY-pB->aBasePoint.fy)*pE->fYScale+pE->aP0.fy;
+ aP.fz=(aBox.fMaxZ-pB->aBasePoint.fz)*pE->fZScale+pE->aP0.fz;
+ rBox.Union(aP);
+ break;
+ }
+ case DXF_ATTDEF: {
+ //const DXFAttDefEntity * pE = (DXFAttDefEntity*)pBE;
+ //???
+ break;
+ }
+ case DXF_ATTRIB: {
+ //const DXFAttribEntity * pE = (DXFAttribEntity*)pBE;
+ //???
+ break;
+ }
+ case DXF_VERTEX: {
+ const DXFVertexEntity * pE = static_cast<const DXFVertexEntity*>(pBE);
+ rBox.Union(pE->aP0);
+ break;
+ }
+ case DXF_3DFACE: {
+ const DXF3DFaceEntity * pE = static_cast<const DXF3DFaceEntity*>(pBE);
+ rBox.Union(pE->aP0);
+ rBox.Union(pE->aP1);
+ rBox.Union(pE->aP2);
+ rBox.Union(pE->aP3);
+ break;
+ }
+ case DXF_DIMENSION: {
+ const DXFDimensionEntity * pE = static_cast<const DXFDimensionEntity*>(pBE);
+ DXFBlock * pB;
+ DXFBoundingBox aBox;
+ DXFVector aP;
+ pB = aBlocks.Search(pE->m_sPseudoBlock);
+ if (pB==nullptr) break;
+ CalcBoundingBox(*pB,aBox);
+ if (aBox.bEmpty) break;
+ aP.fx=aBox.fMinX-pB->aBasePoint.fx;
+ aP.fy=aBox.fMinY-pB->aBasePoint.fy;
+ aP.fz=aBox.fMinZ-pB->aBasePoint.fz;
+ rBox.Union(aP);
+ aP.fx=aBox.fMaxX-pB->aBasePoint.fx;
+ aP.fy=aBox.fMaxY-pB->aBasePoint.fy;
+ aP.fz=aBox.fMaxZ-pB->aBasePoint.fz;
+ rBox.Union(aP);
+ break;
+ }
+ case DXF_POLYLINE: {
+ //const DXFAttribEntity * pE = (DXFAttribEntity*)pBE;
+ //???
+ break;
+ }
+ case DXF_SEQEND: {
+ //const DXFAttribEntity * pE = (DXFAttribEntity*)pBE;
+ //???
+ break;
+ }
+ case DXF_HATCH :
+ break;
+ case DXF_LWPOLYLINE :
+ break;
+ }
+ pBE=pBE->pSucc;
+ }
+ mbInCalc = false;
+}
+
+namespace {
+ bool lcl_isDec(sal_Unicode ch)
+ {
+ return ch >= L'0' && ch <= L'9';
+ }
+ bool lcl_isHex(sal_Unicode ch)
+ {
+ return lcl_isDec(ch) || (ch >= L'A' && ch <= L'F') || (ch >= L'a' && ch <= L'f');
+ }
+}
+
+OUString DXFRepresentation::ToOUString(std::string_view s) const
+{
+ OUString result = OStringToOUString(s, getTextEncoding(),
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR);
+ result = result.replaceAll("%%o", "") // Overscore - simply remove
+ .replaceAll("%%u", "") // Underscore - simply remove
+ .replaceAll("%%d", u"\u00B0") // Degrees symbol (°)
+ .replaceAll("%%p", u"\u00B1") // Tolerance symbol (±)
+ .replaceAll("%%c", u"\u2205") // Diameter symbol
+ .replaceAll("%%%", "%"); // Percent symbol
+
+ sal_Int32 pos = result.indexOf("%%"); // %%nnn, where nnn - 3-digit decimal ASCII code
+ while (pos != -1 && pos <= result.getLength() - 5) {
+ OUString asciiNum = result.copy(pos + 2, 3);
+ if (lcl_isDec(asciiNum[0]) &&
+ lcl_isDec(asciiNum[1]) &&
+ lcl_isDec(asciiNum[2]))
+ {
+ char ch = static_cast<char>(asciiNum.toUInt32());
+ OUString codePt(&ch, 1, mEnc);
+ result = result.replaceAll(result.subView(pos, 5), codePt, pos);
+ }
+ pos = result.indexOf("%%", pos + 1);
+ }
+
+ pos = result.indexOf("\\U+"); // \U+XXXX, where XXXX - 4-digit hex unicode
+ while (pos != -1 && pos <= result.getLength() - 7) {
+ OUString codePtNum = result.copy(pos + 3, 4);
+ if (lcl_isHex(codePtNum[0]) &&
+ lcl_isHex(codePtNum[1]) &&
+ lcl_isHex(codePtNum[2]) &&
+ lcl_isHex(codePtNum[3]))
+ {
+ OUString codePt(static_cast<sal_Unicode>(codePtNum.toUInt32(16)));
+ result = result.replaceAll(result.subView(pos, 7), codePt, pos);
+ }
+ pos = result.indexOf("\\U+", pos + 1);
+ }
+ return result;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfreprd.hxx b/vcl/source/filter/idxf/dxfreprd.hxx
new file mode 100644
index 000000000..e9c6bc653
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfreprd.hxx
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFREPRD_HXX
+#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFREPRD_HXX
+
+#include "dxfblkrd.hxx"
+#include "dxftblrd.hxx"
+#include <array>
+#include <string_view>
+
+//--------------------Other stuff---------------------------------------------
+
+
+//-------------------A 3D-Min/Max-Box-----------------------------------------
+
+class DXFBoundingBox {
+public:
+ bool bEmpty;
+ double fMinX;
+ double fMinY;
+ double fMinZ;
+ double fMaxX;
+ double fMaxY;
+ double fMaxZ;
+
+ DXFBoundingBox():bEmpty(true), fMinX(0.0), fMinY(0.0), fMinZ(0.0), fMaxX(0.0), fMaxY(0.0), fMaxZ(0.0) {}
+ void Union(const DXFVector & rVector);
+};
+
+
+//-------------------The (constant) palette for DXF-------------------------
+
+class DXFPalette {
+
+public:
+
+ DXFPalette();
+
+ sal_uInt8 GetRed(sal_uInt8 nIndex) const;
+ sal_uInt8 GetGreen(sal_uInt8 nIndex) const;
+ sal_uInt8 GetBlue(sal_uInt8 nIndex) const;
+
+private:
+ std::array<sal_uInt8, 256> pRed;
+ std::array<sal_uInt8, 256> pGreen;
+ std::array<sal_uInt8, 256> pBlue;
+ void SetColor(sal_uInt8 nIndex, sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue);
+};
+
+
+//-----------------read and represent DXF file--------------------------------
+
+
+class DXFRepresentation {
+
+public:
+
+ DXFPalette aPalette;
+ // The always equal DXF color palette
+
+ DXFBoundingBox aBoundingBox;
+ // is equal to the AutoCAD variables EXTMIN, EXTMAX if those exist
+ // within the DXF file. Otherwise the BoundingBox gets calculated (in Read())
+
+ DXFTables aTables;
+ // the tables of the DXF file
+
+ DXFBlocks aBlocks;
+ // the blocks of the DXF file
+
+ DXFEntities aEntities;
+ // the entities (from the Entities-Section) of the DXF file
+
+ rtl_TextEncoding mEnc; // $DWGCODEPAGE
+
+ double mfGlobalLineTypeScale; // $LTSCALE
+
+ bool mbInCalc; // guard for self-recursive bounding box calc
+
+ DXFRepresentation();
+ ~DXFRepresentation();
+
+ rtl_TextEncoding getTextEncoding() const;
+ void setTextEncoding(rtl_TextEncoding aEnc) { mEnc = aEnc; }
+ OUString ToOUString(std::string_view s) const;
+
+ double getGlobalLineTypeScale() const { return mfGlobalLineTypeScale; }
+ void setGlobalLineTypeScale(double fGlobalLineTypeScale) { mfGlobalLineTypeScale = fGlobalLineTypeScale; }
+
+ bool Read( SvStream & rIStream );
+ // Reads complete DXF file.
+
+private:
+ void ReadHeader(DXFGroupReader & rDGR);
+ void CalcBoundingBox(const DXFEntities & rEntities,
+ DXFBoundingBox & rBox);
+
+ bool isTextEncodingSet() const { return mEnc != RTL_TEXTENCODING_DONTKNOW; }
+};
+
+
+//-------------------inlines--------------------------------------------------
+
+
+inline sal_uInt8 DXFPalette::GetRed(sal_uInt8 nIndex) const { return pRed[nIndex]; }
+inline sal_uInt8 DXFPalette::GetGreen(sal_uInt8 nIndex) const { return pGreen[nIndex]; }
+inline sal_uInt8 DXFPalette::GetBlue(sal_uInt8 nIndex) const { return pBlue[nIndex]; }
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxftblrd.cxx b/vcl/source/filter/idxf/dxftblrd.cxx
new file mode 100644
index 000000000..7e20e6c69
--- /dev/null
+++ b/vcl/source/filter/idxf/dxftblrd.cxx
@@ -0,0 +1,381 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include "dxftblrd.hxx"
+
+//----------------------------------DXFLType-----------------------------------
+
+DXFLType::DXFLType()
+ : pSucc(nullptr)
+ , nFlags(0)
+ , nDashCount(0)
+ , fPatternLength(0.0)
+ , fDash{0.0}
+{
+}
+
+void DXFLType::Read(DXFGroupReader & rDGR)
+{
+ tools::Long nDashIndex=-1;
+
+ while (rDGR.Read()!=0)
+ {
+ switch (rDGR.GetG())
+ {
+ case 2:
+ m_sName = rDGR.GetS();
+ break;
+ case 3:
+ m_sDescription = rDGR.GetS();
+ break;
+ case 70:
+ nFlags=rDGR.GetI();
+ break;
+ case 73:
+ if (nDashIndex!=-1)
+ {
+ rDGR.SetError();
+ return;
+ }
+ nDashCount=rDGR.GetI();
+ if (nDashCount>DXF_MAX_DASH_COUNT)
+ {
+ nDashCount=DXF_MAX_DASH_COUNT;
+ }
+ nDashIndex=0;
+ break;
+ case 40: fPatternLength=rDGR.GetF(); break;
+ case 49:
+ if (nDashCount==-1)
+ {
+ rDGR.SetError();
+ return;
+ }
+ if (nDashIndex < nDashCount)
+ {
+ if (nDashIndex < 0)
+ {
+ rDGR.SetError();
+ return;
+ }
+ fDash[nDashIndex++] = rDGR.GetF();
+ }
+ break;
+ }
+ }
+}
+
+//----------------------------------DXFLayer-----------------------------------
+
+DXFLayer::DXFLayer()
+{
+ pSucc=nullptr;
+ nFlags=0;
+ nColor=-1;
+}
+
+void DXFLayer::Read(DXFGroupReader & rDGR)
+{
+ while (rDGR.Read()!=0)
+ {
+ switch(rDGR.GetG())
+ {
+ case 2:
+ m_sName = rDGR.GetS();
+ break;
+ case 6:
+ m_sLineType = rDGR.GetS();
+ break;
+ case 70:
+ nFlags=rDGR.GetI();
+ break;
+ case 62:
+ nColor=rDGR.GetI();
+ break;
+ }
+ }
+}
+
+//----------------------------------DXFStyle-----------------------------------
+
+DXFStyle::DXFStyle()
+{
+ pSucc=nullptr;
+ nFlags=0;
+ fHeight=0.0;
+ fWidthFak=1.0;
+ fOblAngle=0.0;
+ nTextGenFlags=0;
+ fLastHeightUsed=0.0;
+}
+
+void DXFStyle::Read(DXFGroupReader & rDGR)
+{
+ while (rDGR.Read()!=0)
+ {
+ switch(rDGR.GetG())
+ {
+ case 2:
+ m_sName = rDGR.GetS();
+ break;
+ case 3:
+ m_sPrimFontFile = rDGR.GetS();
+ break;
+ case 4:
+ m_sBigFontFile = rDGR.GetS();
+ break;
+ case 70:
+ nFlags=rDGR.GetI();
+ break;
+ case 40:
+ fHeight=rDGR.GetF();
+ break;
+ case 41:
+ fWidthFak=rDGR.GetF();
+ break;
+ case 42:
+ fLastHeightUsed=rDGR.GetF();
+ break;
+ case 50:
+ fOblAngle=rDGR.GetF();
+ break;
+ case 71:
+ nTextGenFlags=rDGR.GetI();
+ break;
+ }
+ }
+}
+
+//----------------------------------DXFVPort-----------------------------------
+
+DXFVPort::DXFVPort()
+ : pSucc(nullptr)
+ , nFlags(0)
+ , fMinX(0.0)
+ , fMinY(0.0)
+ , fMaxX(0.0)
+ , fMaxY(0.0)
+ , fCenterX(0.0)
+ , fCenterY(0.0)
+ , fSnapBaseX(0.0)
+ , fSnapBaseY(0.0)
+ , fSnapSpacingX(0.0)
+ , fSnapSpacingY(0.0)
+ , fGridX(0.0)
+ , fGridY(0.0)
+ , aDirection(DXFVector(0.0, 0.0, 1.0))
+ , fHeight(0.0)
+ , fAspectRatio(0.0)
+ , fLensLength(0.0)
+ , fFrontClipPlane(0.0)
+ , fBackClipPlane(0.0)
+ , fTwistAngle(0.0)
+ , nStatus(0)
+ , nID(0)
+ , nMode(0)
+ , nCircleZoomPercent(0)
+ , nFastZoom(0)
+ , nUCSICON(0)
+ , nSnap(0)
+ , nGrid(0)
+ , nSnapStyle(0)
+ , nSnapIsopair(0)
+{
+}
+
+void DXFVPort::Read(DXFGroupReader & rDGR)
+{
+ while (rDGR.Read()!=0)
+ {
+ switch(rDGR.GetG())
+ {
+ case 2:
+ m_sName = rDGR.GetS();
+ break;
+ case 10: fMinX=rDGR.GetF(); break;
+ case 11: fMaxX=rDGR.GetF(); break;
+ case 12: fCenterX=rDGR.GetF(); break;
+ case 13: fSnapBaseX=rDGR.GetF(); break;
+ case 14: fSnapSpacingX=rDGR.GetF(); break;
+ case 15: fGridX=rDGR.GetF(); break;
+ case 16: aDirection.fx=rDGR.GetF(); break;
+ case 17: aTarget.fx=rDGR.GetF(); break;
+ case 20: fMinY=rDGR.GetF(); break;
+ case 21: fMaxY=rDGR.GetF(); break;
+ case 22: fCenterY=rDGR.GetF(); break;
+ case 23: fSnapBaseY=rDGR.GetF(); break;
+ case 24: fSnapSpacingY=rDGR.GetF(); break;
+ case 25: fGridY=rDGR.GetF(); break;
+ case 26: aDirection.fy=rDGR.GetF(); break;
+ case 27: aTarget.fy=rDGR.GetF(); break;
+ case 36: aDirection.fz=rDGR.GetF(); break;
+ case 37: aTarget.fz=rDGR.GetF(); break;
+ case 40: fHeight=rDGR.GetF(); break;
+ case 41: fAspectRatio=rDGR.GetF(); break;
+ case 42: fLensLength=rDGR.GetF(); break;
+ case 43: fFrontClipPlane=rDGR.GetF(); break;
+ case 44: fBackClipPlane=rDGR.GetF(); break;
+ case 51: fTwistAngle=rDGR.GetF(); break;
+ case 68: nStatus=rDGR.GetI(); break;
+ case 69: nID=rDGR.GetI(); break;
+ case 70: nFlags=rDGR.GetI(); break;
+ case 71: nMode=rDGR.GetI(); break;
+ case 72: nCircleZoomPercent=rDGR.GetI(); break;
+ case 73: nFastZoom=rDGR.GetI(); break;
+ case 74: nUCSICON=rDGR.GetI(); break;
+ case 75: nSnap=rDGR.GetI(); break;
+ case 76: nGrid=rDGR.GetI(); break;
+ case 77: nSnapStyle=rDGR.GetI(); break;
+ case 78: nSnapIsopair=rDGR.GetI(); break;
+ }
+ }
+}
+
+//----------------------------------DXFTables----------------------------------
+
+
+DXFTables::DXFTables()
+{
+ pLTypes=nullptr;
+ pLayers=nullptr;
+ pStyles=nullptr;
+ pVPorts=nullptr;
+}
+
+
+DXFTables::~DXFTables()
+{
+ Clear();
+}
+
+
+void DXFTables::Read(DXFGroupReader & rDGR)
+{
+ DXFLType * * ppLT, * pLT;
+ DXFLayer * * ppLa, * pLa;
+ DXFStyle * * ppSt, * pSt;
+ DXFVPort * * ppVP, * pVP;
+
+ ppLT=&pLTypes;
+ while(*ppLT!=nullptr) ppLT=&((*ppLT)->pSucc);
+
+ ppLa=&pLayers;
+ while(*ppLa!=nullptr) ppLa=&((*ppLa)->pSucc);
+
+ ppSt=&pStyles;
+ while(*ppSt!=nullptr) ppSt=&((*ppSt)->pSucc);
+
+ ppVP=&pVPorts;
+ while(*ppVP!=nullptr) ppVP=&((*ppVP)->pSucc);
+
+ for (;;) {
+ while (rDGR.GetG()!=0) rDGR.Read();
+ if (rDGR.GetS() == "EOF" ||
+ rDGR.GetS() == "ENDSEC") break;
+ else if (rDGR.GetS() == "LTYPE") {
+ pLT=new DXFLType;
+ pLT->Read(rDGR);
+ *ppLT=pLT;
+ ppLT=&(pLT->pSucc);
+ }
+ else if (rDGR.GetS() == "LAYER") {
+ pLa=new DXFLayer;
+ pLa->Read(rDGR);
+ *ppLa=pLa;
+ ppLa=&(pLa->pSucc);
+ }
+ else if (rDGR.GetS() == "STYLE") {
+ pSt=new DXFStyle;
+ pSt->Read(rDGR);
+ *ppSt=pSt;
+ ppSt=&(pSt->pSucc);
+ }
+ else if (rDGR.GetS() == "VPORT") {
+ pVP=new DXFVPort;
+ pVP->Read(rDGR);
+ *ppVP=pVP;
+ ppVP=&(pVP->pSucc);
+ }
+ else rDGR.Read();
+ }
+}
+
+
+void DXFTables::Clear()
+{
+ DXFLType * pLT;
+ DXFLayer * pLa;
+ DXFStyle * pSt;
+ DXFVPort * pVP;
+
+ while (pStyles!=nullptr) {
+ pSt=pStyles;
+ pStyles=pSt->pSucc;
+ delete pSt;
+ }
+ while (pLayers!=nullptr) {
+ pLa=pLayers;
+ pLayers=pLa->pSucc;
+ delete pLa;
+ }
+ while (pLTypes!=nullptr) {
+ pLT=pLTypes;
+ pLTypes=pLT->pSucc;
+ delete pLT;
+ }
+ while (pVPorts!=nullptr) {
+ pVP=pVPorts;
+ pVPorts=pVP->pSucc;
+ delete pVP;
+ }
+}
+
+
+DXFLType * DXFTables::SearchLType(std::string_view rName) const
+{
+ DXFLType * p;
+ for (p=pLTypes; p!=nullptr; p=p->pSucc) {
+ if (rName == p->m_sName) break;
+ }
+ return p;
+}
+
+
+DXFLayer * DXFTables::SearchLayer(std::string_view rName) const
+{
+ DXFLayer * p;
+ for (p=pLayers; p!=nullptr; p=p->pSucc) {
+ if (rName == p->m_sName) break;
+ }
+ return p;
+}
+
+
+DXFVPort * DXFTables::SearchVPort(std::string_view rName) const
+{
+ DXFVPort * p;
+ for (p=pVPorts; p!=nullptr; p=p->pSucc) {
+ if (rName == p->m_sName) break;
+ }
+ return p;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxftblrd.hxx b/vcl/source/filter/idxf/dxftblrd.hxx
new file mode 100644
index 000000000..f60c0461e
--- /dev/null
+++ b/vcl/source/filter/idxf/dxftblrd.hxx
@@ -0,0 +1,175 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFTBLRD_HXX
+#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFTBLRD_HXX
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include "dxfgrprd.hxx"
+#include "dxfvec.hxx"
+
+
+//------------------- Line Type ----------------------------------------------
+
+
+#define DXF_MAX_DASH_COUNT 32
+
+class DXFLType {
+
+public:
+
+ DXFLType * pSucc;
+
+ OString m_sName; // 2
+ tools::Long nFlags; // 70
+ OString m_sDescription; // 3
+ tools::Long nDashCount; // 73
+ double fPatternLength; // 40
+ double fDash[DXF_MAX_DASH_COUNT]; // 49,49,...
+
+ DXFLType();
+ void Read(DXFGroupReader & rDGR);
+};
+
+
+//------------------ Layer ---------------------------------------------------
+
+
+class DXFLayer {
+
+public:
+
+ DXFLayer * pSucc;
+
+ OString m_sName; // 2
+ tools::Long nFlags; // 70
+ tools::Long nColor; // 62
+ OString m_sLineType; // 6
+
+ DXFLayer();
+ void Read(DXFGroupReader & rDGR);
+};
+
+
+//------------------ Style ---------------------------------------------------
+
+
+class DXFStyle {
+
+public:
+
+ DXFStyle * pSucc;
+
+ OString m_sName; // 2
+ tools::Long nFlags; // 70
+ double fHeight; // 40
+ double fWidthFak; // 41
+ double fOblAngle; // 50
+ tools::Long nTextGenFlags; // 71
+ double fLastHeightUsed; // 42
+ OString m_sPrimFontFile; // 3
+ OString m_sBigFontFile; // 4
+
+ DXFStyle();
+ void Read(DXFGroupReader & rDGR);
+};
+
+
+//------------------ VPort ---------------------------------------------------
+
+
+class DXFVPort {
+
+public:
+
+ DXFVPort * pSucc;
+
+ OString m_sName; // 2
+ tools::Long nFlags; // 70
+ double fMinX; // 10
+ double fMinY; // 20
+ double fMaxX; // 11
+ double fMaxY; // 21
+ double fCenterX; // 12
+ double fCenterY; // 22
+ double fSnapBaseX; // 13
+ double fSnapBaseY; // 23
+ double fSnapSpacingX; // 14
+ double fSnapSpacingY; // 24
+ double fGridX; // 15
+ double fGridY; // 25
+ DXFVector aDirection; // 16,26,36
+ DXFVector aTarget; // 17,27,37
+ double fHeight; // 40
+ double fAspectRatio; // 41
+ double fLensLength; // 42
+ double fFrontClipPlane; // 43
+ double fBackClipPlane; // 44
+ double fTwistAngle; // 51
+ tools::Long nStatus; // 68
+ tools::Long nID; // 69
+ tools::Long nMode; // 71
+ tools::Long nCircleZoomPercent; // 72
+ tools::Long nFastZoom; // 73
+ tools::Long nUCSICON; // 74
+ tools::Long nSnap; // 75
+ tools::Long nGrid; // 76
+ tools::Long nSnapStyle; // 77
+ tools::Long nSnapIsopair; // 78
+
+ DXFVPort();
+ void Read(DXFGroupReader & rDGR);
+};
+
+
+//------------------ Tables --------------------------------------------------
+
+
+class DXFTables {
+
+ DXFLType * pLTypes; // list of line types
+ DXFLayer * pLayers; // list of layers
+ DXFStyle * pStyles; // list of styles
+ DXFVPort * pVPorts; // list of viewports
+
+public:
+
+ DXFTables();
+ ~DXFTables();
+
+ void Read(DXFGroupReader & rDGR);
+ // Reads the table until an ENDSEC or EOF
+ // (Unknown things/tables will be skipped)
+
+ void Clear();
+
+ // look for table entries:
+ DXFLType * SearchLType(std::string_view rName) const;
+ DXFLayer * SearchLayer(std::string_view rName) const;
+ DXFVPort * SearchVPort(std::string_view rName) const;
+
+};
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfvec.cxx b/vcl/source/filter/idxf/dxfvec.cxx
new file mode 100644
index 000000000..dc5f39835
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfvec.cxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <math.h>
+#include "dxfvec.hxx"
+#include <tools/gen.hxx>
+
+
+//---------------------------- DXFVector ---------------------------------------
+
+
+double DXFVector::Abs() const
+{
+ return sqrt(SProd(*this));
+}
+
+
+DXFVector DXFVector::Unit() const
+{
+ double flen;
+
+ flen=Abs();
+ if (flen!=0) return (*this)*(1.0/flen);
+ else return DXFVector(1.0,0.0,0.0);
+}
+
+
+//---------------------------- DXFTransform ------------------------------------
+
+
+DXFTransform::DXFTransform() :
+ aMX(1.0, 0.0, 0.0),
+ aMY(0.0, 1.0, 0.0),
+ aMZ(0.0, 0.0, 1.0),
+ aMP(0.0, 0.0, 0.0)
+{
+}
+
+
+DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
+ const DXFVector & rShift) :
+ aMX(fScaleX, 0.0, 0.0),
+ aMY(0.0, fScaleY, 0.0),
+ aMZ(0.0, 0.0, fScaleZ),
+ aMP(rShift)
+{
+}
+
+
+DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
+ double fRotAngle,
+ const DXFVector & rShift) :
+ aMX(0.0, 0.0, 0.0),
+ aMY(0.0, 0.0, 0.0),
+ aMZ(0.0, 0.0, fScaleZ),
+ aMP(rShift)
+{
+ aMX.fx=cos(basegfx::deg2rad(fRotAngle));
+ aMX.fy=sin(basegfx::deg2rad(fRotAngle));
+ aMY.fx=-aMX.fy;
+ aMY.fy=aMX.fx;
+ aMX*=fScaleX;
+ aMY*=fScaleY;
+}
+
+
+DXFTransform::DXFTransform(const DXFVector & rExtrusion) :
+ aMP(0.0, 0.0, 0.0)
+{
+ // 'Arbitrary Axis Algorithm' (cf. DXF documentation by Autodesk)
+ if ( fabs(rExtrusion.fx) < 1.0/64.0 && fabs(rExtrusion.fy) < 1.0/64.0) {
+ aMX = DXFVector(0.0, 1.0, 0.0) * rExtrusion;
+ }
+ else {
+ aMX = DXFVector(0.0, 0.0, 1.0) * rExtrusion;
+ }
+ aMX=aMX.Unit();
+ aMY=(rExtrusion*aMX).Unit();
+ aMZ=rExtrusion.Unit();
+}
+
+
+DXFTransform::DXFTransform(const DXFVector & rViewDir, const DXFVector & rViewTarget)
+{
+ DXFVector aV;
+
+ aV=rViewDir.Unit();
+ aMX.fz=aV.fx;
+ aMY.fz=aV.fy;
+ aMZ.fz=aV.fz;
+
+ aMZ.fx=0;
+ if (aV.fx==0) aMY.fx=0; else aMY.fx=sqrt(1/(1+aV.fy*aV.fy/(aV.fx*aV.fx)));
+ aMX.fx=sqrt(1-aMY.fx*aMY.fx);
+ if (aV.fx*aV.fy*aMY.fx>0) aMX.fx=-aMX.fx;
+
+ aV=aV*DXFVector(aMX.fx,aMY.fx,aMZ.fx);
+ aMX.fy=aV.fx;
+ aMY.fy=aV.fy;
+ aMZ.fy=aV.fz;
+
+ if (aMZ.fy<0) {
+ aMX.fy=-aMX.fy;
+ aMY.fy=-aMY.fy;
+ aMZ.fy=-aMZ.fy;
+ aMX.fx=-aMX.fx;
+ aMY.fx=-aMY.fx;
+ }
+
+ aV=DXFVector(0,0,0)-rViewTarget;
+ aMP.fx = aV.fx * aMX.fx + aV.fy * aMY.fx + aV.fz * aMZ.fx;
+ aMP.fy = aV.fx * aMX.fy + aV.fy * aMY.fy + aV.fz * aMZ.fy;
+ aMP.fz = aV.fx * aMX.fz + aV.fy * aMY.fz + aV.fz * aMZ.fz;
+}
+
+
+DXFTransform::DXFTransform(const DXFTransform & rT1, const DXFTransform & rT2)
+{
+ rT2.TransDir(rT1.aMX,aMX);
+ rT2.TransDir(rT1.aMY,aMY);
+ rT2.TransDir(rT1.aMZ,aMZ);
+ rT2.Transform(rT1.aMP,aMP);
+}
+
+
+void DXFTransform::Transform(const DXFVector & rSrc, DXFVector & rTgt) const
+{
+ rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx;
+ rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy;
+ rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz + aMP.fz;
+}
+
+
+void DXFTransform::Transform(const DXFVector & rSrc, Point & rTgt) const
+{
+ rTgt.setX(static_cast<tools::Long>( rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx + 0.5 ) );
+ rTgt.setY(static_cast<tools::Long>( rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy + 0.5 ) );
+}
+
+
+void DXFTransform::TransDir(const DXFVector & rSrc, DXFVector & rTgt) const
+{
+ rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx;
+ rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy;
+ rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz;
+}
+
+
+bool DXFTransform::TransCircleToEllipse(double fRadius, double & rEx, double & rEy) const
+{
+ double fMXAbs=aMX.Abs();
+ double fMYAbs=aMY.Abs();
+ double fNearNull=(fMXAbs+fMYAbs)*0.001;
+
+ if (fabs(aMX.fy)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
+ fabs(aMY.fx)<=fNearNull && fabs(aMY.fz)<=fNearNull)
+ {
+ rEx=fabs(aMX.fx*fRadius);
+ rEy=fabs(aMY.fy*fRadius);
+ return true;
+ }
+ else if (fabs(aMX.fx)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
+ fabs(aMY.fy)<=fNearNull && fabs(aMY.fz)<=fNearNull)
+ {
+ rEx=fabs(aMY.fx*fRadius);
+ rEy=fabs(aMX.fy*fRadius);
+ return true;
+ }
+ else if (fabs(fMXAbs-fMYAbs)<=fNearNull &&
+ fabs(aMX.fz)<=fNearNull && fabs(aMY.fz)<=fNearNull)
+ {
+ rEx=rEy=fabs(((fMXAbs+fMYAbs)/2)*fRadius);
+ return true;
+ }
+ else return false;
+}
+
+LineInfo DXFTransform::Transform(const DXFLineInfo& aDXFLineInfo) const
+{
+ double fex,fey,scale;
+
+ fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
+ fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
+ scale = (fex+fey)/2.0;
+
+ LineInfo aLineInfo;
+
+ aLineInfo.SetStyle( aDXFLineInfo.eStyle );
+ aLineInfo.SetWidth( 0 );
+ aLineInfo.SetDashCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDashCount ) );
+ aLineInfo.SetDashLen( aDXFLineInfo.fDashLen * scale );
+ aLineInfo.SetDotCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDotCount ) );
+ aLineInfo.SetDotLen( aDXFLineInfo.fDotLen * scale );
+ aLineInfo.SetDistance( aDXFLineInfo.fDistance * scale );
+
+ if ( aLineInfo.GetDashCount() > 0 && aLineInfo.GetDashLen() == 0 )
+ aLineInfo.SetDashLen(1);
+
+ if ( aLineInfo.GetDotCount() > 0 && aLineInfo.GetDotLen() == 0 )
+ aLineInfo.SetDotLen(1);
+
+ return aLineInfo;
+}
+
+double DXFTransform::CalcRotAngle() const
+{
+ return basegfx::rad2deg(atan2(aMX.fy,aMX.fx));
+}
+
+bool DXFTransform::Mirror() const
+{
+ return aMZ.SProd(aMX*aMY)<0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/dxfvec.hxx b/vcl/source/filter/idxf/dxfvec.hxx
new file mode 100644
index 000000000..59b6babc2
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfvec.hxx
@@ -0,0 +1,218 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFVEC_HXX
+#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IDXF_DXFVEC_HXX
+
+#include <sal/types.h>
+#include <vcl/lineinfo.hxx>
+
+class Point;
+
+class DXFLineInfo {
+public:
+ LineStyle eStyle;
+ sal_Int32 nDashCount;
+ double fDashLen;
+ sal_Int32 nDotCount;
+ double fDotLen;
+ double fDistance;
+
+ DXFLineInfo() :
+ eStyle(LineStyle::Solid),
+ nDashCount(0),
+ fDashLen(0),
+ nDotCount(0),
+ fDotLen(0),
+ fDistance(0) {}
+};
+
+
+//---------------------------- DXFVector ---------------------------------------
+
+// common 3D vector with doubles
+
+class DXFVector {
+
+public:
+
+ double fx,fy,fz; // public ! - why not?
+
+ inline DXFVector(double fX=0.0, double fY=0.0, double fZ=0.0);
+
+ // summation/subtraktion:
+ DXFVector & operator += (const DXFVector & rV);
+ DXFVector operator + (const DXFVector & rV) const;
+ DXFVector operator - (const DXFVector & rV) const;
+
+ // vector product
+ DXFVector operator * (const DXFVector & rV) const;
+
+ // scalar product:
+ double SProd(const DXFVector & rV) const;
+
+ // multiplication with scalar:
+ DXFVector & operator *= (double fs);
+ DXFVector operator * (double fs) const;
+
+ // length:
+ double Abs() const;
+
+ // vector with same direction and a length of 1:
+ DXFVector Unit() const;
+
+ // equivalence or net:
+ bool operator == (const DXFVector & rV) const;
+};
+
+
+//---------------------------- DXFTransform ------------------------------------
+
+// a transformation matrice specialized for our problem
+
+class DXFTransform {
+
+public:
+
+ DXFTransform();
+ // destination coordinate = source coordinate
+
+ DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
+ const DXFVector & rShift);
+ // dest coordinate = translate(scale(source coordinate))
+
+ DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
+ double fRotAngle,
+ const DXFVector & rShift);
+ // dest coordinate = translate(rotate(scale(source coordinate)))
+ // rotation around z-axis, fRotAngle in degrees.
+
+ DXFTransform(const DXFVector & rExtrusion);
+ // Transformation "ECS->WCS" via "Entity Extrusion Direction"
+ // ant the "Arbitrary Axis Algorithm"
+ // (See DXF-Docu from AutoDesk)
+
+ DXFTransform(const DXFVector & rViewDir, const DXFVector & rViewTarget);
+ // Transformation object space->picture space on the basis of direction
+ // destination point of a viewport
+ // (See DXF-Docu from AutoDesk: VPORT)
+
+ DXFTransform(const DXFTransform & rT1, const DXFTransform & rT2);
+ // destination coordinate = rT2(rT1(source coordinate))
+
+
+ void Transform(const DXFVector & rSrc, DXFVector & rTgt) const;
+ // Transformation from DXFVector to DXFVector
+
+ void Transform(const DXFVector & rSrc, Point & rTgt) const;
+ // Transformation from DXFVector to SvPoint
+
+ void TransDir(const DXFVector & rSrc, DXFVector & rTgt) const;
+ // Transformation of a relative vector (so no translation)
+
+ bool TransCircleToEllipse(double fRadius, double & rEx, double & rEy) const;
+ // Attempt to transform a circle (in xy plane) so that it results
+ // in an aligned ellipse. If the does not work because an ellipse of
+ // arbitrary position would be created, sal_False is returned.
+ // (The center point will not be transformed, use Transform(..))
+
+ double CalcRotAngle() const;
+ // Calculates the rotation angle around z-axis (in degrees)
+
+ bool Mirror() const;
+ // Returns sal_True, if the matrice represents a left-handed coordinate system
+
+ LineInfo Transform(const DXFLineInfo& aDXFLineInfo) const;
+ // Transform to LineInfo
+
+private:
+ DXFVector aMX;
+ DXFVector aMY;
+ DXFVector aMZ;
+ DXFVector aMP;
+};
+
+
+//------------------------------- inlines --------------------------------------
+
+
+inline DXFVector::DXFVector(double fX, double fY, double fZ)
+{
+ fx=fX; fy=fY; fz=fZ;
+}
+
+
+inline DXFVector & DXFVector::operator += (const DXFVector & rV)
+{
+ fx+=rV.fx; fy+=rV.fy; fz+=rV.fz;
+ return *this;
+}
+
+
+inline DXFVector DXFVector::operator + (const DXFVector & rV) const
+{
+ return DXFVector(fx+rV.fx, fy+rV.fy, fz+rV.fz);
+}
+
+
+inline DXFVector DXFVector::operator - (const DXFVector & rV) const
+{
+ return DXFVector(fx-rV.fx, fy-rV.fy, fz-rV.fz);
+}
+
+
+inline DXFVector DXFVector::operator * (const DXFVector & rV) const
+{
+ return DXFVector(
+ fy * rV.fz - fz * rV.fy,
+ fz * rV.fx - fx * rV.fz,
+ fx * rV.fy - fy * rV.fx
+ );
+}
+
+
+inline double DXFVector::SProd(const DXFVector & rV) const
+{
+ return fx*rV.fx + fy*rV.fy + fz*rV.fz;
+}
+
+
+inline DXFVector & DXFVector::operator *= (double fs)
+{
+ fx*=fs; fy*=fs; fz*=fs;
+ return *this;
+}
+
+
+inline DXFVector DXFVector::operator * (double fs) const
+{
+ return DXFVector(fx*fs,fy*fs,fz*fs);
+}
+
+
+inline bool DXFVector::operator == (const DXFVector & rV) const
+{
+ if (fx==rV.fx && fy==rV.fy && fz==rV.fz) return true;
+ else return false;
+}
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/filter/idxf/idxf.cxx b/vcl/source/filter/idxf/idxf.cxx
new file mode 100644
index 000000000..26d42b10c
--- /dev/null
+++ b/vcl/source/filter/idxf/idxf.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <filter/DxfReader.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/graph.hxx>
+#include "dxf2mtf.hxx"
+
+//================== GraphicImport - the exported function ================
+
+bool ImportDxfGraphic(SvStream & rStream, Graphic & rGraphic)
+{
+ DXFRepresentation aDXF;
+ DXF2GDIMetaFile aConverter;
+ GDIMetaFile aMTF;
+
+ if ( !aDXF.Read( rStream ) )
+ return false;
+ if ( !aConverter.Convert( aDXF, aMTF, 60, 100 ) )
+ return false;
+ rGraphic = Graphic(aMTF);
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */