Update ooo320-m1
[ooovba.git] / goodies / source / filter.vcl / idxf / dxf2mtf.cxx
blob720b2b2c75937e2f20311ddfb7c26a365944f27c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dxf2mtf.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
34 #include <string.h>
35 #include <vcl/gdimtf.hxx>
36 #include <vcl/virdev.hxx>
37 #include <tools/poly.hxx>
38 #include "dxf2mtf.hxx"
40 #include <math.h>
43 ULONG DXF2GDIMetaFile::CountEntities(const DXFEntities & rEntities)
45 const DXFBasicEntity * pBE;
46 ULONG nRes;
48 nRes=0;
49 for (pBE=rEntities.pFirst; pBE!=NULL; pBE=pBE->pSucc) nRes++;
50 return nRes;
54 void DXF2GDIMetaFile::MayCallback(ULONG /*nMainEntitiesProcessed*/)
56 // ULONG nPercent;
58 if (pCallback!=NULL && nMainEntitiesCount!=0) {
59 nPercent=nMinPercent+(nMaxPercent-nMinPercent)*nMainEntitiesProcessed/nMainEntitiesCount;
60 if (nPercent>=nLastPercent+4) {
61 if (((*pCallback)(pCallerData,(USHORT)nPercent))==TRUE) bStatus=FALSE;
62 nLastPercent=nPercent;
68 Color DXF2GDIMetaFile::ConvertColor(BYTE nColor)
70 return Color(
71 pDXF->aPalette.GetRed( nColor ),
72 pDXF->aPalette.GetGreen( nColor ),
73 pDXF->aPalette.GetBlue( nColor ) );
76 long DXF2GDIMetaFile::GetEntityColor(const DXFBasicEntity & rE)
78 long nColor;
79 const DXFLayer * pLayer;
81 nColor=rE.nColor;
82 if (nColor==256) {
83 if (rE.sLayer[0]=='0' && rE.sLayer[1]==0) nColor=nParentLayerColor;
84 else {
85 pLayer=pDXF->aTables.SearchLayer(rE.sLayer);
86 if (pLayer!=NULL) nColor=pLayer->nColor;
87 else nColor=nParentLayerColor;
90 else if (nColor==0) nColor=nBlockColor;
91 return nColor;
94 DXFLineInfo DXF2GDIMetaFile::LTypeToDXFLineInfo(const char * sLineType)
96 const DXFLType * pLT;
97 DXFLineInfo aDXFLineInfo;
99 pLT=pDXF->aTables.SearchLType(sLineType);
100 if (pLT==NULL || pLT->nDashCount == 0) {
101 aDXFLineInfo.eStyle = LINE_SOLID;
103 else {
104 sal_Int32 i;
105 double x;
106 aDXFLineInfo.eStyle = LINE_DASH;
107 for (i=0; i < (pLT->nDashCount); i++) {
108 x = pLT->fDash[i] * pDXF->getGlobalLineTypeScale();
109 // ####
110 // x = (sal_Int32) rTransform.TransLineWidth( pLT->fDash[i] * pDXF->getGlobalLineTypeScale() );
111 if ( x >= 0.0 ) {
112 if ( aDXFLineInfo.nDotCount == 0 ) {
113 aDXFLineInfo.nDotCount ++;
114 aDXFLineInfo.fDotLen = x;
116 else if ( aDXFLineInfo.fDotLen == x ) {
117 aDXFLineInfo.nDotCount ++;
119 else if ( aDXFLineInfo.nDashCount == 0 ) {
120 aDXFLineInfo.nDashCount ++;
121 aDXFLineInfo.fDashLen = x;
123 else if ( aDXFLineInfo.fDashLen == x ) {
124 aDXFLineInfo.nDashCount ++;
126 else {
127 // It is impossible to be converted.
130 else {
131 if ( aDXFLineInfo.fDistance == 0 ) {
132 aDXFLineInfo.fDistance = -1 * x;
134 else {
135 // It is impossible to be converted.
142 #if 0
143 if (aDXFLineInfo.DashCount > 0 && aDXFLineInfo.DashLen == 0.0)
144 aDXFLineInfo.DashLen ( 1 );
145 if (aDXFLineInfo.DotCount > 0 && aDXFLineInfo.DotLen() == 0.0)
146 aDXFLineInfo.SetDotLen( 1 );
147 if (aDXFLineInfo.GetDashCount > 0 || aDXFLineInfo.GetDotCount > 0)
148 if (aDXFLineInfo.GetDistance() == 0)
149 aDXFLineInfo.SetDistance( 1 );
150 #endif
152 return aDXFLineInfo;
155 DXFLineInfo DXF2GDIMetaFile::GetEntityDXFLineInfo(const DXFBasicEntity & rE)
157 DXFLineInfo aDXFLineInfo;
158 const DXFLayer * pLayer;
160 aDXFLineInfo.eStyle = LINE_SOLID;
161 aDXFLineInfo.fWidth = 0;
162 aDXFLineInfo.nDashCount = 0;
163 aDXFLineInfo.fDashLen = 0;
164 aDXFLineInfo.nDotCount = 0;
165 aDXFLineInfo.fDotLen = 0;
166 aDXFLineInfo.fDistance = 0;
168 if (strcmp(rE.sLineType,"BYLAYER")==0) {
169 if (rE.sLayer[0]=='0' && rE.sLayer[1]==0) aDXFLineInfo=aParentLayerDXFLineInfo;
170 else {
171 pLayer=pDXF->aTables.SearchLayer(rE.sLayer);
172 if (pLayer!=NULL) aDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType);
173 else aDXFLineInfo=aParentLayerDXFLineInfo;
176 else if (strcmp(rE.sLineType,"BYBLOCK")==0) {
177 aDXFLineInfo=aBlockDXFLineInfo;
179 else aDXFLineInfo=LTypeToDXFLineInfo(rE.sLineType);
180 return aDXFLineInfo;
184 BOOL DXF2GDIMetaFile::SetLineAttribute(const DXFBasicEntity & rE, ULONG /*nWidth*/)
186 long nColor;
187 Color aColor;
189 nColor=GetEntityColor(rE);
190 if (nColor<0) return FALSE;
191 aColor=ConvertColor((BYTE)nColor);
193 if (aActLineColor!=aColor) {
194 pVirDev->SetLineColor( aActLineColor = aColor );
197 if (aActFillColor!=Color( COL_TRANSPARENT )) {
198 pVirDev->SetFillColor(aActFillColor = Color( COL_TRANSPARENT ));
200 return TRUE;
204 BOOL DXF2GDIMetaFile::SetAreaAttribute(const DXFBasicEntity & rE)
206 long nColor;
207 Color aColor;
209 nColor=GetEntityColor(rE);
210 if (nColor<0) return FALSE;
211 aColor=ConvertColor((BYTE)nColor);
213 if (aActLineColor!=aColor) {
214 pVirDev->SetLineColor( aActLineColor = aColor );
217 if ( aActFillColor == Color( COL_TRANSPARENT ) || aActFillColor != aColor) {
218 pVirDev->SetFillColor( aActFillColor = aColor );
220 return TRUE;
224 BOOL DXF2GDIMetaFile::SetFontAttribute(const DXFBasicEntity & rE, short nAngle, USHORT nHeight, double /*fWidthScale*/)
226 long nColor;
227 Color aColor;
228 Font aFont;
230 nAngle=-nAngle;
231 while (nAngle>3600) nAngle-=3600;
232 while (nAngle<0) nAngle+=3600;
234 nColor=GetEntityColor(rE);
235 if (nColor<0) return FALSE;
236 aColor=ConvertColor((BYTE)nColor);
238 aFont.SetColor(aColor);
239 aFont.SetTransparent(TRUE);
240 aFont.SetFamily(FAMILY_SWISS);
241 aFont.SetSize(Size(0,nHeight));
242 aFont.SetAlign(ALIGN_BASELINE);
243 aFont.SetOrientation(nAngle);
244 if (aActFont!=aFont) {
245 aActFont=aFont;
246 pVirDev->SetFont(aActFont);
249 return TRUE;
253 void DXF2GDIMetaFile::DrawLineEntity(const DXFLineEntity & rE, const DXFTransform & rTransform)
255 if (SetLineAttribute(rE)) {
256 Point aP0,aP1;
257 rTransform.Transform(rE.aP0,aP0);
258 rTransform.Transform(rE.aP1,aP1);
260 DXFLineInfo aDXFLineInfo;
261 aDXFLineInfo=GetEntityDXFLineInfo(rE);
262 LineInfo aLineInfo;
263 aLineInfo = rTransform.Transform(aDXFLineInfo);
265 #if 0
266 printf("%f\n", rTransform.TransLineWidth(1000.0));
268 // LINE_NONE = 0, LINE_SOLID = 1, LINE_DASH = 2, LineStyle_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
269 aLineInfo.SetStyle( LINE_DASH );
270 aLineInfo.SetWidth( 300 );
271 aLineInfo.SetDashCount( 2 );
272 aLineInfo.SetDashLen( 100 );
273 aLineInfo.SetDotCount( 1 );
274 aLineInfo.SetDotLen( 0 );
275 aLineInfo.SetDistance( 500 );
276 #endif
278 pVirDev->DrawLine(aP0,aP1,aLineInfo);
279 if (rE.fThickness!=0) {
280 Point aP2,aP3;
281 rTransform.Transform(rE.aP0+DXFVector(0,0,rE.fThickness),aP2);
282 rTransform.Transform(rE.aP1+DXFVector(0,0,rE.fThickness),aP3);
283 pVirDev->DrawLine(aP2,aP3);
284 pVirDev->DrawLine(aP0,aP2);
285 pVirDev->DrawLine(aP1,aP3);
291 void DXF2GDIMetaFile::DrawPointEntity(const DXFPointEntity & rE, const DXFTransform & rTransform)
294 if (SetLineAttribute(rE)) {
295 Point aP0;
296 rTransform.Transform(rE.aP0,aP0);
297 if (rE.fThickness==0) pVirDev->DrawPixel(aP0);
298 else {
299 Point aP1;
300 rTransform.Transform(rE.aP0+DXFVector(0,0,rE.fThickness),aP1);
301 pVirDev->DrawLine(aP0,aP1);
307 void DXF2GDIMetaFile::DrawCircleEntity(const DXFCircleEntity & rE, const DXFTransform & rTransform)
309 double frx,fry,fAng;
310 USHORT nPoints,i;
311 DXFVector aC;
313 if (SetLineAttribute(rE)==FALSE) return;
314 rTransform.Transform(rE.aP0,aC);
315 if (rE.fThickness==0 && rTransform.TransCircleToEllipse(rE.fRadius,frx,fry)==TRUE) {
316 pVirDev->DrawEllipse(
317 Rectangle((long)(aC.fx-frx+0.5),(long)(aC.fy-fry+0.5),
318 (long)(aC.fx+frx+0.5),(long)(aC.fy+fry+0.5)));
320 else {
321 nPoints=OptPointsPerCircle;
322 Polygon aPoly(nPoints);
323 for (i=0; i<nPoints; i++) {
324 fAng=2*3.14159265359/(double)(nPoints-1)*(double)i;
325 rTransform.Transform(
326 rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),0),
327 aPoly[i]
330 pVirDev->DrawPolyLine(aPoly);
331 if (rE.fThickness!=0) {
332 Polygon aPoly2(nPoints);
333 for (i=0; i<nPoints; i++) {
334 fAng=2*3.14159265359/(double)(nPoints-1)*(double)i;
335 rTransform.Transform(
336 rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),rE.fThickness),
337 aPoly2[i]
341 pVirDev->DrawPolyLine(aPoly2);
342 for (i=0; i<nPoints-1; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
348 void DXF2GDIMetaFile::DrawArcEntity(const DXFArcEntity & rE, const DXFTransform & rTransform)
350 double frx,fry,fA1,fdA,fAng;
351 USHORT nPoints,i;
352 DXFVector aC;
353 Point aPS,aPE;
355 if (SetLineAttribute(rE)==FALSE) return;
356 fA1=rE.fStart;
357 fdA=rE.fEnd-fA1;
358 while (fdA>=360.0) fdA-=360.0;
359 while (fdA<=0) fdA+=360.0;
360 rTransform.Transform(rE.aP0,aC);
361 if (rE.fThickness==0 && fdA>5.0 && rTransform.TransCircleToEllipse(rE.fRadius,frx,fry)==TRUE) {
362 DXFVector aVS(cos(fA1/180.0*3.14159265359),sin(fA1/180.0*3.14159265359),0.0);
363 aVS*=rE.fRadius;
364 aVS+=rE.aP0;
365 DXFVector aVE(cos((fA1+fdA)/180.0*3.14159265359),sin((fA1+fdA)/180.0*3.14159265359),0.0);
366 aVE*=rE.fRadius;
367 aVE+=rE.aP0;
368 if (rTransform.Mirror()==TRUE) {
369 rTransform.Transform(aVS,aPS);
370 rTransform.Transform(aVE,aPE);
372 else {
373 rTransform.Transform(aVS,aPE);
374 rTransform.Transform(aVE,aPS);
376 pVirDev->DrawArc(
377 Rectangle((long)(aC.fx-frx+0.5),(long)(aC.fy-fry+0.5),
378 (long)(aC.fx+frx+0.5),(long)(aC.fy+fry+0.5)),
379 aPS,aPE
382 else {
383 nPoints=(USHORT)(fdA/360.0*(double)OptPointsPerCircle+0.5);
384 if (nPoints<2) nPoints=2;
385 Polygon aPoly(nPoints);
386 for (i=0; i<nPoints; i++) {
387 fAng=3.14159265359/180.0 * ( fA1 + fdA/(double)(nPoints-1)*(double)i );
388 rTransform.Transform(
389 rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),0),
390 aPoly[i]
393 pVirDev->DrawPolyLine(aPoly);
394 if (rE.fThickness!=0) {
395 Polygon aPoly2(nPoints);
396 for (i=0; i<nPoints; i++) {
397 fAng=3.14159265359/180.0 * ( fA1 + fdA/(double)(nPoints-1)*(double)i );
398 rTransform.Transform(
399 rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),rE.fThickness),
400 aPoly2[i]
403 pVirDev->DrawPolyLine(aPoly2);
404 for (i=0; i<nPoints; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
410 void DXF2GDIMetaFile::DrawTraceEntity(const DXFTraceEntity & rE, const DXFTransform & rTransform)
412 if (SetLineAttribute(rE)) {
413 Polygon aPoly(4);
414 rTransform.Transform(rE.aP0,aPoly[0]);
415 rTransform.Transform(rE.aP1,aPoly[1]);
416 rTransform.Transform(rE.aP3,aPoly[2]);
417 rTransform.Transform(rE.aP2,aPoly[3]);
418 pVirDev->DrawPolygon(aPoly);
419 if (rE.fThickness!=0) {
420 USHORT i;
421 Polygon aPoly2(4);
422 DXFVector aVAdd(0,0,rE.fThickness);
423 rTransform.Transform(rE.aP0+aVAdd,aPoly2[0]);
424 rTransform.Transform(rE.aP1+aVAdd,aPoly2[1]);
425 rTransform.Transform(rE.aP3+aVAdd,aPoly2[2]);
426 rTransform.Transform(rE.aP2+aVAdd,aPoly2[3]);
427 pVirDev->DrawPolygon(aPoly2);
428 for (i=0; i<4; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
434 void DXF2GDIMetaFile::DrawSolidEntity(const DXFSolidEntity & rE, const DXFTransform & rTransform)
436 if (SetAreaAttribute(rE)) {
437 USHORT nN;
438 if (rE.aP2==rE.aP3) nN=3; else nN=4;
439 Polygon aPoly(nN);
440 rTransform.Transform(rE.aP0,aPoly[0]);
441 rTransform.Transform(rE.aP1,aPoly[1]);
442 rTransform.Transform(rE.aP3,aPoly[2]);
443 if (nN>3) rTransform.Transform(rE.aP2,aPoly[3]);
444 pVirDev->DrawPolygon(aPoly);
445 if (rE.fThickness!=0) {
446 Polygon aPoly2(nN);
447 DXFVector aVAdd(0,0,rE.fThickness);
448 rTransform.Transform(rE.aP0+aVAdd,aPoly2[0]);
449 rTransform.Transform(rE.aP1+aVAdd,aPoly2[1]);
450 rTransform.Transform(rE.aP3+aVAdd,aPoly2[2]);
451 if (nN>3) rTransform.Transform(rE.aP2+aVAdd,aPoly2[3]);
452 pVirDev->DrawPolygon(aPoly2);
453 if (SetLineAttribute(rE)) {
454 USHORT i;
455 for (i=0; i<nN; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
462 void DXF2GDIMetaFile::DrawTextEntity(const DXFTextEntity & rE, const DXFTransform & rTransform)
464 DXFVector aV;
465 Point aPt;
466 double fA;
467 USHORT nHeight;
468 short nAng;
469 ByteString aStr( rE.sText );
470 DXFTransform aT( DXFTransform(rE.fXScale,rE.fHeight,1.0,rE.fRotAngle,rE.aP0), rTransform );
471 aT.TransDir(DXFVector(0,1,0),aV);
472 nHeight=(USHORT)(aV.Abs()+0.5);
473 fA=aT.CalcRotAngle();
474 nAng=(short)(fA*10.0+0.5);
475 aT.TransDir(DXFVector(1,0,0),aV);
476 if ( SetFontAttribute( rE,nAng, nHeight, aV. Abs() ) )
478 String aUString( aStr, pDXF->getTextEncoding() );
479 aT.Transform( DXFVector( 0, 0, 0 ), aPt );
480 pVirDev->DrawText( aPt, aUString );
485 void DXF2GDIMetaFile::DrawInsertEntity(const DXFInsertEntity & rE, const DXFTransform & rTransform)
487 const DXFBlock * pB;
488 pB=pDXF->aBlocks.Search(rE.sName);
489 if (pB!=NULL) {
490 DXFTransform aDXFTransform1(1.0,1.0,1.0,DXFVector(0.0,0.0,0.0)-pB->aBasePoint);
491 DXFTransform aDXFTransform2(rE.fXScale,rE.fYScale,rE.fZScale,rE.fRotAngle,rE.aP0);
492 DXFTransform aT(
493 DXFTransform( aDXFTransform1, aDXFTransform2 ),
494 rTransform
496 long nSavedBlockColor, nSavedParentLayerColor;
497 DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo;
498 nSavedBlockColor=nBlockColor;
499 nSavedParentLayerColor=nParentLayerColor;
500 aSavedBlockDXFLineInfo=aBlockDXFLineInfo;
501 aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo;
502 nBlockColor=GetEntityColor(rE);
503 aBlockDXFLineInfo=GetEntityDXFLineInfo(rE);
504 if (rE.sLayer[0]!='0' || rE.sLayer[1]!=0) {
505 DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.sLayer);
506 if (pLayer!=NULL) {
507 nParentLayerColor=pLayer->nColor;
508 aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType);
511 DrawEntities(*pB,aT,FALSE);
512 aBlockDXFLineInfo=aSavedBlockDXFLineInfo;
513 aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo;
514 nBlockColor=nSavedBlockColor;
515 nParentLayerColor=nSavedParentLayerColor;
520 void DXF2GDIMetaFile::DrawAttribEntity(const DXFAttribEntity & rE, const DXFTransform & rTransform)
522 if ((rE.nAttrFlags&1)==0) {
523 DXFVector aV;
524 Point aPt;
525 double fA;
526 USHORT nHeight;
527 short nAng;
528 ByteString aStr( rE.sText );
529 DXFTransform aT( DXFTransform( rE.fXScale, rE.fHeight, 1.0, rE.fRotAngle, rE.aP0 ), rTransform );
530 aT.TransDir(DXFVector(0,1,0),aV);
531 nHeight=(USHORT)(aV.Abs()+0.5);
532 fA=aT.CalcRotAngle();
533 nAng=(short)(fA*10.0+0.5);
534 aT.TransDir(DXFVector(1,0,0),aV);
535 if (SetFontAttribute(rE,nAng,nHeight,aV.Abs()))
537 String aUString( aStr, pDXF->getTextEncoding() );
538 aT.Transform( DXFVector( 0, 0, 0 ), aPt );
539 pVirDev->DrawText( aPt, aUString );
545 void DXF2GDIMetaFile::DrawPolyLineEntity(const DXFPolyLineEntity & rE, const DXFTransform & rTransform)
547 USHORT i,nPolySize;
548 double fW;
549 const DXFBasicEntity * pBE;
551 nPolySize=0;
552 pBE=rE.pSucc;
553 while (pBE!=NULL && pBE->eType==DXF_VERTEX) {
554 nPolySize++;
555 pBE=pBE->pSucc;
557 if (nPolySize<2) return;
558 Polygon aPoly(nPolySize);
559 fW=0.0;
560 pBE=rE.pSucc;
561 for (i=0; i<nPolySize; i++) {
562 rTransform.Transform(((DXFVertexEntity*)pBE)->aP0,aPoly[i]);
563 if (i+1<nPolySize || (rE.nFlags&1)!=0) {
564 if (((DXFVertexEntity*)pBE)->fSWidth>=0.0) fW+=((DXFVertexEntity*)pBE)->fSWidth;
565 else fW+=rE.fSWidth;
566 if (((DXFVertexEntity*)pBE)->fEWidth>=0.0) fW+=((DXFVertexEntity*)pBE)->fEWidth;
567 else fW+=rE.fEWidth;
569 pBE=pBE->pSucc;
571 fW/=2.0;
572 if ((rE.nFlags&1)!=0) fW/=(double)nPolySize;
573 else fW/=(double)(nPolySize-1);
574 if (SetLineAttribute(rE,rTransform.TransLineWidth(fW))) {
575 if ((rE.nFlags&1)!=0) pVirDev->DrawPolygon(aPoly);
576 else pVirDev->DrawPolyLine(aPoly);
577 if (rE.fThickness!=0) {
578 Polygon aPoly2(nPolySize);
579 pBE=rE.pSucc;
580 for (i=0; i<nPolySize; i++) {
581 rTransform.Transform(
582 (((DXFVertexEntity*)pBE)->aP0)+DXFVector(0,0,rE.fThickness),
583 aPoly2[i]
585 pBE=pBE->pSucc;
587 if ((rE.nFlags&1)!=0) pVirDev->DrawPolygon(aPoly2);
588 else pVirDev->DrawPolyLine(aPoly2);
589 for (i=0; i<nPolySize; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
594 void DXF2GDIMetaFile::DrawLWPolyLineEntity(const DXFLWPolyLineEntity & rE, const DXFTransform & rTransform )
596 sal_Int32 i, nPolySize = rE.nCount;
597 if ( nPolySize && rE.pP )
599 Polygon aPoly( (sal_uInt16)nPolySize);
600 for ( i = 0; i < nPolySize; i++ )
602 rTransform.Transform( rE.pP[ (sal_uInt16)i ], aPoly[ (sal_uInt16)i ] );
604 double fW = rE.fConstantWidth;
605 if ( SetLineAttribute( rE, rTransform.TransLineWidth( fW ) ) )
607 if ( ( rE.nFlags & 1 ) != 0 )
608 pVirDev->DrawPolygon( aPoly );
609 else
610 pVirDev->DrawPolyLine( aPoly );
611 // ####
612 //pVirDev->DrawPolyLine( aPoly, aDXFLineInfo );
617 void DXF2GDIMetaFile::DrawHatchEntity(const DXFHatchEntity & rE, const DXFTransform & rTransform )
619 if ( rE.nBoundaryPathCount )
621 SetAreaAttribute( rE );
622 sal_Int32 j = 0;
623 PolyPolygon aPolyPoly;
624 for ( j = 0; j < rE.nBoundaryPathCount; j++ )
626 DXFPointArray aPtAry;
627 const DXFBoundaryPathData& rPathData = rE.pBoundaryPathData[ j ];
628 if ( rPathData.bIsPolyLine )
630 sal_Int32 i;
631 for( i = 0; i < rPathData.nPointCount; i++ )
633 Point aPt;
634 rTransform.Transform( rPathData.pP[ i ], aPt );
635 aPtAry.push_back( aPt );
638 else
640 sal_uInt32 i;
641 for ( i = 0; i < rPathData.aEdges.size(); i++ )
643 const DXFEdgeType* pEdge = rPathData.aEdges[ i ];
644 switch( pEdge->nEdgeType )
646 case 1 :
648 Point aPt;
649 rTransform.Transform( ((DXFEdgeTypeLine*)pEdge)->aStartPoint, aPt );
650 aPtAry.push_back( aPt );
651 rTransform.Transform( ((DXFEdgeTypeLine*)pEdge)->aEndPoint, aPt );
652 aPtAry.push_back( aPt );
654 break;
655 case 2 :
658 double frx,fry,fA1,fdA,fAng;
659 USHORT nPoints,i;
660 DXFVector aC;
661 Point aPS,aPE;
662 fA1=((DXFEdgeTypeCircularArc*)pEdge)->fStartAngle;
663 fdA=((DXFEdgeTypeCircularArc*)pEdge)->fEndAngle - fA1;
664 while ( fdA >= 360.0 )
665 fdA -= 360.0;
666 while ( fdA <= 0 )
667 fdA += 360.0;
668 rTransform.Transform(((DXFEdgeTypeCircularArc*)pEdge)->aCenter, aC);
669 if ( fdA > 5.0 && rTransform.TransCircleToEllipse(((DXFEdgeTypeCircularArc*)pEdge)->fRadius,frx,fry ) == TRUE )
671 DXFVector aVS(cos(fA1/180.0*3.14159265359),sin(fA1/180.0*3.14159265359),0.0);
672 aVS*=((DXFEdgeTypeCircularArc*)pEdge)->fRadius;
673 aVS+=((DXFEdgeTypeCircularArc*)pEdge)->aCenter;
674 DXFVector aVE(cos((fA1+fdA)/180.0*3.14159265359),sin((fA1+fdA)/180.0*3.14159265359),0.0);
675 aVE*=((DXFEdgeTypeCircularArc*)pEdge)->fRadius;
676 aVE+=((DXFEdgeTypeCircularArc*)pEdge)->aCenter;
677 if ( rTransform.Mirror() == TRUE )
679 rTransform.Transform(aVS,aPS);
680 rTransform.Transform(aVE,aPE);
682 else
684 rTransform.Transform(aVS,aPE);
685 rTransform.Transform(aVE,aPS);
687 pVirDev->DrawArc(
688 Rectangle((long)(aC.fx-frx+0.5),(long)(aC.fy-fry+0.5),
689 (long)(aC.fx+frx+0.5),(long)(aC.fy+fry+0.5)),
690 aPS,aPE
695 break;
696 case 3 :
697 case 4 :
698 break;
702 sal_uInt16 i, nSize = (sal_uInt16)aPtAry.size();
703 if ( nSize )
705 Polygon aPoly( nSize );
706 for ( i = 0; i < nSize; i++ )
707 aPoly[ i ] = aPtAry[ i ];
708 aPolyPoly.Insert( aPoly, POLYPOLY_APPEND );
711 if ( aPolyPoly.Count() )
712 pVirDev->DrawPolyPolygon( aPolyPoly );
716 void DXF2GDIMetaFile::Draw3DFaceEntity(const DXF3DFaceEntity & rE, const DXFTransform & rTransform)
718 USHORT nN,i;
719 if (SetLineAttribute(rE)) {
720 if (rE.aP2==rE.aP3) nN=3; else nN=4;
721 Polygon aPoly(nN);
722 rTransform.Transform(rE.aP0,aPoly[0]);
723 rTransform.Transform(rE.aP1,aPoly[1]);
724 rTransform.Transform(rE.aP2,aPoly[2]);
725 if (nN>3) rTransform.Transform(rE.aP3,aPoly[3]);
726 if ((rE.nIEFlags&0x0f)==0) pVirDev->DrawPolygon(aPoly);
727 else {
728 for (i=0; i<nN; i++) {
729 if ( (rE.nIEFlags & (1<<i)) == 0 ) {
730 pVirDev->DrawLine(aPoly[i],aPoly[(i+1)%nN]);
738 void DXF2GDIMetaFile::DrawDimensionEntity(const DXFDimensionEntity & rE, const DXFTransform & rTransform)
740 const DXFBlock * pB;
741 pB=pDXF->aBlocks.Search(rE.sPseudoBlock);
742 if (pB!=NULL) {
743 DXFTransform aT(
744 DXFTransform(1.0,1.0,1.0,DXFVector(0.0,0.0,0.0)-pB->aBasePoint),
745 rTransform
747 long nSavedBlockColor, nSavedParentLayerColor;
748 DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo;
749 nSavedBlockColor=nBlockColor;
750 nSavedParentLayerColor=nParentLayerColor;
751 aSavedBlockDXFLineInfo=aBlockDXFLineInfo;
752 aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo;
753 nBlockColor=GetEntityColor(rE);
754 aBlockDXFLineInfo=GetEntityDXFLineInfo(rE);
755 if (rE.sLayer[0]!='0' || rE.sLayer[1]!=0) {
756 DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.sLayer);
757 if (pLayer!=NULL) {
758 nParentLayerColor=pLayer->nColor;
759 aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType);
762 DrawEntities(*pB,aT,FALSE);
763 aBlockDXFLineInfo=aSavedBlockDXFLineInfo;
764 aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo;
765 nBlockColor=nSavedBlockColor;
766 nParentLayerColor=nSavedParentLayerColor;
771 void DXF2GDIMetaFile::DrawEntities(const DXFEntities & rEntities,
772 const DXFTransform & rTransform,
773 BOOL bTopEntities)
775 ULONG nCount=0;
776 DXFTransform aET;
777 const DXFTransform * pT;
779 const DXFBasicEntity * pE=rEntities.pFirst;
781 while (pE!=NULL && bStatus==TRUE) {
782 if (pE->nSpace==0) {
783 if (pE->aExtrusion.fz==1.0) {
784 pT=&rTransform;
786 else {
787 aET=DXFTransform(DXFTransform(pE->aExtrusion),rTransform);
788 pT=&aET;
790 switch (pE->eType) {
791 case DXF_LINE:
792 DrawLineEntity((DXFLineEntity&)*pE,*pT);
793 break;
794 case DXF_POINT:
795 DrawPointEntity((DXFPointEntity&)*pE,*pT);
796 break;
797 case DXF_CIRCLE:
798 DrawCircleEntity((DXFCircleEntity&)*pE,*pT);
799 break;
800 case DXF_ARC:
801 DrawArcEntity((DXFArcEntity&)*pE,*pT);
802 break;
803 case DXF_TRACE:
804 DrawTraceEntity((DXFTraceEntity&)*pE,*pT);
805 break;
806 case DXF_SOLID:
807 DrawSolidEntity((DXFSolidEntity&)*pE,*pT);
808 break;
809 case DXF_TEXT:
810 DrawTextEntity((DXFTextEntity&)*pE,*pT);
811 break;
812 case DXF_INSERT:
813 DrawInsertEntity((DXFInsertEntity&)*pE,*pT);
814 break;
815 case DXF_ATTRIB:
816 DrawAttribEntity((DXFAttribEntity&)*pE,*pT);
817 break;
818 case DXF_POLYLINE:
819 DrawPolyLineEntity((DXFPolyLineEntity&)*pE,*pT);
820 break;
821 case DXF_LWPOLYLINE :
822 DrawLWPolyLineEntity((DXFLWPolyLineEntity&)*pE, *pT);
823 break;
824 case DXF_HATCH :
825 DrawHatchEntity((DXFHatchEntity&)*pE, *pT);
826 break;
827 case DXF_3DFACE:
828 Draw3DFaceEntity((DXF3DFaceEntity&)*pE,*pT);
829 break;
830 case DXF_DIMENSION:
831 DrawDimensionEntity((DXFDimensionEntity&)*pE,*pT);
832 break;
833 default:
834 break; // four other values not handled -Wall
837 pE=pE->pSucc;
838 nCount++;
839 if (bTopEntities) MayCallback(nCount);
844 DXF2GDIMetaFile::DXF2GDIMetaFile()
849 DXF2GDIMetaFile::~DXF2GDIMetaFile()
854 BOOL DXF2GDIMetaFile::Convert(const DXFRepresentation & rDXF, GDIMetaFile & rMTF, USHORT nminpercent, USHORT nmaxpercent)
856 double fWidth,fHeight,fScale;
857 DXFTransform aTransform;
858 Size aPrefSize;
859 const DXFLayer * pLayer;
860 const DXFVPort * pVPort;
862 pVirDev = new VirtualDevice;
863 pDXF = &rDXF;
864 bStatus = TRUE;
866 OptPointsPerCircle=50;
868 nMinPercent=(ULONG)nminpercent;
869 nMaxPercent=(ULONG)nmaxpercent;
870 nLastPercent=nMinPercent;
871 nMainEntitiesCount=CountEntities(pDXF->aEntities);
873 nBlockColor=7;
874 aBlockDXFLineInfo.eStyle = LINE_SOLID;
875 aBlockDXFLineInfo.fWidth = 0;
876 aBlockDXFLineInfo.nDashCount = 0;
877 aBlockDXFLineInfo.fDashLen = 0;
878 aBlockDXFLineInfo.nDotCount = 0;
879 aBlockDXFLineInfo.fDotLen = 0;
880 aBlockDXFLineInfo.fDistance = 0;
882 pLayer=pDXF->aTables.SearchLayer("0");
883 if (pLayer!=NULL) {
884 nParentLayerColor=pLayer->nColor & 0xff;
885 aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType);
887 else {
888 nParentLayerColor=7;
889 aParentLayerDXFLineInfo.eStyle = LINE_SOLID;
890 aParentLayerDXFLineInfo.fWidth = 0;
891 aParentLayerDXFLineInfo.nDashCount = 0;
892 aParentLayerDXFLineInfo.fDashLen = 0;
893 aParentLayerDXFLineInfo.nDotCount = 0;
894 aParentLayerDXFLineInfo.fDotLen = 0;
895 aParentLayerDXFLineInfo.fDistance = 0;
898 pVirDev->EnableOutput(FALSE);
899 rMTF.Record(pVirDev);
901 aActLineColor = pVirDev->GetLineColor();
902 aActFillColor = pVirDev->GetFillColor();
903 aActFont = pVirDev->GetFont();
905 pVPort=pDXF->aTables.SearchVPort("*ACTIVE");
906 if (pVPort!=NULL) {
907 if (pVPort->aDirection.fx==0 && pVPort->aDirection.fy==0)
908 pVPort=NULL;
911 if (pVPort==NULL) {
912 if (pDXF->aBoundingBox.bEmpty==TRUE)
913 bStatus=FALSE;
914 else {
915 fWidth=pDXF->aBoundingBox.fMaxX-pDXF->aBoundingBox.fMinX;
916 fHeight=pDXF->aBoundingBox.fMaxY-pDXF->aBoundingBox.fMinY;
917 if (fWidth<=0 || fHeight<=0) {
918 bStatus=FALSE;
919 fScale = 0; // -Wall added this...
921 else {
922 // if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) {
923 if (fWidth>fHeight)
924 fScale=10000.0/fWidth;
925 else
926 fScale=10000.0/fHeight;
927 // }
928 // else
929 // fScale=1.0;
930 aTransform=DXFTransform(fScale,-fScale,fScale,
931 DXFVector(-pDXF->aBoundingBox.fMinX*fScale,
932 pDXF->aBoundingBox.fMaxY*fScale,
933 -pDXF->aBoundingBox.fMinZ*fScale));
935 aPrefSize.Width() =(long)(fWidth*fScale+1.5);
936 aPrefSize.Height()=(long)(fHeight*fScale+1.5);
939 else {
940 fHeight=pVPort->fHeight;
941 fWidth=fHeight*pVPort->fAspectRatio;
942 // if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) {
943 if (fWidth>fHeight)
944 fScale=10000.0/fWidth;
945 else
946 fScale=10000.0/fHeight;
947 // }
948 // else
949 // fScale=1.0;
950 aTransform=DXFTransform(
951 DXFTransform(pVPort->aDirection,pVPort->aTarget),
952 DXFTransform(
953 DXFTransform(1.0,-1.0,1.0,DXFVector(fWidth/2-pVPort->fCenterX,fHeight/2+pVPort->fCenterY,0)),
954 DXFTransform(fScale,fScale,fScale,DXFVector(0,0,0))
957 aPrefSize.Width() =(long)(fWidth*fScale+1.5);
958 aPrefSize.Height()=(long)(fHeight*fScale+1.5);
961 if (bStatus==TRUE)
962 DrawEntities(pDXF->aEntities,aTransform,TRUE);
964 rMTF.Stop();
966 if ( bStatus==TRUE )
968 rMTF.SetPrefSize( aPrefSize );
970 // MapMode einfach, falls Grafik dann nicht zu klein wird (<0,5cm),
971 // auf 1/100-mm (1/10-mm) setzen
972 if( ( aPrefSize.Width() < 500 ) && ( aPrefSize.Height() < 500 ) )
973 rMTF.SetPrefMapMode( MapMode( MAP_10TH_MM ) );
974 else
975 rMTF.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
978 delete pVirDev;
979 return bStatus;