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 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/28/2010 Added this text. :-)
15 #include "rs_filterdxf1.h"
18 #include "rs_filterdxf.h"
20 #include "rs_information.h"
21 #include "rs_utility.h"
22 #include "rs_system.h"
23 #include "rs_dimlinear.h"
24 #include "rs_dimaligned.h"
25 #include "rs_dimangular.h"
26 #include "rs_dimdiametric.h"
27 #include "rs_dimradial.h"
30 * Default constructor.
32 RS_FilterDXF1::RS_FilterDXF1(): RS_FilterInterface()
34 RS_DEBUG->print("Setting up DXF 1 filter...");
36 addImportFormat(RS2::FormatDXF1);
40 * Implementation of the method used for RS_Import to communicate
43 * @param graphic The graphic in which the entities from the file
44 * will be created or the graphics from which the entities are
45 * taken to be stored in a file.
47 bool RS_FilterDXF1::fileImport(Drawing& g, const QString& file, RS2::FormatType /*type*/)
49 RS_DEBUG->print("DXF1 Filter: importing file '%s'...", file.toLatin1().data());
60 if (readFileInBuffer())
63 return readFromBuffer();
72 * Reads a dxf1 file from buffer.
74 bool RS_FilterDXF1::readFromBuffer()
76 RS_DEBUG->print("\nDXF: Read from buffer");
78 bool ret; // returned value
79 QString dxfLine; // A line in the dxf file
80 QString dxfCode; // A Code in the dxf file as string
81 int code = -1; // Dxf-code as number
82 double vx1 = 0.0, vy1 = 0.0; // Start point
83 double vx2 = 0.0, vy2 = 0.0; // End point
84 double vcx = 0.0, vcy = 0.0; // Centre
85 double vcr = 0.0; // Radius
86 double va1 = 0.0, va2 = 0.0; // Start / End Angle
87 //double vab=0.0, // Bulge
88 // vpx=0.0, vpy=0.0; // First Polyline point
89 //double ax=0.0, ay=0.0; // Current coordinate
90 //bool plClose=false; // Polyline closed-flag
91 QString lastLayer; // Last used layer name (test adding only
92 // if the new layer!=lastLayer)
93 //int currentLayerNum=0; // Current layer number
94 RS_Layer * currentLayer = 0; // Pointer to current layer
95 //QList<RGraphic> blockList; // List of blocks
96 //blockList.setAutoDelete( true );
97 //bool oldColorNumbers=false; // use old color numbers (qcad<1.5.3)
100 ///if(!add) graphic->clearLayers();
102 //graphic->addLayer(DEF_DEFAULTLAYER);
104 //RS_DEBUG->print( "\nDefault layer added" );
106 // Loaded graphics without unit information: load as unit less:
107 //graphic->setUnit( None );
109 RS_DEBUG->print("\nUnit set");
115 RS_DEBUG->print("\nBuffer OK");
116 RS_DEBUG->print("\nBuffer: ");
117 RS_DEBUG->print(fBuf);
121 dxfLine = getBufLine();
122 pen = RS_Pen(RS_Color(RS2::FlagByLayer), RS2::WidthByLayer, RS2::LineByLayer);
124 RS_DEBUG->print("\ndxfLine: ");
125 RS_DEBUG->print(dxfLine.toAscii().data());
127 // $-Setting in the header of DXF found
129 if (!dxfLine.isEmpty() && dxfLine[0] == '$')
133 if (dxfLine == "$INSUNITS")
135 dxfCode = getBufLine();
136 if (!dxfCode.isEmpty())
138 if (dxfCode.toInt() == 70)
140 dxfLine = getBufLine();
141 if (!dxfLine.isEmpty())
143 graphic->addVariable("$INSUNITS", dxfLine, 70);
145 switch( dxfLine.toInt() ) {
146 case 0: graphic->setUnit( RS2::None ); break;
147 case 1: graphic->setUnit( RS2::Inch ); break;
148 case 2: graphic->setUnit( RS2::Foot ); break;
149 case 3: graphic->setUnit( RS2::Mile ); break;
150 case 4: graphic->setUnit( RS2::Millimeter ); break;
151 case 5: graphic->setUnit( RS2::Centimeter ); break;
152 case 6: graphic->setUnit( RS2::Meter ); break;
153 case 7: graphic->setUnit( RS2::Kilometer ); break;
154 case 8: graphic->setUnit( RS2::Microinch ); break;
155 case 9: graphic->setUnit( RS2::Mil ); break;
156 case 10: graphic->setUnit( RS2::Yard ); break;
157 case 11: graphic->setUnit( RS2::Angstrom ); break;
158 case 12: graphic->setUnit( RS2::Nanometer ); break;
159 case 13: graphic->setUnit( RS2::Micron ); break;
160 case 14: graphic->setUnit( RS2::Decimeter ); break;
161 case 15: graphic->setUnit( RS2::Decameter ); break;
162 case 16: graphic->setUnit( RS2::Hectometer ); break;
163 case 17: graphic->setUnit( RS2::Gigameter ); break;
164 case 18: graphic->setUnit( RS2::Astro ); break;
165 case 19: graphic->setUnit( RS2::Lightyear ); break;
166 case 20: graphic->setUnit( RS2::Parsec ); break;
169 graphic->setDimensionUnit( graphic->getUnit() );
170 //graphic->setGridUnit( graphic->getUnit() );
179 else if (dxfLine == "$DIMALT")
181 dxfCode = getBufLine();
182 if (!dxfCode.isEmpty())
184 if (dxfCode.toInt() == 70)
186 dxfLine = getBufLine();
187 if (!dxfLine.isEmpty())
189 graphic->addVariable("$DIMALT", dxfLine, 70);
191 switch( dxfLine.toInt() ) {
192 case 0: graphic->setDimensionUnit( RS2::None ); break;
193 case 1: graphic->setDimensionUnit( RS2::Inch ); break;
194 case 2: graphic->setDimensionUnit( RS2::Foot ); break;
195 case 3: graphic->setDimensionUnit( RS2::Mile ); break;
196 case 4: graphic->setDimensionUnit( RS2::Millimeter ); break;
197 case 5: graphic->setDimensionUnit( RS2::Centimeter ); break;
198 case 6: graphic->setDimensionUnit( RS2::Meter ); break;
199 case 7: graphic->setDimensionUnit( RS2::Kilometer ); break;
200 case 8: graphic->setDimensionUnit( RS2::Microinch ); break;
201 case 9: graphic->setDimensionUnit( RS2::Mil ); break;
202 case 10: graphic->setDimensionUnit( RS2::Yard ); break;
203 case 11: graphic->setDimensionUnit( RS2::Angstrom ); break;
204 case 12: graphic->setDimensionUnit( RS2::Nanometer ); break;
205 case 13: graphic->setDimensionUnit( RS2::Micron ); break;
206 case 14: graphic->setDimensionUnit( RS2::Decimeter ); break;
207 case 15: graphic->setDimensionUnit( RS2::Decameter ); break;
208 case 16: graphic->setDimensionUnit( RS2::Hectometer ); break;
209 case 17: graphic->setDimensionUnit( RS2::Gigameter ); break;
210 case 18: graphic->setDimensionUnit( RS2::Astro ); break;
211 case 19: graphic->setDimensionUnit( RS2::Lightyear ); break;
212 case 20: graphic->setDimensionUnit( RS2::Parsec ); break;
222 /*else if( dxfLine=="$DIMLUNIT" ) {
223 if(dxfCode=getBufLine()) {
224 if( dxfCode.toInt()==70 ) {
225 if( dxfLine=getBufLine() ) {
226 switch( dxfLine.toInt() ) {
227 case 1: graphic->setDimensionFormat( Scientific ); break;
229 case 3: graphic->setDimensionFormat( Decimal ); break;
231 case 5: graphic->setDimensionFormat( Fractional ); break;
239 // Dimension Arrow Size:
241 else if (dxfLine == "$DIMASZ")
243 dxfCode = getBufLine();
244 if (!dxfCode.isEmpty() && dxfCode.toInt() == 40)
246 dxfLine = getBufLine();
247 if (!dxfLine.isEmpty())
249 graphic->addVariable("$DIMASZ", dxfLine, 40);
250 //graphic->setDimensionArrowSize( dxfLine.toDouble() );
258 else if( dxfLine=="$DIMSCALE" ) {
259 if(dxfCode=getBufLine()) {
260 if( dxfCode.toInt()==40 ) {
261 if( dxfLine=getBufLine() ) {
262 graphic->setDimensionScale( dxfLine.toDouble() );
269 // Dimension Text Height:
271 else if (dxfLine == "$DIMTXT")
273 dxfCode = getBufLine();
274 if (!dxfCode.isEmpty())
276 if (dxfCode.toInt() == 40)
278 dxfLine = getBufLine();
279 if (!dxfLine.isEmpty())
281 graphic->addVariable("$DIMTXT", dxfLine, 40);
282 //graphic->setDimensionTextHeight( dxfLine.toDouble() );
288 // Dimension exactness:
290 else if (dxfLine == "$DIMRND")
292 dxfCode = getBufLine();
293 if (dxfCode.toInt() == 40)
295 dxfLine = getBufLine();
296 if (!dxfLine.isEmpty())
298 graphic->addVariable("$DIMRND", dxfLine, 40);
299 //if( dxfLine.toDouble()>0.000001 ) {
300 //graphic->setDimensionExactness( dxfLine.toDouble() );
306 // Dimension over length:
308 else if (dxfLine == "$DIMEXE")
310 dxfCode = getBufLine();
311 if (dxfCode.toInt() == 40)
313 dxfLine = getBufLine();
314 if (!dxfLine.isEmpty())
316 graphic->addVariable("$DIMEXE", dxfLine, 40);
317 //graphic->setDimensionOverLength( dxfLine.toDouble() );
322 // Dimension under length:
324 else if( dxfLine=="$DIMEXO" )
326 dxfCode = getBufLine();
327 if( dxfCode.toInt()==40 )
329 dxfLine = getBufLine();
330 if (!dxfLine.isEmpty())
332 graphic->addVariable("$DIMEXO", dxfLine, 40);
333 //graphic->setDimensionUnderLength( dxfLine.toDouble() );
339 // Angle dimension format:
341 else if( dxfLine=="$DIMAUNIT" )
343 dxfCode = getBufLine();
344 if( dxfCode.toInt()==70 )
346 dxfLine = getBufLine();
347 if (!dxfLine.isEmpty())
349 graphic->addVariable("$DIMAUNIT", dxfLine, 70);
351 switch( dxfLine.toInt() ) {
352 case 0: graphic->setAngleDimensionFormat( DecimalDegrees ); break;
353 case 1: graphic->setAngleDimensionFormat( DegreesMinutesSeconds ); break;
354 case 2: graphic->setAngleDimensionFormat( Gradians ); break;
355 case 3: graphic->setAngleDimensionFormat( Radians ); break;
356 case 4: graphic->setAngleDimensionFormat( Surveyor ); break;
364 // Angle dimension exactness:
366 else if( dxfLine=="$DIMADEC" )
368 dxfCode = getBufLine();
369 if( dxfCode.toInt()==70 )
371 dxfLine = getBufLine();
372 if (!dxfLine.isEmpty())
374 graphic->addVariable("$DIMADEC", dxfLine, 70);
375 //graphic->setAngleDimensionExactness( RS_Math::pow(0.1, dxfLine.toInt()) );
382 else if (dxfLine == "$GRIDUNIT")
384 dxfCode = getBufLine();
386 if (dxfCode.toInt() == 10)
388 dxfLine = getBufLine();
390 if (!dxfLine.isEmpty())
392 double x = atof(dxfLine.toAscii().data());
393 dxfLine = getBufLine();
395 if (!dxfLine.isEmpty())
397 double y = atof(dxfLine.toAscii().data());
399 graphic->addVariable("$GRIDUNIT", Vector(x, y), 10);
405 double gx=dxfLine.toDouble();
406 if (gx<0.0001) gx=0.0001;
407 graphic->setMinGridX(gx);
408 graphic->setGridFormat( Fractional );
410 for( double q=0.00000001; q<=100000.0; q*=10.0 ) {
411 if( mtCompFloat(gx, q, q/1000.0) ) {
412 graphic->setGridFormat( Decimal );
420 if(dxfCode=getBufLine()) {
421 if( dxfCode.toInt()==20 ) {
422 if( dxfLine=getBufLine() ) {
423 double gy=dxfLine.toDouble();
424 if (gy<0.0001) gy=0.0001;
425 graphic->setMinGridY(gy);
431 // Page limits min x/y:
433 /*else if( dxfLine=="$PLIMMIN" ) {
434 if(dxfCode=getBufLine()) {
435 if( dxfCode.toInt()==10 ) {
436 if( dxfLine=getBufLine() ) {
437 graphic->setPageOriginX( dxfLine.toDouble() );
441 if(dxfCode=getBufLine()) {
442 if( dxfCode.toInt()==20 ) {
443 if( dxfLine=getBufLine() ) {
444 graphic->setPageOriginY( dxfLine.toDouble() );
451 // Page limits min x/y:
454 else if( dxfLine=="$PLIMMAX" ) {
455 if(dxfCode=getBufLine()) {
456 if( dxfCode.toInt()==10 ) {
457 if( dxfLine=getBufLine() ) {
458 graphic->setPageSizeX( dxfLine.toDouble() - graphic->getPageOriginX() );
462 if(dxfCode=getBufLine()) {
463 if( dxfCode.toInt()==20 ) {
464 if( dxfLine=getBufLine() ) {
465 graphic->setPageSizeY( dxfLine.toDouble() - graphic->getPageOriginY() );
472 // Paper space scale:
475 else if( dxfLine=="$PSVPSCALE" ) {
476 if(dxfCode=getBufLine()) {
477 if( dxfCode.toInt()==40 ) {
478 if( dxfLine=getBufLine() ) {
479 graphic->setPaperSpace( dxfLine.toDouble() );
490 else if (!dxfLine.isEmpty() &&
491 dxfLine[0] >= 'A' && dxfLine[0] <= 'Z')
493 if (dxfLine == "EOF")
495 // End of file reached
502 else if (dxfLine == "LAYER")
507 dxfCode = getBufLine();
508 if(!dxfCode.isEmpty())
509 code = dxfCode.toInt();
510 if(!dxfCode.isEmpty() && code != 0)
512 dxfLine = getBufLine();
513 if (!dxfLine.isEmpty())
517 case 2: // Layer name
518 if (dxfLine=="(null)" || dxfLine=="default") {
521 graphic->addLayer(new RS_Layer(dxfLine));
522 graphic->activateLayer(dxfLine);
523 currentLayer = graphic->getActiveLayer();
526 case 70: // Visibility
528 if(dxfLine.toInt()&5) {
529 if(currentLayerNum>=0 && currentLayerNum<DEF_MAXLAYERS) {
530 graphic->layer[currentLayerNum].DelFlag(Y_VISIBLE);
537 //currentLayer->setStyle( graphic->nameToStyle(dxfLine) );
538 pen.setLineType(RS_FilterDXF::nameToLineType(dxfLine));
540 case 39: // Thickness
541 //if(currentLayer) currentLayer->setWidth(dxfLine.toInt());
542 pen.setWidth(RS_FilterDXF::numberToWidth(dxfLine.toInt()));
545 pen.setColor(RS_FilterDXF::numberToColor(dxfLine.toInt()));
547 // currentLayer->setColor( graphic->numberToColor(dxfLine.toInt(), !oldColorNumbers));
556 while(!dxfCode.isEmpty() && code != 0);
560 currentLayer->setPen(pen);
562 //graphic->setStyle("CONTINOUS");
563 //graphic->setWidth(0);
564 //graphic->setColor(0, false);
570 else if(dxfLine=="POINT") {
572 dxfCode=getBufLine();
573 if(!dxfCode.isEmpty())
574 code=dxfCode.toInt();
575 if(!dxfCode.isEmpty() && code!=0) {
576 dxfLine=getBufLine();
577 if(!dxfLine.isEmpty()) {
580 pen.setLineType(RS_FilterDXF::nameToLineType(dxfLine));
583 //if(dxfLine!=lastLayer) {
584 if (dxfLine=="(null)" || dxfLine=="default") {
587 graphic->activateLayer(dxfLine);
592 dxfLine.replace( QRegExp(","), "." );
593 vx1 = dxfLine.toDouble();
596 dxfLine.replace( QRegExp(","), "." );
597 vy1 = dxfLine.toDouble();
599 case 39: // Thickness
600 pen.setWidth(RS_FilterDXF::numberToWidth(dxfLine.toInt()));
603 pen.setColor(RS_FilterDXF::numberToColor(dxfLine.toInt()));
611 while(!dxfCode.isEmpty() && code != 0);
613 graphic->setActivePen(pen);
614 graphic->addEntity(new RS_Point(graphic,
615 RS_PointData(Vector(vx1, vy1))));
621 else if(dxfLine=="LINE") {
623 dxfCode=getBufLine();
625 if(!dxfCode.isEmpty())
626 code=dxfCode.toInt();
627 if(!dxfCode.isEmpty() && code!=0) {
629 dxfLine=getBufLine();
631 if(!dxfLine.isEmpty()) {
634 pen.setLineType(RS_FilterDXF::nameToLineType(dxfLine));
637 //if(dxfLine!=lastLayer) {
638 if (dxfLine=="(null)" || dxfLine=="default") {
641 graphic->activateLayer(dxfLine);
646 dxfLine.replace( QRegExp(","), "." );
647 vx1 = dxfLine.toDouble();
650 dxfLine.replace( QRegExp(","), "." );
651 vy1 = dxfLine.toDouble();
654 dxfLine.replace( QRegExp(","), "." );
655 vx2 = dxfLine.toDouble();
658 dxfLine.replace( QRegExp(","), "." );
659 vy2 = dxfLine.toDouble();
661 case 39: // Thickness
662 pen.setWidth(RS_FilterDXF::numberToWidth(dxfLine.toInt()));
665 pen.setColor(RS_FilterDXF::numberToColor(dxfLine.toInt()));
672 } while(!dxfCode.isEmpty() && code!=0);
674 //if(!mtCompFloat(vx1, vx2) || !mtCompFloat(vy1, vy2)) {
675 //graphic->addLine(vx1, vy1, vx2, vy2, currentLayerNum, add);
676 graphic->setActivePen(pen);
677 graphic->addEntity(new RS_Line(graphic,
678 RS_LineData(Vector(vx1, vy1), Vector(vx2, vy2))));
686 else if(dxfLine=="ARC") {
688 dxfCode=getBufLine();
689 if(!dxfCode.isEmpty())
690 code=dxfCode.toInt();
691 if(!dxfCode.isEmpty() && code!=0) {
692 dxfLine=getBufLine();
693 if(!dxfLine.isEmpty()) {
696 pen.setLineType(RS_FilterDXF::nameToLineType(dxfLine));
699 //if(dxfLine!=lastLayer) {
700 if (dxfLine=="(null)" || dxfLine=="default") {
703 graphic->activateLayer(dxfLine);
708 dxfLine.replace( QRegExp(","), "." );
709 vcx = dxfLine.toDouble();
712 dxfLine.replace( QRegExp(","), "." );
713 vcy = dxfLine.toDouble();
716 dxfLine.replace( QRegExp(","), "." );
717 vcr = dxfLine.toDouble();
719 case 50: // Start Angle
720 dxfLine.replace( QRegExp(","), "." );
721 va1 = RS_Math::correctAngle(dxfLine.toDouble()/ARAD);
723 case 51: // End Angle
724 dxfLine.replace( QRegExp(","), "." );
725 va2 = RS_Math::correctAngle(dxfLine.toDouble()/ARAD);
727 case 39: // Thickness
728 pen.setWidth(RS_FilterDXF::numberToWidth(dxfLine.toInt()));
731 pen.setColor(RS_FilterDXF::numberToColor(dxfLine.toInt()));
738 } while(!dxfCode.isEmpty() && code!=0);
739 //if(vcr>0.0 && !mtCompFloat(va1, va2)) {
740 // graphic->addArc(vcx, vcy, vcr, va1, va2, false, currentLayerNum, add);
742 graphic->setActivePen(pen);
743 graphic->addEntity(new RS_Arc(graphic,
744 RS_ArcData(Vector(vcx, vcy),
745 vcr, va1, va2, false)));
751 else if(dxfLine=="CIRCLE") {
753 dxfCode=getBufLine();
754 if(!dxfCode.isEmpty())
755 code=dxfCode.toInt();
756 if(!dxfCode.isEmpty() && code!=0) {
757 dxfLine=getBufLine();
758 if(!dxfLine.isEmpty()) {
761 pen.setLineType(RS_FilterDXF::nameToLineType(dxfLine));
764 //if(dxfLine!=lastLayer) {
765 if (dxfLine=="(null)" || dxfLine=="default") {
768 graphic->activateLayer(dxfLine);
773 dxfLine.replace( QRegExp(","), "." );
774 vcx = dxfLine.toDouble();
777 dxfLine.replace( QRegExp(","), "." );
778 vcy = dxfLine.toDouble();
781 dxfLine.replace( QRegExp(","), "." );
782 vcr = dxfLine.toDouble();
784 case 39: // Thickness
785 pen.setWidth(RS_FilterDXF::numberToWidth(dxfLine.toInt()));
788 pen.setColor(RS_FilterDXF::numberToColor(dxfLine.toInt()));
795 } while(!dxfCode.isEmpty() && code!=0);
797 graphic->addCircle(vcx, vcy, vcr, 0.0, 360.0, false, currentLayerNum, add);
799 graphic->setActivePen(pen);
800 graphic->addEntity(new RS_Circle(graphic,
801 RS_CircleData(Vector(vcx, vcy),
810 if(dxfLine=="HATCH") {
812 dxfCode=getBufLine();
813 if(dxfCode) code=dxfCode.toInt();
814 if(dxfCode && code!=0) {
815 dxfLine=getBufLine();
819 // if(dxfLine!=lastLayer) {
820 if (dxfLine=="(null)" || dxfLine=="default") {
823 graphic->activateLayer(dxfLine);
828 vx1 = dxfLine.toDouble();
831 vy1 = dxfLine.toDouble();
832 //graphic->Vec[vc].CreatePoint(vy1, vx1, currentLayerNum);
833 //if(vc<vElements-1) ++vc;
836 vx2 = dxfLine.toDouble();
839 vy2 = dxfLine.toDouble();
840 //graphic->Vec[vc].CreatePoint(vy2, vx2, currentLayerNum);
841 //if(vc<vElements-1) ++vc;
848 }while(dxfCode && code!=0);
850 if(!mt.CompFloat(vx1, vx2) || !mt.CompFloat(vy1, vy2)) {
851 graphic->Vec[vc].CreateLine(vx1, vy1, vx2, vy2, currentLayerNum);
852 if(vc<vElements-1) ++vc;
854 if(++updProgress==1000) {
855 np->getStateWin()->UpdateProgressBar((int)(pcFact*vc)+25);
866 else if(dxfLine=="TEXT") {
868 QString vtext; // the text
869 char vtextStyle[256]; // text style (normal_ro, cursive_ri, normal_st, ...)
870 double vheight=10.0; // text height
871 double vtextAng=0.0; // text angle
872 //double vradius=0.0; // text radius
873 //double vletterspace=2.0; // Text letter space
874 //double vwordspace=6.0; // Text wordspace
875 QString vfont; // font "normal", "cursive", ...
876 RS2::HAlign vhalign=RS2::HAlignLeft;
877 // alignment (0=left, 1=center, 2=right)
878 //int vattachement=7; // 1=top left, 2, 3, 4, 5, 6, 7, 8, 9=bottom right
879 //uint vfl=0; // special flags
880 bool codeSeven=false; // Have we found a code seven?
882 vtextStyle[0] = '\0';
886 dxfCode=getBufLine();
887 if(!dxfCode.isEmpty())
888 code=dxfCode.toInt();
889 if(!dxfCode.isEmpty() && code!=0) {
890 if(code!=1 && code!=3 && code!=7)
891 dxfLine=getBufLine();
892 if(!dxfLine.isEmpty() || code==1 || code==3 || code==7) {
896 case 1: // Text itself
897 vtext = getBufLine();
898 strDecodeDxfString(vtext);
901 case 3: // Text parts (always 250 chars)
902 vtext = getBufLine();
906 pen.setLineType(RS_FilterDXF::nameToLineType(dxfLine));
910 // Text style (normal_ro#50.0,
911 // cursive_ri#20.0, normal_st)
912 qstrncpy(vtextStyle, getBufLine().toAscii().data(), 249);
918 sscanf(vtextStyle, "%[^_#\n]", dummy);
925 if(strstr(vtextStyle, "_ro"))
927 else if(strstr(vtextStyle, "_ri"))
934 /*if(strstr(vtextStyle, "_fix")) {
935 vfl=vfl|E_FIXEDWIDTH;
938 // get radius, letterspace, wordspace:
941 char * ptr; // pointer to value
942 ptr = strchr(vtextStyle, '#');
947 /*if(vfl&E_ROUNDOUT || vfl&E_ROUNDIN) {
950 sscanf(ptr, "%lf", &vradius);
952 ptr = strchr(ptr, '#');
955 // Parse letter space:
958 sscanf(ptr, "%lf", &vletterspace);
961 ptr = strchr(ptr, '#');
965 sscanf(ptr, "%lf", &vwordspace);
975 //if(dxfLine!=lastLayer) {
976 if (dxfLine == "(null)" || dxfLine == "default")
981 graphic->activateLayer(dxfLine);
987 dxfLine.replace( QRegExp(","), "." );
988 vx1 = dxfLine.toDouble();
991 dxfLine.replace( QRegExp(","), "." );
992 vy1 = dxfLine.toDouble();
995 dxfLine.replace( QRegExp(","), "." );
996 vheight = dxfLine.toDouble();
998 vletterspace = vheight*0.2;
999 vwordspace = vheight*0.6;
1003 dxfLine.replace( QRegExp(","), "." );
1004 vtextAng = dxfLine.toDouble() / ARAD;
1006 case 72: {// alignment
1008 int v = dxfLine.toInt();
1010 vhalign = RS2::HAlignCenter;
1012 vhalign = RS2::HAlignRight;
1014 vhalign = RS2::HAlignLeft;
1018 case 39: // Thickness
1019 pen.setWidth(RS_FilterDXF::numberToWidth(dxfLine.toInt()));
1022 pen.setColor(RS_FilterDXF::numberToColor(dxfLine.toInt()));
1030 while(!dxfCode.isEmpty() && code != 0);
1032 char * i = strchr(vtextStyle, '#');
1040 new RS_Text(graphic,
1061 else if(dxfLine=="DIMENSION") {
1063 double v10=0.0, v20=0.0;
1064 double v13=0.0, v23=0.0;
1065 double v14=0.0, v24=0.0;
1066 double v15=0.0, v25=0.0;
1067 double v16=0.0, v26=0.0;
1068 double v40=0.0, v50=0.0;
1071 dxfCode=getBufLine();
1072 if(!dxfCode.isEmpty()) {
1073 code=dxfCode.toInt();
1075 if(!dxfCode.isEmpty() && code!=0) {
1076 dxfLine=getBufLine();
1077 if(!dxfLine.isEmpty()) {
1079 case 1: // Text (if any)
1082 // Mend unproper savings of older versions:
1083 if(dimText==" " || dimText==";;")
1086 //else dimText.replace(QRegExp("%%c"), "�");
1088 strDecodeDxfString(dimText);
1091 pen.setLineType(RS_FilterDXF::nameToLineType(dxfLine));
1094 //if(dxfLine!=lastLayer) {
1095 if (dxfLine=="(null)" || dxfLine=="default") {
1098 graphic->activateLayer(dxfLine);
1099 //lastLayer=dxfLine;
1102 case 10: // line position x
1103 dxfLine.replace( QRegExp(","), "." );
1104 v10 = dxfLine.toDouble();
1106 case 20: // line position y
1107 dxfLine.replace( QRegExp(","), "." );
1108 v20 = dxfLine.toDouble();
1111 dxfLine.replace( QRegExp(","), "." );
1112 v13 = dxfLine.toDouble();
1115 dxfLine.replace( QRegExp(","), "." );
1116 v23 = dxfLine.toDouble();
1119 dxfLine.replace( QRegExp(","), "." );
1120 v14 = dxfLine.toDouble();
1123 dxfLine.replace( QRegExp(","), "." );
1124 v24 = dxfLine.toDouble();
1127 dxfLine.replace( QRegExp(","), "." );
1128 v15 = dxfLine.toDouble();
1131 dxfLine.replace( QRegExp(","), "." );
1132 v25 = dxfLine.toDouble();
1135 dxfLine.replace( QRegExp(","), "." );
1136 v16 = dxfLine.toDouble();
1139 dxfLine.replace( QRegExp(","), "." );
1140 v26 = dxfLine.toDouble();
1143 dxfLine.replace( QRegExp(","), "." );
1144 v40 = dxfLine.toDouble();
1147 dxfLine.replace( QRegExp(","), "." );
1148 v50 = dxfLine.toDouble();
1151 typ = dxfLine.toInt();
1153 case 39: // Thickness
1154 pen.setWidth(RS_FilterDXF::numberToWidth(dxfLine.toInt()));
1157 pen.setColor(RS_FilterDXF::numberToColor(dxfLine.toInt()));
1165 } while(!dxfCode.isEmpty() && code!=0);
1169 // Remove Bit values:
1171 typ-=128; // Location of Text
1174 typ-= 64; // Ordinate
1202 graphic->addEntity(d);
1209 Vector(v13, v23).angleTo(Vector(v10,v20));
1211 Vector(v13, v23).distanceTo(Vector(v10,v20));
1214 defP.setPolar(dist, angle);
1215 defP+=Vector(v14, v24);
1237 graphic->addEntity(d);
1244 RS_LineData(Vector(v13, v23),
1247 RS_LineData(Vector(v10, v20),
1251 //bool inters=false;
1252 //tmpEl1.getIntersection(&tmpEl2,
1253 // &inters, &vcx, &vcy, 0,0,0,0, false);
1254 s = RS_Information::getIntersection(
1257 if (s.get(0).valid) {
1260 //vcr = Vector(vcx, vcy).distanceTo(v16, v26);
1262 /*if(Vector(vcx,vcy).distanceTo(v13,v23)<vcr) {
1263 va1 = tl1.getAngle1();
1265 va1 = tl2.getAngle2();
1268 if(Vector(vcx,vcy).distanceTo(v10,v20)<vcr) {
1269 va2 = tl2.getAngle1();
1271 va2 = tl2.getAngle2();
1275 graphic->addDimension(vcx, vcy, va1, va2,
1276 mtGetDistance(vcx, vcy, v13, v23),
1277 mtGetDistance(vcx, vcy, v10, v20),
1307 graphic->addEntity(d);
1315 graphic->addDimension(v10, v20, v15, v25,
1318 E_STRAIGHT|E_RADIUS,
1325 .angleTo(Vector(v15, v25));
1327 v2.setPolar(v40, ang);
1343 Vector(v10, v20) + v2,
1348 graphic->addEntity(d);
1355 graphic->addDimension(v13, v23, v14, v24,
1364 .angleTo(Vector(v15, v25));
1366 v2.setPolar(v40, ang);
1367 RS_DimDiametric* d =
1368 new RS_DimDiametric(
1381 RS_DimDiametricData(
1382 Vector(v10, v20) + v2,
1387 graphic->addEntity(d);
1389 RS_LeaderData data(true);
1391 new RS_Leader(graphic, data);
1392 d->addVertex(Vector(v14, v24));
1393 d->addVertex(Vector(v10, v20));
1395 graphic->addEntity(d);
1399 //graphic->elementCurrent()->setText(dimText);
1408 else if(dxfLine=="HATCH") {
1409 QString patternName="45";
1410 double patternScale=1.0;
1413 int nextObjectTyp=T_LINE;
1414 double v10=0.0, v20=0.0,
1419 dxfCode=getBufLine();
1420 if(dxfCode) code=dxfCode.toInt();
1421 if(dxfCode && code!=0) {
1422 dxfLine=getBufLine();
1426 patternName = dxfLine;
1429 pen.setLineType(RS_FilterDXF::nameToLineType(dxfLine));
1432 // if(dxfLine!=lastLayer) {
1433 if (dxfLine=="(null)" || dxfLine=="default") {
1436 graphic->activateLayer(dxfLine);
1437 //lastLayer=dxfLine;
1440 case 10: // Start point/center of boundary line/arc
1441 dxfLine.replace( QRegExp(","), "." );
1442 v10=dxfLine.toDouble();
1444 case 20: // Start point/center of boundary line/arc
1445 dxfLine.replace( QRegExp(","), "." );
1446 v20=dxfLine.toDouble();
1448 case 11: // End point of boundary line
1449 dxfLine.replace( QRegExp(","), "." );
1450 v11=dxfLine.toDouble();
1452 case 21: // End point of boundary line
1453 dxfLine.replace( QRegExp(","), "." );
1454 v21=dxfLine.toDouble();
1455 if(nextObjectTyp==T_LINE) {
1456 int elnu=graphic->addLine(v10, v20, v11, v21, currentLayerNum, add);
1457 graphic->elementAt(elnu)->setFlag(E_TAGGED);
1460 case 40: // Radius of boundary entity
1461 dxfLine.replace( QRegExp(","), "." );
1462 v40=dxfLine.toDouble();
1464 case 50: // Start angle
1465 dxfLine.replace( QRegExp(","), "." );
1466 v50=dxfLine.toDouble();
1468 case 51: // End angle
1469 dxfLine.replace( QRegExp(","), "." );
1470 v51=dxfLine.toDouble();
1472 case 73: // Counterclockwise?
1473 if(nextObjectTyp==T_ARC) {
1475 if( mtCompFloat( v50, 0.0 ) && mtCompFloat( v51, 0.0 ) ) {
1476 elnu=graphic->addCircle(v10, v20, v40, 0.0, 360.0, (bool)dxfLine.toInt(), currentLayerNum, add);
1479 elnu=graphic->addArc(v10, v20, v40, v50, v51, (bool)dxfLine.toInt(), currentLayerNum, add);
1481 graphic->elementAt(elnu)->setFlag(E_TAGGED);
1482 //newEl = new RElement( graphic );
1483 //newEl->createArc(v10, v20, v40, v50, v51, (bool)dxfLine.toInt());
1484 //boundaryList.append(newEl);
1488 dxfLine.replace( QRegExp(","), "." );
1489 patternScale=dxfLine.toDouble();
1494 case 70: // Solid (=1) or pattern (=0)
1497 case 39: // Thickness
1498 pen.setWidth(RS_FilterDXF::numberToWidth(dxfLine.toInt()));
1501 pen.setColor(RS_FilterDXF::numberToColor(dxfLine.toInt()));
1503 case 91: // Number of boundary paths (loops)
1504 //numPaths=dxfLine.toInt();
1506 case 92: // Typ of boundary
1509 case 93: // Number of edges in this boundary
1510 //numEdges=dxfLine.toInt();
1512 case 72: // Edge typ
1513 switch(dxfLine.toInt()) {
1514 case 1: nextObjectTyp=T_LINE; break;
1515 case 2: nextObjectTyp=T_ARC; break;
1525 }while(dxfCode && code!=0);
1527 graphic->addHatching(patternScale,
1532 graphic->editDelete(false);
1539 #warning "This will probably fail since it was expecting to be null on EOF"
1540 while (!dxfLine.isEmpty() && dxfLine != "EOF");
1542 //graphic->terminateAction();
1544 //graphic->debugElements();
1557 * Resets the whole object
1560 void RS_FilterDXF1::reset()
1576 * Reset buffer pointer to the beginning of the buffer:
1578 void RS_FilterDXF1::resetBufP()
1584 * Set buffer pointer to the given index:
1586 void RS_FilterDXF1::setBufP(int _fBufP)
1588 if (_fBufP < (int)fSize)
1595 void RS_FilterDXF1::delBuffer()
1605 * Remove any 13-characters in the buffer:
1607 void RS_FilterDXF1::dos2unix()
1609 char * src = fBuf, * dst = fBuf;
1614 while (*src != '\0')
1627 // Get next line in the buffer:
1628 // and overread ALL seperators
1630 // return: -Null-string: end of buffer
1631 // -String which is the next line in buffer
1633 QString RS_FilterDXF1::getBufLine()
1638 if (fBufP >= (int)fSize)
1639 return QString::null;
1643 // Move fBufP pointer to the next line
1644 while (fBufP < (int)fSize && fBuf[fBufP++] != '\0')
1647 // str = QString::fromLocal8Bit(ret).stripWhiteSpace();
1648 str = QString::fromLocal8Bit(ret).simplified();
1650 // if (str.isNull())
1661 // Get next line in the buffer:
1662 // and overread ALL seperators
1664 // return: -Null-string: end of buffer
1665 // -String which is the next line in buffer
1667 char * RS_FilterDXF1::getBufLineCh()
1671 if (fBufP >= (int)fSize)
1677 /*if (*ret == '\0' && noEmptyLines) {
1678 while (++fBufP < (int)fSize && fBuf[fBufP] == '\0')
1680 if (fBufP >= (int)fSize)
1685 // Move fBufP pointer to the next line
1686 while (fBufP < (int)fSize && fBuf[fBufP++] != '\0')
1693 // Copy buffer from a given string:
1695 void RS_FilterDXF1::copyBufFrom(const char * _buf)
1699 fBuf = new char[strlen(_buf) + 16];
1705 // Go to the next '_lstr'-line in buffer:
1707 // return: true: line found
1708 // false: end of buffer
1710 bool RS_FilterDXF1::gotoBufLine(char * _lstr)
1718 while (!l.isNull() && l!=_lstr);
1727 // Goto next line where the string _lstr appears:
1729 // return: true: string in line found
1730 // false: end of buffer
1733 bool RS_FilterDXF1::gotoBufLineString(char * _lstr)
1741 while (!l.isNull() && l.contains(_lstr));
1750 // Replace bynary Bytes (<32) by an other (given) byte:
1752 void RS_FilterDXF1::replaceBinaryBytesBy(char _c)
1756 for(bc=0; bc<(int)fSize; ++bc)
1758 if (fBuf[bc] < 32 && fBuf[bc] >= 0)
1766 // Separate buffer (change chars sc1 and sc2 in '\0'
1768 void RS_FilterDXF1::separateBuf(char _c1,
1773 for(int bc=0; bc<(int)fSize; ++bc)
1775 if (fBuf[bc] == _c1 || fBuf[bc] == _c2 ||
1776 fBuf[bc] == _c3 || fBuf[bc] == _c4)
1784 // remove comment between '_fc' and '_lc'
1785 // comments get replaced by '\0'
1787 void RS_FilterDXF1::removeComment(char _fc, char _lc)
1789 bool rem = false; // Are we removing currrently?
1792 for(bc=0; bc<(int)fSize; ++bc)
1794 if (fBuf[bc] == _fc)
1797 if (fBuf[bc] == _lc)
1808 // Read file '_name' in buffer (buf)
1810 // '_bNum' : Max number of Bytes
1812 // return: true: successful
1813 // false: file not found
1815 bool RS_FilterDXF1::readFileInBuffer(char * _name, int _bNum)
1817 // file.setName(_name);
1818 file.setFileName(_name);
1819 return readFileInBuffer(_bNum);
1822 // Read file in buffer (buf)
1824 // 'bNum' : Max number of Bytes
1826 // return: true: successful
1827 // false: file not found
1829 bool RS_FilterDXF1::readFileInBuffer(int _bNum)
1831 fPointer = fopen(name.toAscii().data(), "rb");
1833 if (fPointer != NULL)
1835 // if (file.open(QIODevice::ReadOnly, fPointer))
1836 if (file.open(fPointer, QIODevice::ReadOnly))
1838 fSize = file.size();
1843 fBuf = new char[_bNum + 16];
1845 // file.readBlock(fBuf, _bNum);
1846 file.read(fBuf, _bNum);
1853 // Convert 13/10 to 10
1864 // Decode a DXF string to the C-convention (special character \P is a \n)
1866 void RS_FilterDXF1::strDecodeDxfString(QString & str)
1871 str.replace(QRegExp("%%c"), QChar(0xF8)); // Diameter
1872 str.replace(QRegExp("%%d"), QChar(0xB0)); // Degree
1873 str.replace(QRegExp("%%p"), QChar(0xB1)); // Plus/minus
1874 str.replace(QRegExp("\\\\[pP]"), QChar('\n'));
1878 // Compare two double values:
1880 // return: true: values are equal
1881 // false: values are not equal
1883 bool RS_FilterDXF1::mtCompFloat(double _v1, double _v2, double _tol)
1885 double delta = _v2 - _v1;
1887 if (delta > -_tol && delta < _tol)