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