1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26
27 #include <string.h>
28 #include <vcl/gdimtf.hxx>
29 #include <vcl/virdev.hxx>
30 #include <tools/poly.hxx>
31 #include "dxf2mtf.hxx"
32
33 #include <math.h>
34
35
CountEntities(const DXFEntities & rEntities)36 sal_uLong DXF2GDIMetaFile::CountEntities(const DXFEntities & rEntities)
37 {
38 const DXFBasicEntity * pBE;
39 sal_uLong nRes;
40
41 nRes=0;
42 for (pBE=rEntities.pFirst; pBE!=NULL; pBE=pBE->pSucc) nRes++;
43 return nRes;
44 }
45
46
MayCallback(sal_uLong)47 void DXF2GDIMetaFile::MayCallback(sal_uLong /*nMainEntitiesProcessed*/)
48 {
49 // sal_uLong nPercent;
50 /*
51 if (pCallback!=NULL && nMainEntitiesCount!=0) {
52 nPercent=nMinPercent+(nMaxPercent-nMinPercent)*nMainEntitiesProcessed/nMainEntitiesCount;
53 if (nPercent>=nLastPercent+4) {
54 if (((*pCallback)(pCallerData,(sal_uInt16)nPercent))==sal_True) bStatus=sal_False;
55 nLastPercent=nPercent;
56 }
57 }
58 */
59 }
60
ConvertColor(sal_uInt8 nColor)61 Color DXF2GDIMetaFile::ConvertColor(sal_uInt8 nColor)
62 {
63 return Color(
64 pDXF->aPalette.GetRed( nColor ),
65 pDXF->aPalette.GetGreen( nColor ),
66 pDXF->aPalette.GetBlue( nColor ) );
67 }
68
GetEntityColor(const DXFBasicEntity & rE)69 long DXF2GDIMetaFile::GetEntityColor(const DXFBasicEntity & rE)
70 {
71 long nColor;
72 const DXFLayer * pLayer;
73
74 nColor=rE.nColor;
75 if (nColor==256) {
76 if (rE.sLayer[0]=='0' && rE.sLayer[1]==0) nColor=nParentLayerColor;
77 else {
78 pLayer=pDXF->aTables.SearchLayer(rE.sLayer);
79 if (pLayer!=NULL) nColor=pLayer->nColor;
80 else nColor=nParentLayerColor;
81 }
82 }
83 else if (nColor==0) nColor=nBlockColor;
84 return nColor;
85 }
86
LTypeToDXFLineInfo(const char * sLineType)87 DXFLineInfo DXF2GDIMetaFile::LTypeToDXFLineInfo(const char * sLineType)
88 {
89 const DXFLType * pLT;
90 DXFLineInfo aDXFLineInfo;
91
92 pLT=pDXF->aTables.SearchLType(sLineType);
93 if (pLT==NULL || pLT->nDashCount == 0) {
94 aDXFLineInfo.eStyle = LINE_SOLID;
95 }
96 else {
97 sal_Int32 i;
98 double x;
99 aDXFLineInfo.eStyle = LINE_DASH;
100 for (i=0; i < (pLT->nDashCount); i++) {
101 x = pLT->fDash[i] * pDXF->getGlobalLineTypeScale();
102 // ####
103 // x = (sal_Int32) rTransform.TransLineWidth( pLT->fDash[i] * pDXF->getGlobalLineTypeScale() );
104 if ( x >= 0.0 ) {
105 if ( aDXFLineInfo.nDotCount == 0 ) {
106 aDXFLineInfo.nDotCount ++;
107 aDXFLineInfo.fDotLen = x;
108 }
109 else if ( aDXFLineInfo.fDotLen == x ) {
110 aDXFLineInfo.nDotCount ++;
111 }
112 else if ( aDXFLineInfo.nDashCount == 0 ) {
113 aDXFLineInfo.nDashCount ++;
114 aDXFLineInfo.fDashLen = x;
115 }
116 else if ( aDXFLineInfo.fDashLen == x ) {
117 aDXFLineInfo.nDashCount ++;
118 }
119 else {
120 // It is impossible to be converted.
121 }
122 }
123 else {
124 if ( aDXFLineInfo.fDistance == 0 ) {
125 aDXFLineInfo.fDistance = -1 * x;
126 }
127 else {
128 // It is impossible to be converted.
129 }
130 }
131
132 }
133 }
134
135 #if 0
136 if (aDXFLineInfo.DashCount > 0 && aDXFLineInfo.DashLen == 0.0)
137 aDXFLineInfo.DashLen ( 1 );
138 if (aDXFLineInfo.DotCount > 0 && aDXFLineInfo.DotLen() == 0.0)
139 aDXFLineInfo.SetDotLen( 1 );
140 if (aDXFLineInfo.GetDashCount > 0 || aDXFLineInfo.GetDotCount > 0)
141 if (aDXFLineInfo.GetDistance() == 0)
142 aDXFLineInfo.SetDistance( 1 );
143 #endif
144
145 return aDXFLineInfo;
146 }
147
GetEntityDXFLineInfo(const DXFBasicEntity & rE)148 DXFLineInfo DXF2GDIMetaFile::GetEntityDXFLineInfo(const DXFBasicEntity & rE)
149 {
150 DXFLineInfo aDXFLineInfo;
151 const DXFLayer * pLayer;
152
153 aDXFLineInfo.eStyle = LINE_SOLID;
154 aDXFLineInfo.fWidth = 0;
155 aDXFLineInfo.nDashCount = 0;
156 aDXFLineInfo.fDashLen = 0;
157 aDXFLineInfo.nDotCount = 0;
158 aDXFLineInfo.fDotLen = 0;
159 aDXFLineInfo.fDistance = 0;
160
161 if (strcmp(rE.sLineType,"BYLAYER")==0) {
162 if (rE.sLayer[0]=='0' && rE.sLayer[1]==0) aDXFLineInfo=aParentLayerDXFLineInfo;
163 else {
164 pLayer=pDXF->aTables.SearchLayer(rE.sLayer);
165 if (pLayer!=NULL) aDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType);
166 else aDXFLineInfo=aParentLayerDXFLineInfo;
167 }
168 }
169 else if (strcmp(rE.sLineType,"BYBLOCK")==0) {
170 aDXFLineInfo=aBlockDXFLineInfo;
171 }
172 else aDXFLineInfo=LTypeToDXFLineInfo(rE.sLineType);
173 return aDXFLineInfo;
174 }
175
176
SetLineAttribute(const DXFBasicEntity & rE,sal_uLong)177 sal_Bool DXF2GDIMetaFile::SetLineAttribute(const DXFBasicEntity & rE, sal_uLong /*nWidth*/)
178 {
179 long nColor;
180 Color aColor;
181
182 nColor=GetEntityColor(rE);
183 if (nColor<0) return sal_False;
184 aColor=ConvertColor((sal_uInt8)nColor);
185
186 if (aActLineColor!=aColor) {
187 pVirDev->SetLineColor( aActLineColor = aColor );
188 }
189
190 if (aActFillColor!=Color( COL_TRANSPARENT )) {
191 pVirDev->SetFillColor(aActFillColor = Color( COL_TRANSPARENT ));
192 }
193 return sal_True;
194 }
195
196
SetAreaAttribute(const DXFBasicEntity & rE)197 sal_Bool DXF2GDIMetaFile::SetAreaAttribute(const DXFBasicEntity & rE)
198 {
199 long nColor;
200 Color aColor;
201
202 nColor=GetEntityColor(rE);
203 if (nColor<0) return sal_False;
204 aColor=ConvertColor((sal_uInt8)nColor);
205
206 if (aActLineColor!=aColor) {
207 pVirDev->SetLineColor( aActLineColor = aColor );
208 }
209
210 if ( aActFillColor == Color( COL_TRANSPARENT ) || aActFillColor != aColor) {
211 pVirDev->SetFillColor( aActFillColor = aColor );
212 }
213 return sal_True;
214 }
215
216
SetFontAttribute(const DXFBasicEntity & rE,short nAngle,sal_uInt16 nHeight,double)217 sal_Bool DXF2GDIMetaFile::SetFontAttribute(const DXFBasicEntity & rE, short nAngle, sal_uInt16 nHeight, double /*fWidthScale*/)
218 {
219 long nColor;
220 Color aColor;
221 Font aFont;
222
223 nAngle=-nAngle;
224 while (nAngle>3600) nAngle-=3600;
225 while (nAngle<0) nAngle+=3600;
226
227 nColor=GetEntityColor(rE);
228 if (nColor<0) return sal_False;
229 aColor=ConvertColor((sal_uInt8)nColor);
230
231 aFont.SetColor(aColor);
232 aFont.SetTransparent(sal_True);
233 aFont.SetFamily(FAMILY_SWISS);
234 aFont.SetSize(Size(0,nHeight));
235 aFont.SetAlign(ALIGN_BASELINE);
236 aFont.SetOrientation(nAngle);
237 if (aActFont!=aFont) {
238 aActFont=aFont;
239 pVirDev->SetFont(aActFont);
240 }
241
242 return sal_True;
243 }
244
245
DrawLineEntity(const DXFLineEntity & rE,const DXFTransform & rTransform)246 void DXF2GDIMetaFile::DrawLineEntity(const DXFLineEntity & rE, const DXFTransform & rTransform)
247 {
248 if (SetLineAttribute(rE)) {
249 Point aP0,aP1;
250 rTransform.Transform(rE.aP0,aP0);
251 rTransform.Transform(rE.aP1,aP1);
252
253 DXFLineInfo aDXFLineInfo;
254 aDXFLineInfo=GetEntityDXFLineInfo(rE);
255 LineInfo aLineInfo;
256 aLineInfo = rTransform.Transform(aDXFLineInfo);
257
258 #if 0
259 printf("%f\n", rTransform.TransLineWidth(1000.0));
260
261 // LINE_NONE = 0, LINE_SOLID = 1, LINE_DASH = 2, LineStyle_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
262 aLineInfo.SetStyle( LINE_DASH );
263 aLineInfo.SetWidth( 300 );
264 aLineInfo.SetDashCount( 2 );
265 aLineInfo.SetDashLen( 100 );
266 aLineInfo.SetDotCount( 1 );
267 aLineInfo.SetDotLen( 0 );
268 aLineInfo.SetDistance( 500 );
269 #endif
270
271 pVirDev->DrawLine(aP0,aP1,aLineInfo);
272 if (rE.fThickness!=0) {
273 Point aP2,aP3;
274 rTransform.Transform(rE.aP0+DXFVector(0,0,rE.fThickness),aP2);
275 rTransform.Transform(rE.aP1+DXFVector(0,0,rE.fThickness),aP3);
276 pVirDev->DrawLine(aP2,aP3);
277 pVirDev->DrawLine(aP0,aP2);
278 pVirDev->DrawLine(aP1,aP3);
279 }
280 }
281 }
282
283
DrawPointEntity(const DXFPointEntity & rE,const DXFTransform & rTransform)284 void DXF2GDIMetaFile::DrawPointEntity(const DXFPointEntity & rE, const DXFTransform & rTransform)
285 {
286
287 if (SetLineAttribute(rE)) {
288 Point aP0;
289 rTransform.Transform(rE.aP0,aP0);
290 if (rE.fThickness==0) pVirDev->DrawPixel(aP0);
291 else {
292 Point aP1;
293 rTransform.Transform(rE.aP0+DXFVector(0,0,rE.fThickness),aP1);
294 pVirDev->DrawLine(aP0,aP1);
295 }
296 }
297 }
298
299
DrawCircleEntity(const DXFCircleEntity & rE,const DXFTransform & rTransform)300 void DXF2GDIMetaFile::DrawCircleEntity(const DXFCircleEntity & rE, const DXFTransform & rTransform)
301 {
302 double frx,fry,fAng;
303 sal_uInt16 nPoints,i;
304 DXFVector aC;
305
306 if (SetLineAttribute(rE)==sal_False) return;
307 rTransform.Transform(rE.aP0,aC);
308 if (rE.fThickness==0 && rTransform.TransCircleToEllipse(rE.fRadius,frx,fry)==sal_True) {
309 pVirDev->DrawEllipse(
310 Rectangle((long)(aC.fx-frx+0.5),(long)(aC.fy-fry+0.5),
311 (long)(aC.fx+frx+0.5),(long)(aC.fy+fry+0.5)));
312 }
313 else {
314 nPoints=OptPointsPerCircle;
315 Polygon aPoly(nPoints);
316 for (i=0; i<nPoints; i++) {
317 fAng=2*3.14159265359/(double)(nPoints-1)*(double)i;
318 rTransform.Transform(
319 rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),0),
320 aPoly[i]
321 );
322 }
323 pVirDev->DrawPolyLine(aPoly);
324 if (rE.fThickness!=0) {
325 Polygon aPoly2(nPoints);
326 for (i=0; i<nPoints; i++) {
327 fAng=2*3.14159265359/(double)(nPoints-1)*(double)i;
328 rTransform.Transform(
329 rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),rE.fThickness),
330 aPoly2[i]
331 );
332
333 }
334 pVirDev->DrawPolyLine(aPoly2);
335 for (i=0; i<nPoints-1; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
336 }
337 }
338 }
339
340
DrawArcEntity(const DXFArcEntity & rE,const DXFTransform & rTransform)341 void DXF2GDIMetaFile::DrawArcEntity(const DXFArcEntity & rE, const DXFTransform & rTransform)
342 {
343 double frx,fry,fA1,fdA,fAng;
344 sal_uInt16 nPoints,i;
345 DXFVector aC;
346 Point aPS,aPE;
347
348 if (SetLineAttribute(rE)==sal_False) return;
349 fA1=rE.fStart;
350 fdA=rE.fEnd-fA1;
351 while (fdA>=360.0) fdA-=360.0;
352 while (fdA<=0) fdA+=360.0;
353 rTransform.Transform(rE.aP0,aC);
354 if (rE.fThickness==0 && fdA>5.0 && rTransform.TransCircleToEllipse(rE.fRadius,frx,fry)==sal_True) {
355 DXFVector aVS(cos(fA1/180.0*3.14159265359),sin(fA1/180.0*3.14159265359),0.0);
356 aVS*=rE.fRadius;
357 aVS+=rE.aP0;
358 DXFVector aVE(cos((fA1+fdA)/180.0*3.14159265359),sin((fA1+fdA)/180.0*3.14159265359),0.0);
359 aVE*=rE.fRadius;
360 aVE+=rE.aP0;
361 if (rTransform.Mirror()==sal_True) {
362 rTransform.Transform(aVS,aPS);
363 rTransform.Transform(aVE,aPE);
364 }
365 else {
366 rTransform.Transform(aVS,aPE);
367 rTransform.Transform(aVE,aPS);
368 }
369 pVirDev->DrawArc(
370 Rectangle((long)(aC.fx-frx+0.5),(long)(aC.fy-fry+0.5),
371 (long)(aC.fx+frx+0.5),(long)(aC.fy+fry+0.5)),
372 aPS,aPE
373 );
374 }
375 else {
376 nPoints=(sal_uInt16)(fdA/360.0*(double)OptPointsPerCircle+0.5);
377 if (nPoints<2) nPoints=2;
378 Polygon aPoly(nPoints);
379 for (i=0; i<nPoints; i++) {
380 fAng=3.14159265359/180.0 * ( fA1 + fdA/(double)(nPoints-1)*(double)i );
381 rTransform.Transform(
382 rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),0),
383 aPoly[i]
384 );
385 }
386 pVirDev->DrawPolyLine(aPoly);
387 if (rE.fThickness!=0) {
388 Polygon aPoly2(nPoints);
389 for (i=0; i<nPoints; i++) {
390 fAng=3.14159265359/180.0 * ( fA1 + fdA/(double)(nPoints-1)*(double)i );
391 rTransform.Transform(
392 rE.aP0+DXFVector(rE.fRadius*cos(fAng),rE.fRadius*sin(fAng),rE.fThickness),
393 aPoly2[i]
394 );
395 }
396 pVirDev->DrawPolyLine(aPoly2);
397 for (i=0; i<nPoints; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
398 }
399 }
400 }
401
402
DrawTraceEntity(const DXFTraceEntity & rE,const DXFTransform & rTransform)403 void DXF2GDIMetaFile::DrawTraceEntity(const DXFTraceEntity & rE, const DXFTransform & rTransform)
404 {
405 if (SetLineAttribute(rE)) {
406 Polygon aPoly(4);
407 rTransform.Transform(rE.aP0,aPoly[0]);
408 rTransform.Transform(rE.aP1,aPoly[1]);
409 rTransform.Transform(rE.aP3,aPoly[2]);
410 rTransform.Transform(rE.aP2,aPoly[3]);
411 pVirDev->DrawPolygon(aPoly);
412 if (rE.fThickness!=0) {
413 sal_uInt16 i;
414 Polygon aPoly2(4);
415 DXFVector aVAdd(0,0,rE.fThickness);
416 rTransform.Transform(rE.aP0+aVAdd,aPoly2[0]);
417 rTransform.Transform(rE.aP1+aVAdd,aPoly2[1]);
418 rTransform.Transform(rE.aP3+aVAdd,aPoly2[2]);
419 rTransform.Transform(rE.aP2+aVAdd,aPoly2[3]);
420 pVirDev->DrawPolygon(aPoly2);
421 for (i=0; i<4; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
422 }
423 }
424 }
425
426
DrawSolidEntity(const DXFSolidEntity & rE,const DXFTransform & rTransform)427 void DXF2GDIMetaFile::DrawSolidEntity(const DXFSolidEntity & rE, const DXFTransform & rTransform)
428 {
429 if (SetAreaAttribute(rE)) {
430 sal_uInt16 nN;
431 if (rE.aP2==rE.aP3) nN=3; else nN=4;
432 Polygon aPoly(nN);
433 rTransform.Transform(rE.aP0,aPoly[0]);
434 rTransform.Transform(rE.aP1,aPoly[1]);
435 rTransform.Transform(rE.aP3,aPoly[2]);
436 if (nN>3) rTransform.Transform(rE.aP2,aPoly[3]);
437 pVirDev->DrawPolygon(aPoly);
438 if (rE.fThickness!=0) {
439 Polygon aPoly2(nN);
440 DXFVector aVAdd(0,0,rE.fThickness);
441 rTransform.Transform(rE.aP0+aVAdd,aPoly2[0]);
442 rTransform.Transform(rE.aP1+aVAdd,aPoly2[1]);
443 rTransform.Transform(rE.aP3+aVAdd,aPoly2[2]);
444 if (nN>3) rTransform.Transform(rE.aP2+aVAdd,aPoly2[3]);
445 pVirDev->DrawPolygon(aPoly2);
446 if (SetLineAttribute(rE)) {
447 sal_uInt16 i;
448 for (i=0; i<nN; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
449 }
450 }
451 }
452 }
453
454
DrawTextEntity(const DXFTextEntity & rE,const DXFTransform & rTransform)455 void DXF2GDIMetaFile::DrawTextEntity(const DXFTextEntity & rE, const DXFTransform & rTransform)
456 {
457 DXFVector aV;
458 Point aPt;
459 double fA;
460 sal_uInt16 nHeight;
461 short nAng;
462 ByteString aStr( rE.sText );
463 DXFTransform aT( DXFTransform(rE.fXScale,rE.fHeight,1.0,rE.fRotAngle,rE.aP0), rTransform );
464 aT.TransDir(DXFVector(0,1,0),aV);
465 nHeight=(sal_uInt16)(aV.Abs()+0.5);
466 fA=aT.CalcRotAngle();
467 nAng=(short)(fA*10.0+0.5);
468 aT.TransDir(DXFVector(1,0,0),aV);
469 if ( SetFontAttribute( rE,nAng, nHeight, aV. Abs() ) )
470 {
471 String aUString( aStr, pDXF->getTextEncoding() );
472 aT.Transform( DXFVector( 0, 0, 0 ), aPt );
473 pVirDev->DrawText( aPt, aUString );
474 }
475 }
476
477
DrawInsertEntity(const DXFInsertEntity & rE,const DXFTransform & rTransform)478 void DXF2GDIMetaFile::DrawInsertEntity(const DXFInsertEntity & rE, const DXFTransform & rTransform)
479 {
480 const DXFBlock * pB;
481 pB=pDXF->aBlocks.Search(rE.sName);
482 if (pB!=NULL) {
483 DXFTransform aDXFTransform1(1.0,1.0,1.0,DXFVector(0.0,0.0,0.0)-pB->aBasePoint);
484 DXFTransform aDXFTransform2(rE.fXScale,rE.fYScale,rE.fZScale,rE.fRotAngle,rE.aP0);
485 DXFTransform aT(
486 DXFTransform( aDXFTransform1, aDXFTransform2 ),
487 rTransform
488 );
489 long nSavedBlockColor, nSavedParentLayerColor;
490 DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo;
491 nSavedBlockColor=nBlockColor;
492 nSavedParentLayerColor=nParentLayerColor;
493 aSavedBlockDXFLineInfo=aBlockDXFLineInfo;
494 aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo;
495 nBlockColor=GetEntityColor(rE);
496 aBlockDXFLineInfo=GetEntityDXFLineInfo(rE);
497 if (rE.sLayer[0]!='0' || rE.sLayer[1]!=0) {
498 DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.sLayer);
499 if (pLayer!=NULL) {
500 nParentLayerColor=pLayer->nColor;
501 aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType);
502 }
503 }
504 DrawEntities(*pB,aT,sal_False);
505 aBlockDXFLineInfo=aSavedBlockDXFLineInfo;
506 aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo;
507 nBlockColor=nSavedBlockColor;
508 nParentLayerColor=nSavedParentLayerColor;
509 }
510 }
511
512
DrawAttribEntity(const DXFAttribEntity & rE,const DXFTransform & rTransform)513 void DXF2GDIMetaFile::DrawAttribEntity(const DXFAttribEntity & rE, const DXFTransform & rTransform)
514 {
515 if ((rE.nAttrFlags&1)==0) {
516 DXFVector aV;
517 Point aPt;
518 double fA;
519 sal_uInt16 nHeight;
520 short nAng;
521 ByteString aStr( rE.sText );
522 DXFTransform aT( DXFTransform( rE.fXScale, rE.fHeight, 1.0, rE.fRotAngle, rE.aP0 ), rTransform );
523 aT.TransDir(DXFVector(0,1,0),aV);
524 nHeight=(sal_uInt16)(aV.Abs()+0.5);
525 fA=aT.CalcRotAngle();
526 nAng=(short)(fA*10.0+0.5);
527 aT.TransDir(DXFVector(1,0,0),aV);
528 if (SetFontAttribute(rE,nAng,nHeight,aV.Abs()))
529 {
530 String aUString( aStr, pDXF->getTextEncoding() );
531 aT.Transform( DXFVector( 0, 0, 0 ), aPt );
532 pVirDev->DrawText( aPt, aUString );
533 }
534 }
535 }
536
537
DrawPolyLineEntity(const DXFPolyLineEntity & rE,const DXFTransform & rTransform)538 void DXF2GDIMetaFile::DrawPolyLineEntity(const DXFPolyLineEntity & rE, const DXFTransform & rTransform)
539 {
540 sal_uInt16 i,nPolySize;
541 double fW;
542 const DXFBasicEntity * pBE;
543
544 nPolySize=0;
545 pBE=rE.pSucc;
546 while (pBE!=NULL && pBE->eType==DXF_VERTEX) {
547 nPolySize++;
548 pBE=pBE->pSucc;
549 }
550 if (nPolySize<2) return;
551 Polygon aPoly(nPolySize);
552 fW=0.0;
553 pBE=rE.pSucc;
554 for (i=0; i<nPolySize; i++) {
555 rTransform.Transform(((DXFVertexEntity*)pBE)->aP0,aPoly[i]);
556 if (i+1<nPolySize || (rE.nFlags&1)!=0) {
557 if (((DXFVertexEntity*)pBE)->fSWidth>=0.0) fW+=((DXFVertexEntity*)pBE)->fSWidth;
558 else fW+=rE.fSWidth;
559 if (((DXFVertexEntity*)pBE)->fEWidth>=0.0) fW+=((DXFVertexEntity*)pBE)->fEWidth;
560 else fW+=rE.fEWidth;
561 }
562 pBE=pBE->pSucc;
563 }
564 fW/=2.0;
565 if ((rE.nFlags&1)!=0) fW/=(double)nPolySize;
566 else fW/=(double)(nPolySize-1);
567 if (SetLineAttribute(rE,rTransform.TransLineWidth(fW))) {
568 if ((rE.nFlags&1)!=0) pVirDev->DrawPolygon(aPoly);
569 else pVirDev->DrawPolyLine(aPoly);
570 if (rE.fThickness!=0) {
571 Polygon aPoly2(nPolySize);
572 pBE=rE.pSucc;
573 for (i=0; i<nPolySize; i++) {
574 rTransform.Transform(
575 (((DXFVertexEntity*)pBE)->aP0)+DXFVector(0,0,rE.fThickness),
576 aPoly2[i]
577 );
578 pBE=pBE->pSucc;
579 }
580 if ((rE.nFlags&1)!=0) pVirDev->DrawPolygon(aPoly2);
581 else pVirDev->DrawPolyLine(aPoly2);
582 for (i=0; i<nPolySize; i++) pVirDev->DrawLine(aPoly[i],aPoly2[i]);
583 }
584 }
585 }
586
DrawLWPolyLineEntity(const DXFLWPolyLineEntity & rE,const DXFTransform & rTransform)587 void DXF2GDIMetaFile::DrawLWPolyLineEntity(const DXFLWPolyLineEntity & rE, const DXFTransform & rTransform )
588 {
589 sal_Int32 i, nPolySize = rE.nCount;
590 if ( nPolySize && rE.pP )
591 {
592 Polygon aPoly( (sal_uInt16)nPolySize);
593 for ( i = 0; i < nPolySize; i++ )
594 {
595 rTransform.Transform( rE.pP[ (sal_uInt16)i ], aPoly[ (sal_uInt16)i ] );
596 }
597 double fW = rE.fConstantWidth;
598 if ( SetLineAttribute( rE, rTransform.TransLineWidth( fW ) ) )
599 {
600 if ( ( rE.nFlags & 1 ) != 0 )
601 pVirDev->DrawPolygon( aPoly );
602 else
603 pVirDev->DrawPolyLine( aPoly );
604 // ####
605 //pVirDev->DrawPolyLine( aPoly, aDXFLineInfo );
606 }
607 }
608 }
609
DrawHatchEntity(const DXFHatchEntity & rE,const DXFTransform & rTransform)610 void DXF2GDIMetaFile::DrawHatchEntity(const DXFHatchEntity & rE, const DXFTransform & rTransform )
611 {
612 if ( rE.nBoundaryPathCount )
613 {
614 SetAreaAttribute( rE );
615 sal_Int32 j = 0;
616 PolyPolygon aPolyPoly;
617 for ( j = 0; j < rE.nBoundaryPathCount; j++ )
618 {
619 DXFPointArray aPtAry;
620 const DXFBoundaryPathData& rPathData = rE.pBoundaryPathData[ j ];
621 if ( rPathData.bIsPolyLine )
622 {
623 sal_Int32 i;
624 for( i = 0; i < rPathData.nPointCount; i++ )
625 {
626 Point aPt;
627 rTransform.Transform( rPathData.pP[ i ], aPt );
628 aPtAry.push_back( aPt );
629 }
630 }
631 else
632 {
633 sal_uInt32 i;
634 for ( i = 0; i < rPathData.aEdges.size(); i++ )
635 {
636 const DXFEdgeType* pEdge = rPathData.aEdges[ i ];
637 switch( pEdge->nEdgeType )
638 {
639 case 1 :
640 {
641 Point aPt;
642 rTransform.Transform( ((DXFEdgeTypeLine*)pEdge)->aStartPoint, aPt );
643 aPtAry.push_back( aPt );
644 rTransform.Transform( ((DXFEdgeTypeLine*)pEdge)->aEndPoint, aPt );
645 aPtAry.push_back( aPt );
646 }
647 break;
648 case 2 :
649 {
650 /*
651 double frx,fry,fA1,fdA,fAng;
652 sal_uInt16 nPoints,i;
653 DXFVector aC;
654 Point aPS,aPE;
655 fA1=((DXFEdgeTypeCircularArc*)pEdge)->fStartAngle;
656 fdA=((DXFEdgeTypeCircularArc*)pEdge)->fEndAngle - fA1;
657 while ( fdA >= 360.0 )
658 fdA -= 360.0;
659 while ( fdA <= 0 )
660 fdA += 360.0;
661 rTransform.Transform(((DXFEdgeTypeCircularArc*)pEdge)->aCenter, aC);
662 if ( fdA > 5.0 && rTransform.TransCircleToEllipse(((DXFEdgeTypeCircularArc*)pEdge)->fRadius,frx,fry ) == sal_True )
663 {
664 DXFVector aVS(cos(fA1/180.0*3.14159265359),sin(fA1/180.0*3.14159265359),0.0);
665 aVS*=((DXFEdgeTypeCircularArc*)pEdge)->fRadius;
666 aVS+=((DXFEdgeTypeCircularArc*)pEdge)->aCenter;
667 DXFVector aVE(cos((fA1+fdA)/180.0*3.14159265359),sin((fA1+fdA)/180.0*3.14159265359),0.0);
668 aVE*=((DXFEdgeTypeCircularArc*)pEdge)->fRadius;
669 aVE+=((DXFEdgeTypeCircularArc*)pEdge)->aCenter;
670 if ( rTransform.Mirror() == sal_True )
671 {
672 rTransform.Transform(aVS,aPS);
673 rTransform.Transform(aVE,aPE);
674 }
675 else
676 {
677 rTransform.Transform(aVS,aPE);
678 rTransform.Transform(aVE,aPS);
679 }
680 pVirDev->DrawArc(
681 Rectangle((long)(aC.fx-frx+0.5),(long)(aC.fy-fry+0.5),
682 (long)(aC.fx+frx+0.5),(long)(aC.fy+fry+0.5)),
683 aPS,aPE
684 );
685 }
686 */
687 }
688 break;
689 case 3 :
690 case 4 :
691 break;
692 }
693 }
694 }
695 sal_uInt16 i, nSize = (sal_uInt16)aPtAry.size();
696 if ( nSize )
697 {
698 Polygon aPoly( nSize );
699 for ( i = 0; i < nSize; i++ )
700 aPoly[ i ] = aPtAry[ i ];
701 aPolyPoly.Insert( aPoly, POLYPOLY_APPEND );
702 }
703 }
704 if ( aPolyPoly.Count() )
705 pVirDev->DrawPolyPolygon( aPolyPoly );
706 }
707 }
708
Draw3DFaceEntity(const DXF3DFaceEntity & rE,const DXFTransform & rTransform)709 void DXF2GDIMetaFile::Draw3DFaceEntity(const DXF3DFaceEntity & rE, const DXFTransform & rTransform)
710 {
711 sal_uInt16 nN,i;
712 if (SetLineAttribute(rE)) {
713 if (rE.aP2==rE.aP3) nN=3; else nN=4;
714 Polygon aPoly(nN);
715 rTransform.Transform(rE.aP0,aPoly[0]);
716 rTransform.Transform(rE.aP1,aPoly[1]);
717 rTransform.Transform(rE.aP2,aPoly[2]);
718 if (nN>3) rTransform.Transform(rE.aP3,aPoly[3]);
719 if ((rE.nIEFlags&0x0f)==0) pVirDev->DrawPolygon(aPoly);
720 else {
721 for (i=0; i<nN; i++) {
722 if ( (rE.nIEFlags & (1<<i)) == 0 ) {
723 pVirDev->DrawLine(aPoly[i],aPoly[(i+1)%nN]);
724 }
725 }
726 }
727 }
728 }
729
730
DrawDimensionEntity(const DXFDimensionEntity & rE,const DXFTransform & rTransform)731 void DXF2GDIMetaFile::DrawDimensionEntity(const DXFDimensionEntity & rE, const DXFTransform & rTransform)
732 {
733 const DXFBlock * pB;
734 pB=pDXF->aBlocks.Search(rE.sPseudoBlock);
735 if (pB!=NULL) {
736 DXFTransform aT(
737 DXFTransform(1.0,1.0,1.0,DXFVector(0.0,0.0,0.0)-pB->aBasePoint),
738 rTransform
739 );
740 long nSavedBlockColor, nSavedParentLayerColor;
741 DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo;
742 nSavedBlockColor=nBlockColor;
743 nSavedParentLayerColor=nParentLayerColor;
744 aSavedBlockDXFLineInfo=aBlockDXFLineInfo;
745 aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo;
746 nBlockColor=GetEntityColor(rE);
747 aBlockDXFLineInfo=GetEntityDXFLineInfo(rE);
748 if (rE.sLayer[0]!='0' || rE.sLayer[1]!=0) {
749 DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.sLayer);
750 if (pLayer!=NULL) {
751 nParentLayerColor=pLayer->nColor;
752 aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType);
753 }
754 }
755 DrawEntities(*pB,aT,sal_False);
756 aBlockDXFLineInfo=aSavedBlockDXFLineInfo;
757 aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo;
758 nBlockColor=nSavedBlockColor;
759 nParentLayerColor=nSavedParentLayerColor;
760 }
761 }
762
763
DrawEntities(const DXFEntities & rEntities,const DXFTransform & rTransform,sal_Bool bTopEntities)764 void DXF2GDIMetaFile::DrawEntities(const DXFEntities & rEntities,
765 const DXFTransform & rTransform,
766 sal_Bool bTopEntities)
767 {
768 sal_uLong nCount=0;
769 DXFTransform aET;
770 const DXFTransform * pT;
771
772 const DXFBasicEntity * pE=rEntities.pFirst;
773
774 while (pE!=NULL && bStatus==sal_True) {
775 if (pE->nSpace==0) {
776 if (pE->aExtrusion.fz==1.0) {
777 pT=&rTransform;
778 }
779 else {
780 aET=DXFTransform(DXFTransform(pE->aExtrusion),rTransform);
781 pT=&aET;
782 }
783 switch (pE->eType) {
784 case DXF_LINE:
785 DrawLineEntity((DXFLineEntity&)*pE,*pT);
786 break;
787 case DXF_POINT:
788 DrawPointEntity((DXFPointEntity&)*pE,*pT);
789 break;
790 case DXF_CIRCLE:
791 DrawCircleEntity((DXFCircleEntity&)*pE,*pT);
792 break;
793 case DXF_ARC:
794 DrawArcEntity((DXFArcEntity&)*pE,*pT);
795 break;
796 case DXF_TRACE:
797 DrawTraceEntity((DXFTraceEntity&)*pE,*pT);
798 break;
799 case DXF_SOLID:
800 DrawSolidEntity((DXFSolidEntity&)*pE,*pT);
801 break;
802 case DXF_TEXT:
803 DrawTextEntity((DXFTextEntity&)*pE,*pT);
804 break;
805 case DXF_INSERT:
806 DrawInsertEntity((DXFInsertEntity&)*pE,*pT);
807 break;
808 case DXF_ATTRIB:
809 DrawAttribEntity((DXFAttribEntity&)*pE,*pT);
810 break;
811 case DXF_POLYLINE:
812 DrawPolyLineEntity((DXFPolyLineEntity&)*pE,*pT);
813 break;
814 case DXF_LWPOLYLINE :
815 DrawLWPolyLineEntity((DXFLWPolyLineEntity&)*pE, *pT);
816 break;
817 case DXF_HATCH :
818 DrawHatchEntity((DXFHatchEntity&)*pE, *pT);
819 break;
820 case DXF_3DFACE:
821 Draw3DFaceEntity((DXF3DFaceEntity&)*pE,*pT);
822 break;
823 case DXF_DIMENSION:
824 DrawDimensionEntity((DXFDimensionEntity&)*pE,*pT);
825 break;
826 default:
827 break; // four other values not handled -Wall
828 }
829 }
830 pE=pE->pSucc;
831 nCount++;
832 if (bTopEntities) MayCallback(nCount);
833 }
834 }
835
836
DXF2GDIMetaFile()837 DXF2GDIMetaFile::DXF2GDIMetaFile()
838 {
839 }
840
841
~DXF2GDIMetaFile()842 DXF2GDIMetaFile::~DXF2GDIMetaFile()
843 {
844 }
845
846
Convert(const DXFRepresentation & rDXF,GDIMetaFile & rMTF,sal_uInt16 nminpercent,sal_uInt16 nmaxpercent)847 sal_Bool DXF2GDIMetaFile::Convert(const DXFRepresentation & rDXF, GDIMetaFile & rMTF, sal_uInt16 nminpercent, sal_uInt16 nmaxpercent)
848 {
849 double fWidth,fHeight,fScale;
850 DXFTransform aTransform;
851 Size aPrefSize;
852 const DXFLayer * pLayer;
853 const DXFVPort * pVPort;
854
855 pVirDev = new VirtualDevice;
856 pDXF = &rDXF;
857 bStatus = sal_True;
858
859 OptPointsPerCircle=50;
860
861 nMinPercent=(sal_uLong)nminpercent;
862 nMaxPercent=(sal_uLong)nmaxpercent;
863 nLastPercent=nMinPercent;
864 nMainEntitiesCount=CountEntities(pDXF->aEntities);
865
866 nBlockColor=7;
867 aBlockDXFLineInfo.eStyle = LINE_SOLID;
868 aBlockDXFLineInfo.fWidth = 0;
869 aBlockDXFLineInfo.nDashCount = 0;
870 aBlockDXFLineInfo.fDashLen = 0;
871 aBlockDXFLineInfo.nDotCount = 0;
872 aBlockDXFLineInfo.fDotLen = 0;
873 aBlockDXFLineInfo.fDistance = 0;
874
875 pLayer=pDXF->aTables.SearchLayer("0");
876 if (pLayer!=NULL) {
877 nParentLayerColor=pLayer->nColor & 0xff;
878 aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType);
879 }
880 else {
881 nParentLayerColor=7;
882 aParentLayerDXFLineInfo.eStyle = LINE_SOLID;
883 aParentLayerDXFLineInfo.fWidth = 0;
884 aParentLayerDXFLineInfo.nDashCount = 0;
885 aParentLayerDXFLineInfo.fDashLen = 0;
886 aParentLayerDXFLineInfo.nDotCount = 0;
887 aParentLayerDXFLineInfo.fDotLen = 0;
888 aParentLayerDXFLineInfo.fDistance = 0;
889 }
890
891 pVirDev->EnableOutput(sal_False);
892 rMTF.Record(pVirDev);
893
894 aActLineColor = pVirDev->GetLineColor();
895 aActFillColor = pVirDev->GetFillColor();
896 aActFont = pVirDev->GetFont();
897
898 pVPort=pDXF->aTables.SearchVPort("*ACTIVE");
899 if (pVPort!=NULL) {
900 if (pVPort->aDirection.fx==0 && pVPort->aDirection.fy==0)
901 pVPort=NULL;
902 }
903
904 if (pVPort==NULL) {
905 if (pDXF->aBoundingBox.bEmpty==sal_True)
906 bStatus=sal_False;
907 else {
908 fWidth=pDXF->aBoundingBox.fMaxX-pDXF->aBoundingBox.fMinX;
909 fHeight=pDXF->aBoundingBox.fMaxY-pDXF->aBoundingBox.fMinY;
910 if (fWidth<=0 || fHeight<=0) {
911 bStatus=sal_False;
912 fScale = 0; // -Wall added this...
913 }
914 else {
915 // if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) {
916 if (fWidth>fHeight)
917 fScale=10000.0/fWidth;
918 else
919 fScale=10000.0/fHeight;
920 // }
921 // else
922 // fScale=1.0;
923 aTransform=DXFTransform(fScale,-fScale,fScale,
924 DXFVector(-pDXF->aBoundingBox.fMinX*fScale,
925 pDXF->aBoundingBox.fMaxY*fScale,
926 -pDXF->aBoundingBox.fMinZ*fScale));
927 }
928 aPrefSize.Width() =(long)(fWidth*fScale+1.5);
929 aPrefSize.Height()=(long)(fHeight*fScale+1.5);
930 }
931 }
932 else {
933 fHeight=pVPort->fHeight;
934 fWidth=fHeight*pVPort->fAspectRatio;
935 // if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) {
936 if (fWidth>fHeight)
937 fScale=10000.0/fWidth;
938 else
939 fScale=10000.0/fHeight;
940 // }
941 // else
942 // fScale=1.0;
943 aTransform=DXFTransform(
944 DXFTransform(pVPort->aDirection,pVPort->aTarget),
945 DXFTransform(
946 DXFTransform(1.0,-1.0,1.0,DXFVector(fWidth/2-pVPort->fCenterX,fHeight/2+pVPort->fCenterY,0)),
947 DXFTransform(fScale,fScale,fScale,DXFVector(0,0,0))
948 )
949 );
950 aPrefSize.Width() =(long)(fWidth*fScale+1.5);
951 aPrefSize.Height()=(long)(fHeight*fScale+1.5);
952 }
953
954 if (bStatus==sal_True)
955 DrawEntities(pDXF->aEntities,aTransform,sal_True);
956
957 rMTF.Stop();
958
959 if ( bStatus==sal_True )
960 {
961 rMTF.SetPrefSize( aPrefSize );
962
963 // MapMode einfach, falls Grafik dann nicht zu klein wird (<0,5cm),
964 // auf 1/100-mm (1/10-mm) setzen
965 if( ( aPrefSize.Width() < 500 ) && ( aPrefSize.Height() < 500 ) )
966 rMTF.SetPrefMapMode( MapMode( MAP_10TH_MM ) );
967 else
968 rMTF.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
969 }
970
971 delete pVirDev;
972 return bStatus;
973 }
974
975
976
977