1 /********************************************************** 2 * Version $Id: dl_writer.h 911 2011-02-14 16:38:15Z reklov_w $ 3 *********************************************************/ 4 /**************************************************************************** 5 ** $Id: dl_writer.h 911 2011-02-14 16:38:15Z reklov_w $ 6 ** 7 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved. 8 ** Copyright (C) 2001 Robert J. Campbell Jr. 9 ** 10 ** This file is part of the dxflib project. 11 ** 12 ** This file may be distributed and/or modified under the terms of the 13 ** GNU General Public License version 2 as published by the Free Software 14 ** Foundation and appearing in the file LICENSE.GPL included in the 15 ** packaging of this file. 16 ** 17 ** Licensees holding valid dxflib Professional Edition licenses may use 18 ** this file in accordance with the dxflib Commercial License 19 ** Agreement provided with the Software. 20 ** 21 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 22 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 23 ** 24 ** See http://www.ribbonsoft.com for further details. 25 ** 26 ** Contact info@ribbonsoft.com if any conditions of this licensing are 27 ** not clear to you. 28 ** 29 **********************************************************************/ 30 31 #ifndef DL_WRITER_H 32 #define DL_WRITER_H 33 34 #if _MSC_VER > 1000 35 #pragma once 36 #endif // _MSC_VER > 1000 37 38 #if defined(__OS2__)||defined(__EMX__) 39 #define strcasecmp(s,t) stricmp(s,t) 40 #endif 41 42 #if defined(WIN32) 43 #define strcasecmp(s,t) _stricmp(s,t) 44 #endif 45 46 #include <iostream> 47 48 #include "dl_attributes.h" 49 #include "dl_codes.h" 50 51 52 53 /** 54 * Defines interface for writing low level DXF constructs to 55 * a file. Implementation is defined in derived classes that write 56 * to binary or ASCII files. 57 * 58 * Implements functions that write higher level constructs in terms of 59 * the low level ones. 60 * 61 * @todo Add error checking for string/entry length. 62 */ 63 class DL_Writer { 64 public: 65 /** 66 * @para version DXF version. Defaults to VER_2002. 67 */ DL_Writer(DL_Codes::version version)68 DL_Writer(DL_Codes::version version) : m_handle(0x30) { 69 this->version = version; 70 modelSpaceHandle = 0; 71 paperSpaceHandle = 0; 72 paperSpace0Handle = 0; 73 } 74 ~DL_Writer()75 virtual ~DL_Writer() {} 76 ; 77 78 /** Generic section for section 'name'. 79 * 80 * <pre> 81 * 0 82 * SECTION 83 * 2 84 * name 85 * </pre> 86 */ section(const char * name)87 void section(const char* name) const { 88 dxfString(0, "SECTION"); 89 dxfString(2, name); 90 } 91 92 /** 93 * Section HEADER 94 * 95 * <pre> 96 * 0 97 * SECTION 98 * 2 99 * HEADER 100 * </pre> 101 */ sectionHeader()102 void sectionHeader() const { 103 section("HEADER"); 104 } 105 106 /** 107 * Section TABLES 108 * 109 * <pre> 110 * 0 111 * SECTION 112 * 2 113 * TABLES 114 * </pre> 115 */ sectionTables()116 void sectionTables() const { 117 section("TABLES"); 118 } 119 120 /** 121 * Section BLOCKS 122 * 123 * <pre> 124 * 0 125 * SECTION 126 * 2 127 * BLOCKS 128 * </pre> 129 */ sectionBlocks()130 void sectionBlocks() const { 131 section("BLOCKS"); 132 } 133 134 /** 135 * Section ENTITIES 136 * 137 * <pre> 138 * 0 139 * SECTION 140 * 2 141 * ENTITIES 142 * </pre> 143 */ sectionEntities()144 void sectionEntities() const { 145 section("ENTITIES"); 146 } 147 148 /** 149 * Section CLASSES 150 * 151 * <pre> 152 * 0 153 * SECTION 154 * 2 155 * CLASSES 156 * </pre> 157 */ sectionClasses()158 void sectionClasses() const { 159 section("CLASSES"); 160 } 161 162 /** 163 * Section OBJECTS 164 * 165 * <pre> 166 * 0 167 * SECTION 168 * 2 169 * OBJECTS 170 * </pre> 171 */ sectionObjects()172 void sectionObjects() const { 173 section("OBJECTS"); 174 } 175 176 /** 177 * End of a section. 178 * 179 * <pre> 180 * 0 181 * ENDSEC 182 * </pre> 183 */ sectionEnd()184 void sectionEnd() const { 185 dxfString(0, "ENDSEC"); 186 } 187 188 /** 189 * Generic table for table 'name' with 'num' entries: 190 * 191 * <pre> 192 * 0 193 * TABLE 194 * 2 195 * name 196 * 70 197 * num 198 * </pre> 199 */ table(const char * name,int num,int handle)200 void table(const char* name, int num, int handle) const { 201 dxfString(0, "TABLE"); 202 dxfString(2, name); 203 if (version>=VER_2000) { 204 dxfHex(5, handle); 205 dxfString(100, "AcDbSymbolTable"); 206 } 207 dxfInt(70, num); 208 } 209 210 /** Table for layers. 211 * 212 * @param num Number of layers in total. 213 * 214 * <pre> 215 * 0 216 * TABLE 217 * 2 218 * LAYER 219 * 70 220 * num 221 * </pre> 222 */ tableLayers(int num)223 void tableLayers(int num) const { 224 table("LAYER", num, 2); 225 } 226 227 /** Table for line types. 228 * 229 * @param num Number of line types in total. 230 * 231 * <pre> 232 * 0 233 * TABLE 234 * 2 235 * LTYPE 236 * 70 237 * num 238 * </pre> 239 */ tableLineTypes(int num)240 void tableLineTypes(int num) const { 241 //lineTypeHandle = 5; 242 table("LTYPE", num, 5); 243 } 244 245 /** Table for application id. 246 * 247 * @param num Number of registered applications in total. 248 * 249 * <pre> 250 * 0 251 * TABLE 252 * 2 253 * APPID 254 * 70 255 * num 256 * </pre> 257 */ tableAppid(int num)258 void tableAppid(int num) const { 259 table("APPID", num, 9); 260 } 261 262 /** 263 * End of a table. 264 * 265 * <pre> 266 * 0 267 * ENDTAB 268 * </pre> 269 */ tableEnd()270 void tableEnd() const { 271 dxfString(0, "ENDTAB"); 272 } 273 274 /** 275 * End of the DXF file. 276 * 277 * <pre> 278 * 0 279 * EOF 280 * </pre> 281 */ dxfEOF()282 void dxfEOF() const { 283 dxfString(0, "EOF"); 284 } 285 286 /** 287 * Comment. 288 * 289 * <pre> 290 * 999 291 * text 292 * </pre> 293 */ comment(const char * text)294 void comment(const char* text) const { 295 dxfString(999, text); 296 } 297 298 /** 299 * Entity. 300 * 301 * <pre> 302 * 0 303 * entTypeName 304 * </pre> 305 * 306 * @return Unique handle or 0. 307 */ entity(const char * entTypeName)308 void entity(const char* entTypeName) const { 309 dxfString(0, entTypeName); 310 if (version>=VER_2000) { 311 handle(); 312 } 313 } 314 315 /** 316 * Attributes of an entity. 317 * 318 * <pre> 319 * 8 320 * layer 321 * 62 322 * color 323 * 39 324 * width 325 * 6 326 * linetype 327 * </pre> 328 */ entityAttributes(const DL_Attributes & attrib)329 void entityAttributes(const DL_Attributes& attrib) const { 330 331 // layer name: 332 dxfString(8, attrib.getLayer()); 333 334 // R12 doesn't accept BYLAYER values. The value has to be missing 335 // in that case. 336 if (version>=VER_2000 || 337 attrib.getColor()!=256) { 338 dxfInt(62, attrib.getColor()); 339 } 340 if (version>=VER_2000) { 341 dxfInt(370, attrib.getWidth()); 342 } 343 if (version>=VER_2000 || 344 strcasecmp(attrib.getLineType().c_str(), "BYLAYER")) { 345 dxfString(6, attrib.getLineType()); 346 } 347 } 348 349 /** 350 * Subclass. 351 */ subClass(const char * sub)352 void subClass(const char* sub) const { 353 dxfString(100, sub); 354 } 355 356 /** 357 * Layer (must be in the TABLES section LAYER). 358 * 359 * <pre> 360 * 0 361 * LAYER 362 * </pre> 363 */ 364 void tableLayerEntry(unsigned long int h=0) const { 365 dxfString(0, "LAYER"); 366 if (version>=VER_2000) { 367 if (h==0) { 368 handle(); 369 } else { 370 dxfHex(5, h); 371 } 372 dxfString(100, "AcDbSymbolTableRecord"); 373 dxfString(100, "AcDbLayerTableRecord"); 374 } 375 } 376 377 /** 378 * Line type (must be in the TABLES section LTYPE). 379 * 380 * <pre> 381 * 0 382 * LTYPE 383 * </pre> 384 */ 385 void tableLineTypeEntry(unsigned long int h=0) const { 386 dxfString(0, "LTYPE"); 387 if (version>=VER_2000) { 388 if (h==0) { 389 handle(); 390 } else { 391 dxfHex(5, h); 392 } 393 //dxfHex(330, 0x5); 394 dxfString(100, "AcDbSymbolTableRecord"); 395 dxfString(100, "AcDbLinetypeTableRecord"); 396 } 397 } 398 399 /** 400 * Appid (must be in the TABLES section APPID). 401 * 402 * <pre> 403 * 0 404 * APPID 405 * </pre> 406 */ 407 void tableAppidEntry(unsigned long int h=0) const { 408 dxfString(0, "APPID"); 409 if (version>=VER_2000) { 410 if (h==0) { 411 handle(); 412 } else { 413 dxfHex(5, h); 414 } 415 //dxfHex(330, 0x9); 416 dxfString(100, "AcDbSymbolTableRecord"); 417 dxfString(100, "AcDbRegAppTableRecord"); 418 } 419 } 420 421 /** 422 * Block (must be in the section BLOCKS). 423 * 424 * <pre> 425 * 0 426 * BLOCK 427 * </pre> 428 */ 429 void sectionBlockEntry(unsigned long int h=0) const { 430 dxfString(0, "BLOCK"); 431 if (version>=VER_2000) { 432 if (h==0) { 433 handle(); 434 } else { 435 dxfHex(5, h); 436 } 437 //dxfHex(330, blockHandle); 438 dxfString(100, "AcDbEntity"); 439 if (h==0x1C) { 440 dxfInt(67, 1); 441 } 442 dxfString(8, "0"); // TODO: Layer for block 443 dxfString(100, "AcDbBlockBegin"); 444 } 445 } 446 447 /** 448 * End of Block (must be in the section BLOCKS). 449 * 450 * <pre> 451 * 0 452 * ENDBLK 453 * </pre> 454 */ 455 void sectionBlockEntryEnd(unsigned long int h=0) const { 456 dxfString(0, "ENDBLK"); 457 if (version>=VER_2000) { 458 if (h==0) { 459 handle(); 460 } else { 461 dxfHex(5, h); 462 } 463 //dxfHex(330, blockHandle); 464 dxfString(100, "AcDbEntity"); 465 if (h==0x1D) { 466 dxfInt(67, 1); 467 } 468 dxfString(8, "0"); // TODO: Layer for block 469 dxfString(100, "AcDbBlockEnd"); 470 } 471 } 472 473 void color(int col=256) const { 474 dxfInt(62, col); 475 } lineType(const char * lt)476 void lineType(const char *lt) const { 477 dxfString(6, lt); 478 } lineTypeScale(double scale)479 void lineTypeScale(double scale) const { 480 dxfReal(48, scale); 481 } lineWeight(int lw)482 void lineWeight(int lw) const { 483 dxfInt(370, lw); 484 } 485 486 void coord(int gc, double x, double y, double z=0) const { 487 dxfReal(gc, x); 488 dxfReal(gc+10, y); 489 dxfReal(gc+20, z); 490 } 491 coordTriplet(int gc,const double * value)492 void coordTriplet(int gc, const double* value) const { 493 if (value) { 494 dxfReal(gc, *value++); 495 dxfReal(gc+10, *value++); 496 dxfReal(gc+20, *value++); 497 } 498 } 499 resetHandle()500 void resetHandle() const { 501 m_handle = 1; 502 } 503 504 /** 505 * Writes a unique handle and returns it. 506 */ 507 unsigned long handle(int gc=5) const { 508 // handle has to be hex 509 dxfHex(gc, m_handle); 510 return m_handle++; 511 } 512 513 /** 514 * @return Next handle that will be written. 515 */ getNextHandle()516 unsigned long getNextHandle() const { 517 return m_handle; 518 } 519 520 /** 521 * Increases handle, so that the handle returned remains available. 522 */ incHandle()523 unsigned long incHandle() const { 524 return m_handle++; 525 } 526 527 /** 528 * Sets the handle of the model space. Entities refer to 529 * this handle. 530 */ setModelSpaceHandle(unsigned long h)531 void setModelSpaceHandle(unsigned long h) { 532 modelSpaceHandle = h; 533 } 534 getModelSpaceHandle()535 unsigned long getModelSpaceHandle() { 536 return modelSpaceHandle; 537 } 538 539 /** 540 * Sets the handle of the paper space. Some special blocks refer to 541 * this handle. 542 */ setPaperSpaceHandle(unsigned long h)543 void setPaperSpaceHandle(unsigned long h) { 544 paperSpaceHandle = h; 545 } 546 getPaperSpaceHandle()547 unsigned long getPaperSpaceHandle() { 548 return paperSpaceHandle; 549 } 550 551 /** 552 * Sets the handle of the paper space 0. Some special blocks refer to 553 * this handle. 554 */ setPaperSpace0Handle(unsigned long h)555 void setPaperSpace0Handle(unsigned long h) { 556 paperSpace0Handle = h; 557 } 558 getPaperSpace0Handle()559 unsigned long getPaperSpace0Handle() { 560 return paperSpace0Handle; 561 } 562 563 /** 564 * Must be overwritten by the implementing class to write a 565 * real value to the file. 566 * 567 * @param gc Group code. 568 * @param value The real value. 569 */ 570 virtual void dxfReal(int gc, double value) const = 0; 571 572 /** 573 * Must be overwritten by the implementing class to write an 574 * int value to the file. 575 * 576 * @param gc Group code. 577 * @param value The int value. 578 */ 579 virtual void dxfInt(int gc, int value) const = 0; 580 581 /** 582 * Must be overwritten by the implementing class to write an 583 * int value (hex) to the file. 584 * 585 * @param gc Group code. 586 * @param value The int value. 587 */ 588 virtual void dxfHex(int gc, int value) const = 0; 589 590 /** 591 * Must be overwritten by the implementing class to write a 592 * string to the file. 593 * 594 * @param gc Group code. 595 * @param value The string. 596 */ 597 virtual void dxfString(int gc, const char* value) const = 0; 598 599 /** 600 * Must be overwritten by the implementing class to write a 601 * string to the file. 602 * 603 * @param gc Group code. 604 * @param value The string. 605 */ 606 virtual void dxfString(int gc, const string& value) const = 0; 607 608 protected: 609 mutable unsigned long m_handle; 610 mutable unsigned long modelSpaceHandle; 611 mutable unsigned long paperSpaceHandle; 612 mutable unsigned long paperSpace0Handle; 613 614 /** 615 * DXF version to be created. 616 */ 617 DL_Codes::version version; 618 private: 619 }; 620 621 #endif 622