Seamly2D
Code documentation
dxiface.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** **
3 ** Copyright (C) 2015 José F. Soriano, rallazz@gmail.com **
4 ** **
5 ** This library is free software, licensed under the terms of the GNU **
6 ** General Public License as published by the Free Software Foundation, **
7 ** either version 2 of the License, or (at your option) any later version. **
8 ** You should have received a copy of the GNU General Public License **
9 ** along with this program. If not, see <http://www.gnu.org/licenses/>. **
10 ******************************************************************************/
11 
12 #include "dxiface.h"
13 #include "libdxfrw/libdxfrw.h"
14 #include "../vmisc/vabstractapplication.h"
15 
16 #include <iostream>
17 #include <algorithm>
18 #include <QDateTime>
19 #include <QFont>
20 #include <QLocale>
21 
22 dx_iface::dx_iface(const std::string &file, DRW::Version v, VarMeasurement varMeasurement, VarInsunits varInsunits)
23  : dxfW(new dxfRW(file.c_str())),
24  cData(),
25  version(v)
26 {
27  InitHeader(varMeasurement, varInsunits);
29  InitAppId();
30 }
31 
33 {
34  delete dxfW;
35 }
36 
37 bool dx_iface::fileExport(bool binary)
38 {
39  bool success = dxfW->write(this, version, binary);
40  return success;
41 }
42 
43 void dx_iface::writeEntity(DRW_Entity* e){
44  switch (e->eType) {
45  case DRW::POINT:
46  dxfW->writePoint(static_cast<DRW_Point*>(e));
47  break;
48  case DRW::LINE:
49  dxfW->writeLine(static_cast<DRW_Line*>(e));
50  break;
51  case DRW::CIRCLE:
52  dxfW->writeCircle(static_cast<DRW_Circle*>(e));
53  break;
54  case DRW::ARC:
55  dxfW->writeArc(static_cast<DRW_Arc*>(e));
56  break;
57  case DRW::SOLID:
58  dxfW->writeSolid(static_cast<DRW_Solid*>(e));
59  break;
60  case DRW::ELLIPSE:
61  dxfW->writeEllipse(static_cast<DRW_Ellipse*>(e));
62  break;
63  case DRW::LWPOLYLINE:
64  dxfW->writeLWPolyline(static_cast<DRW_LWPolyline*>(e));
65  break;
66  case DRW::POLYLINE:
67  dxfW->writePolyline(static_cast<DRW_Polyline*>(e));
68  break;
69  case DRW::SPLINE:
70  dxfW->writeSpline(static_cast<DRW_Spline*>(e));
71  break;
72 // case RS2::EntitySplinePoints:
73 // writeSplinePoints(static_cast<DRW_Point*>(e));
74 // break;
75 // case RS2::EntityVertex:
76 // break;
77  case DRW::INSERT:
78  dxfW->writeInsert(static_cast<DRW_Insert*>(e));
79  break;
80  case DRW::MTEXT:
81  dxfW->writeMText(static_cast<DRW_MText*>(e));
82  break;
83  case DRW::TEXT:
84  dxfW->writeText(static_cast<DRW_Text*>(e));
85  break;
86  case DRW::DIMLINEAR:
87  case DRW::DIMALIGNED:
88  case DRW::DIMANGULAR:
89  case DRW::DIMANGULAR3P:
90  case DRW::DIMRADIAL:
91  case DRW::DIMDIAMETRIC:
92  case DRW::DIMORDINATE:
93  dxfW->writeDimension(static_cast<DRW_Dimension*>(e));
94  break;
95  case DRW::LEADER:
96  dxfW->writeLeader(static_cast<DRW_Leader*>(e));
97  break;
98  case DRW::HATCH:
99  dxfW->writeHatch(static_cast<DRW_Hatch*>(e));
100  break;
101  case DRW::IMAGE:
102  dxfW->writeImage(static_cast<DRW_Image*>(e), static_cast<dx_ifaceImg*>(e)->path);
103  break;
104  default:
105  break;
106  }
107 }
108 
109 void dx_iface::writeHeader(DRW_Header &data){
110  //complete copy of header vars:
111  data = cData.headerC;
112  //or copy one by one:
113  // for (std::map<std::string,DRW_Variant*>::iterator it=cData->headerC.vars.begin(); it != cData->headerC.vars.end(); ++it)
114  // data.vars[it->first] = new DRW_Variant( *(it->second) );
115 }
116 
118  //write each block
119  for (std::list<dx_ifaceBlock*>::iterator it=cData.blocks.begin(); it != cData.blocks.end(); ++it){
120  dx_ifaceBlock* bk = *it;
121  dxfW->writeBlock(bk);
122  //and write each entity in block
123  for (std::list<DRW_Entity*>::const_iterator it=bk->ent.begin(); it!=bk->ent.end(); ++it)
124  writeEntity(*it);
125  }
126 }
127 
129  for (std::list<dx_ifaceBlock*>::iterator it=cData.blocks.begin(); it != cData.blocks.end(); ++it)
130  dxfW->writeBlockRecord((*it)->name);
131 }
132 
134  for (std::list<DRW_Entity*>::const_iterator it=cData.mBlock->ent.begin(); it!=cData.mBlock->ent.end(); ++it)
135  writeEntity(*it);
136 }
137 
139  for (std::list<DRW_LType>::iterator it=cData.lineTypes.begin(); it != cData.lineTypes.end(); ++it)
140  dxfW->writeLineType(&(*it));
141 }
142 
144  for (std::list<DRW_Layer>::iterator it=cData.layers.begin(); it != cData.layers.end(); ++it)
145  dxfW->writeLayer(&(*it));
146 }
147 
149  for (std::list<DRW_Textstyle>::iterator it=cData.textStyles.begin(); it != cData.textStyles.end(); ++it)
150  dxfW->writeTextstyle(&(*it));
151 }
152 
154  for (std::list<DRW_Vport>::iterator it=cData.VPorts.begin(); it != cData.VPorts.end(); ++it)
155  dxfW->writeVport(&(*it));
156 }
157 
159  for (std::list<DRW_Dimstyle>::iterator it=cData.dimStyles.begin(); it != cData.dimStyles.end(); ++it)
160  dxfW->writeDimstyle(&(*it));
161 }
162 
164  for (std::list<DRW_AppId>::iterator it=cData.appIds.begin(); it != cData.appIds.end(); ++it)
165  dxfW->writeAppId(&(*it));
166 }
167 
168 void dx_iface::InitHeader(VarMeasurement varMeasurement, VarInsunits varInsunits)
169 {
170  cData.headerC.addComment("Seamly2D DXF File");
171 
172  // 1 = Clockwise angles, 0 = Counterclockwise
173  cData.headerC.addInt("$ANGDIR", 0, 70);// Qt use counterclockwise
174 
175  // Sets drawing units: 0 = English; 1 = Metric
176  cData.headerC.addInt("$MEASUREMENT", static_cast<int>(varMeasurement), 70);
177  cData.headerC.addInt("$INSUNITS", static_cast<int>(varInsunits), 70);
178 
179  QString dateTime = QDateTime::currentDateTime().toString("yyyyMMdd.HHmmsszzz");
180  dateTime.chop(1);// we need hundredths of a second
181  cData.headerC.addStr("$TDCREATE", dateTime.toStdString(), 40);
182 
183  if (version >= DRW::AC1021)
184  { // Full support Unicode
185  cData.headerC.addStr("$DWGCODEPAGE", "UTF-8", 3);
186  }
187  else
188  {
189  cData.headerC.addStr("$DWGCODEPAGE", LocaleToISO(), 3);
190  }
191 }
192 
194 {
195  DRW_LType ltype;
196  ltype.name = "DOT";
197  ltype.desc = "Dot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .";
198  ltype.size = 2;
199  ltype.length = 0.125;
200  ltype.path.push_back(0.0);
201  ltype.path.push_back(-0.125);
202  cData.lineTypes.push_back(ltype);
203 
204  ltype.path.clear();
205  ltype.name = "DASHED";
206  ltype.desc = "Dashed _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _";
207  ltype.size = 2;
208  ltype.length = 0.375;
209  ltype.path.push_back(0.25);
210  ltype.path.push_back(-0.125);
211  cData.lineTypes.push_back(ltype);
212 
213  ltype.path.clear();
214  ltype.name = "DASHDOT2";
215  ltype.desc = "Dash dot2 _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._.";
216  ltype.size = 4;
217  ltype.length = 0.5;
218  ltype.path.push_back(0.25);
219  ltype.path.push_back(-0.125);
220  ltype.path.push_back(0.0);
221  ltype.path.push_back(-0.125);
222  cData.lineTypes.push_back(ltype);
223 
224  ltype.path.clear();
225  ltype.name = "DIVIDE2";
226  ltype.desc = "Divide2 __..__..__..__..__..__..__..__..__..__..__..__..__..__..__..__..";
227  ltype.size = 6;
228  ltype.length = 0.625;
229  ltype.path.push_back(0.25);
230  ltype.path.push_back(-0.125);
231  ltype.path.push_back(0.0);
232  ltype.path.push_back(-0.125);
233  ltype.path.push_back(0.0);
234  ltype.path.push_back(-0.125);
235  cData.lineTypes.push_back(ltype);
236 }
237 
239 {
240  DRW_Layer layer;
241 
242  layer.name = "1";// CUT, OUTLINE
243  layer.color = DRW::black;
244  cData.layers.push_back(layer);
245 
246  layer.name = "8";// DRAW, INK
247  layer.color = DRW::black;
248  cData.layers.push_back(layer);
249 
250  layer.name = "7";// GRAINLINE
251  layer.color = DRW::black;
252  cData.layers.push_back(layer);
253 
254 // layer.name = "6";// MIRROR LINES
255 // layer.color = DRW::black;
256 // cData.layers.push_back(layer);
257 
258  layer.name = "11";// INTCUT
259  layer.color = DRW::black;
260  cData.layers.push_back(layer);
261 
262 // layer.name = "13";// DRILL
263 // layer.color = DRW::black;
264 // cData.layers.push_back(layer);
265 
266  layer.name = "4";// NOTCH
267  layer.color = DRW::black;
268  cData.layers.push_back(layer);
269 
270  // Optitex doesn't like this layer
271 // layer.name = "19";// TEXT
272 // layer.color = DRW::black;
273 // cData.layers.push_back(layer);
274 
275 // layer.name = "26";// REF
276 // layer.color = DRW::black;
277 // cData.layers.push_back(layer);
278 }
279 
281 {
282  cData.headerC.addStr("$CLAYER", "1", 8);
283 }
284 
286 {
287  DRW_Layer defLayer;
288  defLayer.name = "0";
289  defLayer.color = DRW::black; // default color
290  defLayer.lWeight = DRW_LW_Conv::width03; // default width
291  cData.layers.push_back(defLayer);
292 }
293 
295 {
296  DRW_Textstyle style;
297  style.name = "Standard";
298  style.lastHeight = 2.5;
299  style.font = "txt";
300 
301  cData.textStyles.push_back(style);
302 }
303 
305 {
306  DRW_AppId ai;
307  ai.name ="Seamly2D";
308  cData.appIds.push_back(ai);
309 }
310 
311 void dx_iface::AddEntity(DRW_Entity *e)
312 {
313  cData.mBlock->ent.push_back(e);
314 }
315 
316 UTF8STRING dx_iface::AddFont(const QFont &f)
317 {
318  DRW_Textstyle ts;
319  ts.name = f.family().toUpper().toStdString();
320 
321  // Idea source https://stackoverflow.com/questions/20111522/writing-text-styles-into-dxf-from-a-delphi-application
322  if (f.bold())
323  {
324  ts.name += "_BOLD";
325  ts.fontFamily += 0x2000000;
326  }
327 
328  if (f.italic())
329  {
330  ts.name += "_ITALIC";
331  ts.fontFamily += 0x1000000;
332  }
333 
334  for (auto it = cData.textStyles.begin() ; it !=cData.textStyles.end() ; ++it)
335  {
336  if ((*it).name == ts.name)
337  {
338  return ts.name;
339  }
340  }
341 
342  ts.font = f.family().toStdString();
343 
344  cData.textStyles.push_back(ts);
345 
346  return ts.name;
347 }
348 
350 {
351  cData.blocks.push_back(block);
352 }
353 
355 {
357  locMap["croatian"] = "ISO8859-2";
358  locMap["cs"] = "ISO8859-2";
359  locMap["cs_CS"] = "ISO8859-2";
360  locMap["cs_CZ"] = "ISO8859-2";
361  locMap["cz"] = "ISO8859-2";
362  locMap["cz_CZ"] = "ISO8859-2";
363  locMap["czech"] = "ISO8859-2";
364  locMap["hr"] = "ISO8859-2";
365  locMap["hr_HR"] = "ISO8859-2";
366  locMap["hu"] = "ISO8859-2";
367  locMap["hu_HU"] = "ISO8859-2";
368  locMap["hungarian"] = "ISO8859-2";
369  locMap["pl"] = "ISO8859-2";
370  locMap["pl_PL"] = "ISO8859-2";
371  locMap["polish"] = "ISO8859-2";
372  locMap["ro"] = "ISO8859-2";
373  locMap["ro_RO"] = "ISO8859-2";
374  locMap["rumanian"] = "ISO8859-2";
375  locMap["serbocroatian"] = "ISO8859-2";
376  locMap["sh"] = "ISO8859-2";
377  locMap["sh_SP"] = "ISO8859-2";
378  locMap["sh_YU"] = "ISO8859-2";
379  locMap["sk"] = "ISO8859-2";
380  locMap["sk_SK"] = "ISO8859-2";
381  locMap["sl"] = "ISO8859-2";
382  locMap["sl_CS"] = "ISO8859-2";
383  locMap["sl_SI"] = "ISO8859-2";
384  locMap["slovak"] = "ISO8859-2";
385  locMap["slovene"] = "ISO8859-2";
386  locMap["sr_SP"] = "ISO8859-2";
387 
388  locMap["eo"] = "ISO8859-3";
389 
390  locMap["ee"] = "ISO8859-4";
391  locMap["ee_EE"] = "ISO8859-4";
392 
393  locMap["mk"] = "ISO8859-5";
394  locMap["mk_MK"] = "ISO8859-5";
395  locMap["sp"] = "ISO8859-5";
396  locMap["sp_YU"] = "ISO8859-5";
397 
398  locMap["ar_AA"] = "ISO8859-6";
399  locMap["ar_SA"] = "ISO8859-6";
400  locMap["arabic"] = "ISO8859-6";
401 
402  locMap["el"] = "ISO8859-7";
403  locMap["el_GR"] = "ISO8859-7";
404  locMap["greek"] = "ISO8859-7";
405 
406  locMap["hebrew"] = "ISO8859-8";
407  locMap["he"] = "ISO8859-8";
408  locMap["he_IL"] = "ISO8859-8";
409  locMap["iw"] = "ISO8859-8";
410  locMap["iw_IL"] = "ISO8859-8";
411 
412  locMap["tr"] = "ISO8859-9";
413  locMap["tr_TR"] = "ISO8859-9";
414  locMap["turkish"] = "ISO8859-9";
415 
416  locMap["lt"] = "ISO8859-13";
417  locMap["lt_LT"] = "ISO8859-13";
418  locMap["lv"] = "ISO8859-13";
419  locMap["lv_LV"] = "ISO8859-13";
420 
421  locMap["et"] = "ISO8859-15";
422  locMap["et_EE"] = "ISO8859-15";
423  locMap["br_FR"] = "ISO8859-15";
424  locMap["ca_ES"] = "ISO8859-15";
425  locMap["de"] = "ISO8859-15";
426  locMap["de_AT"] = "ISO8859-15";
427  locMap["de_BE"] = "ISO8859-15";
428  locMap["de_DE"] = "ISO8859-15";
429  locMap["de_LU"] = "ISO8859-15";
430  locMap["en_IE"] = "ISO8859-15";
431  locMap["es"] = "ISO8859-15";
432  locMap["es_ES"] = "ISO8859-15";
433  locMap["eu_ES"] = "ISO8859-15";
434  locMap["fi"] = "ISO8859-15";
435  locMap["fi_FI"] = "ISO8859-15";
436  locMap["finnish"] = "ISO8859-15";
437  locMap["fr"] = "ISO8859-15";
438  locMap["fr_FR"] = "ISO8859-15";
439  locMap["fr_BE"] = "ISO8859-15";
440  locMap["fr_LU"] = "ISO8859-15";
441  locMap["french"] = "ISO8859-15";
442  locMap["ga_IE"] = "ISO8859-15";
443  locMap["gl_ES"] = "ISO8859-15";
444  locMap["it"] = "ISO8859-15";
445  locMap["it_IT"] = "ISO8859-15";
446  locMap["oc_FR"] = "ISO8859-15";
447  locMap["nl"] = "ISO8859-15";
448  locMap["nl_BE"] = "ISO8859-15";
449  locMap["nl_NL"] = "ISO8859-15";
450  locMap["pt"] = "ISO8859-15";
451  locMap["pt_PT"] = "ISO8859-15";
452  locMap["sv_FI"] = "ISO8859-15";
453  locMap["wa_BE"] = "ISO8859-15";
454 
455  locMap["uk"] = "KOI8-U";
456  locMap["uk_UA"] = "KOI8-U";
457  locMap["ru_YA"] = "KOI8-U";
458  locMap["ukrainian"] = "KOI8-U";
459  locMap["ru_RU"] = "KOI8-U";
460 
461  locMap["be"] = "KOI8-R";
462  locMap["be_BY"] = "KOI8-R";
463  locMap["bg"] = "KOI8-R";
464  locMap["bg_BG"] = "KOI8-R";
465  locMap["bulgarian"] = "KOI8-R";
466  locMap["ba_RU"] = "KOI8-R";
467  locMap["ky"] = "KOI8-R";
468  locMap["ky_KG"] = "KOI8-R";
469  locMap["kk"] = "KOI8-R";
470  locMap["kk_KZ"] = "KOI8-R";
471 
472  QLocale locale(qApp->Settings()->GetLocale());
473  return locMap.value(locale.name().toStdString(), "ISO8859-1");
474 }
dx_ifaceBlock * mBlock
Definition: dxiface.h:90
DRW_Header headerC
Definition: dxiface.h:80
std::list< DRW_AppId > appIds
Definition: dxiface.h:86
std::list< DRW_Dimstyle > dimStyles
Definition: dxiface.h:83
std::list< DRW_Vport > VPorts
Definition: dxiface.h:84
std::list< dx_ifaceBlock * > blocks
Definition: dxiface.h:87
std::list< DRW_LType > lineTypes
Definition: dxiface.h:81
std::list< DRW_Layer > layers
Definition: dxiface.h:82
std::list< DRW_Textstyle > textStyles
Definition: dxiface.h:85
std::list< DRW_Entity * > ent
Definition: dxiface.h:53
DRW::Version version
Definition: dxiface.h:132
virtual void writeAppId()
Definition: dxiface.cpp:163
void AddBlock(dx_ifaceBlock *block)
Definition: dxiface.cpp:349
void InitTextstyles()
Definition: dxiface.cpp:294
void InitAppId()
Definition: dxiface.cpp:304
void AddQtLTypes()
Definition: dxiface.cpp:193
virtual void writeVports()
Definition: dxiface.cpp:153
virtual void writeDimstyles()
Definition: dxiface.cpp:158
dx_data cData
Definition: dxiface.h:131
void AddEntity(DRW_Entity *e)
Definition: dxiface.cpp:311
void AddDefLayers()
Definition: dxiface.cpp:285
dxfRW * dxfW
Definition: dxiface.h:130
virtual void writeEntities()
Definition: dxiface.cpp:133
virtual void writeLTypes()
Definition: dxiface.cpp:138
virtual void writeHeader(DRW_Header &data)
Definition: dxiface.cpp:109
virtual void writeLayers()
Definition: dxiface.cpp:143
bool fileExport(bool binary)
Definition: dxiface.cpp:37
void writeEntity(DRW_Entity *e)
Definition: dxiface.cpp:43
UTF8STRING AddFont(const QFont &f)
Definition: dxiface.cpp:316
dx_iface(const std::string &file, DRW::Version v, VarMeasurement varMeasurement, VarInsunits varInsunits)
Definition: dxiface.cpp:22
void AddAAMALayers()
Definition: dxiface.cpp:238
virtual ~dx_iface()
Definition: dxiface.cpp:32
virtual void writeBlockRecords()
Definition: dxiface.cpp:128
void InitHeader(VarMeasurement varMeasurement, VarInsunits varInsunits)
Definition: dxiface.cpp:168
virtual void writeBlocks()
Definition: dxiface.cpp:117
void AddAAMAHeaderData()
Definition: dxiface.cpp:280
virtual void writeTextstyles()
Definition: dxiface.cpp:148
static std::string LocaleToISO()
Definition: dxiface.cpp:354
VarMeasurement
Definition: dxfdef.h:61
VarInsunits
Definition: dxfdef.h:64
#define qApp
Definition: vapplication.h:67