LibreOffice Module vcl (master)  1
dxfreprd.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include "dxfreprd.hxx"
22 #include <osl/nlsupport.h>
24 #include <unotools/wincodepage.hxx>
25 
26 //------------------DXFBoundingBox--------------------------------------------
27 
28 
29 void DXFBoundingBox::Union(const DXFVector & rVector)
30 {
31  if (bEmpty) {
32  fMinX=rVector.fx;
33  fMinY=rVector.fy;
34  fMinZ=rVector.fz;
35  fMaxX=rVector.fx;
36  fMaxY=rVector.fy;
37  fMaxZ=rVector.fz;
38  bEmpty=false;
39  }
40  else {
41  if (fMinX>rVector.fx) fMinX=rVector.fx;
42  if (fMinY>rVector.fy) fMinY=rVector.fy;
43  if (fMinZ>rVector.fz) fMinZ=rVector.fz;
44  if (fMaxX<rVector.fx) fMaxX=rVector.fx;
45  if (fMaxY<rVector.fy) fMaxY=rVector.fy;
46  if (fMaxZ<rVector.fz) fMaxZ=rVector.fz;
47  }
48 }
49 
50 
51 //------------------DXFPalette------------------------------------------------
52 
53 
55 {
56  short i,j,nHue,nNSat,nVal,nC[3],nmax,nmed,nmin;
57  sal_uInt8 nV;
58 
59  // colors 0 - 9 (normal colors)
60  SetColor(0, 0x00, 0x00, 0x00); // actually never being used
61  SetColor(1, 0xff, 0x00, 0x00);
62  SetColor(2, 0xff, 0xff, 0x00);
63  SetColor(3, 0x00, 0xff, 0x00);
64  SetColor(4, 0x00, 0xff, 0xff);
65  SetColor(5, 0x00, 0x00, 0xff);
66  SetColor(6, 0xff, 0x00, 0xff);
67  SetColor(7, 0x0f, 0x0f, 0x0f); // actually white???
68  SetColor(8, 0x80, 0x80, 0x80);
69  SetColor(9, 0xc0, 0xc0, 0xc0);
70 
71  // colors 10 - 249
72  // (Universal-Palette: 24 hues * 5 lightnesses * 2 saturations )
73  i=10;
74  for (nHue=0; nHue<24; nHue++) {
75  for (nVal=5; nVal>=1; nVal--) {
76  for (nNSat=0; nNSat<2; nNSat++) {
77  nmax=((nHue+3)>>3)%3;
78  j=nHue-(nmax<<3); if (j>4) j=j-24;
79  if (j>=0) {
80  nmed=(nmax+1)%3;
81  nmin=(nmax+2)%3;
82  }
83  else {
84  nmed=(nmax+2)%3;
85  nmin=(nmax+1)%3;
86  j=-j;
87  }
88  nC[nmin]=0;
89  nC[nmed]=255*j/4;
90  nC[nmax]=255;
91  if (nNSat!=0) {
92  for (j=0; j<3; j++) nC[j]=(nC[j]>>1)+128;
93  }
94  for (j=0; j<3; j++) nC[j]=nC[j]*nVal/5;
95  SetColor(static_cast<sal_uInt8>(i++),static_cast<sal_uInt8>(nC[0]),static_cast<sal_uInt8>(nC[1]),static_cast<sal_uInt8>(nC[2]));
96  }
97  }
98  }
99 
100  // Farben 250 - 255 (shades of gray)
101  for (i=0; i<6; i++) {
102  nV=static_cast<sal_uInt8>(i*38+65);
103  SetColor(static_cast<sal_uInt8>(250+i),nV,nV,nV);
104  }
105 }
106 
107 
109 {
110 }
111 
112 
113 void DXFPalette::SetColor(sal_uInt8 nIndex, sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
114 {
115  pRed[nIndex]=nRed;
116  pGreen[nIndex]=nGreen;
117  pBlue[nIndex]=nBlue;
118 }
119 
120 
121 //------------------DXFRepresentation-----------------------------------------
122 
123 
125  : mEnc(RTL_TEXTENCODING_DONTKNOW)
126  , mbInCalc(false)
127 {
129 }
130 
132 {
133 }
134 
135 rtl_TextEncoding DXFRepresentation::getTextEncoding() const
136 {
137  return (isTextEncodingSet()) ?
138  mEnc :
139  osl_getTextEncodingFromLocale(nullptr); // Use default encoding if none specified
140 }
141 
143 {
144  bool bRes;
145 
146  aTables.Clear();
147  aBlocks.Clear();
148  aEntities.Clear();
149 
150  DXFGroupReader DGR( rIStream );
151 
152  DGR.Read();
153  while (DGR.GetG()!=0 || (DGR.GetS() != "EOF")) {
154  if (DGR.GetG()==0 && DGR.GetS() == "SECTION") {
155  if (DGR.Read()!=2) {
156  DGR.SetError();
157  break;
158  }
159  if (DGR.GetS() == "HEADER") ReadHeader(DGR);
160  else if (DGR.GetS() == "TABLES") aTables.Read(DGR);
161  else if (DGR.GetS() == "BLOCKS") aBlocks.Read(DGR);
162  else if (DGR.GetS() == "ENTITIES") aEntities.Read(DGR);
163  else DGR.Read();
164  }
165  else DGR.Read();
166  }
167 
168  bRes=DGR.GetStatus();
169 
170  if (bRes && aBoundingBox.bEmpty)
172 
173  return bRes;
174 }
175 
177 {
178  while (rDGR.GetG()!=0 || (rDGR.GetS() != "EOF" && rDGR.GetS() != "ENDSEC") )
179  {
180  if (rDGR.GetG()==9) {
181  if (rDGR.GetS() == "$EXTMIN" ||
182  rDGR.GetS() == "$EXTMAX")
183  {
184  DXFVector aVector;
185  while (rDGR.Read()!=9 && rDGR.GetG()!=0) {
186  switch (rDGR.GetG()) {
187  case 10: aVector.fx = rDGR.GetF(); break;
188  case 20: aVector.fy = rDGR.GetF(); break;
189  case 30: aVector.fz = rDGR.GetF(); break;
190  }
191  }
192  aBoundingBox.Union(aVector);
193  }
194  else if (rDGR.GetS() == "$ACADVER")
195  {
196  if (!rDGR.Read(1))
197  continue;
198  // Versions of AutoCAD up to Release 12 (inclusive, AC1009)
199  // were DOS software and used OEM encoding for storing strings.
200  // Release 13 (AC1012) had both DOS and Windows variants.
201  // Its Windows variant, and later releases used ANSI encodings for
202  // strings (up to version 2006, which was the last one to do so).
203  // Later versions (2007+, AC1021+) use UTF-8 for that.
204  // Other (non-Autodesk) implementations may have used different
205  // encodings for storing to corresponding formats, but there's
206  // no way to know that.
207  // See http://autodesk.blogs.com/between_the_lines/autocad-release-history.html
208  if ((rDGR.GetS() <= "AC1009") || (rDGR.GetS() == "AC2.22") || (rDGR.GetS() == "AC2.21") || (rDGR.GetS() == "AC2.10") ||
209  (rDGR.GetS() == "AC1.50") || (rDGR.GetS() == "AC1.40") || (rDGR.GetS() == "AC1.2") || (rDGR.GetS() == "MC0.0"))
210  {
211  // Set OEM encoding for old DOS formats
212  // only if the encoding is not set yet
213  // e.g. by previous $DWGCODEPAGE
214  if (!isTextEncodingSet())
217  }
218  else if (rDGR.GetS() >= "AC1021")
219  setTextEncoding(RTL_TEXTENCODING_UTF8);
220  else
221  {
222  // Set ANSI encoding for old Windows formats
223  // only if the encoding is not set yet
224  // e.g. by previous $DWGCODEPAGE
225  if (!isTextEncodingSet())
228  }
229  }
230  else if (rDGR.GetS() == "$DWGCODEPAGE")
231  {
232  if (!rDGR.Read(3))
233  continue;
234 
235  // If we already use UTF8, then don't update encoding anymore
236  if (mEnc == RTL_TEXTENCODING_UTF8)
237  continue;
238  // FIXME: we really need a whole table of
239  // $DWGCODEPAGE to encodings mappings
240  else if ( (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_932")) ||
241  (rDGR.GetS().equalsIgnoreAsciiCase("DOS932")) )
242  {
243  setTextEncoding(RTL_TEXTENCODING_MS_932);
244  }
245  else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_936"))
246  {
247  setTextEncoding(RTL_TEXTENCODING_MS_936);
248  }
249  else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_949"))
250  {
251  setTextEncoding(RTL_TEXTENCODING_MS_949);
252  }
253  else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_950"))
254  {
255  setTextEncoding(RTL_TEXTENCODING_MS_950);
256  }
257  else if (rDGR.GetS().equalsIgnoreAsciiCase("ANSI_1251"))
258  {
259  setTextEncoding(RTL_TEXTENCODING_MS_1251);
260  }
261  }
262  else if (rDGR.GetS() == "$LTSCALE")
263  {
264  if (!rDGR.Read(40))
265  continue;
267  }
268  else rDGR.Read();
269  }
270  else rDGR.Read();
271  }
272 }
273 
275  DXFBoundingBox & rBox)
276 {
277  if (mbInCalc)
278  return;
279  mbInCalc = true;
280 
281  DXFBasicEntity * pBE=rEntities.pFirst;
282  while (pBE!=nullptr) {
283  switch (pBE->eType) {
284  case DXF_LINE: {
285  const DXFLineEntity * pE = static_cast<const DXFLineEntity*>(pBE);
286  rBox.Union(pE->aP0);
287  rBox.Union(pE->aP1);
288  break;
289  }
290  case DXF_POINT: {
291  const DXFPointEntity * pE = static_cast<const DXFPointEntity*>(pBE);
292  rBox.Union(pE->aP0);
293  break;
294  }
295  case DXF_CIRCLE: {
296  const DXFCircleEntity * pE = static_cast<const DXFCircleEntity*>(pBE);
297  DXFVector aP;
298  aP=pE->aP0;
299  aP.fx-=pE->fRadius;
300  aP.fy-=pE->fRadius;
301  rBox.Union(aP);
302  aP=pE->aP0;
303  aP.fx+=pE->fRadius;
304  aP.fy+=pE->fRadius;
305  rBox.Union(aP);
306  break;
307  }
308  case DXF_ARC: {
309  const DXFArcEntity * pE = static_cast<const DXFArcEntity*>(pBE);
310  DXFVector aP;
311  aP=pE->aP0;
312  aP.fx-=pE->fRadius;
313  aP.fy-=pE->fRadius;
314  rBox.Union(aP);
315  aP=pE->aP0;
316  aP.fx+=pE->fRadius;
317  aP.fy+=pE->fRadius;
318  rBox.Union(aP);
319  break;
320  }
321  case DXF_TRACE: {
322  const DXFTraceEntity * pE = static_cast<const DXFTraceEntity*>(pBE);
323  rBox.Union(pE->aP0);
324  rBox.Union(pE->aP1);
325  rBox.Union(pE->aP2);
326  rBox.Union(pE->aP3);
327  break;
328  }
329  case DXF_SOLID: {
330  const DXFSolidEntity * pE = static_cast<const DXFSolidEntity*>(pBE);
331  rBox.Union(pE->aP0);
332  rBox.Union(pE->aP1);
333  rBox.Union(pE->aP2);
334  rBox.Union(pE->aP3);
335  break;
336  }
337  case DXF_TEXT: {
338  //const DXFTextEntity * pE = (DXFTextEntity*)pBE;
339  //???
340  break;
341  }
342  case DXF_SHAPE: {
343  //const DXFShapeEntity * pE = (DXFShapeEntity*)pBE;
344  //???
345  break;
346  }
347  case DXF_INSERT: {
348  const DXFInsertEntity * pE = static_cast<const DXFInsertEntity*>(pBE);
349  DXFBlock * pB;
350  DXFBoundingBox aBox;
351  DXFVector aP;
352  pB=aBlocks.Search(pE->m_sName);
353  if (pB==nullptr) break;
354  CalcBoundingBox(*pB,aBox);
355  if (aBox.bEmpty) break;
356  aP.fx=(aBox.fMinX-pB->aBasePoint.fx)*pE->fXScale+pE->aP0.fx;
357  aP.fy=(aBox.fMinY-pB->aBasePoint.fy)*pE->fYScale+pE->aP0.fy;
358  aP.fz=(aBox.fMinZ-pB->aBasePoint.fz)*pE->fZScale+pE->aP0.fz;
359  rBox.Union(aP);
360  aP.fx=(aBox.fMaxX-pB->aBasePoint.fx)*pE->fXScale+pE->aP0.fx;
361  aP.fy=(aBox.fMaxY-pB->aBasePoint.fy)*pE->fYScale+pE->aP0.fy;
362  aP.fz=(aBox.fMaxZ-pB->aBasePoint.fz)*pE->fZScale+pE->aP0.fz;
363  rBox.Union(aP);
364  break;
365  }
366  case DXF_ATTDEF: {
367  //const DXFAttDefEntity * pE = (DXFAttDefEntity*)pBE;
368  //???
369  break;
370  }
371  case DXF_ATTRIB: {
372  //const DXFAttribEntity * pE = (DXFAttribEntity*)pBE;
373  //???
374  break;
375  }
376  case DXF_VERTEX: {
377  const DXFVertexEntity * pE = static_cast<const DXFVertexEntity*>(pBE);
378  rBox.Union(pE->aP0);
379  break;
380  }
381  case DXF_3DFACE: {
382  const DXF3DFaceEntity * pE = static_cast<const DXF3DFaceEntity*>(pBE);
383  rBox.Union(pE->aP0);
384  rBox.Union(pE->aP1);
385  rBox.Union(pE->aP2);
386  rBox.Union(pE->aP3);
387  break;
388  }
389  case DXF_DIMENSION: {
390  const DXFDimensionEntity * pE = static_cast<const DXFDimensionEntity*>(pBE);
391  DXFBlock * pB;
392  DXFBoundingBox aBox;
393  DXFVector aP;
394  pB = aBlocks.Search(pE->m_sPseudoBlock);
395  if (pB==nullptr) break;
396  CalcBoundingBox(*pB,aBox);
397  if (aBox.bEmpty) break;
398  aP.fx=aBox.fMinX-pB->aBasePoint.fx;
399  aP.fy=aBox.fMinY-pB->aBasePoint.fy;
400  aP.fz=aBox.fMinZ-pB->aBasePoint.fz;
401  rBox.Union(aP);
402  aP.fx=aBox.fMaxX-pB->aBasePoint.fx;
403  aP.fy=aBox.fMaxY-pB->aBasePoint.fy;
404  aP.fz=aBox.fMaxZ-pB->aBasePoint.fz;
405  rBox.Union(aP);
406  break;
407  }
408  case DXF_POLYLINE: {
409  //const DXFAttribEntity * pE = (DXFAttribEntity*)pBE;
410  //???
411  break;
412  }
413  case DXF_SEQEND: {
414  //const DXFAttribEntity * pE = (DXFAttribEntity*)pBE;
415  //???
416  break;
417  }
418  case DXF_HATCH :
419  break;
420  case DXF_LWPOLYLINE :
421  break;
422  }
423  pBE=pBE->pSucc;
424  }
425  mbInCalc = false;
426 }
427 
428 namespace {
429  bool lcl_isDec(sal_Unicode ch)
430  {
431  return ch >= L'0' && ch <= L'9';
432  }
433  bool lcl_isHex(sal_Unicode ch)
434  {
435  return lcl_isDec(ch) || (ch >= L'A' && ch <= L'F') || (ch >= L'a' && ch <= L'f');
436  }
437 }
438 
439 OUString DXFRepresentation::ToOUString(std::string_view s) const
440 {
441  OUString result = OStringToOUString(s, getTextEncoding(),
442  RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
443  | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
444  | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR);
445  result = result.replaceAll("%%o", "") // Overscore - simply remove
446  .replaceAll("%%u", "") // Underscore - simply remove
447  .replaceAll("%%d", u"\u00B0") // Degrees symbol (°)
448  .replaceAll("%%p", u"\u00B1") // Tolerance symbol (±)
449  .replaceAll("%%c", u"\u2205") // Diameter symbol
450  .replaceAll("%%%", "%"); // Percent symbol
451 
452  sal_Int32 pos = result.indexOf("%%"); // %%nnn, where nnn - 3-digit decimal ASCII code
453  while (pos != -1 && pos <= result.getLength() - 5) {
454  OUString asciiNum = result.copy(pos + 2, 3);
455  if (lcl_isDec(asciiNum[0]) &&
456  lcl_isDec(asciiNum[1]) &&
457  lcl_isDec(asciiNum[2]))
458  {
459  char ch = static_cast<char>(asciiNum.toUInt32());
460  OUString codePt(&ch, 1, mEnc);
461  result = result.replaceAll(result.subView(pos, 5), codePt, pos);
462  }
463  pos = result.indexOf("%%", pos + 1);
464  }
465 
466  pos = result.indexOf("\\U+"); // \U+XXXX, where XXXX - 4-digit hex unicode
467  while (pos != -1 && pos <= result.getLength() - 7) {
468  OUString codePtNum = result.copy(pos + 3, 4);
469  if (lcl_isHex(codePtNum[0]) &&
470  lcl_isHex(codePtNum[1]) &&
471  lcl_isHex(codePtNum[2]) &&
472  lcl_isHex(codePtNum[3]))
473  {
474  OUString codePt(static_cast<sal_Unicode>(codePtNum.toUInt32(16)));
475  result = result.replaceAll(result.subView(pos, 7), codePt, pos);
476  }
477  pos = result.indexOf("\\U+", pos + 1);
478  }
479  return result;
480 }
481 
482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void Read(DXFGroupReader &rDGR)
Definition: dxftblrd.cxx:268
DXFEntityType eType
Definition: dxfentrd.hxx:60
DXFVector aP0
Definition: dxfentrd.hxx:114
std::array< sal_uInt8, 256 > pGreen
Definition: dxfreprd.hxx:63
double fx
Definition: dxfvec.hxx:55
double GetF() const
Definition: dxfgrprd.hxx:102
DXFVector aP3
Definition: dxfentrd.hxx:176
DXFBlocks aBlocks
Definition: dxfreprd.hxx:86
DXFVector aP0
Definition: dxfentrd.hxx:481
double fMinZ
Definition: dxfreprd.hxx:38
void CalcBoundingBox(const DXFEntities &rEntities, DXFBoundingBox &rBox)
Definition: dxfreprd.cxx:274
FormulaCommand pE
OUString ToOUString(std::string_view s) const
Definition: dxfreprd.cxx:439
std::array< sal_uInt8, 256 > pBlue
Definition: dxfreprd.hxx:64
DXFVector aP0
Definition: dxfentrd.hxx:141
DXFVector aP1
Definition: dxfentrd.hxx:101
void Clear()
Definition: dxfblkrd.cxx:113
void Read(DXFGroupReader &rDGR)
Definition: dxfblkrd.cxx:81
DXFVector aP0
Definition: dxfentrd.hxx:157
double fMinX
Definition: dxfreprd.hxx:36
double fMaxY
Definition: dxfreprd.hxx:40
double fMaxX
Definition: dxfreprd.hxx:39
void setTextEncoding(rtl_TextEncoding aEnc)
Definition: dxfreprd.hxx:102
DXFVector aP1
Definition: dxfentrd.hxx:482
DXFVector aP0
Definition: dxfentrd.hxx:100
sal_uInt16 sal_Unicode
rtl_TextEncoding getTextEncoding() const
Definition: dxfreprd.cxx:135
DXFBlock * Search(std::string_view rName) const
Definition: dxfblkrd.cxx:103
double fz
Definition: dxfvec.hxx:55
size_t pos
rtl_TextEncoding utl_getWinTextEncodingFromLangStr(const OUString &sLanguage, bool bOEM)
void Clear()
Definition: dxftblrd.cxx:320
OString m_sName
Definition: dxfentrd.hxx:231
DXFVector aP3
Definition: dxfentrd.hxx:484
sal_uInt16 Read()
Definition: dxfgrprd.cxx:118
double fMaxZ
Definition: dxfreprd.hxx:41
void Union(const DXFVector &rVector)
Definition: dxfreprd.cxx:29
bool isTextEncodingSet() const
Definition: dxfreprd.hxx:116
int i
DXFVector aP0
Definition: dxfentrd.hxx:232
DXFVector aP2
Definition: dxfentrd.hxx:175
DXFVector aP2
Definition: dxfentrd.hxx:159
DXFVector aBasePoint
Definition: dxfblkrd.hxx:44
double fy
Definition: dxfvec.hxx:55
DXFVector aP2
Definition: dxfentrd.hxx:483
bool GetStatus() const
Definition: dxfgrprd.hxx:81
float u
DXFVector aP0
Definition: dxfentrd.hxx:456
DXFTables aTables
Definition: dxfreprd.hxx:83
void setGlobalLineTypeScale(double fGlobalLineTypeScale)
Definition: dxfreprd.hxx:106
double fMinY
Definition: dxfreprd.hxx:37
double getGlobalLineTypeScale() const
Definition: dxfreprd.hxx:105
sal_uInt16 GetG() const
Definition: dxfgrprd.hxx:92
DXFBoundingBox aBoundingBox
Definition: dxfreprd.hxx:79
void Read(DXFGroupReader &rDGR)
Definition: dxfentrd.cxx:794
DXFBasicEntity * pSucc
Definition: dxfentrd.hxx:57
void SetError()
Definition: dxfgrprd.hxx:87
DXFVector aP0
Definition: dxfentrd.hxx:173
unsigned char sal_uInt8
const OString & GetS() const
Definition: dxfgrprd.hxx:107
DXFVector aP3
Definition: dxfentrd.hxx:160
DXFEntities aEntities
Definition: dxfreprd.hxx:89
Any result
DXFVector aP0
Definition: dxfentrd.hxx:127
DXFVector aP1
Definition: dxfentrd.hxx:174
bool Read(SvStream &rIStream)
Definition: dxfreprd.cxx:142
void SetColor(sal_uInt8 nIndex, sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
Definition: dxfreprd.cxx:113
void Clear()
Definition: dxfentrd.cxx:839
rtl_TextEncoding mEnc
Definition: dxfreprd.hxx:92
OUString utl_getLocaleForGlobalDefaultEncoding()
DXFBasicEntity * pFirst
Definition: dxfentrd.hxx:524
double fRadius
Definition: dxfentrd.hxx:142
OString m_sPseudoBlock
Definition: dxfentrd.hxx:498
DXFVector aP1
Definition: dxfentrd.hxx:158
void ReadHeader(DXFGroupReader &rDGR)
Definition: dxfreprd.cxx:176
std::array< sal_uInt8, 256 > pRed
Definition: dxfreprd.hxx:62