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