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