1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <unotools/configmgr.hxx>
22 #include <vcl/gdimtf.hxx>
23 #include <vcl/metaact.hxx>
24 #include <vcl/virdev.hxx>
25 #include <tools/poly.hxx>
26 #include "dxf2mtf.hxx"
31 sal_uInt64
DXF2GDIMetaFile::CountEntities(const DXFEntities
& rEntities
)
33 const DXFBasicEntity
* pBE
;
37 for (pBE
=rEntities
.pFirst
; pBE
!=nullptr; pBE
=pBE
->pSucc
) nRes
++;
41 Color
DXF2GDIMetaFile::ConvertColor(sal_uInt8 nColor
)
44 pDXF
->aPalette
.GetRed( nColor
),
45 pDXF
->aPalette
.GetGreen( nColor
),
46 pDXF
->aPalette
.GetBlue( nColor
) );
49 tools::Long
DXF2GDIMetaFile::GetEntityColor(const DXFBasicEntity
& rE
)
55 if (rE
.m_sLayer
.getLength() < 2) {
56 nColor
=nParentLayerColor
;
58 const DXFLayer
* pLayer
=pDXF
->aTables
.SearchLayer(rE
.m_sLayer
);
59 if (pLayer
!=nullptr) nColor
=pLayer
->nColor
;
60 else nColor
=nParentLayerColor
;
63 else if (nColor
==0) nColor
=nBlockColor
;
67 DXFLineInfo
DXF2GDIMetaFile::LTypeToDXFLineInfo(OString
const& rLineType
)
70 DXFLineInfo aDXFLineInfo
;
72 pLT
= pDXF
->aTables
.SearchLType(rLineType
);
73 if (pLT
==nullptr || pLT
->nDashCount
== 0) {
74 aDXFLineInfo
.eStyle
= LineStyle::Solid
;
77 aDXFLineInfo
.eStyle
= LineStyle::Dash
;
78 for (tools::Long i
=0; i
< (pLT
->nDashCount
); i
++) {
79 const double x
= pLT
->fDash
[i
] * pDXF
->getGlobalLineTypeScale();
81 if ( aDXFLineInfo
.nDotCount
== 0 ) {
82 aDXFLineInfo
.nDotCount
++;
83 aDXFLineInfo
.fDotLen
= x
;
85 else if ( aDXFLineInfo
.fDotLen
== x
) {
86 aDXFLineInfo
.nDotCount
++;
88 else if ( aDXFLineInfo
.nDashCount
== 0 ) {
89 aDXFLineInfo
.nDashCount
++;
90 aDXFLineInfo
.fDashLen
= x
;
92 else if ( aDXFLineInfo
.fDashLen
== x
) {
93 aDXFLineInfo
.nDashCount
++;
96 // It is impossible to be converted.
100 if ( aDXFLineInfo
.fDistance
== 0 ) {
101 aDXFLineInfo
.fDistance
= -1 * x
;
104 // It is impossible to be converted.
114 DXFLineInfo
DXF2GDIMetaFile::GetEntityDXFLineInfo(const DXFBasicEntity
& rE
)
116 DXFLineInfo aDXFLineInfo
;
118 aDXFLineInfo
.eStyle
= LineStyle::Solid
;
119 aDXFLineInfo
.nDashCount
= 0;
120 aDXFLineInfo
.fDashLen
= 0;
121 aDXFLineInfo
.nDotCount
= 0;
122 aDXFLineInfo
.fDotLen
= 0;
123 aDXFLineInfo
.fDistance
= 0;
125 if (rE
.m_sLineType
== "BYLAYER") {
126 if (rE
.m_sLayer
.getLength() < 2) {
127 aDXFLineInfo
=aParentLayerDXFLineInfo
;
129 const DXFLayer
* pLayer
=pDXF
->aTables
.SearchLayer(rE
.m_sLayer
);
130 if (pLayer
!=nullptr) {
131 aDXFLineInfo
= LTypeToDXFLineInfo(pLayer
->m_sLineType
);
133 else aDXFLineInfo
=aParentLayerDXFLineInfo
;
136 else if (rE
.m_sLineType
== "BYBLOCK") {
137 aDXFLineInfo
=aBlockDXFLineInfo
;
140 aDXFLineInfo
= LTypeToDXFLineInfo(rE
.m_sLineType
);
146 bool DXF2GDIMetaFile::SetLineAttribute(const DXFBasicEntity
& rE
)
151 nColor
=GetEntityColor(rE
);
152 if (nColor
<0) return false;
153 aColor
=ConvertColor(static_cast<sal_uInt8
>(nColor
));
155 if (aActLineColor
!=aColor
) {
156 aActLineColor
= aColor
;
157 pVirDev
->SetLineColor( aActLineColor
);
160 if (aActFillColor
!=COL_TRANSPARENT
) {
161 aActFillColor
= COL_TRANSPARENT
;
162 pVirDev
->SetFillColor(aActFillColor
);
168 bool DXF2GDIMetaFile::SetAreaAttribute(const DXFBasicEntity
& rE
)
173 nColor
=GetEntityColor(rE
);
174 if (nColor
<0) return false;
175 aColor
=ConvertColor(static_cast<sal_uInt8
>(nColor
));
177 if (aActLineColor
!=aColor
) {
178 aActLineColor
= aColor
;
179 pVirDev
->SetLineColor( aActLineColor
);
182 if ( aActFillColor
== COL_TRANSPARENT
|| aActFillColor
!= aColor
) {
183 aActFillColor
= aColor
;
184 pVirDev
->SetFillColor( aActFillColor
);
190 bool DXF2GDIMetaFile::SetFontAttribute(const DXFBasicEntity
& rE
, short nAngle
, sal_uInt16 nHeight
)
197 while (nAngle
>=3600) nAngle
-=3600;
198 while (nAngle
<0) nAngle
+=3600;
200 nColor
=GetEntityColor(rE
);
201 if (nColor
<0) return false;
202 aColor
=ConvertColor(static_cast<sal_uInt8
>(nColor
));
204 aFont
.SetColor(aColor
);
205 aFont
.SetTransparent(true);
206 aFont
.SetFamily(FAMILY_SWISS
);
207 aFont
.SetFontSize(Size(0,nHeight
));
208 aFont
.SetAlignment(ALIGN_BASELINE
);
209 aFont
.SetOrientation(Degree10(nAngle
));
210 if (aActFont
!=aFont
) {
212 pVirDev
->SetFont(aActFont
);
219 void DXF2GDIMetaFile::DrawLineEntity(const DXFLineEntity
& rE
, const DXFTransform
& rTransform
)
221 if (!SetLineAttribute(rE
))
225 rTransform
.Transform(rE
.aP0
,aP0
);
226 rTransform
.Transform(rE
.aP1
,aP1
);
228 DXFLineInfo aDXFLineInfo
=GetEntityDXFLineInfo(rE
);
230 aLineInfo
= rTransform
.Transform(aDXFLineInfo
);
232 pVirDev
->DrawLine(aP0
,aP1
,aLineInfo
);
233 if (rE
.fThickness
!=0) {
235 rTransform
.Transform(rE
.aP0
+DXFVector(0,0,rE
.fThickness
),aP2
);
236 rTransform
.Transform(rE
.aP1
+DXFVector(0,0,rE
.fThickness
),aP3
);
244 void DXF2GDIMetaFile::DrawPointEntity(const DXFPointEntity
& rE
, const DXFTransform
& rTransform
)
247 if (SetLineAttribute(rE
)) {
249 rTransform
.Transform(rE
.aP0
,aP0
);
250 if (rE
.fThickness
==0) pVirDev
->DrawPixel(aP0
);
253 rTransform
.Transform(rE
.aP0
+DXFVector(0,0,rE
.fThickness
),aP1
);
260 void DXF2GDIMetaFile::DrawCircleEntity(const DXFCircleEntity
& rE
, const DXFTransform
& rTransform
)
263 sal_uInt16 nPoints
,i
;
266 if (!SetLineAttribute(rE
)) return;
267 rTransform
.Transform(rE
.aP0
,aC
);
268 if (rE
.fThickness
==0 && rTransform
.TransCircleToEllipse(rE
.fRadius
,frx
,fry
)) {
269 pVirDev
->DrawEllipse(
270 tools::Rectangle(static_cast<tools::Long
>(aC
.fx
-frx
+0.5),static_cast<tools::Long
>(aC
.fy
-fry
+0.5),
271 static_cast<tools::Long
>(aC
.fx
+frx
+0.5),static_cast<tools::Long
>(aC
.fy
+fry
+0.5)));
275 nPoints
=OptPointsPerCircle
;
276 tools::Polygon
aPoly(nPoints
);
277 for (i
=0; i
<nPoints
; i
++) {
278 fAng
=2*3.14159265359/static_cast<double>(nPoints
-1)*static_cast<double>(i
);
279 rTransform
.Transform(
280 rE
.aP0
+DXFVector(rE
.fRadius
*cos(fAng
),rE
.fRadius
*sin(fAng
),0),
284 pVirDev
->DrawPolyLine(aPoly
);
285 if (rE
.fThickness
!=0) {
286 tools::Polygon
aPoly2(nPoints
);
287 for (i
=0; i
<nPoints
; i
++) {
288 fAng
=2*3.14159265359/static_cast<double>(nPoints
-1)*static_cast<double>(i
);
289 rTransform
.Transform(
290 rE
.aP0
+DXFVector(rE
.fRadius
*cos(fAng
),rE
.fRadius
*sin(fAng
),rE
.fThickness
),
295 pVirDev
->DrawPolyLine(aPoly2
);
296 for (i
=0; i
<nPoints
-1; i
++) DrawLine(aPoly
[i
],aPoly2
[i
]);
301 void DXF2GDIMetaFile::DrawLine(const Point
& rA
, const Point
& rB
)
303 if (utl::ConfigManager::IsFuzzing())
305 GDIMetaFile
* pMetaFile
= pVirDev
->GetConnectMetaFile();
307 //use AddAction instead of OutputDevice::DrawLine so that we can explicitly share
308 //the aDefaultLineInfo between the MetaLineActions to reduce memory use
309 pMetaFile
->AddAction(new MetaLineAction(rA
, rB
, aDefaultLineInfo
));
312 void DXF2GDIMetaFile::DrawArcEntity(const DXFArcEntity
& rE
, const DXFTransform
& rTransform
)
315 sal_uInt16 nPoints
,i
;
318 if (!SetLineAttribute(rE
)) return;
319 double fA1
=rE
.fStart
;
320 double fdA
=rE
.fEnd
-fA1
;
321 fdA
= fmod(fdA
, 360.0);
322 if (fdA
<=0) fdA
+=360.0;
323 rTransform
.Transform(rE
.aP0
,aC
);
324 if (rE
.fThickness
==0 && fdA
>5.0 && rTransform
.TransCircleToEllipse(rE
.fRadius
,frx
,fry
)) {
325 DXFVector
aVS(cos(fA1
/180.0*3.14159265359),sin(fA1
/180.0*3.14159265359),0.0);
328 DXFVector
aVE(cos((fA1
+fdA
)/180.0*3.14159265359),sin((fA1
+fdA
)/180.0*3.14159265359),0.0);
332 if (rTransform
.Mirror()) {
333 rTransform
.Transform(aVS
,aPS
);
334 rTransform
.Transform(aVE
,aPE
);
337 rTransform
.Transform(aVS
,aPE
);
338 rTransform
.Transform(aVE
,aPS
);
341 tools::Rectangle(static_cast<tools::Long
>(aC
.fx
-frx
+0.5),static_cast<tools::Long
>(aC
.fy
-fry
+0.5),
342 static_cast<tools::Long
>(aC
.fx
+frx
+0.5),static_cast<tools::Long
>(aC
.fy
+fry
+0.5)),
348 nPoints
=static_cast<sal_uInt16
>(fdA
/360.0*static_cast<double>(OptPointsPerCircle
)+0.5);
349 if (nPoints
<2) nPoints
=2;
350 tools::Polygon
aPoly(nPoints
);
351 for (i
=0; i
<nPoints
; i
++) {
352 fAng
=3.14159265359/180.0 * ( fA1
+ fdA
/static_cast<double>(nPoints
-1)*static_cast<double>(i
) );
353 rTransform
.Transform(
354 rE
.aP0
+DXFVector(rE
.fRadius
*cos(fAng
),rE
.fRadius
*sin(fAng
),0),
358 pVirDev
->DrawPolyLine(aPoly
);
359 if (rE
.fThickness
!=0) {
360 tools::Polygon
aPoly2(nPoints
);
361 for (i
=0; i
<nPoints
; i
++) {
362 fAng
=3.14159265359/180.0 * ( fA1
+ fdA
/static_cast<double>(nPoints
-1)*static_cast<double>(i
) );
363 rTransform
.Transform(
364 rE
.aP0
+DXFVector(rE
.fRadius
*cos(fAng
),rE
.fRadius
*sin(fAng
),rE
.fThickness
),
368 pVirDev
->DrawPolyLine(aPoly2
);
369 for (i
=0; i
<nPoints
; i
++)
370 DrawLine(aPoly
[i
], aPoly2
[i
]);
375 void DXF2GDIMetaFile::DrawTraceEntity(const DXFTraceEntity
& rE
, const DXFTransform
& rTransform
)
377 if (!SetLineAttribute(rE
))
380 tools::Polygon
aPoly(4);
381 rTransform
.Transform(rE
.aP0
,aPoly
[0]);
382 rTransform
.Transform(rE
.aP1
,aPoly
[1]);
383 rTransform
.Transform(rE
.aP3
,aPoly
[2]);
384 rTransform
.Transform(rE
.aP2
,aPoly
[3]);
385 pVirDev
->DrawPolygon(aPoly
);
386 if (rE
.fThickness
!=0) {
388 tools::Polygon
aPoly2(4);
389 DXFVector
aVAdd(0,0,rE
.fThickness
);
390 rTransform
.Transform(rE
.aP0
+aVAdd
,aPoly2
[0]);
391 rTransform
.Transform(rE
.aP1
+aVAdd
,aPoly2
[1]);
392 rTransform
.Transform(rE
.aP3
+aVAdd
,aPoly2
[2]);
393 rTransform
.Transform(rE
.aP2
+aVAdd
,aPoly2
[3]);
394 pVirDev
->DrawPolygon(aPoly2
);
395 for (i
=0; i
<4; i
++) DrawLine(aPoly
[i
],aPoly2
[i
]);
400 void DXF2GDIMetaFile::DrawSolidEntity(const DXFSolidEntity
& rE
, const DXFTransform
& rTransform
)
402 if (!SetAreaAttribute(rE
))
406 if (rE
.aP2
==rE
.aP3
) nN
=3; else nN
=4;
407 tools::Polygon
aPoly(nN
);
408 rTransform
.Transform(rE
.aP0
,aPoly
[0]);
409 rTransform
.Transform(rE
.aP1
,aPoly
[1]);
410 rTransform
.Transform(rE
.aP3
,aPoly
[2]);
411 if (nN
>3) rTransform
.Transform(rE
.aP2
,aPoly
[3]);
412 pVirDev
->DrawPolygon(aPoly
);
413 if (rE
.fThickness
==0) return;
415 tools::Polygon
aPoly2(nN
);
416 DXFVector
aVAdd(0,0,rE
.fThickness
);
417 rTransform
.Transform(rE
.aP0
+aVAdd
,aPoly2
[0]);
418 rTransform
.Transform(rE
.aP1
+aVAdd
,aPoly2
[1]);
419 rTransform
.Transform(rE
.aP3
+aVAdd
,aPoly2
[2]);
420 if (nN
>3) rTransform
.Transform(rE
.aP2
+aVAdd
,aPoly2
[3]);
421 pVirDev
->DrawPolygon(aPoly2
);
422 if (SetLineAttribute(rE
)) {
424 for (i
=0; i
<nN
; i
++) DrawLine(aPoly
[i
],aPoly2
[i
]);
429 void DXF2GDIMetaFile::DrawTextEntity(const DXFTextEntity
& rE
, const DXFTransform
& rTransform
)
435 DXFTransform
aT( DXFTransform(rE
.fXScale
,rE
.fHeight
,1.0,rE
.fRotAngle
,rE
.aP0
), rTransform
);
436 aT
.TransDir(DXFVector(0,1,0),aV
);
437 nHeight
=static_cast<sal_uInt16
>(aV
.Abs()+0.5);
438 fA
=aT
.CalcRotAngle();
439 nAng
=static_cast<short>(fA
*10.0+0.5);
440 aT
.TransDir(DXFVector(1,0,0),aV
);
441 if ( SetFontAttribute( rE
,nAng
, nHeight
) )
443 OUString
const aUString(pDXF
->ToOUString(rE
.m_sText
));
445 aT
.Transform( DXFVector( 0, 0, 0 ), aPt
);
446 pVirDev
->DrawText( aPt
, aUString
);
451 void DXF2GDIMetaFile::DrawInsertEntity(const DXFInsertEntity
& rE
, const DXFTransform
& rTransform
)
454 pB
=pDXF
->aBlocks
.Search(rE
.m_sName
);
458 DXFTransform
aDXFTransform1(1.0,1.0,1.0,DXFVector(0.0,0.0,0.0)-pB
->aBasePoint
);
459 DXFTransform
aDXFTransform2(rE
.fXScale
,rE
.fYScale
,rE
.fZScale
,rE
.fRotAngle
,rE
.aP0
);
461 DXFTransform( aDXFTransform1
, aDXFTransform2
),
464 tools::Long nSavedBlockColor
, nSavedParentLayerColor
;
465 DXFLineInfo aSavedBlockDXFLineInfo
, aSavedParentLayerDXFLineInfo
;
466 nSavedBlockColor
=nBlockColor
;
467 nSavedParentLayerColor
=nParentLayerColor
;
468 aSavedBlockDXFLineInfo
=aBlockDXFLineInfo
;
469 aSavedParentLayerDXFLineInfo
=aParentLayerDXFLineInfo
;
470 nBlockColor
=GetEntityColor(rE
);
471 aBlockDXFLineInfo
=GetEntityDXFLineInfo(rE
);
472 if (rE
.m_sLayer
.getLength() > 1) {
473 DXFLayer
* pLayer
=pDXF
->aTables
.SearchLayer(rE
.m_sLayer
);
474 if (pLayer
!=nullptr) {
475 nParentLayerColor
=pLayer
->nColor
;
476 aParentLayerDXFLineInfo
= LTypeToDXFLineInfo(pLayer
->m_sLineType
);
479 DrawEntities(*pB
,aT
);
480 aBlockDXFLineInfo
=aSavedBlockDXFLineInfo
;
481 aParentLayerDXFLineInfo
=aSavedParentLayerDXFLineInfo
;
482 nBlockColor
=nSavedBlockColor
;
483 nParentLayerColor
=nSavedParentLayerColor
;
487 void DXF2GDIMetaFile::DrawAttribEntity(const DXFAttribEntity
& rE
, const DXFTransform
& rTransform
)
489 if ((rE
.nAttrFlags
&1)!=0)
496 DXFTransform
aT( DXFTransform( rE
.fXScale
, rE
.fHeight
, 1.0, rE
.fRotAngle
, rE
.aP0
), rTransform
);
497 aT
.TransDir(DXFVector(0,1,0),aV
);
498 nHeight
=static_cast<sal_uInt16
>(aV
.Abs()+0.5);
499 fA
=aT
.CalcRotAngle();
500 nAng
=static_cast<short>(fA
*10.0+0.5);
501 aT
.TransDir(DXFVector(1,0,0),aV
);
502 if (SetFontAttribute(rE
,nAng
,nHeight
))
504 OUString
const aUString(pDXF
->ToOUString(rE
.m_sText
));
506 aT
.Transform( DXFVector( 0, 0, 0 ), aPt
);
507 pVirDev
->DrawText( aPt
, aUString
);
512 void DXF2GDIMetaFile::DrawPolyLineEntity(const DXFPolyLineEntity
& rE
, const DXFTransform
& rTransform
)
514 sal_uInt16 i
,nPolySize
;
515 const DXFBasicEntity
* pBE
;
519 while (pBE
!=nullptr && pBE
->eType
==DXF_VERTEX
) {
525 tools::Polygon
aPoly(nPolySize
);
527 for (i
=0; i
<nPolySize
; i
++) {
528 rTransform
.Transform(static_cast<const DXFVertexEntity
*>(pBE
)->aP0
,aPoly
[i
]);
532 if (!SetLineAttribute(rE
))
535 if ((rE
.nFlags
&1)!=0) pVirDev
->DrawPolygon(aPoly
);
536 else pVirDev
->DrawPolyLine(aPoly
);
537 if (rE
.fThickness
==0)
540 tools::Polygon
aPoly2(nPolySize
);
542 for (i
=0; i
<nPolySize
; i
++) {
543 rTransform
.Transform(
544 (static_cast<const DXFVertexEntity
*>(pBE
)->aP0
)+DXFVector(0,0,rE
.fThickness
),
549 if ((rE
.nFlags
&1)!=0) pVirDev
->DrawPolygon(aPoly2
);
550 else pVirDev
->DrawPolyLine(aPoly2
);
551 for (i
=0; i
<nPolySize
; i
++) DrawLine(aPoly
[i
],aPoly2
[i
]);
554 void DXF2GDIMetaFile::DrawLWPolyLineEntity(const DXFLWPolyLineEntity
& rE
, const DXFTransform
& rTransform
)
556 sal_Int32 nPolySize
= rE
.aP
.size();
560 tools::Polygon
aPoly( static_cast<sal_uInt16
>(nPolySize
));
561 for (sal_Int32 i
= 0; i
< nPolySize
; ++i
)
563 rTransform
.Transform( rE
.aP
[ static_cast<sal_uInt16
>(i
) ], aPoly
[ static_cast<sal_uInt16
>(i
) ] );
565 if ( SetLineAttribute( rE
) )
567 if ( ( rE
.nFlags
& 1 ) != 0 )
568 pVirDev
->DrawPolygon( aPoly
);
570 pVirDev
->DrawPolyLine( aPoly
);
574 void DXF2GDIMetaFile::DrawHatchEntity(const DXFHatchEntity
& rE
, const DXFTransform
& rTransform
)
576 if ( !rE
.nBoundaryPathCount
)
579 SetAreaAttribute( rE
);
581 tools::PolyPolygon aPolyPoly
;
582 for ( j
= 0; j
< rE
.nBoundaryPathCount
; j
++ )
584 std::vector
< Point
> aPtAry
;
585 const DXFBoundaryPathData
& rPathData
= rE
.pBoundaryPathData
[ j
];
586 if ( rPathData
.bIsPolyLine
)
588 for (const auto& a
: rPathData
.aP
)
591 rTransform
.Transform(a
, aPt
);
592 aPtAry
.push_back( aPt
);
597 for ( auto& rEdge
: rPathData
.aEdges
)
599 const DXFEdgeType
* pEdge
= rEdge
.get();
600 switch( pEdge
->nEdgeType
)
605 rTransform
.Transform( static_cast<const DXFEdgeTypeLine
*>(pEdge
)->aStartPoint
, aPt
);
606 aPtAry
.push_back( aPt
);
607 rTransform
.Transform( static_cast<const DXFEdgeTypeLine
*>(pEdge
)->aEndPoint
, aPt
);
608 aPtAry
.push_back( aPt
);
618 sal_uInt16 i
, nSize
= static_cast<sal_uInt16
>(aPtAry
.size());
621 tools::Polygon
aPoly( nSize
);
622 for ( i
= 0; i
< nSize
; i
++ )
623 aPoly
[ i
] = aPtAry
[ i
];
624 aPolyPoly
.Insert( aPoly
);
627 if ( aPolyPoly
.Count() )
628 pVirDev
->DrawPolyPolygon( aPolyPoly
);
631 void DXF2GDIMetaFile::Draw3DFaceEntity(const DXF3DFaceEntity
& rE
, const DXFTransform
& rTransform
)
634 if (!SetLineAttribute(rE
))
637 if (rE
.aP2
==rE
.aP3
) nN
=3; else nN
=4;
638 tools::Polygon
aPoly(nN
);
639 rTransform
.Transform(rE
.aP0
,aPoly
[0]);
640 rTransform
.Transform(rE
.aP1
,aPoly
[1]);
641 rTransform
.Transform(rE
.aP2
,aPoly
[2]);
642 if (nN
>3) rTransform
.Transform(rE
.aP3
,aPoly
[3]);
643 if ((rE
.nIEFlags
&0x0f)==0) pVirDev
->DrawPolygon(aPoly
);
645 for (i
=0; i
<nN
; i
++) {
646 if ( (rE
.nIEFlags
& (static_cast<tools::Long
>(1)<<i
)) == 0 ) {
647 DrawLine(aPoly
[i
],aPoly
[(i
+1)%nN
]);
653 void DXF2GDIMetaFile::DrawDimensionEntity(const DXFDimensionEntity
& rE
, const DXFTransform
& rTransform
)
656 pB
=pDXF
->aBlocks
.Search(rE
.m_sPseudoBlock
);
661 DXFTransform(1.0,1.0,1.0,DXFVector(0.0,0.0,0.0)-pB
->aBasePoint
),
664 tools::Long nSavedBlockColor
, nSavedParentLayerColor
;
665 DXFLineInfo aSavedBlockDXFLineInfo
, aSavedParentLayerDXFLineInfo
;
666 nSavedBlockColor
=nBlockColor
;
667 nSavedParentLayerColor
=nParentLayerColor
;
668 aSavedBlockDXFLineInfo
=aBlockDXFLineInfo
;
669 aSavedParentLayerDXFLineInfo
=aParentLayerDXFLineInfo
;
670 nBlockColor
=GetEntityColor(rE
);
671 aBlockDXFLineInfo
=GetEntityDXFLineInfo(rE
);
672 if (rE
.m_sLayer
.getLength() > 1) {
673 DXFLayer
* pLayer
=pDXF
->aTables
.SearchLayer(rE
.m_sLayer
);
674 if (pLayer
!=nullptr) {
675 nParentLayerColor
=pLayer
->nColor
;
676 aParentLayerDXFLineInfo
= LTypeToDXFLineInfo(pLayer
->m_sLineType
);
679 DrawEntities(*pB
,aT
);
680 aBlockDXFLineInfo
=aSavedBlockDXFLineInfo
;
681 aParentLayerDXFLineInfo
=aSavedParentLayerDXFLineInfo
;
682 nBlockColor
=nSavedBlockColor
;
683 nParentLayerColor
=nSavedParentLayerColor
;
687 void DXF2GDIMetaFile::DrawEntities(const DXFEntities
& rEntities
,
688 const DXFTransform
& rTransform
)
690 if (rEntities
.mbBeingDrawn
)
692 rEntities
.mbBeingDrawn
= true;
695 const DXFTransform
* pT
;
697 const DXFBasicEntity
* pE
=rEntities
.pFirst
;
699 while (pE
!=nullptr && bStatus
) {
701 if (pE
->aExtrusion
.fz
==1.0) {
705 aET
=DXFTransform(DXFTransform(pE
->aExtrusion
),rTransform
);
710 DrawLineEntity(static_cast<const DXFLineEntity
&>(*pE
),*pT
);
713 DrawPointEntity(static_cast<const DXFPointEntity
&>(*pE
),*pT
);
716 DrawCircleEntity(static_cast<const DXFCircleEntity
&>(*pE
),*pT
);
719 DrawArcEntity(static_cast<const DXFArcEntity
&>(*pE
),*pT
);
722 DrawTraceEntity(static_cast<const DXFTraceEntity
&>(*pE
),*pT
);
725 DrawSolidEntity(static_cast<const DXFSolidEntity
&>(*pE
),*pT
);
728 DrawTextEntity(static_cast<const DXFTextEntity
&>(*pE
),*pT
);
731 DrawInsertEntity(static_cast<const DXFInsertEntity
&>(*pE
),*pT
);
734 DrawAttribEntity(static_cast<const DXFAttribEntity
&>(*pE
),*pT
);
737 DrawPolyLineEntity(static_cast<const DXFPolyLineEntity
&>(*pE
),*pT
);
739 case DXF_LWPOLYLINE
:
740 DrawLWPolyLineEntity(static_cast<const DXFLWPolyLineEntity
&>(*pE
), *pT
);
743 DrawHatchEntity(static_cast<const DXFHatchEntity
&>(*pE
), *pT
);
746 Draw3DFaceEntity(static_cast<const DXF3DFaceEntity
&>(*pE
),*pT
);
749 DrawDimensionEntity(static_cast<const DXFDimensionEntity
&>(*pE
),*pT
);
752 break; // four other values not handled -Wall
758 rEntities
.mbBeingDrawn
= false;
762 DXF2GDIMetaFile::DXF2GDIMetaFile()
766 , OptPointsPerCircle(0)
770 , nMainEntitiesCount(0)
772 , nParentLayerColor(0)
777 DXF2GDIMetaFile::~DXF2GDIMetaFile()
782 bool DXF2GDIMetaFile::Convert(const DXFRepresentation
& rDXF
, GDIMetaFile
& rMTF
, sal_uInt16 nminpercent
, sal_uInt16 nmaxpercent
)
784 double fWidth
,fHeight
,fScale(0.0);
785 DXFTransform aTransform
;
787 const DXFLayer
* pLayer
;
788 const DXFVPort
* pVPort
;
790 pVirDev
= VclPtr
<VirtualDevice
>::Create();
794 OptPointsPerCircle
=50;
796 nMinPercent
=nminpercent
;
797 nMaxPercent
=nmaxpercent
;
798 nLastPercent
=nMinPercent
;
799 nMainEntitiesCount
=CountEntities(pDXF
->aEntities
);
802 aBlockDXFLineInfo
.eStyle
= LineStyle::Solid
;
803 aBlockDXFLineInfo
.nDashCount
= 0;
804 aBlockDXFLineInfo
.fDashLen
= 0;
805 aBlockDXFLineInfo
.nDotCount
= 0;
806 aBlockDXFLineInfo
.fDotLen
= 0;
807 aBlockDXFLineInfo
.fDistance
= 0;
809 pLayer
=pDXF
->aTables
.SearchLayer("0");
810 if (pLayer
!=nullptr) {
811 nParentLayerColor
=pLayer
->nColor
& 0xff;
812 aParentLayerDXFLineInfo
= LTypeToDXFLineInfo(pLayer
->m_sLineType
);
816 aParentLayerDXFLineInfo
.eStyle
= LineStyle::Solid
;
817 aParentLayerDXFLineInfo
.nDashCount
= 0;
818 aParentLayerDXFLineInfo
.fDashLen
= 0;
819 aParentLayerDXFLineInfo
.nDotCount
= 0;
820 aParentLayerDXFLineInfo
.fDotLen
= 0;
821 aParentLayerDXFLineInfo
.fDistance
= 0;
824 pVirDev
->EnableOutput(false);
825 if (!utl::ConfigManager::IsFuzzing()) // for fuzzing don't bother recording the drawing
826 rMTF
.Record(pVirDev
);
828 aActLineColor
= pVirDev
->GetLineColor();
829 aActFillColor
= pVirDev
->GetFillColor();
830 aActFont
= pVirDev
->GetFont();
832 pVPort
=pDXF
->aTables
.SearchVPort("*ACTIVE");
833 if (pVPort
!=nullptr) {
834 if (pVPort
->aDirection
.fx
==0 && pVPort
->aDirection
.fy
==0)
838 if (pVPort
==nullptr) {
839 if (pDXF
->aBoundingBox
.bEmpty
)
842 fWidth
=pDXF
->aBoundingBox
.fMaxX
-pDXF
->aBoundingBox
.fMinX
;
843 fHeight
=pDXF
->aBoundingBox
.fMaxY
-pDXF
->aBoundingBox
.fMinY
;
844 if (fWidth
<=0 || fHeight
<=0) {
849 fScale
=10000.0/fWidth
;
851 fScale
=10000.0/fHeight
;
852 aTransform
=DXFTransform(fScale
,-fScale
,fScale
,
853 DXFVector(-pDXF
->aBoundingBox
.fMinX
*fScale
,
854 pDXF
->aBoundingBox
.fMaxY
*fScale
,
855 -pDXF
->aBoundingBox
.fMinZ
*fScale
));
857 aPrefSize
.setWidth(static_cast<tools::Long
>(fWidth
*fScale
+1.5) );
858 aPrefSize
.setHeight(static_cast<tools::Long
>(fHeight
*fScale
+1.5) );
862 fHeight
=pVPort
->fHeight
;
863 fWidth
=fHeight
*pVPort
->fAspectRatio
;
864 if (fWidth
<=0 || fHeight
<=0) {
868 fScale
=10000.0/fWidth
;
870 fScale
=10000.0/fHeight
;
871 aTransform
=DXFTransform(
872 DXFTransform(pVPort
->aDirection
,pVPort
->aTarget
),
874 DXFTransform(1.0,-1.0,1.0,DXFVector(fWidth
/2-pVPort
->fCenterX
,fHeight
/2+pVPort
->fCenterY
,0)),
875 DXFTransform(fScale
,fScale
,fScale
,DXFVector(0,0,0))
879 aPrefSize
.setWidth(static_cast<tools::Long
>(fWidth
*fScale
+1.5) );
880 aPrefSize
.setHeight(static_cast<tools::Long
>(fHeight
*fScale
+1.5) );
884 DrawEntities(pDXF
->aEntities
,aTransform
);
890 rMTF
.SetPrefSize( aPrefSize
);
891 // simply set map mode to 1/100-mm (1/10-mm) if the graphic
892 // does not get not too small (<0.5cm)
893 if( ( aPrefSize
.Width() < 500 ) && ( aPrefSize
.Height() < 500 ) )
894 rMTF
.SetPrefMapMode( MapMode( MapUnit::Map10thMM
) );
896 rMTF
.SetPrefMapMode( MapMode( MapUnit::Map100thMM
) );
899 pVirDev
.disposeAndClear();
904 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */