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 <dxfreprd.hxx>
29 
30 
31 //------------------DXFBoundingBox--------------------------------------------
32 
33 
Union(const DXFVector & rVector)34 void DXFBoundingBox::Union(const DXFVector & rVector)
35 {
36 	if (bEmpty==sal_True) {
37 		fMinX=rVector.fx;
38 		fMinY=rVector.fy;
39 		fMinZ=rVector.fz;
40 		fMaxX=rVector.fx;
41 		fMaxY=rVector.fy;
42 		fMaxZ=rVector.fz;
43 		bEmpty=sal_False;
44 	}
45 	else {
46 		if (fMinX>rVector.fx) fMinX=rVector.fx;
47 		if (fMinY>rVector.fy) fMinY=rVector.fy;
48 		if (fMinZ>rVector.fz) fMinZ=rVector.fz;
49 		if (fMaxX<rVector.fx) fMaxX=rVector.fx;
50 		if (fMaxY<rVector.fy) fMaxY=rVector.fy;
51 		if (fMaxZ<rVector.fz) fMaxZ=rVector.fz;
52 	}
53 }
54 
55 
56 //------------------DXFPalette------------------------------------------------
57 
58 
DXFPalette()59 DXFPalette::DXFPalette()
60 {
61 	short i,j,nHue,nNSat,nVal,nC[3],nmax,nmed,nmin;
62 	sal_uInt8 nV;
63 
64 	pRed  =new sal_uInt8[256];
65 	pGreen=new sal_uInt8[256];
66 	pBlue =new sal_uInt8[256];
67 
68 	// Farben 0 - 9 (normale Farben)
69 	SetColor(0, 0x00, 0x00, 0x00); // eigentlich nie benutzt
70 	SetColor(1, 0xff, 0x00, 0x00);
71 	SetColor(2, 0xff, 0xff, 0x00);
72 	SetColor(3, 0x00, 0xff, 0x00);
73 	SetColor(4, 0x00, 0xff, 0xff);
74 	SetColor(5, 0x00, 0x00, 0xff);
75 	SetColor(6, 0xff, 0x00, 0xff);
76 	SetColor(7, 0x0f, 0x0f, 0x0f); // eigentlich weiss ???
77 	SetColor(8, 0x80, 0x80, 0x80);
78 	SetColor(9, 0xc0, 0xc0, 0xc0);
79 
80 	// Farben 10 - 249
81 	// (Universal-Palette: 24 Farbtoene * 5 Helligkeiten * 2 Saettigungen )
82 	i=10;
83 	for (nHue=0; nHue<24; nHue++) {
84 		for (nVal=5; nVal>=1; nVal--) {
85 			for (nNSat=0; nNSat<2; nNSat++) {
86 				nmax=((nHue+3)>>3)%3;
87 				j=nHue-(nmax<<3); if (j>4) j=j-24;
88 				if (j>=0) {
89 					nmed=(nmax+1)%3;
90 					nmin=(nmax+2)%3;
91 				}
92 				else {
93 					nmed=(nmax+2)%3;
94 					nmin=(nmax+1)%3;
95 					j=-j;
96 				}
97 				nC[nmin]=0;
98 				nC[nmed]=255*j/4;
99 				nC[nmax]=255;
100 				if (nNSat!=0) {
101 					for (j=0; j<3; j++) nC[j]=(nC[j]>>1)+128;
102 				}
103 				for (j=0; j<3; j++) nC[j]=nC[j]*nVal/5;
104 				SetColor((sal_uInt8)(i++),(sal_uInt8)nC[0],(sal_uInt8)nC[1],(sal_uInt8)nC[2]);
105 			}
106 		}
107 	}
108 
109 	// Farben 250 - 255 (Grautoenne)
110 	for (i=0; i<6; i++) {
111 		nV=(sal_uInt8)(i*38+65);
112 		SetColor((sal_uInt8)(250+i),nV,nV,nV);
113 	}
114 }
115 
116 
~DXFPalette()117 DXFPalette::~DXFPalette()
118 {
119 	delete[] pBlue;
120 	delete[] pGreen;
121 	delete[] pRed;
122 }
123 
124 
SetColor(sal_uInt8 nIndex,sal_uInt8 nRed,sal_uInt8 nGreen,sal_uInt8 nBlue)125 void DXFPalette::SetColor(sal_uInt8 nIndex, sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
126 {
127 	pRed[nIndex]=nRed;
128 	pGreen[nIndex]=nGreen;
129 	pBlue[nIndex]=nBlue;
130 }
131 
132 
133 //------------------DXFRepresentation-----------------------------------------
134 
135 
DXFRepresentation()136 DXFRepresentation::DXFRepresentation()
137 {
138 	setTextEncoding(RTL_TEXTENCODING_IBM_437);
139         setGlobalLineTypeScale(1.0);
140 }
141 
142 
~DXFRepresentation()143 DXFRepresentation::~DXFRepresentation()
144 {
145 }
146 
147 
Read(SvStream & rIStream,sal_uInt16 nMinPercent,sal_uInt16 nMaxPercent)148 sal_Bool DXFRepresentation::Read( SvStream & rIStream, sal_uInt16 nMinPercent, sal_uInt16 nMaxPercent)
149 {
150 	DXFGroupReader * pDGR;
151 	sal_Bool bRes;
152 
153 	aTables.Clear();
154 	aBlocks.Clear();
155 	aEntities.Clear();
156 
157 	pDGR = new DXFGroupReader( rIStream, nMinPercent, nMaxPercent );
158 
159 	pDGR->Read();
160 	while (pDGR->GetG()!=0 || strcmp(pDGR->GetS(),"EOF")!=0) {
161 		if (pDGR->GetG()==0 && strcmp(pDGR->GetS(),"SECTION")==0) {
162 			if (pDGR->Read()!=2) {
163 				pDGR->SetError();
164 				break;
165 			}
166 			if      (strcmp(pDGR->GetS(),"HEADER"  )==0) ReadHeader(*pDGR);
167 			else if (strcmp(pDGR->GetS(),"TABLES"  )==0) aTables.Read(*pDGR);
168 			else if (strcmp(pDGR->GetS(),"BLOCKS"  )==0) aBlocks.Read(*pDGR);
169 			else if (strcmp(pDGR->GetS(),"ENTITIES")==0) aEntities.Read(*pDGR);
170 			else pDGR->Read();
171 		}
172 		else pDGR->Read();
173 	}
174 
175 	bRes=pDGR->GetStatus();
176 
177 	delete pDGR;
178 
179 	if (bRes==sal_True && aBoundingBox.bEmpty==sal_True)
180 		CalcBoundingBox(aEntities,aBoundingBox);
181 
182 	return bRes;
183 }
184 
185 
ReadHeader(DXFGroupReader & rDGR)186 void DXFRepresentation::ReadHeader(DXFGroupReader & rDGR)
187 {
188 
189          while (rDGR.GetG()!=0 || (strcmp(rDGR.GetS(),"EOF")!=0 &&  strcmp(rDGR.GetS(),"ENDSEC")!=0) )
190          {
191                  if (rDGR.GetG()==9) {
192                          if (strcmp(rDGR.GetS(),"$EXTMIN")==0 ||
193                                  strcmp(rDGR.GetS(),"$EXTMAX")==0)
194                          {
195                                  DXFVector aVector;
196                                  rDGR.SetF(10,0.0);
197                                  rDGR.SetF(20,0.0);
198                                  rDGR.SetF(30,0.0);
199                                  do {
200                                          rDGR.Read();
201                                  } while (rDGR.GetG()!=9 && rDGR.GetG()!=0);
202                                  aVector.fx=rDGR.GetF(10);
203                                  aVector.fy=rDGR.GetF(20);
204                                  aVector.fz=rDGR.GetF(30);
205                                  aBoundingBox.Union(aVector);
206                          } else {
207                                  if (strcmp(rDGR.GetS(),"$DWGCODEPAGE")==0)
208                                  {
209                                          rDGR.Read();
210 
211                                          // FIXME: we really need a whole table of
212                                          // $DWGCODEPAGE to encodings mappings
213                                          if ( (strcmp(rDGR.GetS(),"ANSI_932")==0) ||
214 					      (strcmp(rDGR.GetS(),"ansi_932")==0) ||
215                                               (strcmp(rDGR.GetS(),"DOS932")==0) ||
216                                               (strcmp(rDGR.GetS(),"dos932")==0) )
217                                          {
218                                                  setTextEncoding(RTL_TEXTENCODING_MS_932);
219                                          }
220                                  }
221 				 else if (strcmp(rDGR.GetS(),"$LTSCALE")==0)
222                                  {
223                                          rDGR.Read();
224                                          setGlobalLineTypeScale(getGlobalLineTypeScale() * rDGR.GetF());
225                                  }
226                                  else rDGR.Read();
227                          }
228                  }
229                  else rDGR.Read();
230          }
231 }
232 
233 
CalcBoundingBox(const DXFEntities & rEntities,DXFBoundingBox & rBox)234 void DXFRepresentation::CalcBoundingBox(const DXFEntities & rEntities,
235 										DXFBoundingBox & rBox)
236 {
237 	DXFBasicEntity * pBE=rEntities.pFirst;
238 	while (pBE!=NULL) {
239 		switch (pBE->eType) {
240 			case DXF_LINE: {
241 				const DXFLineEntity * pE = (DXFLineEntity*)pBE;
242 				rBox.Union(pE->aP0);
243 				rBox.Union(pE->aP1);
244 				break;
245 			}
246 			case DXF_POINT: {
247 				const DXFPointEntity * pE = (DXFPointEntity*)pBE;
248 				rBox.Union(pE->aP0);
249 				break;
250 			}
251 			case DXF_CIRCLE: {
252 				const DXFCircleEntity * pE = (DXFCircleEntity*)pBE;
253 				DXFVector aP;
254 				aP=pE->aP0;
255 				aP.fx-=pE->fRadius;
256 				aP.fy-=pE->fRadius;
257 				rBox.Union(aP);
258 				aP=pE->aP0;
259 				aP.fx+=pE->fRadius;
260 				aP.fy+=pE->fRadius;
261 				rBox.Union(aP);
262 				break;
263 			}
264 			case DXF_ARC: {
265 				const DXFArcEntity * pE = (DXFArcEntity*)pBE;
266 				DXFVector aP;
267 				aP=pE->aP0;
268 				aP.fx-=pE->fRadius;
269 				aP.fy-=pE->fRadius;
270 				rBox.Union(aP);
271 				aP=pE->aP0;
272 				aP.fx+=pE->fRadius;
273 				aP.fy+=pE->fRadius;
274 				rBox.Union(aP);
275 				break;
276 			}
277 			case DXF_TRACE: {
278 				const DXFTraceEntity * pE = (DXFTraceEntity*)pBE;
279 				rBox.Union(pE->aP0);
280 				rBox.Union(pE->aP1);
281 				rBox.Union(pE->aP2);
282 				rBox.Union(pE->aP3);
283 				break;
284 			}
285 			case DXF_SOLID: {
286 				const DXFSolidEntity * pE = (DXFSolidEntity*)pBE;
287 				rBox.Union(pE->aP0);
288 				rBox.Union(pE->aP1);
289 				rBox.Union(pE->aP2);
290 				rBox.Union(pE->aP3);
291 				break;
292 			}
293 			case DXF_TEXT: {
294 				//const DXFTextEntity * pE = (DXFTextEntity*)pBE;
295 				//???
296 				break;
297 			}
298 			case DXF_SHAPE: {
299 				//const DXFShapeEntity * pE = (DXFShapeEntity*)pBE;
300 				//???
301 				break;
302 			}
303 			case DXF_INSERT: {
304 				const DXFInsertEntity * pE = (DXFInsertEntity*)pBE;
305 				DXFBlock * pB;
306 				DXFBoundingBox aBox;
307 				DXFVector aP;
308 				pB=aBlocks.Search(pE->sName);
309 				if (pB==NULL) break;
310 				CalcBoundingBox(*pB,aBox);
311 				if (aBox.bEmpty==sal_True) break;
312 				aP.fx=(aBox.fMinX-pB->aBasePoint.fx)*pE->fXScale+pE->aP0.fx;
313 				aP.fy=(aBox.fMinY-pB->aBasePoint.fy)*pE->fYScale+pE->aP0.fy;
314 				aP.fz=(aBox.fMinZ-pB->aBasePoint.fz)*pE->fZScale+pE->aP0.fz;
315 				rBox.Union(aP);
316 				aP.fx=(aBox.fMaxX-pB->aBasePoint.fx)*pE->fXScale+pE->aP0.fx;
317 				aP.fy=(aBox.fMaxY-pB->aBasePoint.fy)*pE->fYScale+pE->aP0.fy;
318 				aP.fz=(aBox.fMaxZ-pB->aBasePoint.fz)*pE->fZScale+pE->aP0.fz;
319 				rBox.Union(aP);
320 				break;
321 			}
322 			case DXF_ATTDEF: {
323 				//const DXFAttDefEntity * pE = (DXFAttDefEntity*)pBE;
324 				//???
325 				break;
326 			}
327 			case DXF_ATTRIB: {
328 				//const DXFAttribEntity * pE = (DXFAttribEntity*)pBE;
329 				//???
330 				break;
331 			}
332 			case DXF_VERTEX: {
333 				const DXFVertexEntity * pE = (DXFVertexEntity*)pBE;
334 				rBox.Union(pE->aP0);
335 				break;
336 			}
337 			case DXF_3DFACE: {
338 				const DXF3DFaceEntity * pE = (DXF3DFaceEntity*)pBE;
339 				rBox.Union(pE->aP0);
340 				rBox.Union(pE->aP1);
341 				rBox.Union(pE->aP2);
342 				rBox.Union(pE->aP3);
343 				break;
344 			}
345 			case DXF_DIMENSION: {
346 				const DXFDimensionEntity * pE = (DXFDimensionEntity*)pBE;
347 				DXFBlock * pB;
348 				DXFBoundingBox aBox;
349 				DXFVector aP;
350 				pB=aBlocks.Search(pE->sPseudoBlock);
351 				if (pB==NULL) break;
352 				CalcBoundingBox(*pB,aBox);
353 				if (aBox.bEmpty==sal_True) break;
354 				aP.fx=aBox.fMinX-pB->aBasePoint.fx;
355 				aP.fy=aBox.fMinY-pB->aBasePoint.fy;
356 				aP.fz=aBox.fMinZ-pB->aBasePoint.fz;
357 				rBox.Union(aP);
358 				aP.fx=aBox.fMaxX-pB->aBasePoint.fx;
359 				aP.fy=aBox.fMaxY-pB->aBasePoint.fy;
360 				aP.fz=aBox.fMaxZ-pB->aBasePoint.fz;
361 				rBox.Union(aP);
362 				break;
363 			}
364 			case DXF_POLYLINE: {
365 				//const DXFAttribEntity * pE = (DXFAttribEntity*)pBE;
366 				//???
367 				break;
368 			}
369 			case DXF_SEQEND: {
370 				//const DXFAttribEntity * pE = (DXFAttribEntity*)pBE;
371 				//???
372 				break;
373 			}
374 			case DXF_HATCH :
375 				break;
376 			case DXF_LWPOLYLINE :
377 				break;
378 		}
379 		pBE=pBE->pSucc;
380 	}
381 }
382