3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/28/2010 Added this text. :-)
17 #include "filterdxf1.h"
20 #include "filterdxf.h"
22 #include "information.h"
25 #include "dimlinear.h"
26 #include "dimaligned.h"
27 #include "dimangular.h"
28 #include "dimdiametric.h"
29 #include "dimradial.h"
32 * Default constructor.
34 FilterDXF1::FilterDXF1(): FilterInterface()
36 DEBUG->print("Setting up DXF 1 filter...");
38 addImportFormat(RS2::FormatDXF1);
42 * Implementation of the method used for RS_Import to communicate
45 * @param graphic The graphic in which the entities from the file
46 * will be created or the graphics from which the entities are
47 * taken to be stored in a file.
49 bool FilterDXF1::fileImport(Drawing& g, const QString& file, RS2::FormatType /*type*/)
51 DEBUG->print("DXF1 Filter: importing file '%s'...", file.toLatin1().data());
62 if (readFileInBuffer())
65 return readFromBuffer();
74 * Reads a dxf1 file from buffer.
76 bool FilterDXF1::readFromBuffer()
78 DEBUG->print("\nDXF: Read from buffer");
80 bool ret; // returned value
81 QString dxfLine; // A line in the dxf file
82 QString dxfCode; // A Code in the dxf file as string
83 int code = -1; // Dxf-code as number
84 double vx1 = 0.0, vy1 = 0.0; // Start point
85 double vx2 = 0.0, vy2 = 0.0; // End point
86 double vcx = 0.0, vcy = 0.0; // Centre
87 double vcr = 0.0; // Radius
88 double va1 = 0.0, va2 = 0.0; // Start / End Angle
89 //double vab=0.0, // Bulge
90 // vpx=0.0, vpy=0.0; // First Polyline point
91 //double ax=0.0, ay=0.0; // Current coordinate
92 //bool plClose=false; // Polyline closed-flag
93 QString lastLayer; // Last used layer name (test adding only
94 // if the new layer!=lastLayer)
95 //int currentLayerNum=0; // Current layer number
96 Layer * currentLayer = 0; // Pointer to current layer
97 //QList<RGraphic> blockList; // List of blocks
98 //blockList.setAutoDelete( true );
99 //bool oldColorNumbers=false; // use old color numbers (qcad<1.5.3)
102 ///if(!add) graphic->clearLayers();
104 //graphic->addLayer(DEF_DEFAULTLAYER);
106 //DEBUG->print( "\nDefault layer added" );
108 // Loaded graphics without unit information: load as unit less:
109 //graphic->setUnit( None );
111 DEBUG->print("\nUnit set");
117 DEBUG->print("\nBuffer OK");
118 DEBUG->print("\nBuffer: ");
123 dxfLine = getBufLine();
124 pen = Pen(Color(RS2::FlagByLayer), RS2::WidthByLayer, RS2::LineByLayer);
126 DEBUG->print("\ndxfLine: ");
127 DEBUG->print(dxfLine.toAscii().data());
129 // $-Setting in the header of DXF found
131 if (!dxfLine.isEmpty() && dxfLine[0] == '$')
135 if (dxfLine == "$INSUNITS")
137 dxfCode = getBufLine();
138 if (!dxfCode.isEmpty())
140 if (dxfCode.toInt() == 70)
142 dxfLine = getBufLine();
143 if (!dxfLine.isEmpty())
145 graphic->addVariable("$INSUNITS", dxfLine, 70);
147 switch( dxfLine.toInt() ) {
148 case 0: graphic->setUnit( RS2::None ); break;
149 case 1: graphic->setUnit( RS2::Inch ); break;
150 case 2: graphic->setUnit( RS2::Foot ); break;
151 case 3: graphic->setUnit( RS2::Mile ); break;
152 case 4: graphic->setUnit( RS2::Millimeter ); break;
153 case 5: graphic->setUnit( RS2::Centimeter ); break;
154 case 6: graphic->setUnit( RS2::Meter ); break;
155 case 7: graphic->setUnit( RS2::Kilometer ); break;
156 case 8: graphic->setUnit( RS2::Microinch ); break;
157 case 9: graphic->setUnit( RS2::Mil ); break;
158 case 10: graphic->setUnit( RS2::Yard ); break;
159 case 11: graphic->setUnit( RS2::Angstrom ); break;
160 case 12: graphic->setUnit( RS2::Nanometer ); break;
161 case 13: graphic->setUnit( RS2::Micron ); break;
162 case 14: graphic->setUnit( RS2::Decimeter ); break;
163 case 15: graphic->setUnit( RS2::Decameter ); break;
164 case 16: graphic->setUnit( RS2::Hectometer ); break;
165 case 17: graphic->setUnit( RS2::Gigameter ); break;
166 case 18: graphic->setUnit( RS2::Astro ); break;
167 case 19: graphic->setUnit( RS2::Lightyear ); break;
168 case 20: graphic->setUnit( RS2::Parsec ); break;
171 graphic->setDimensionUnit( graphic->getUnit() );
172 //graphic->setGridUnit( graphic->getUnit() );
181 else if (dxfLine == "$DIMALT")
183 dxfCode = getBufLine();
184 if (!dxfCode.isEmpty())
186 if (dxfCode.toInt() == 70)
188 dxfLine = getBufLine();
189 if (!dxfLine.isEmpty())
191 graphic->addVariable("$DIMALT", dxfLine, 70);
193 switch( dxfLine.toInt() ) {
194 case 0: graphic->setDimensionUnit( RS2::None ); break;
195 case 1: graphic->setDimensionUnit( RS2::Inch ); break;
196 case 2: graphic->setDimensionUnit( RS2::Foot ); break;
197 case 3: graphic->setDimensionUnit( RS2::Mile ); break;
198 case 4: graphic->setDimensionUnit( RS2::Millimeter ); break;
199 case 5: graphic->setDimensionUnit( RS2::Centimeter ); break;
200 case 6: graphic->setDimensionUnit( RS2::Meter ); break;
201 case 7: graphic->setDimensionUnit( RS2::Kilometer ); break;
202 case 8: graphic->setDimensionUnit( RS2::Microinch ); break;
203 case 9: graphic->setDimensionUnit( RS2::Mil ); break;
204 case 10: graphic->setDimensionUnit( RS2::Yard ); break;
205 case 11: graphic->setDimensionUnit( RS2::Angstrom ); break;
206 case 12: graphic->setDimensionUnit( RS2::Nanometer ); break;
207 case 13: graphic->setDimensionUnit( RS2::Micron ); break;
208 case 14: graphic->setDimensionUnit( RS2::Decimeter ); break;
209 case 15: graphic->setDimensionUnit( RS2::Decameter ); break;
210 case 16: graphic->setDimensionUnit( RS2::Hectometer ); break;
211 case 17: graphic->setDimensionUnit( RS2::Gigameter ); break;
212 case 18: graphic->setDimensionUnit( RS2::Astro ); break;
213 case 19: graphic->setDimensionUnit( RS2::Lightyear ); break;
214 case 20: graphic->setDimensionUnit( RS2::Parsec ); break;
224 /*else if( dxfLine=="$DIMLUNIT" ) {
225 if(dxfCode=getBufLine()) {
226 if( dxfCode.toInt()==70 ) {
227 if( dxfLine=getBufLine() ) {
228 switch( dxfLine.toInt() ) {
229 case 1: graphic->setDimensionFormat( Scientific ); break;
231 case 3: graphic->setDimensionFormat( Decimal ); break;
233 case 5: graphic->setDimensionFormat( Fractional ); break;
241 // Dimension Arrow Size:
243 else if (dxfLine == "$DIMASZ")
245 dxfCode = getBufLine();
246 if (!dxfCode.isEmpty() && dxfCode.toInt() == 40)
248 dxfLine = getBufLine();
249 if (!dxfLine.isEmpty())
251 graphic->addVariable("$DIMASZ", dxfLine, 40);
252 //graphic->setDimensionArrowSize( dxfLine.toDouble() );
260 else if( dxfLine=="$DIMSCALE" ) {
261 if(dxfCode=getBufLine()) {
262 if( dxfCode.toInt()==40 ) {
263 if( dxfLine=getBufLine() ) {
264 graphic->setDimensionScale( dxfLine.toDouble() );
271 // Dimension Text Height:
273 else if (dxfLine == "$DIMTXT")
275 dxfCode = getBufLine();
276 if (!dxfCode.isEmpty())
278 if (dxfCode.toInt() == 40)
280 dxfLine = getBufLine();
281 if (!dxfLine.isEmpty())
283 graphic->addVariable("$DIMTXT", dxfLine, 40);
284 //graphic->setDimensionTextHeight( dxfLine.toDouble() );
290 // Dimension exactness:
292 else if (dxfLine == "$DIMRND")
294 dxfCode = getBufLine();
295 if (dxfCode.toInt() == 40)
297 dxfLine = getBufLine();
298 if (!dxfLine.isEmpty())
300 graphic->addVariable("$DIMRND", dxfLine, 40);
301 //if( dxfLine.toDouble()>0.000001 ) {
302 //graphic->setDimensionExactness( dxfLine.toDouble() );
308 // Dimension over length:
310 else if (dxfLine == "$DIMEXE")
312 dxfCode = getBufLine();
313 if (dxfCode.toInt() == 40)
315 dxfLine = getBufLine();
316 if (!dxfLine.isEmpty())
318 graphic->addVariable("$DIMEXE", dxfLine, 40);
319 //graphic->setDimensionOverLength( dxfLine.toDouble() );
324 // Dimension under length:
326 else if( dxfLine=="$DIMEXO" )
328 dxfCode = getBufLine();
329 if( dxfCode.toInt()==40 )
331 dxfLine = getBufLine();
332 if (!dxfLine.isEmpty())
334 graphic->addVariable("$DIMEXO", dxfLine, 40);
335 //graphic->setDimensionUnderLength( dxfLine.toDouble() );
341 // Angle dimension format:
343 else if( dxfLine=="$DIMAUNIT" )
345 dxfCode = getBufLine();
346 if( dxfCode.toInt()==70 )
348 dxfLine = getBufLine();
349 if (!dxfLine.isEmpty())
351 graphic->addVariable("$DIMAUNIT", dxfLine, 70);
353 switch( dxfLine.toInt() ) {
354 case 0: graphic->setAngleDimensionFormat( DecimalDegrees ); break;
355 case 1: graphic->setAngleDimensionFormat( DegreesMinutesSeconds ); break;
356 case 2: graphic->setAngleDimensionFormat( Gradians ); break;
357 case 3: graphic->setAngleDimensionFormat( Radians ); break;
358 case 4: graphic->setAngleDimensionFormat( Surveyor ); break;
366 // Angle dimension exactness:
368 else if( dxfLine=="$DIMADEC" )
370 dxfCode = getBufLine();
371 if( dxfCode.toInt()==70 )
373 dxfLine = getBufLine();
374 if (!dxfLine.isEmpty())
376 graphic->addVariable("$DIMADEC", dxfLine, 70);
377 //graphic->setAngleDimensionExactness( Math::pow(0.1, dxfLine.toInt()) );
384 else if (dxfLine == "$GRIDUNIT")
386 dxfCode = getBufLine();
388 if (dxfCode.toInt() == 10)
390 dxfLine = getBufLine();
392 if (!dxfLine.isEmpty())
394 double x = atof(dxfLine.toAscii().data());
395 dxfLine = getBufLine();
397 if (!dxfLine.isEmpty())
399 double y = atof(dxfLine.toAscii().data());
401 graphic->addVariable("$GRIDUNIT", Vector(x, y), 10);
407 double gx=dxfLine.toDouble();
408 if (gx<0.0001) gx=0.0001;
409 graphic->setMinGridX(gx);
410 graphic->setGridFormat( Fractional );
412 for( double q=0.00000001; q<=100000.0; q*=10.0 ) {
413 if( mtCompFloat(gx, q, q/1000.0) ) {
414 graphic->setGridFormat( Decimal );
422 if(dxfCode=getBufLine()) {
423 if( dxfCode.toInt()==20 ) {
424 if( dxfLine=getBufLine() ) {
425 double gy=dxfLine.toDouble();
426 if (gy<0.0001) gy=0.0001;
427 graphic->setMinGridY(gy);
433 // Page limits min x/y:
435 /*else if( dxfLine=="$PLIMMIN" ) {
436 if(dxfCode=getBufLine()) {
437 if( dxfCode.toInt()==10 ) {
438 if( dxfLine=getBufLine() ) {
439 graphic->setPageOriginX( dxfLine.toDouble() );
443 if(dxfCode=getBufLine()) {
444 if( dxfCode.toInt()==20 ) {
445 if( dxfLine=getBufLine() ) {
446 graphic->setPageOriginY( dxfLine.toDouble() );
453 // Page limits min x/y:
456 else if( dxfLine=="$PLIMMAX" ) {
457 if(dxfCode=getBufLine()) {
458 if( dxfCode.toInt()==10 ) {
459 if( dxfLine=getBufLine() ) {
460 graphic->setPageSizeX( dxfLine.toDouble() - graphic->getPageOriginX() );
464 if(dxfCode=getBufLine()) {
465 if( dxfCode.toInt()==20 ) {
466 if( dxfLine=getBufLine() ) {
467 graphic->setPageSizeY( dxfLine.toDouble() - graphic->getPageOriginY() );
474 // Paper space scale:
477 else if( dxfLine=="$PSVPSCALE" ) {
478 if(dxfCode=getBufLine()) {
479 if( dxfCode.toInt()==40 ) {
480 if( dxfLine=getBufLine() ) {
481 graphic->setPaperSpace( dxfLine.toDouble() );
492 else if (!dxfLine.isEmpty() &&
493 dxfLine[0] >= 'A' && dxfLine[0] <= 'Z')
495 if (dxfLine == "EOF")
497 // End of file reached
504 else if (dxfLine == "LAYER")
509 dxfCode = getBufLine();
510 if(!dxfCode.isEmpty())
511 code = dxfCode.toInt();
512 if(!dxfCode.isEmpty() && code != 0)
514 dxfLine = getBufLine();
515 if (!dxfLine.isEmpty())
519 case 2: // Layer name
520 if (dxfLine=="(null)" || dxfLine=="default") {
523 graphic->addLayer(new Layer(dxfLine));
524 graphic->activateLayer(dxfLine);
525 currentLayer = graphic->getActiveLayer();
528 case 70: // Visibility
530 if(dxfLine.toInt()&5) {
531 if(currentLayerNum>=0 && currentLayerNum<DEF_MAXLAYERS) {
532 graphic->layer[currentLayerNum].DelFlag(Y_VISIBLE);
539 //currentLayer->setStyle( graphic->nameToStyle(dxfLine) );
540 pen.setLineType(FilterDXF::nameToLineType(dxfLine));
542 case 39: // Thickness
543 //if(currentLayer) currentLayer->setWidth(dxfLine.toInt());
544 pen.setWidth(FilterDXF::numberToWidth(dxfLine.toInt()));
547 pen.setColor(FilterDXF::numberToColor(dxfLine.toInt()));
549 // currentLayer->setColor( graphic->numberToColor(dxfLine.toInt(), !oldColorNumbers));
558 while(!dxfCode.isEmpty() && code != 0);
562 currentLayer->setPen(pen);
564 //graphic->setStyle("CONTINOUS");
565 //graphic->setWidth(0);
566 //graphic->setColor(0, false);
572 else if(dxfLine=="POINT") {
574 dxfCode=getBufLine();
575 if(!dxfCode.isEmpty())
576 code=dxfCode.toInt();
577 if(!dxfCode.isEmpty() && code!=0) {
578 dxfLine=getBufLine();
579 if(!dxfLine.isEmpty()) {
582 pen.setLineType(FilterDXF::nameToLineType(dxfLine));
585 //if(dxfLine!=lastLayer) {
586 if (dxfLine=="(null)" || dxfLine=="default") {
589 graphic->activateLayer(dxfLine);
594 dxfLine.replace( QRegExp(","), "." );
595 vx1 = dxfLine.toDouble();
598 dxfLine.replace( QRegExp(","), "." );
599 vy1 = dxfLine.toDouble();
601 case 39: // Thickness
602 pen.setWidth(FilterDXF::numberToWidth(dxfLine.toInt()));
605 pen.setColor(FilterDXF::numberToColor(dxfLine.toInt()));
613 while(!dxfCode.isEmpty() && code != 0);
615 graphic->setActivePen(pen);
616 graphic->addEntity(new Point(graphic,
617 PointData(Vector(vx1, vy1))));
623 else if(dxfLine=="LINE") {
625 dxfCode=getBufLine();
627 if(!dxfCode.isEmpty())
628 code=dxfCode.toInt();
629 if(!dxfCode.isEmpty() && code!=0) {
631 dxfLine=getBufLine();
633 if(!dxfLine.isEmpty()) {
636 pen.setLineType(FilterDXF::nameToLineType(dxfLine));
639 //if(dxfLine!=lastLayer) {
640 if (dxfLine=="(null)" || dxfLine=="default") {
643 graphic->activateLayer(dxfLine);
648 dxfLine.replace( QRegExp(","), "." );
649 vx1 = dxfLine.toDouble();
652 dxfLine.replace( QRegExp(","), "." );
653 vy1 = dxfLine.toDouble();
656 dxfLine.replace( QRegExp(","), "." );
657 vx2 = dxfLine.toDouble();
660 dxfLine.replace( QRegExp(","), "." );
661 vy2 = dxfLine.toDouble();
663 case 39: // Thickness
664 pen.setWidth(FilterDXF::numberToWidth(dxfLine.toInt()));
667 pen.setColor(FilterDXF::numberToColor(dxfLine.toInt()));
674 } while(!dxfCode.isEmpty() && code!=0);
676 //if(!mtCompFloat(vx1, vx2) || !mtCompFloat(vy1, vy2)) {
677 //graphic->addLine(vx1, vy1, vx2, vy2, currentLayerNum, add);
678 graphic->setActivePen(pen);
679 graphic->addEntity(new Line(graphic,
680 LineData(Vector(vx1, vy1), Vector(vx2, vy2))));
688 else if(dxfLine=="ARC") {
690 dxfCode=getBufLine();
691 if(!dxfCode.isEmpty())
692 code=dxfCode.toInt();
693 if(!dxfCode.isEmpty() && code!=0) {
694 dxfLine=getBufLine();
695 if(!dxfLine.isEmpty()) {
698 pen.setLineType(FilterDXF::nameToLineType(dxfLine));
701 //if(dxfLine!=lastLayer) {
702 if (dxfLine=="(null)" || dxfLine=="default") {
705 graphic->activateLayer(dxfLine);
710 dxfLine.replace( QRegExp(","), "." );
711 vcx = dxfLine.toDouble();
714 dxfLine.replace( QRegExp(","), "." );
715 vcy = dxfLine.toDouble();
718 dxfLine.replace( QRegExp(","), "." );
719 vcr = dxfLine.toDouble();
721 case 50: // Start Angle
722 dxfLine.replace( QRegExp(","), "." );
723 va1 = Math::correctAngle(dxfLine.toDouble()/ARAD);
725 case 51: // End Angle
726 dxfLine.replace( QRegExp(","), "." );
727 va2 = Math::correctAngle(dxfLine.toDouble()/ARAD);
729 case 39: // Thickness
730 pen.setWidth(FilterDXF::numberToWidth(dxfLine.toInt()));
733 pen.setColor(FilterDXF::numberToColor(dxfLine.toInt()));
740 } while(!dxfCode.isEmpty() && code!=0);
741 //if(vcr>0.0 && !mtCompFloat(va1, va2)) {
742 // graphic->addArc(vcx, vcy, vcr, va1, va2, false, currentLayerNum, add);
744 graphic->setActivePen(pen);
745 graphic->addEntity(new Arc(graphic,
746 ArcData(Vector(vcx, vcy),
747 vcr, va1, va2, false)));
753 else if(dxfLine=="CIRCLE") {
755 dxfCode=getBufLine();
756 if(!dxfCode.isEmpty())
757 code=dxfCode.toInt();
758 if(!dxfCode.isEmpty() && code!=0) {
759 dxfLine=getBufLine();
760 if(!dxfLine.isEmpty()) {
763 pen.setLineType(FilterDXF::nameToLineType(dxfLine));
766 //if(dxfLine!=lastLayer) {
767 if (dxfLine=="(null)" || dxfLine=="default") {
770 graphic->activateLayer(dxfLine);
775 dxfLine.replace( QRegExp(","), "." );
776 vcx = dxfLine.toDouble();
779 dxfLine.replace( QRegExp(","), "." );
780 vcy = dxfLine.toDouble();
783 dxfLine.replace( QRegExp(","), "." );
784 vcr = dxfLine.toDouble();
786 case 39: // Thickness
787 pen.setWidth(FilterDXF::numberToWidth(dxfLine.toInt()));
790 pen.setColor(FilterDXF::numberToColor(dxfLine.toInt()));
797 } while(!dxfCode.isEmpty() && code!=0);
799 graphic->addCircle(vcx, vcy, vcr, 0.0, 360.0, false, currentLayerNum, add);
801 graphic->setActivePen(pen);
802 graphic->addEntity(new Circle(graphic,
803 CircleData(Vector(vcx, vcy),
812 if(dxfLine=="HATCH") {
814 dxfCode=getBufLine();
815 if(dxfCode) code=dxfCode.toInt();
816 if(dxfCode && code!=0) {
817 dxfLine=getBufLine();
821 // if(dxfLine!=lastLayer) {
822 if (dxfLine=="(null)" || dxfLine=="default") {
825 graphic->activateLayer(dxfLine);
830 vx1 = dxfLine.toDouble();
833 vy1 = dxfLine.toDouble();
834 //graphic->Vec[vc].CreatePoint(vy1, vx1, currentLayerNum);
835 //if(vc<vElements-1) ++vc;
838 vx2 = dxfLine.toDouble();
841 vy2 = dxfLine.toDouble();
842 //graphic->Vec[vc].CreatePoint(vy2, vx2, currentLayerNum);
843 //if(vc<vElements-1) ++vc;
850 }while(dxfCode && code!=0);
852 if(!mt.CompFloat(vx1, vx2) || !mt.CompFloat(vy1, vy2)) {
853 graphic->Vec[vc].CreateLine(vx1, vy1, vx2, vy2, currentLayerNum);
854 if(vc<vElements-1) ++vc;
856 if(++updProgress==1000) {
857 np->getStateWin()->UpdateProgressBar((int)(pcFact*vc)+25);
868 else if(dxfLine=="TEXT") {
870 QString vtext; // the text
871 char vtextStyle[256]; // text style (normal_ro, cursive_ri, normal_st, ...)
872 double vheight=10.0; // text height
873 double vtextAng=0.0; // text angle
874 //double vradius=0.0; // text radius
875 //double vletterspace=2.0; // Text letter space
876 //double vwordspace=6.0; // Text wordspace
877 QString vfont; // font "normal", "cursive", ...
878 RS2::HAlign vhalign=RS2::HAlignLeft;
879 // alignment (0=left, 1=center, 2=right)
880 //int vattachement=7; // 1=top left, 2, 3, 4, 5, 6, 7, 8, 9=bottom right
881 //uint vfl=0; // special flags
882 bool codeSeven=false; // Have we found a code seven?
884 vtextStyle[0] = '\0';
888 dxfCode=getBufLine();
889 if(!dxfCode.isEmpty())
890 code=dxfCode.toInt();
891 if(!dxfCode.isEmpty() && code!=0) {
892 if(code!=1 && code!=3 && code!=7)
893 dxfLine=getBufLine();
894 if(!dxfLine.isEmpty() || code==1 || code==3 || code==7) {
898 case 1: // Text itself
899 vtext = getBufLine();
900 strDecodeDxfString(vtext);
903 case 3: // Text parts (always 250 chars)
904 vtext = getBufLine();
908 pen.setLineType(FilterDXF::nameToLineType(dxfLine));
912 // Text style (normal_ro#50.0,
913 // cursive_ri#20.0, normal_st)
914 qstrncpy(vtextStyle, getBufLine().toAscii().data(), 249);
920 sscanf(vtextStyle, "%[^_#\n]", dummy);
927 if(strstr(vtextStyle, "_ro"))
929 else if(strstr(vtextStyle, "_ri"))
936 /*if(strstr(vtextStyle, "_fix")) {
937 vfl=vfl|E_FIXEDWIDTH;
940 // get radius, letterspace, wordspace:
943 char * ptr; // pointer to value
944 ptr = strchr(vtextStyle, '#');
949 /*if(vfl&E_ROUNDOUT || vfl&E_ROUNDIN) {
952 sscanf(ptr, "%lf", &vradius);
954 ptr = strchr(ptr, '#');
957 // Parse letter space:
960 sscanf(ptr, "%lf", &vletterspace);
963 ptr = strchr(ptr, '#');
967 sscanf(ptr, "%lf", &vwordspace);
977 //if(dxfLine!=lastLayer) {
978 if (dxfLine == "(null)" || dxfLine == "default")
983 graphic->activateLayer(dxfLine);
989 dxfLine.replace( QRegExp(","), "." );
990 vx1 = dxfLine.toDouble();
993 dxfLine.replace( QRegExp(","), "." );
994 vy1 = dxfLine.toDouble();
997 dxfLine.replace( QRegExp(","), "." );
998 vheight = dxfLine.toDouble();
1000 vletterspace = vheight*0.2;
1001 vwordspace = vheight*0.6;
1005 dxfLine.replace( QRegExp(","), "." );
1006 vtextAng = dxfLine.toDouble() / ARAD;
1008 case 72: {// alignment
1010 int v = dxfLine.toInt();
1012 vhalign = RS2::HAlignCenter;
1014 vhalign = RS2::HAlignRight;
1016 vhalign = RS2::HAlignLeft;
1020 case 39: // Thickness
1021 pen.setWidth(FilterDXF::numberToWidth(dxfLine.toInt()));
1024 pen.setColor(FilterDXF::numberToColor(dxfLine.toInt()));
1032 while(!dxfCode.isEmpty() && code != 0);
1034 char * i = strchr(vtextStyle, '#');
1063 else if(dxfLine=="DIMENSION") {
1065 double v10=0.0, v20=0.0;
1066 double v13=0.0, v23=0.0;
1067 double v14=0.0, v24=0.0;
1068 double v15=0.0, v25=0.0;
1069 double v16=0.0, v26=0.0;
1070 double v40=0.0, v50=0.0;
1073 dxfCode=getBufLine();
1074 if(!dxfCode.isEmpty()) {
1075 code=dxfCode.toInt();
1077 if(!dxfCode.isEmpty() && code!=0) {
1078 dxfLine=getBufLine();
1079 if(!dxfLine.isEmpty()) {
1081 case 1: // Text (if any)
1084 // Mend unproper savings of older versions:
1085 if(dimText==" " || dimText==";;")
1088 //else dimText.replace(QRegExp("%%c"), "�");
1090 strDecodeDxfString(dimText);
1093 pen.setLineType(FilterDXF::nameToLineType(dxfLine));
1096 //if(dxfLine!=lastLayer) {
1097 if (dxfLine=="(null)" || dxfLine=="default") {
1100 graphic->activateLayer(dxfLine);
1101 //lastLayer=dxfLine;
1104 case 10: // line position x
1105 dxfLine.replace( QRegExp(","), "." );
1106 v10 = dxfLine.toDouble();
1108 case 20: // line position y
1109 dxfLine.replace( QRegExp(","), "." );
1110 v20 = dxfLine.toDouble();
1113 dxfLine.replace( QRegExp(","), "." );
1114 v13 = dxfLine.toDouble();
1117 dxfLine.replace( QRegExp(","), "." );
1118 v23 = dxfLine.toDouble();
1121 dxfLine.replace( QRegExp(","), "." );
1122 v14 = dxfLine.toDouble();
1125 dxfLine.replace( QRegExp(","), "." );
1126 v24 = dxfLine.toDouble();
1129 dxfLine.replace( QRegExp(","), "." );
1130 v15 = dxfLine.toDouble();
1133 dxfLine.replace( QRegExp(","), "." );
1134 v25 = dxfLine.toDouble();
1137 dxfLine.replace( QRegExp(","), "." );
1138 v16 = dxfLine.toDouble();
1141 dxfLine.replace( QRegExp(","), "." );
1142 v26 = dxfLine.toDouble();
1145 dxfLine.replace( QRegExp(","), "." );
1146 v40 = dxfLine.toDouble();
1149 dxfLine.replace( QRegExp(","), "." );
1150 v50 = dxfLine.toDouble();
1153 typ = dxfLine.toInt();
1155 case 39: // Thickness
1156 pen.setWidth(FilterDXF::numberToWidth(dxfLine.toInt()));
1159 pen.setColor(FilterDXF::numberToColor(dxfLine.toInt()));
1167 } while(!dxfCode.isEmpty() && code!=0);
1171 // Remove Bit values:
1173 typ-=128; // Location of Text
1176 typ-= 64; // Ordinate
1204 graphic->addEntity(d);
1211 Vector(v13, v23).angleTo(Vector(v10,v20));
1213 Vector(v13, v23).distanceTo(Vector(v10,v20));
1216 defP.setPolar(dist, angle);
1217 defP+=Vector(v14, v24);
1239 graphic->addEntity(d);
1246 LineData(Vector(v13, v23),
1249 LineData(Vector(v10, v20),
1253 //bool inters=false;
1254 //tmpEl1.getIntersection(&tmpEl2,
1255 // &inters, &vcx, &vcy, 0,0,0,0, false);
1256 s = Information::getIntersection(
1259 if (s.get(0).valid) {
1262 //vcr = Vector(vcx, vcy).distanceTo(v16, v26);
1264 /*if(Vector(vcx,vcy).distanceTo(v13,v23)<vcr) {
1265 va1 = tl1.getAngle1();
1267 va1 = tl2.getAngle2();
1270 if(Vector(vcx,vcy).distanceTo(v10,v20)<vcr) {
1271 va2 = tl2.getAngle1();
1273 va2 = tl2.getAngle2();
1277 graphic->addDimension(vcx, vcy, va1, va2,
1278 mtGetDistance(vcx, vcy, v13, v23),
1279 mtGetDistance(vcx, vcy, v10, v20),
1309 graphic->addEntity(d);
1317 graphic->addDimension(v10, v20, v15, v25,
1320 E_STRAIGHT|E_RADIUS,
1327 .angleTo(Vector(v15, v25));
1329 v2.setPolar(v40, ang);
1345 Vector(v10, v20) + v2,
1350 graphic->addEntity(d);
1357 graphic->addDimension(v13, v23, v14, v24,
1366 .angleTo(Vector(v15, v25));
1368 v2.setPolar(v40, ang);
1384 Vector(v10, v20) + v2,
1389 graphic->addEntity(d);
1391 LeaderData data(true);
1393 new Leader(graphic, data);
1394 d->addVertex(Vector(v14, v24));
1395 d->addVertex(Vector(v10, v20));
1397 graphic->addEntity(d);
1401 //graphic->elementCurrent()->setText(dimText);
1410 else if(dxfLine=="HATCH") {
1411 QString patternName="45";
1412 double patternScale=1.0;
1415 int nextObjectTyp=T_LINE;
1416 double v10=0.0, v20=0.0,
1421 dxfCode=getBufLine();
1422 if(dxfCode) code=dxfCode.toInt();
1423 if(dxfCode && code!=0) {
1424 dxfLine=getBufLine();
1428 patternName = dxfLine;
1431 pen.setLineType(FilterDXF::nameToLineType(dxfLine));
1434 // if(dxfLine!=lastLayer) {
1435 if (dxfLine=="(null)" || dxfLine=="default") {
1438 graphic->activateLayer(dxfLine);
1439 //lastLayer=dxfLine;
1442 case 10: // Start point/center of boundary line/arc
1443 dxfLine.replace( QRegExp(","), "." );
1444 v10=dxfLine.toDouble();
1446 case 20: // Start point/center of boundary line/arc
1447 dxfLine.replace( QRegExp(","), "." );
1448 v20=dxfLine.toDouble();
1450 case 11: // End point of boundary line
1451 dxfLine.replace( QRegExp(","), "." );
1452 v11=dxfLine.toDouble();
1454 case 21: // End point of boundary line
1455 dxfLine.replace( QRegExp(","), "." );
1456 v21=dxfLine.toDouble();
1457 if(nextObjectTyp==T_LINE) {
1458 int elnu=graphic->addLine(v10, v20, v11, v21, currentLayerNum, add);
1459 graphic->elementAt(elnu)->setFlag(E_TAGGED);
1462 case 40: // Radius of boundary entity
1463 dxfLine.replace( QRegExp(","), "." );
1464 v40=dxfLine.toDouble();
1466 case 50: // Start angle
1467 dxfLine.replace( QRegExp(","), "." );
1468 v50=dxfLine.toDouble();
1470 case 51: // End angle
1471 dxfLine.replace( QRegExp(","), "." );
1472 v51=dxfLine.toDouble();
1474 case 73: // Counterclockwise?
1475 if(nextObjectTyp==T_ARC) {
1477 if( mtCompFloat( v50, 0.0 ) && mtCompFloat( v51, 0.0 ) ) {
1478 elnu=graphic->addCircle(v10, v20, v40, 0.0, 360.0, (bool)dxfLine.toInt(), currentLayerNum, add);
1481 elnu=graphic->addArc(v10, v20, v40, v50, v51, (bool)dxfLine.toInt(), currentLayerNum, add);
1483 graphic->elementAt(elnu)->setFlag(E_TAGGED);
1484 //newEl = new RElement( graphic );
1485 //newEl->createArc(v10, v20, v40, v50, v51, (bool)dxfLine.toInt());
1486 //boundaryList.append(newEl);
1490 dxfLine.replace( QRegExp(","), "." );
1491 patternScale=dxfLine.toDouble();
1496 case 70: // Solid (=1) or pattern (=0)
1499 case 39: // Thickness
1500 pen.setWidth(FilterDXF::numberToWidth(dxfLine.toInt()));
1503 pen.setColor(FilterDXF::numberToColor(dxfLine.toInt()));
1505 case 91: // Number of boundary paths (loops)
1506 //numPaths=dxfLine.toInt();
1508 case 92: // Typ of boundary
1511 case 93: // Number of edges in this boundary
1512 //numEdges=dxfLine.toInt();
1514 case 72: // Edge typ
1515 switch(dxfLine.toInt()) {
1516 case 1: nextObjectTyp=T_LINE; break;
1517 case 2: nextObjectTyp=T_ARC; break;
1527 }while(dxfCode && code!=0);
1529 graphic->addHatching(patternScale,
1534 graphic->editDelete(false);
1541 #warning "This will probably fail since it was expecting to be null on EOF"
1542 while (!dxfLine.isEmpty() && dxfLine != "EOF");
1544 //graphic->terminateAction();
1546 //graphic->debugElements();
1559 * Resets the whole object
1562 void FilterDXF1::reset()
1578 * Reset buffer pointer to the beginning of the buffer:
1580 void FilterDXF1::resetBufP()
1586 * Set buffer pointer to the given index:
1588 void FilterDXF1::setBufP(int _fBufP)
1590 if (_fBufP < (int)fSize)
1597 void FilterDXF1::delBuffer()
1607 * Remove any 13-characters in the buffer:
1609 void FilterDXF1::dos2unix()
1611 char * src = fBuf, * dst = fBuf;
1616 while (*src != '\0')
1629 // Get next line in the buffer:
1630 // and overread ALL seperators
1632 // return: -Null-string: end of buffer
1633 // -String which is the next line in buffer
1635 QString FilterDXF1::getBufLine()
1640 if (fBufP >= (int)fSize)
1641 return QString::null;
1645 // Move fBufP pointer to the next line
1646 while (fBufP < (int)fSize && fBuf[fBufP++] != '\0')
1649 // str = QString::fromLocal8Bit(ret).stripWhiteSpace();
1650 str = QString::fromLocal8Bit(ret).simplified();
1652 // if (str.isNull())
1663 // Get next line in the buffer:
1664 // and overread ALL seperators
1666 // return: -Null-string: end of buffer
1667 // -String which is the next line in buffer
1669 char * FilterDXF1::getBufLineCh()
1673 if (fBufP >= (int)fSize)
1679 /*if (*ret == '\0' && noEmptyLines) {
1680 while (++fBufP < (int)fSize && fBuf[fBufP] == '\0')
1682 if (fBufP >= (int)fSize)
1687 // Move fBufP pointer to the next line
1688 while (fBufP < (int)fSize && fBuf[fBufP++] != '\0')
1695 // Copy buffer from a given string:
1697 void FilterDXF1::copyBufFrom(const char * _buf)
1701 fBuf = new char[strlen(_buf) + 16];
1707 // Go to the next '_lstr'-line in buffer:
1709 // return: true: line found
1710 // false: end of buffer
1712 bool FilterDXF1::gotoBufLine(char * _lstr)
1720 while (!l.isNull() && l!=_lstr);
1729 // Goto next line where the string _lstr appears:
1731 // return: true: string in line found
1732 // false: end of buffer
1735 bool FilterDXF1::gotoBufLineString(char * _lstr)
1743 while (!l.isNull() && l.contains(_lstr));
1752 // Replace bynary Bytes (<32) by an other (given) byte:
1754 void FilterDXF1::replaceBinaryBytesBy(char _c)
1758 for(bc=0; bc<(int)fSize; ++bc)
1760 if (fBuf[bc] < 32 && fBuf[bc] >= 0)
1768 // Separate buffer (change chars sc1 and sc2 in '\0'
1770 void FilterDXF1::separateBuf(char _c1,
1775 for(int bc=0; bc<(int)fSize; ++bc)
1777 if (fBuf[bc] == _c1 || fBuf[bc] == _c2 ||
1778 fBuf[bc] == _c3 || fBuf[bc] == _c4)
1786 // remove comment between '_fc' and '_lc'
1787 // comments get replaced by '\0'
1789 void FilterDXF1::removeComment(char _fc, char _lc)
1791 bool rem = false; // Are we removing currrently?
1794 for(bc=0; bc<(int)fSize; ++bc)
1796 if (fBuf[bc] == _fc)
1799 if (fBuf[bc] == _lc)
1810 // Read file '_name' in buffer (buf)
1812 // '_bNum' : Max number of Bytes
1814 // return: true: successful
1815 // false: file not found
1817 bool FilterDXF1::readFileInBuffer(char * _name, int _bNum)
1819 // file.setName(_name);
1820 file.setFileName(_name);
1821 return readFileInBuffer(_bNum);
1824 // Read file in buffer (buf)
1826 // 'bNum' : Max number of Bytes
1828 // return: true: successful
1829 // false: file not found
1831 bool FilterDXF1::readFileInBuffer(int _bNum)
1833 fPointer = fopen(name.toAscii().data(), "rb");
1835 if (fPointer != NULL)
1837 // if (file.open(QIODevice::ReadOnly, fPointer))
1838 if (file.open(fPointer, QIODevice::ReadOnly))
1840 fSize = file.size();
1845 fBuf = new char[_bNum + 16];
1847 // file.readBlock(fBuf, _bNum);
1848 file.read(fBuf, _bNum);
1855 // Convert 13/10 to 10
1866 // Decode a DXF string to the C-convention (special character \P is a \n)
1868 void FilterDXF1::strDecodeDxfString(QString & str)
1873 str.replace(QRegExp("%%c"), QChar(0xF8)); // Diameter
1874 str.replace(QRegExp("%%d"), QChar(0xB0)); // Degree
1875 str.replace(QRegExp("%%p"), QChar(0xB1)); // Plus/minus
1876 str.replace(QRegExp("\\\\[pP]"), QChar('\n'));
1880 // Compare two double values:
1882 // return: true: values are equal
1883 // false: values are not equal
1885 bool FilterDXF1::mtCompFloat(double _v1, double _v2, double _tol)
1887 double delta = _v2 - _v1;
1889 if (delta > -_tol && delta < _tol)