diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /vcl/source/filter/idxf | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vcl/source/filter/idxf')
-rw-r--r-- | vcl/source/filter/idxf/dxf2mtf.cxx | 902 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxf2mtf.hxx | 119 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfblkrd.cxx | 125 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfblkrd.hxx | 83 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfentrd.cxx | 848 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfentrd.hxx | 538 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfgrprd.cxx | 213 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfgrprd.hxx | 115 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfreprd.cxx | 480 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfreprd.hxx | 129 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxftblrd.cxx | 381 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxftblrd.hxx | 175 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfvec.cxx | 232 | ||||
-rw-r--r-- | vcl/source/filter/idxf/dxfvec.hxx | 218 | ||||
-rw-r--r-- | vcl/source/filter/idxf/idxf.cxx | 43 |
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: */ |