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