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