xref: /AOO41X/main/filter/source/graphicfilter/idxf/dxf2mtf.cxx (revision 9e0fc027f109ec4ffcb6033aeec742a099701108)
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