/* -*- 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 #include #include #include #include #include "dxf2mtf.hxx" #include 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) { return Color( pDXF->aPalette.GetRed( nColor ), pDXF->aPalette.GetGreen( nColor ), pDXF->aPalette.GetBlue( nColor ) ); } tools::Long DXF2GDIMetaFile::GetEntityColor(const DXFBasicEntity & rE) { 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 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(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(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(nColor)); aFont.SetColor(aColor); aFont.SetTransparent(true); aFont.SetFamily(FAMILY_SWISS); aFont.SetFontSize(Size(0,nHeight)); aFont.SetAlignment(TextAlign::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(aC.fx-frx+0.5),static_cast(aC.fy-fry+0.5), static_cast(aC.fx+frx+0.5),static_cast(aC.fy+fry+0.5))); } else { double fAng; nPoints=OptPointsPerCircle; tools::Polygon aPoly(nPoints); for (i=0; i(nPoints-1)*static_cast(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-1)*static_cast(i); rTransform.Transform( rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),rE.fThickness), aPoly2[i] ); } pVirDev->DrawPolyLine(aPoly2); for (i=0; iGetConnectMetaFile(); 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(fA1/180.0*3.14159265359),sin(fA1/180.0*3.14159265359),0.0); aVS*=rE.fRadius; aVS+=rE.aP0; DXFVector aVE(cos((fA1+fdA)/180.0*3.14159265359),sin((fA1+fdA)/180.0*3.14159265359),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(aC.fx-frx+0.5),static_cast(aC.fy-fry+0.5), static_cast(aC.fx+frx+0.5),static_cast(aC.fy+fry+0.5)), aPS,aPE ); } else { double fAng; nPoints=static_cast(fdA/360.0*static_cast(OptPointsPerCircle)+0.5); if (nPoints<2) nPoints=2; tools::Polygon aPoly(nPoints); for (i=0; i(nPoints-1)*static_cast(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-1)*static_cast(i) ); rTransform.Transform( rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),rE.fThickness), aPoly2[i] ); } pVirDev->DrawPolyLine(aPoly2); for (i=0; iDrawPolygon(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(aV.Abs()+0.5); fA=aT.CalcRotAngle(); nAng=static_cast(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(aV.Abs()+0.5); fA=aT.CalcRotAngle(); nAng=static_cast(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(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(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)); for (sal_Int32 i = 0; i < nPolySize; ++i) { rTransform.Transform( rE.aP[ static_cast(i) ], aPoly[ static_cast(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.nBoundaryPathCount ) return; SetAreaAttribute( rE ); sal_Int32 j = 0; tools::PolyPolygon aPolyPoly; for ( j = 0; j < rE.nBoundaryPathCount; j++ ) { std::vector< Point > aPtAry; const DXFBoundaryPathData& rPathData = rE.pBoundaryPathData[ j ]; 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(pEdge)->aStartPoint, aPt ); aPtAry.push_back( aPt ); rTransform.Transform( static_cast(pEdge)->aEndPoint, aPt ); aPtAry.push_back( aPt ); } break; case 2 : case 3 : case 4 : break; } } } sal_uInt16 i, nSize = static_cast(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(1)<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(*pE),*pT); break; case DXF_POINT: DrawPointEntity(static_cast(*pE),*pT); break; case DXF_CIRCLE: DrawCircleEntity(static_cast(*pE),*pT); break; case DXF_ARC: DrawArcEntity(static_cast(*pE),*pT); break; case DXF_TRACE: DrawTraceEntity(static_cast(*pE),*pT); break; case DXF_SOLID: DrawSolidEntity(static_cast(*pE),*pT); break; case DXF_TEXT: DrawTextEntity(static_cast(*pE),*pT); break; case DXF_INSERT: DrawInsertEntity(static_cast(*pE),*pT); break; case DXF_ATTRIB: DrawAttribEntity(static_cast(*pE),*pT); break; case DXF_POLYLINE: DrawPolyLineEntity(static_cast(*pE),*pT); break; case DXF_LWPOLYLINE : DrawLWPolyLineEntity(static_cast(*pE), *pT); break; case DXF_HATCH : DrawHatchEntity(static_cast(*pE), *pT); break; case DXF_3DFACE: Draw3DFaceEntity(static_cast(*pE),*pT); break; case DXF_DIMENSION: DrawDimensionEntity(static_cast(*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::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(fWidth*fScale+1.5) ); aPrefSize.setHeight(static_cast(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(fWidth*fScale+1.5) ); aPrefSize.setHeight(static_cast(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: */