| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_filter.hxx" |
| |
| #include <string.h> |
| #include <vcl/gdimtf.hxx> |
| #include <vcl/virdev.hxx> |
| #include <tools/poly.hxx> |
| #include "dxf2mtf.hxx" |
| |
| #include <math.h> |
| |
| |
| sal_uLong DXF2GDIMetaFile::CountEntities(const DXFEntities & rEntities) |
| { |
| const DXFBasicEntity * pBE; |
| sal_uLong nRes; |
| |
| nRes=0; |
| for (pBE=rEntities.pFirst; pBE!=NULL; pBE=pBE->pSucc) nRes++; |
| return nRes; |
| } |
| |
| |
| void DXF2GDIMetaFile::MayCallback(sal_uLong /*nMainEntitiesProcessed*/) |
| { |
| // sal_uLong nPercent; |
| /* |
| if (pCallback!=NULL && nMainEntitiesCount!=0) { |
| nPercent=nMinPercent+(nMaxPercent-nMinPercent)*nMainEntitiesProcessed/nMainEntitiesCount; |
| if (nPercent>=nLastPercent+4) { |
| if (((*pCallback)(pCallerData,(sal_uInt16)nPercent))==sal_True) bStatus=sal_False; |
| nLastPercent=nPercent; |
| } |
| } |
| */ |
| } |
| |
| Color DXF2GDIMetaFile::ConvertColor(sal_uInt8 nColor) |
| { |
| return Color( |
| pDXF->aPalette.GetRed( nColor ), |
| pDXF->aPalette.GetGreen( nColor ), |
| pDXF->aPalette.GetBlue( nColor ) ); |
| } |
| |
| long DXF2GDIMetaFile::GetEntityColor(const DXFBasicEntity & rE) |
| { |
| long nColor; |
| const DXFLayer * pLayer; |
| |
| nColor=rE.nColor; |
| if (nColor==256) { |
| if (rE.sLayer[0]=='0' && rE.sLayer[1]==0) nColor=nParentLayerColor; |
| else { |
| pLayer=pDXF->aTables.SearchLayer(rE.sLayer); |
| if (pLayer!=NULL) nColor=pLayer->nColor; |
| else nColor=nParentLayerColor; |
| } |
| } |
| else if (nColor==0) nColor=nBlockColor; |
| return nColor; |
| } |
| |
| DXFLineInfo DXF2GDIMetaFile::LTypeToDXFLineInfo(const char * sLineType) |
| { |
| const DXFLType * pLT; |
| DXFLineInfo aDXFLineInfo; |
| |
| pLT=pDXF->aTables.SearchLType(sLineType); |
| if (pLT==NULL || pLT->nDashCount == 0) { |
| aDXFLineInfo.eStyle = LINE_SOLID; |
| } |
| else { |
| sal_Int32 i; |
| double x; |
| aDXFLineInfo.eStyle = LINE_DASH; |
| for (i=0; i < (pLT->nDashCount); i++) { |
| x = pLT->fDash[i] * pDXF->getGlobalLineTypeScale(); |
| // #### |
| // x = (sal_Int32) rTransform.TransLineWidth( 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. |
| } |
| } |
| |
| } |
| } |
| |
| #if 0 |
| if (aDXFLineInfo.DashCount > 0 && aDXFLineInfo.DashLen == 0.0) |
| aDXFLineInfo.DashLen ( 1 ); |
| if (aDXFLineInfo.DotCount > 0 && aDXFLineInfo.DotLen() == 0.0) |
| aDXFLineInfo.SetDotLen( 1 ); |
| if (aDXFLineInfo.GetDashCount > 0 || aDXFLineInfo.GetDotCount > 0) |
| if (aDXFLineInfo.GetDistance() == 0) |
| aDXFLineInfo.SetDistance( 1 ); |
| #endif |
| |
| return aDXFLineInfo; |
| } |
| |
| DXFLineInfo DXF2GDIMetaFile::GetEntityDXFLineInfo(const DXFBasicEntity & rE) |
| { |
| DXFLineInfo aDXFLineInfo; |
| const DXFLayer * pLayer; |
| |
| aDXFLineInfo.eStyle = LINE_SOLID; |
| aDXFLineInfo.fWidth = 0; |
| aDXFLineInfo.nDashCount = 0; |
| aDXFLineInfo.fDashLen = 0; |
| aDXFLineInfo.nDotCount = 0; |
| aDXFLineInfo.fDotLen = 0; |
| aDXFLineInfo.fDistance = 0; |
| |
| if (strcmp(rE.sLineType,"BYLAYER")==0) { |
| if (rE.sLayer[0]=='0' && rE.sLayer[1]==0) aDXFLineInfo=aParentLayerDXFLineInfo; |
| else { |
| pLayer=pDXF->aTables.SearchLayer(rE.sLayer); |
| if (pLayer!=NULL) aDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType); |
| else aDXFLineInfo=aParentLayerDXFLineInfo; |
| } |
| } |
| else if (strcmp(rE.sLineType,"BYBLOCK")==0) { |
| aDXFLineInfo=aBlockDXFLineInfo; |
| } |
| else aDXFLineInfo=LTypeToDXFLineInfo(rE.sLineType); |
| return aDXFLineInfo; |
| } |
| |
| |
| sal_Bool DXF2GDIMetaFile::SetLineAttribute(const DXFBasicEntity & rE, sal_uLong /*nWidth*/) |
| { |
| long nColor; |
| Color aColor; |
| |
| nColor=GetEntityColor(rE); |
| if (nColor<0) return sal_False; |
| aColor=ConvertColor((sal_uInt8)nColor); |
| |
| if (aActLineColor!=aColor) { |
| pVirDev->SetLineColor( aActLineColor = aColor ); |
| } |
| |
| if (aActFillColor!=Color( COL_TRANSPARENT )) { |
| pVirDev->SetFillColor(aActFillColor = Color( COL_TRANSPARENT )); |
| } |
| return sal_True; |
| } |
| |
| |
| sal_Bool DXF2GDIMetaFile::SetAreaAttribute(const DXFBasicEntity & rE) |
| { |
| long nColor; |
| Color aColor; |
| |
| nColor=GetEntityColor(rE); |
| if (nColor<0) return sal_False; |
| aColor=ConvertColor((sal_uInt8)nColor); |
| |
| if (aActLineColor!=aColor) { |
| pVirDev->SetLineColor( aActLineColor = aColor ); |
| } |
| |
| if ( aActFillColor == Color( COL_TRANSPARENT ) || aActFillColor != aColor) { |
| pVirDev->SetFillColor( aActFillColor = aColor ); |
| } |
| return sal_True; |
| } |
| |
| |
| sal_Bool DXF2GDIMetaFile::SetFontAttribute(const DXFBasicEntity & rE, short nAngle, sal_uInt16 nHeight, double /*fWidthScale*/) |
| { |
| long nColor; |
| Color aColor; |
| Font aFont; |
| |
| nAngle=-nAngle; |
| while (nAngle>3600) nAngle-=3600; |
| while (nAngle<0) nAngle+=3600; |
| |
| nColor=GetEntityColor(rE); |
| if (nColor<0) return sal_False; |
| aColor=ConvertColor((sal_uInt8)nColor); |
| |
| aFont.SetColor(aColor); |
| aFont.SetTransparent(sal_True); |
| aFont.SetFamily(FAMILY_SWISS); |
| aFont.SetSize(Size(0,nHeight)); |
| aFont.SetAlign(ALIGN_BASELINE); |
| aFont.SetOrientation(nAngle); |
| if (aActFont!=aFont) { |
| aActFont=aFont; |
| pVirDev->SetFont(aActFont); |
| } |
| |
| return sal_True; |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawLineEntity(const DXFLineEntity & rE, const DXFTransform & rTransform) |
| { |
| if (SetLineAttribute(rE)) { |
| Point aP0,aP1; |
| rTransform.Transform(rE.aP0,aP0); |
| rTransform.Transform(rE.aP1,aP1); |
| |
| DXFLineInfo aDXFLineInfo; |
| aDXFLineInfo=GetEntityDXFLineInfo(rE); |
| LineInfo aLineInfo; |
| aLineInfo = rTransform.Transform(aDXFLineInfo); |
| |
| #if 0 |
| printf("%f\n", rTransform.TransLineWidth(1000.0)); |
| |
| // LINE_NONE = 0, LINE_SOLID = 1, LINE_DASH = 2, LineStyle_FORCE_EQUAL_SIZE = SAL_MAX_ENUM |
| aLineInfo.SetStyle( LINE_DASH ); |
| aLineInfo.SetWidth( 300 ); |
| aLineInfo.SetDashCount( 2 ); |
| aLineInfo.SetDashLen( 100 ); |
| aLineInfo.SetDotCount( 1 ); |
| aLineInfo.SetDotLen( 0 ); |
| aLineInfo.SetDistance( 500 ); |
| #endif |
| |
| 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); |
| pVirDev->DrawLine(aP2,aP3); |
| pVirDev->DrawLine(aP0,aP2); |
| pVirDev->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); |
| pVirDev->DrawLine(aP0,aP1); |
| } |
| } |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawCircleEntity(const DXFCircleEntity & rE, const DXFTransform & rTransform) |
| { |
| double frx,fry,fAng; |
| sal_uInt16 nPoints,i; |
| DXFVector aC; |
| |
| if (SetLineAttribute(rE)==sal_False) return; |
| rTransform.Transform(rE.aP0,aC); |
| if (rE.fThickness==0 && rTransform.TransCircleToEllipse(rE.fRadius,frx,fry)==sal_True) { |
| pVirDev->DrawEllipse( |
| Rectangle((long)(aC.fx-frx+0.5),(long)(aC.fy-fry+0.5), |
| (long)(aC.fx+frx+0.5),(long)(aC.fy+fry+0.5))); |
| } |
| else { |
| nPoints=OptPointsPerCircle; |
| Polygon aPoly(nPoints); |
| for (i=0; i<nPoints; i++) { |
| fAng=2*3.14159265359/(double)(nPoints-1)*(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) { |
| Polygon aPoly2(nPoints); |
| for (i=0; i<nPoints; i++) { |
| fAng=2*3.14159265359/(double)(nPoints-1)*(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++) pVirDev->DrawLine(aPoly[i],aPoly2[i]); |
| } |
| } |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawArcEntity(const DXFArcEntity & rE, const DXFTransform & rTransform) |
| { |
| double frx,fry,fA1,fdA,fAng; |
| sal_uInt16 nPoints,i; |
| DXFVector aC; |
| Point aPS,aPE; |
| |
| if (SetLineAttribute(rE)==sal_False) return; |
| fA1=rE.fStart; |
| fdA=rE.fEnd-fA1; |
| while (fdA>=360.0) fdA-=360.0; |
| while (fdA<=0) fdA+=360.0; |
| rTransform.Transform(rE.aP0,aC); |
| if (rE.fThickness==0 && fdA>5.0 && rTransform.TransCircleToEllipse(rE.fRadius,frx,fry)==sal_True) { |
| 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; |
| if (rTransform.Mirror()==sal_True) { |
| rTransform.Transform(aVS,aPS); |
| rTransform.Transform(aVE,aPE); |
| } |
| else { |
| rTransform.Transform(aVS,aPE); |
| rTransform.Transform(aVE,aPS); |
| } |
| pVirDev->DrawArc( |
| Rectangle((long)(aC.fx-frx+0.5),(long)(aC.fy-fry+0.5), |
| (long)(aC.fx+frx+0.5),(long)(aC.fy+fry+0.5)), |
| aPS,aPE |
| ); |
| } |
| else { |
| nPoints=(sal_uInt16)(fdA/360.0*(double)OptPointsPerCircle+0.5); |
| if (nPoints<2) nPoints=2; |
| Polygon aPoly(nPoints); |
| for (i=0; i<nPoints; i++) { |
| fAng=3.14159265359/180.0 * ( fA1 + fdA/(double)(nPoints-1)*(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) { |
| Polygon aPoly2(nPoints); |
| for (i=0; i<nPoints; i++) { |
| fAng=3.14159265359/180.0 * ( fA1 + fdA/(double)(nPoints-1)*(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++) pVirDev->DrawLine(aPoly[i],aPoly2[i]); |
| } |
| } |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawTraceEntity(const DXFTraceEntity & rE, const DXFTransform & rTransform) |
| { |
| if (SetLineAttribute(rE)) { |
| 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; |
| 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++) pVirDev->DrawLine(aPoly[i],aPoly2[i]); |
| } |
| } |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawSolidEntity(const DXFSolidEntity & rE, const DXFTransform & rTransform) |
| { |
| if (SetAreaAttribute(rE)) { |
| sal_uInt16 nN; |
| if (rE.aP2==rE.aP3) nN=3; else nN=4; |
| 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) { |
| 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++) pVirDev->DrawLine(aPoly[i],aPoly2[i]); |
| } |
| } |
| } |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawTextEntity(const DXFTextEntity & rE, const DXFTransform & rTransform) |
| { |
| DXFVector aV; |
| Point aPt; |
| double fA; |
| sal_uInt16 nHeight; |
| short nAng; |
| ByteString aStr( rE.sText ); |
| DXFTransform aT( DXFTransform(rE.fXScale,rE.fHeight,1.0,rE.fRotAngle,rE.aP0), rTransform ); |
| aT.TransDir(DXFVector(0,1,0),aV); |
| nHeight=(sal_uInt16)(aV.Abs()+0.5); |
| fA=aT.CalcRotAngle(); |
| nAng=(short)(fA*10.0+0.5); |
| aT.TransDir(DXFVector(1,0,0),aV); |
| if ( SetFontAttribute( rE,nAng, nHeight, aV. Abs() ) ) |
| { |
| String aUString( aStr, pDXF->getTextEncoding() ); |
| 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.sName); |
| if (pB!=NULL) { |
| 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 |
| ); |
| long nSavedBlockColor, nSavedParentLayerColor; |
| DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo; |
| nSavedBlockColor=nBlockColor; |
| nSavedParentLayerColor=nParentLayerColor; |
| aSavedBlockDXFLineInfo=aBlockDXFLineInfo; |
| aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo; |
| nBlockColor=GetEntityColor(rE); |
| aBlockDXFLineInfo=GetEntityDXFLineInfo(rE); |
| if (rE.sLayer[0]!='0' || rE.sLayer[1]!=0) { |
| DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.sLayer); |
| if (pLayer!=NULL) { |
| nParentLayerColor=pLayer->nColor; |
| aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType); |
| } |
| } |
| DrawEntities(*pB,aT,sal_False); |
| aBlockDXFLineInfo=aSavedBlockDXFLineInfo; |
| aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo; |
| nBlockColor=nSavedBlockColor; |
| nParentLayerColor=nSavedParentLayerColor; |
| } |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawAttribEntity(const DXFAttribEntity & rE, const DXFTransform & rTransform) |
| { |
| if ((rE.nAttrFlags&1)==0) { |
| DXFVector aV; |
| Point aPt; |
| double fA; |
| sal_uInt16 nHeight; |
| short nAng; |
| ByteString aStr( rE.sText ); |
| DXFTransform aT( DXFTransform( rE.fXScale, rE.fHeight, 1.0, rE.fRotAngle, rE.aP0 ), rTransform ); |
| aT.TransDir(DXFVector(0,1,0),aV); |
| nHeight=(sal_uInt16)(aV.Abs()+0.5); |
| fA=aT.CalcRotAngle(); |
| nAng=(short)(fA*10.0+0.5); |
| aT.TransDir(DXFVector(1,0,0),aV); |
| if (SetFontAttribute(rE,nAng,nHeight,aV.Abs())) |
| { |
| String aUString( aStr, pDXF->getTextEncoding() ); |
| aT.Transform( DXFVector( 0, 0, 0 ), aPt ); |
| pVirDev->DrawText( aPt, aUString ); |
| } |
| } |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawPolyLineEntity(const DXFPolyLineEntity & rE, const DXFTransform & rTransform) |
| { |
| sal_uInt16 i,nPolySize; |
| double fW; |
| const DXFBasicEntity * pBE; |
| |
| nPolySize=0; |
| pBE=rE.pSucc; |
| while (pBE!=NULL && pBE->eType==DXF_VERTEX) { |
| nPolySize++; |
| pBE=pBE->pSucc; |
| } |
| if (nPolySize<2) return; |
| Polygon aPoly(nPolySize); |
| fW=0.0; |
| pBE=rE.pSucc; |
| for (i=0; i<nPolySize; i++) { |
| rTransform.Transform(((DXFVertexEntity*)pBE)->aP0,aPoly[i]); |
| if (i+1<nPolySize || (rE.nFlags&1)!=0) { |
| if (((DXFVertexEntity*)pBE)->fSWidth>=0.0) fW+=((DXFVertexEntity*)pBE)->fSWidth; |
| else fW+=rE.fSWidth; |
| if (((DXFVertexEntity*)pBE)->fEWidth>=0.0) fW+=((DXFVertexEntity*)pBE)->fEWidth; |
| else fW+=rE.fEWidth; |
| } |
| pBE=pBE->pSucc; |
| } |
| fW/=2.0; |
| if ((rE.nFlags&1)!=0) fW/=(double)nPolySize; |
| else fW/=(double)(nPolySize-1); |
| if (SetLineAttribute(rE,rTransform.TransLineWidth(fW))) { |
| if ((rE.nFlags&1)!=0) pVirDev->DrawPolygon(aPoly); |
| else pVirDev->DrawPolyLine(aPoly); |
| if (rE.fThickness!=0) { |
| Polygon aPoly2(nPolySize); |
| pBE=rE.pSucc; |
| for (i=0; i<nPolySize; i++) { |
| rTransform.Transform( |
| (((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++) pVirDev->DrawLine(aPoly[i],aPoly2[i]); |
| } |
| } |
| } |
| |
| void DXF2GDIMetaFile::DrawLWPolyLineEntity(const DXFLWPolyLineEntity & rE, const DXFTransform & rTransform ) |
| { |
| sal_Int32 i, nPolySize = rE.nCount; |
| if ( nPolySize && rE.pP ) |
| { |
| Polygon aPoly( (sal_uInt16)nPolySize); |
| for ( i = 0; i < nPolySize; i++ ) |
| { |
| rTransform.Transform( rE.pP[ (sal_uInt16)i ], aPoly[ (sal_uInt16)i ] ); |
| } |
| double fW = rE.fConstantWidth; |
| if ( SetLineAttribute( rE, rTransform.TransLineWidth( fW ) ) ) |
| { |
| if ( ( rE.nFlags & 1 ) != 0 ) |
| pVirDev->DrawPolygon( aPoly ); |
| else |
| pVirDev->DrawPolyLine( aPoly ); |
| // #### |
| //pVirDev->DrawPolyLine( aPoly, aDXFLineInfo ); |
| } |
| } |
| } |
| |
| void DXF2GDIMetaFile::DrawHatchEntity(const DXFHatchEntity & rE, const DXFTransform & rTransform ) |
| { |
| if ( rE.nBoundaryPathCount ) |
| { |
| SetAreaAttribute( rE ); |
| sal_Int32 j = 0; |
| PolyPolygon aPolyPoly; |
| for ( j = 0; j < rE.nBoundaryPathCount; j++ ) |
| { |
| DXFPointArray aPtAry; |
| const DXFBoundaryPathData& rPathData = rE.pBoundaryPathData[ j ]; |
| if ( rPathData.bIsPolyLine ) |
| { |
| sal_Int32 i; |
| for( i = 0; i < rPathData.nPointCount; i++ ) |
| { |
| Point aPt; |
| rTransform.Transform( rPathData.pP[ i ], aPt ); |
| aPtAry.push_back( aPt ); |
| } |
| } |
| else |
| { |
| sal_uInt32 i; |
| for ( i = 0; i < rPathData.aEdges.size(); i++ ) |
| { |
| const DXFEdgeType* pEdge = rPathData.aEdges[ i ]; |
| switch( pEdge->nEdgeType ) |
| { |
| case 1 : |
| { |
| Point aPt; |
| rTransform.Transform( ((DXFEdgeTypeLine*)pEdge)->aStartPoint, aPt ); |
| aPtAry.push_back( aPt ); |
| rTransform.Transform( ((DXFEdgeTypeLine*)pEdge)->aEndPoint, aPt ); |
| aPtAry.push_back( aPt ); |
| } |
| break; |
| case 2 : |
| { |
| /* |
| double frx,fry,fA1,fdA,fAng; |
| sal_uInt16 nPoints,i; |
| DXFVector aC; |
| Point aPS,aPE; |
| fA1=((DXFEdgeTypeCircularArc*)pEdge)->fStartAngle; |
| fdA=((DXFEdgeTypeCircularArc*)pEdge)->fEndAngle - fA1; |
| while ( fdA >= 360.0 ) |
| fdA -= 360.0; |
| while ( fdA <= 0 ) |
| fdA += 360.0; |
| rTransform.Transform(((DXFEdgeTypeCircularArc*)pEdge)->aCenter, aC); |
| if ( fdA > 5.0 && rTransform.TransCircleToEllipse(((DXFEdgeTypeCircularArc*)pEdge)->fRadius,frx,fry ) == sal_True ) |
| { |
| DXFVector aVS(cos(fA1/180.0*3.14159265359),sin(fA1/180.0*3.14159265359),0.0); |
| aVS*=((DXFEdgeTypeCircularArc*)pEdge)->fRadius; |
| aVS+=((DXFEdgeTypeCircularArc*)pEdge)->aCenter; |
| DXFVector aVE(cos((fA1+fdA)/180.0*3.14159265359),sin((fA1+fdA)/180.0*3.14159265359),0.0); |
| aVE*=((DXFEdgeTypeCircularArc*)pEdge)->fRadius; |
| aVE+=((DXFEdgeTypeCircularArc*)pEdge)->aCenter; |
| if ( rTransform.Mirror() == sal_True ) |
| { |
| rTransform.Transform(aVS,aPS); |
| rTransform.Transform(aVE,aPE); |
| } |
| else |
| { |
| rTransform.Transform(aVS,aPE); |
| rTransform.Transform(aVE,aPS); |
| } |
| pVirDev->DrawArc( |
| Rectangle((long)(aC.fx-frx+0.5),(long)(aC.fy-fry+0.5), |
| (long)(aC.fx+frx+0.5),(long)(aC.fy+fry+0.5)), |
| aPS,aPE |
| ); |
| } |
| */ |
| } |
| break; |
| case 3 : |
| case 4 : |
| break; |
| } |
| } |
| } |
| sal_uInt16 i, nSize = (sal_uInt16)aPtAry.size(); |
| if ( nSize ) |
| { |
| Polygon aPoly( nSize ); |
| for ( i = 0; i < nSize; i++ ) |
| aPoly[ i ] = aPtAry[ i ]; |
| aPolyPoly.Insert( aPoly, POLYPOLY_APPEND ); |
| } |
| } |
| if ( aPolyPoly.Count() ) |
| pVirDev->DrawPolyPolygon( aPolyPoly ); |
| } |
| } |
| |
| void DXF2GDIMetaFile::Draw3DFaceEntity(const DXF3DFaceEntity & rE, const DXFTransform & rTransform) |
| { |
| sal_uInt16 nN,i; |
| if (SetLineAttribute(rE)) { |
| if (rE.aP2==rE.aP3) nN=3; else nN=4; |
| 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 & (1<<i)) == 0 ) { |
| pVirDev->DrawLine(aPoly[i],aPoly[(i+1)%nN]); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawDimensionEntity(const DXFDimensionEntity & rE, const DXFTransform & rTransform) |
| { |
| const DXFBlock * pB; |
| pB=pDXF->aBlocks.Search(rE.sPseudoBlock); |
| if (pB!=NULL) { |
| DXFTransform aT( |
| DXFTransform(1.0,1.0,1.0,DXFVector(0.0,0.0,0.0)-pB->aBasePoint), |
| rTransform |
| ); |
| long nSavedBlockColor, nSavedParentLayerColor; |
| DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo; |
| nSavedBlockColor=nBlockColor; |
| nSavedParentLayerColor=nParentLayerColor; |
| aSavedBlockDXFLineInfo=aBlockDXFLineInfo; |
| aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo; |
| nBlockColor=GetEntityColor(rE); |
| aBlockDXFLineInfo=GetEntityDXFLineInfo(rE); |
| if (rE.sLayer[0]!='0' || rE.sLayer[1]!=0) { |
| DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.sLayer); |
| if (pLayer!=NULL) { |
| nParentLayerColor=pLayer->nColor; |
| aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType); |
| } |
| } |
| DrawEntities(*pB,aT,sal_False); |
| aBlockDXFLineInfo=aSavedBlockDXFLineInfo; |
| aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo; |
| nBlockColor=nSavedBlockColor; |
| nParentLayerColor=nSavedParentLayerColor; |
| } |
| } |
| |
| |
| void DXF2GDIMetaFile::DrawEntities(const DXFEntities & rEntities, |
| const DXFTransform & rTransform, |
| sal_Bool bTopEntities) |
| { |
| sal_uLong nCount=0; |
| DXFTransform aET; |
| const DXFTransform * pT; |
| |
| const DXFBasicEntity * pE=rEntities.pFirst; |
| |
| while (pE!=NULL && bStatus==sal_True) { |
| 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((DXFLineEntity&)*pE,*pT); |
| break; |
| case DXF_POINT: |
| DrawPointEntity((DXFPointEntity&)*pE,*pT); |
| break; |
| case DXF_CIRCLE: |
| DrawCircleEntity((DXFCircleEntity&)*pE,*pT); |
| break; |
| case DXF_ARC: |
| DrawArcEntity((DXFArcEntity&)*pE,*pT); |
| break; |
| case DXF_TRACE: |
| DrawTraceEntity((DXFTraceEntity&)*pE,*pT); |
| break; |
| case DXF_SOLID: |
| DrawSolidEntity((DXFSolidEntity&)*pE,*pT); |
| break; |
| case DXF_TEXT: |
| DrawTextEntity((DXFTextEntity&)*pE,*pT); |
| break; |
| case DXF_INSERT: |
| DrawInsertEntity((DXFInsertEntity&)*pE,*pT); |
| break; |
| case DXF_ATTRIB: |
| DrawAttribEntity((DXFAttribEntity&)*pE,*pT); |
| break; |
| case DXF_POLYLINE: |
| DrawPolyLineEntity((DXFPolyLineEntity&)*pE,*pT); |
| break; |
| case DXF_LWPOLYLINE : |
| DrawLWPolyLineEntity((DXFLWPolyLineEntity&)*pE, *pT); |
| break; |
| case DXF_HATCH : |
| DrawHatchEntity((DXFHatchEntity&)*pE, *pT); |
| break; |
| case DXF_3DFACE: |
| Draw3DFaceEntity((DXF3DFaceEntity&)*pE,*pT); |
| break; |
| case DXF_DIMENSION: |
| DrawDimensionEntity((DXFDimensionEntity&)*pE,*pT); |
| break; |
| default: |
| break; // four other values not handled -Wall |
| } |
| } |
| pE=pE->pSucc; |
| nCount++; |
| if (bTopEntities) MayCallback(nCount); |
| } |
| } |
| |
| |
| DXF2GDIMetaFile::DXF2GDIMetaFile() |
| { |
| } |
| |
| |
| DXF2GDIMetaFile::~DXF2GDIMetaFile() |
| { |
| } |
| |
| |
| sal_Bool DXF2GDIMetaFile::Convert(const DXFRepresentation & rDXF, GDIMetaFile & rMTF, sal_uInt16 nminpercent, sal_uInt16 nmaxpercent) |
| { |
| double fWidth,fHeight,fScale; |
| DXFTransform aTransform; |
| Size aPrefSize; |
| const DXFLayer * pLayer; |
| const DXFVPort * pVPort; |
| |
| pVirDev = new VirtualDevice; |
| pDXF = &rDXF; |
| bStatus = sal_True; |
| |
| OptPointsPerCircle=50; |
| |
| nMinPercent=(sal_uLong)nminpercent; |
| nMaxPercent=(sal_uLong)nmaxpercent; |
| nLastPercent=nMinPercent; |
| nMainEntitiesCount=CountEntities(pDXF->aEntities); |
| |
| nBlockColor=7; |
| aBlockDXFLineInfo.eStyle = LINE_SOLID; |
| aBlockDXFLineInfo.fWidth = 0; |
| aBlockDXFLineInfo.nDashCount = 0; |
| aBlockDXFLineInfo.fDashLen = 0; |
| aBlockDXFLineInfo.nDotCount = 0; |
| aBlockDXFLineInfo.fDotLen = 0; |
| aBlockDXFLineInfo.fDistance = 0; |
| |
| pLayer=pDXF->aTables.SearchLayer("0"); |
| if (pLayer!=NULL) { |
| nParentLayerColor=pLayer->nColor & 0xff; |
| aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType); |
| } |
| else { |
| nParentLayerColor=7; |
| aParentLayerDXFLineInfo.eStyle = LINE_SOLID; |
| aParentLayerDXFLineInfo.fWidth = 0; |
| aParentLayerDXFLineInfo.nDashCount = 0; |
| aParentLayerDXFLineInfo.fDashLen = 0; |
| aParentLayerDXFLineInfo.nDotCount = 0; |
| aParentLayerDXFLineInfo.fDotLen = 0; |
| aParentLayerDXFLineInfo.fDistance = 0; |
| } |
| |
| pVirDev->EnableOutput(sal_False); |
| rMTF.Record(pVirDev); |
| |
| aActLineColor = pVirDev->GetLineColor(); |
| aActFillColor = pVirDev->GetFillColor(); |
| aActFont = pVirDev->GetFont(); |
| |
| pVPort=pDXF->aTables.SearchVPort("*ACTIVE"); |
| if (pVPort!=NULL) { |
| if (pVPort->aDirection.fx==0 && pVPort->aDirection.fy==0) |
| pVPort=NULL; |
| } |
| |
| if (pVPort==NULL) { |
| if (pDXF->aBoundingBox.bEmpty==sal_True) |
| bStatus=sal_False; |
| else { |
| fWidth=pDXF->aBoundingBox.fMaxX-pDXF->aBoundingBox.fMinX; |
| fHeight=pDXF->aBoundingBox.fMaxY-pDXF->aBoundingBox.fMinY; |
| if (fWidth<=0 || fHeight<=0) { |
| bStatus=sal_False; |
| fScale = 0; // -Wall added this... |
| } |
| else { |
| // if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) { |
| if (fWidth>fHeight) |
| fScale=10000.0/fWidth; |
| else |
| fScale=10000.0/fHeight; |
| // } |
| // else |
| // fScale=1.0; |
| aTransform=DXFTransform(fScale,-fScale,fScale, |
| DXFVector(-pDXF->aBoundingBox.fMinX*fScale, |
| pDXF->aBoundingBox.fMaxY*fScale, |
| -pDXF->aBoundingBox.fMinZ*fScale)); |
| } |
| aPrefSize.Width() =(long)(fWidth*fScale+1.5); |
| aPrefSize.Height()=(long)(fHeight*fScale+1.5); |
| } |
| } |
| else { |
| fHeight=pVPort->fHeight; |
| fWidth=fHeight*pVPort->fAspectRatio; |
| // if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) { |
| if (fWidth>fHeight) |
| fScale=10000.0/fWidth; |
| else |
| fScale=10000.0/fHeight; |
| // } |
| // else |
| // fScale=1.0; |
| 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.Width() =(long)(fWidth*fScale+1.5); |
| aPrefSize.Height()=(long)(fHeight*fScale+1.5); |
| } |
| |
| if (bStatus==sal_True) |
| DrawEntities(pDXF->aEntities,aTransform,sal_True); |
| |
| rMTF.Stop(); |
| |
| if ( bStatus==sal_True ) |
| { |
| rMTF.SetPrefSize( aPrefSize ); |
| |
| // MapMode einfach, falls Grafik dann nicht zu klein wird (<0,5cm), |
| // auf 1/100-mm (1/10-mm) setzen |
| if( ( aPrefSize.Width() < 500 ) && ( aPrefSize.Height() < 500 ) ) |
| rMTF.SetPrefMapMode( MapMode( MAP_10TH_MM ) ); |
| else |
| rMTF.SetPrefMapMode( MapMode( MAP_100TH_MM ) ); |
| } |
| |
| delete pVirDev; |
| return bStatus; |
| } |
| |
| |
| |