00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "a2dprec.h"
00013
00014 #ifdef __BORLANDC__
00015 #pragma hdrstop
00016 #endif
00017
00018 #ifndef WX_PRECOMP
00019 #include "wx/wx.h"
00020 #endif
00021
00022 #include <cstring>
00023
00024 #ifdef new
00025 #undef new
00026 #endif
00027
00028 #include "a2dprivate.h"
00029
00030 #if wxART2D_USE_GDSIO
00031
00032 #include "wx/canvas/candefs.h"
00033 #include "wx/canvas/canglob.h"
00034 #include "wx/canvas/algos.h"
00035 #include "wx/canvas/cancom.h"
00036 #include "wx/canvas/canobj.h"
00037 #include "wx/canvas/vpath.h"
00038 #include "wx/canvas/candoc.h"
00039 #include "wx/canvas/layerinf.h"
00040 #include "wx/canvas/recur.h"
00041 #include "wx/canvas/drawer.h"
00042 #include "wx/gdsio/gdsio.h"
00043 #include "wx/gdsio/gdserr.h"
00044
00045 #include <wx/datetime.h>
00046 #include <limits.h>
00047
00048 const a2dError a2dError_GDSIIparse( wxT("a2dError_GDSIIparse"), wxT("gdsii parsing error") );
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #define MAX_G_BYTES 8 // maximum bytes a value can use
00091
00092
00093 struct _ARRAY
00094 {
00095 unsigned char array[MAX_G_BYTES];
00096 };
00097 struct _ARRAYB
00098 {
00099 char array[MAX_G_BYTES];
00100 };
00101
00102
00103 struct a_union_value
00104 {
00105
00106 a_union_value() { memset( array.array, 0, MAX_G_BYTES ); }
00107
00108 union
00109 {
00110 TWO_G_BYTE_SIGNED_INTEGER two_byte_signed_integer;
00111 FOUR_G_BYTE_SIGNED_INTEGER four_byte_signed_integer;
00112 FOUR_G_BYTE_REAL four_byte_real;
00113 EIGHT_G_BYTE_REAL eight_byte_real;
00114 _ARRAY array;
00115 _ARRAYB arrayc;
00116 };
00117 };
00118
00119
00120 unsigned int a2dIOHandlerGDSIn::ReadUnsignedInt()
00121 {
00122 unsigned char swap;
00123 a_union_value a_value;
00124 a_value.eight_byte_real=0;
00125
00126 a2dIOHandlerStrIn::Read( a_value.arrayc.array, 2);
00127
00128 #if wxBYTE_ORDER == wxBIG_ENDIAN
00129 #else
00130 swap = a_value.array.array[1];
00131 a_value.array.array[1] = a_value.array.array[0];
00132 a_value.array.array[0] = swap;
00133 #endif
00134 return a_value.two_byte_signed_integer;
00135 }
00136
00137
00138
00139 int a2dIOHandlerGDSIn::ReadInt()
00140 {
00141 unsigned char swap;
00142 a_union_value a_value;
00143 a_value.eight_byte_real=0;
00144
00145 a2dIOHandlerStrIn::Read( a_value.arrayc.array, 2);
00146
00147 #if wxBYTE_ORDER == wxBIG_ENDIAN
00148 #else
00149 swap = a_value.array.array[1];
00150 a_value.array.array[1] = a_value.array.array[0];
00151 a_value.array.array[0] = swap;
00152 #endif
00153 return a_value.two_byte_signed_integer;
00154 }
00155
00156
00157 long a2dIOHandlerGDSIn::ReadLong()
00158 {
00159 a_union_value a_value;
00160 char array[4];
00161
00162
00163
00164
00165
00166 a2dIOHandlerStrIn::Read( array, 4);
00167
00168 #if wxBYTE_ORDER == wxBIG_ENDIAN
00169 a_value.array.array = array;
00170 #else
00171 {
00172 a_value.array.array[3] = array[0];
00173 a_value.array.array[2] = array[1];
00174 a_value.array.array[1] = array[2];
00175 a_value.array.array[0] = array[3];
00176 }
00177 #endif
00178
00179 return a_value.four_byte_signed_integer;
00180 }
00181
00182
00183 float a2dIOHandlerGDSIn::ReadFloat()
00184 {
00185 a_union_value a_value;
00186
00187
00188
00189
00190 #if wxBYTE_ORDER == wxBIG_ENDIAN
00191 for(short int i=0; i<=3; i++)
00192 #else
00193 for(short int i=3; i>=0; i--)
00194 #endif
00195 a_value.array.array[i] = GetC();
00196
00197
00198
00199
00200
00201
00202
00203 return a_value.four_byte_real;
00204 }
00205
00206
00207
00208 double a2dIOHandlerGDSIn::ReadDouble()
00209 {
00210 a_union_value a_value;
00211 short int i;
00212
00213
00214
00215
00216 for(i=0; i<8; i++)
00217 a_value.array.array[i] = GetC();
00218
00219
00220 gds2double(a_value.array.array);
00221
00222 return a_value.eight_byte_real;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 struct bldun
00270 {
00271 bldun(){ memset( by, 0, sizeof( wxFloat64 ) ); }
00272 union
00273 {
00274 wxByte by[ sizeof( wxFloat64 ) / sizeof( wxByte ) ];
00275 wxUint32 fl[ sizeof( wxFloat64 ) / sizeof( wxUint32 ) ];
00276 wxFloat64 machdb;
00277 };
00278 };
00279
00280
00281
00282
00283
00284
00285
00286 void a2dIOHandlerGDSIn::gds2double(unsigned char fb[])
00287 {
00288 bldun bld;
00289 int j;
00290 wxUint32 carry, e, mantissa[2], s;
00291 # if defined(ultrix) || wxBYTE_ORDER == wxLITTLE_ENDIAN
00292 wxUint32 swap;
00293 # endif
00294
00295 #if wxBYTE_ORDER == wxLITTLE_ENDIAN
00296
00297
00298 for (j = 0; j < 8; j++)
00299 bld.by[j]=fb[7-j];
00300 #else
00301 for (j = 0; j < 8; j++)
00302 bld.by[j]=fb[j];
00303 #endif
00304
00305
00306 #ifdef vax
00307 if( bld.fl[0] == 0 && bld.fl[1] == 0) return;
00308
00309
00310 s = (bld.fl[1] & 0x80000000L) >> 31;
00311
00312 e = (bld.fl[1] & 0x7F000000L) >> 24;
00313
00314
00315 mantissa[0] = bld.fl[1] & 0x00FFFFFFL;
00316 mantissa[1] = bld.fl[0];
00317
00318
00319 e = 4 * (e - 64) + 128;
00320 if (mantissa[0] == 0 && mantissa[1] == 0 && e != 0)
00321 {
00322
00323 bld.fl[1] = 0;
00324
00325 for (j = 0; j < 8; j++)
00326 fb[j]=bld.by[j];
00327 return;
00328 }
00329
00330
00331 while( mantissa[0] < 0x00800000L )
00332 {
00333
00334 carry = mantissa[1] >> 31;
00335
00336 mantissa[0] = mantissa[0] << 1 | carry;
00337
00338 mantissa[1] = mantissa[1] << 1;
00339
00340
00341
00342 e--;
00343 }
00344
00345
00346
00347
00348
00349 bld.fl[0] = (mantissa[0] & 0x007F0000L) >> 16 |
00350 (mantissa[0] & 0x0000FFFFL) << 16 |
00351 s << 15 | e << 7;
00352
00353
00354 bld.fl[1] = mantissa[1] << 16 | mantissa[1] >> 16;
00355
00356 for (j = 0; j < 8; j++)
00357 fb[j] = bld.by[j];
00358
00359 #else
00360
00361
00362 if (bld.fl[0] == 0 && bld.fl[1] == 0 )
00363 return;
00364
00365 #if wxBYTE_ORDER == wxLITTLE_ENDIAN || defined(ultrix)
00366
00367 swap = bld.fl[0] ; bld.fl[0] = bld.fl[1] ; bld.fl[1] = swap ;
00368 #endif
00369
00370 s = (bld.fl[0] & 0x80000000L) >> 31;
00371
00372 e = (bld.fl[0] & 0x7F000000L) >> 24;
00373
00374
00375 mantissa[0] = bld.fl[0] & 0x00FFFFFFL;
00376 mantissa[1] = bld.fl[1];
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 e = 4*(e - 64) + 1023;
00403
00404 if (mantissa[0] == 0 && mantissa[1] == 0 && e != 0)
00405 {
00406
00407 bld.fl[0] = 0x00000000L;
00408 bld.fl[1] = 0x00000000L;
00409
00410
00411 for (j=0;j<8;j++)
00412 fb[j]=bld.by[j];
00413 return;
00414 }
00415
00416
00417 while (mantissa[0] < 0x01000000L)
00418 {
00419
00420 carry = mantissa[1] >> 31;
00421 mantissa[0] = (mantissa[0] << 1) | carry;
00422 mantissa[1] = mantissa[1] << 1;
00423
00424
00425 e--;
00426 }
00427
00428
00429 if( e < 1 || e > 2047 )
00430 {
00431 bld.fl[0] = 0x80000000L;
00432 bld.fl[1] = 0x00000000L;
00433
00434 #if wxBYTE_ORDER == wxLITTLE_ENDIAN || defined(ultrix)
00435 swap = bld.fl[0];
00436 bld.fl[0] = bld.fl[1];
00437 bld.fl[1] = swap;
00438 # endif
00439
00440
00441 for (j=0;j<8;j++)
00442 fb[j]=bld.by[j];
00443 return;
00444 }
00445
00446
00447
00448 bld.fl[0] = ((mantissa[0] & 0x00FFFFFFL) >> 4) | (s << 31) | (e << 20);
00449 bld.fl[1] = (mantissa[0] << 28) | (mantissa[1] >> 4);
00450
00451 #if wxBYTE_ORDER == wxLITTLE_ENDIAN || defined(ultrix)
00452 swap = bld.fl[0];
00453 bld.fl[0] = bld.fl[1];
00454 bld.fl[1] = swap;
00455 # endif
00456
00457 for (j = 0; j < 8; j++)
00458 fb[j]=bld.by[j];
00459 #endif
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 void a2dIOHandlerGDSOut::double2gds(unsigned char fb[])
00487
00488 {
00489 bldun bld;
00490
00491 union
00492 {
00493 wxUint32 f[2];
00494 wxFloat64 check;
00495 } hard_check;
00496 int j;
00497
00498 #ifdef vax
00499 wxUint32 carry, e, f[2], s;
00500
00501
00502 for (j = 0; j < 8; j++)
00503 bld.by[j] = fb[j];
00504
00505 hard_check.f[0] = bld.fl[0];
00506 hard_check.f[1] = bld.fl[1];
00507
00508
00509 s = (bld.fl[0] & 0x00008000L) >> 15;
00510
00511 e = (bld.fl[0] & 0x00007F80L) >> 7;
00512
00513 if( s == 0 & e == 0)
00514 {
00515 bld.fl[0] = bld.fl[1] = 0;
00516
00517 for (j=0;j<8;j++)
00518 fb[j]=bld.by[j];
00519 return;
00520 }
00521
00522
00523 f[0] = (bld.fl[0] & 0x0000007FL) << 16 | bld.fl[0] >> 16 | 0x00800000L;
00524
00525 f[1] = bld.fl[1] << 16 | bld.fl[1] >> 16;
00526
00527
00528 e = e - 128;
00529
00530
00531 while ((e % 4) != 0)
00532 {
00533
00534 carry = f[0] & 0x00000001L;
00535 f[0] = f[0] >> 1;
00536 f[1] = f[1] >> 1 | carry << 31;
00537
00538 e++;
00539 }
00540
00541
00542 e = e/4 + 64;
00543
00544
00545 bld.fl[1] = f[0] | e << 24 | s << 31;
00546 bld.fl[0] = f[1];
00547
00548
00549 if (hard_check.check == 1E-9)
00550 bld.fl[0] = bld.fl[0] & 0XFFFFFF51L;
00551
00552 for (j = 0; j < 8; j++)
00553 bld.by[j] = fb[j];
00554
00555 #else
00556
00557 wxUint32 carry, f[2], s;
00558 #if wxBYTE_ORDER == wxLITTLE_ENDIAN || defined(ultrix)
00559 wxUint32 swap;
00560 # endif
00561
00562 long e;
00563
00564 for (j = 0; j < 8; j++)
00565 bld.by[j]=fb[j];
00566
00567
00568 hard_check.f[0] = bld.fl[0];
00569 hard_check.f[1] = bld.fl[1];
00570
00571 #if wxBYTE_ORDER == wxLITTLE_ENDIAN || defined(ultrix)
00572 swap = bld.fl[0];
00573 bld.fl[0] = bld.fl[1];
00574 bld.fl[1] = swap;
00575 # endif
00576
00577
00578 s = (bld.fl[0] & 0x80000000L) >> 31;
00579
00580 e = (bld.fl[0] & 0x7FF00000L) >> 20;
00581
00582
00583 if( (s == 0) & (e == 0))
00584 {
00585
00586 bld.fl[0] = bld.fl[1] = 0;
00587
00588 #if wxBYTE_ORDER == wxLITTLE_ENDIAN || defined(ultrix)
00589
00590
00591 for (j=0;j<8;j++)
00592 fb[j]=bld.by[7-j];
00593 # else
00594 for (j=0;j<8;j++)
00595 fb[j]=bld.by[j];
00596 # endif
00597
00598 return;
00599 }
00600
00601
00602 f[0] = (bld.fl[0] & 0x000FFFFFL);
00603 f[1] = bld.fl[1];
00604
00605
00606 f[0] |= 0x00100000L;
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 e = e - 1023;
00618
00619
00620 while( (e % 4) != 0 )
00621 {
00622
00623 carry = f[1] >> 31;
00624 f[0] <<= 1;
00625 f[1] <<= 1;
00626 f[0] |= carry;
00627
00628 e--;
00629 }
00630
00631
00632 e = e/4 + 65;
00633
00634
00635 if( e < 0 || e > 127 )
00636 {
00637 bld.fl[0] = 0x80000000L;
00638 bld.fl[1] = 0x00000000L;
00639
00640 #if wxBYTE_ORDER == wxLITTLE_ENDIAN || defined(ultrix)
00641 swap = bld.fl[0];
00642 bld.fl[0] = bld.fl[1];
00643 bld.fl[1] = swap;
00644 # endif
00645
00646 #if wxBYTE_ORDER == wxLITTLE_ENDIAN || defined(ultrix)
00647
00648
00649 for (j=0;j<8;j++)
00650 fb[j]=bld.by[7-j];
00651 # else
00652 for (j=0;j<8;j++)
00653 fb[j]=bld.by[j];
00654 # endif
00655
00656 return;
00657 }
00658
00659
00660 bld.fl[0] = f[0] | (e << 24) | (s << 31);
00661 bld.fl[1] = f[1];
00662
00663
00664 if( hard_check.check == 1E-3)
00665 bld.fl[1] = (bld.fl[1] & 0XFFFFFF00L) | 0X000000EFL;
00666 if( hard_check.check == 1E-9)
00667 bld.fl[1] = (bld.fl[1] & 0XFFFFFF00L) | 0X00000051L;
00668
00669
00670 #if wxBYTE_ORDER == wxLITTLE_ENDIAN || defined(ultrix)
00671 swap = bld.fl[0];
00672 bld.fl[0] = bld.fl[1];
00673 bld.fl[1] = swap;
00674 # endif
00675 #if wxBYTE_ORDER == wxLITTLE_ENDIAN
00676
00677
00678 for (j = 0; j < 8; j++)
00679 fb[j] = bld.by[7-j];
00680 # else
00681 for (j = 0; j < 8; j++)
00682 fb[j] = bld.by[j];
00683 # endif
00684
00685 #endif
00686 }
00687
00688
00689
00690
00691
00692 double Check_int(double getal)
00693
00694 {
00695
00696 if ( (ceil(getal) - getal) < 0.0001)
00697 return ceil(getal);
00698
00699 else if ( (getal - floor(getal)) < 0.0001)
00700
00701 return floor(getal);
00702
00703 return getal;
00704
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
00714 Strans::Strans(double a_angle, double a_scale,
00715
00716 bool a_abs_angle, bool a_abs_scale, bool a_reflection)
00717 {
00718 m_stransflags.total = 0;
00719
00720 SetAbsAngle(a_abs_angle);
00721 SetAbsScale(a_abs_scale);
00722 SetReflection(a_reflection);
00723 SetAngle(a_angle);
00724 SetScale(a_scale);
00725 }
00726
00727 Strans& Strans::operator=(Strans& a_strans)
00728 {
00729 m_stransflags.total = a_strans.m_stransflags.total;
00730
00731 SetAbsAngle( bool(a_strans.m_stransflags.bits.abs_angle) );
00732 SetAbsScale( bool(a_strans.m_stransflags.bits.abs_scale) );
00733 SetReflection( bool(a_strans.m_stransflags.bits.reflection) );
00734 SetAngle(a_strans.m_angle);
00735 SetScale(a_strans.m_scale);
00736
00737 return *this;
00738 }
00739
00740
00741 bool Strans::GetStrans()
00742 {
00743 return m_strans_need;
00744 }
00745
00746 void Strans::SetAngle(double a_angle)
00747 {
00748 m_angle = a_angle;
00749 if ( m_scale != 0)
00750 m_strans_need = true;
00751 }
00752
00753
00754 void Strans::SetScale(double a_scale)
00755 {
00756 m_scale = a_scale;
00757 if ( m_scale != 1)
00758 m_strans_need = true;
00759 }
00760
00761
00762 void Strans::SetAbsAngle(bool b)
00763 {
00764 m_stransflags.bits.abs_angle = b;
00765 }
00766
00767
00768 void Strans::SetAbsScale(bool b)
00769 {
00770 m_stransflags.bits.abs_scale = b;
00771 }
00772
00773
00774 void Strans::SetReflection(bool b)
00775 {
00776 m_stransflags.bits.reflection = b;
00777 }
00778
00779
00780
00781 double Strans::GetAngle()
00782 {
00783 return m_angle;
00784 }
00785
00786
00787 double Strans::GetScale()
00788 {
00789 return m_scale;
00790 }
00791
00792
00793 bool Strans::GetAbsAngle()
00794 {
00795 return (bool) m_stransflags.bits.abs_angle;
00796 }
00797
00798
00799 bool Strans::GetAbsScale()
00800 {
00801 return (bool)m_stransflags.bits.abs_scale;
00802 }
00803
00804
00805 bool Strans::GetReflection()
00806 {
00807 return (bool)m_stransflags.bits.reflection;
00808 }
00809
00810
00811 void Strans::MakeStrans( const a2dAffineMatrix& matrix )
00812 {
00813 double scale_factor = matrix.GetValue(0,0);
00814 double rot_angle;
00815
00816 double temp1 = matrix.GetValue(0,0);
00817
00818 double temp2 = matrix.GetValue(0,1);
00819 bool check_1 = (matrix.GetValue(0,0) < 0);
00820
00821 bool check_2 = (matrix.GetValue(1,1) < 0);
00822
00823 m_strans_need=false;
00824
00825 if (check_1)
00826 {
00827
00828 SetReflection(true);
00829 rot_angle = 180;
00830 SetAngle(rot_angle);
00831 m_strans_need = true;
00832 }
00833
00834 if (check_2)
00835 {
00836
00837 SetReflection(!GetReflection());
00838 m_strans_need = true;
00839 }
00840
00841
00842 if (matrix.GetValue(0,1) != 0)
00843 {
00844
00845 rot_angle = Check_int(atan2(temp2,temp1)*180/wxPI);
00846
00847 SetAngle(rot_angle);
00848 if (rot_angle != 90 && rot_angle != -90)
00849 scale_factor = matrix.GetValue(0,0)/cos((rot_angle/180)*wxPI);
00850 else
00851 scale_factor = matrix.GetValue(1,0)/sin((rot_angle/180)*wxPI);
00852 m_strans_need = true;
00853 }
00854
00855
00856
00857
00858 scale_factor = Check_int(scale_factor);
00859
00860 if (scale_factor < 0)
00861 scale_factor = -scale_factor;
00862
00863 if (scale_factor != 1)
00864 {
00865 SetScale(scale_factor);
00866 m_strans_need = true;
00867 }
00868
00869 }
00870
00871
00872
00873
00874
00875 a2dIOHandlerGDSIn::a2dIOHandlerGDSIn()
00876 {
00877 m_fontType = a2dFONT_STROKED;
00878 m_docClassInfo = &a2dCanvasDocument::ms_classInfo;
00879 }
00880
00881 a2dIOHandlerGDSIn::~a2dIOHandlerGDSIn()
00882 {
00883 }
00884
00885 void a2dIOHandlerGDSIn::InitializeLoad( )
00886 {
00887 a2dIOHandlerStrIn::InitializeLoad();
00888 if (m_doc)
00889 a2dGlobals->SetAberPolyToArc( double(a2dGetCmdh()->GetAberPolyToArc())/m_doc->GetUnitsScale() );
00890 }
00891
00892 void a2dIOHandlerGDSIn::ResetLoad( )
00893 {
00894 a2dIOHandlerStrIn::ResetLoad();
00895 }
00896
00897 bool a2dIOHandlerGDSIn::CanLoad( a2dDocumentInputStream& stream, const wxObject* obj, wxClassInfo* docClassInfo )
00898 {
00899 if ( obj && !wxDynamicCast( obj, a2dCanvasDocument) )
00900 return false;
00901
00902 if ( docClassInfo && m_docClassInfo && !docClassInfo->IsKindOf( m_docClassInfo ) )
00903 return false;
00904
00905 m_streami = &stream;
00906 m_doc = 0;
00907
00908 SeekI( 0 );
00909
00910 m_recordsize = 0;
00911 m_recordtype = 0;
00912 m_datatype = 0;
00913 m_back = false;
00914
00915 if (!ReadHeader(GDS_HEADER))
00916 {
00917 SeekI( 0 );
00918 return false;
00919 }
00920 SeekI( 0 );
00921 return true;
00922 }
00923
00924 bool a2dIOHandlerGDSIn::LinkReferences()
00925 {
00926 bool res = a2dIOHandler::LinkReferences();
00927
00928
00929
00930
00931 a2dCanvasObjectList::iterator rootchild = m_doc->GetRootObject()->GetChildObjectList()->begin();
00932 while ( rootchild != m_doc->GetRootObject()->GetChildObjectList()->end() )
00933 {
00934 a2dCanvasObjectList::iterator delnode = rootchild;
00935 rootchild++;
00936 if ( (*delnode)->GetCheck() )
00937 {
00938 m_doc->GetRootObject()->GetChildObjectList()->erase( delnode );
00939 }
00940 }
00941 return res;
00942 }
00943
00944 bool a2dIOHandlerGDSIn::Load( a2dDocumentInputStream& stream, wxObject* doc )
00945 {
00946 m_streami = &stream;
00947 m_doc = wxStaticCast( doc, a2dCanvasDocument);
00948 InitializeLoad();
00949
00950 wxString path;
00951 path = m_doc->GetFilename().GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR ) + m_doc->GetFilename().GetName() + wxT(".cvg");
00952 if ( wxFileExists( path ) )
00953 m_doc->LoadLayers( path );
00954
00955 m_recordsize = 0;
00956 m_recordtype = 0;
00957 m_datatype = 0;
00958 m_back = false;
00959
00960 unsigned int i;
00961 for (i = 0; i < wxMAXLAYER; i++)
00962 m_mapping[i]=-1;
00963 for (i = 0; i < wxMAXLAYER; i++)
00964 {
00965 if ( m_doc->GetLayerSetup()->GetLayerIndex()[i] != wxNullLayerInfo )
00966 {
00967 int layerIndex = m_doc->GetLayerSetup()->GetInMapping(i);
00968 wxASSERT_MSG( layerIndex >= 0 && layerIndex < wxMAXLAYER, _( "InMap must be > wxMAXLAYER" ) );
00969 m_mapping[ m_doc->GetLayerSetup()->GetInMapping(i) ] = i;
00970 }
00971 }
00972
00973 for (i = 0; i < wxMAXLAYER; i++)
00974 if (m_mapping[i]==-1)
00975 m_mapping[i]=0;
00976
00977 try
00978 {
00979 ReadGdsII();
00980 }
00981 catch (GDS_Error& _error)
00982 {
00983 ResetLoad();
00984 a2dDocviewGlobals->ReportErrorF( a2dError_NotSpecified, _("error in GDSII file \n %s \n"),_error.GetErrorMessage().c_str());
00985 return false;
00986 }
00987
00988 ResetLoad();
00989 return true;
00990 }
00991
00992
00993 void a2dIOHandlerGDSIn::ReadGdsII()
00994 {
00995
00996
00997
00998
00999 a2dWalker_SetBoolProperty setp( PROPID_Check, false );
01000 setp.Start( m_doc->GetRootObject() );
01001
01002
01003
01004
01005
01006 if (!ReadHeader(GDS_HEADER))
01007 throw GDS_Error( _("GDS_HEADER record missing (in GDSII)"), _("Error"));
01008
01009 m_doc->SetVersion( ReadInt() );
01010
01011 if (!ReadBgnlib())
01012 throw GDS_Error( _("BGNLIB record missing (in GDSII)") );
01013
01014 if (!ReadLibrarySettings())
01015 throw GDS_Error( _("LIBNAME missing (in GDSII)") );
01016
01017 while (ReadStructure( m_doc->GetRootObject() ))
01018 {
01019 }
01020
01021 if (!ReadHeader(GDS_ENDLIB))
01022 throw GDS_Error( _("GDS_ENDLIB record missing (in GDSII)"), _("Error") );
01023
01024
01025
01026
01027 LinkReferences();
01028
01029 if ( m_doc->GetRootObject()->GetChildObjectsCount() != 1 )
01030 m_doc->SetMultiRoot();
01031 else
01032 m_doc->SetRootObject( m_doc->GetRootObject()->GetChildObjectList()->front().Get() );
01033 }
01034
01035
01036 bool a2dIOHandlerGDSIn::ReadBgnlib()
01037 {
01038 if (!ReadHeader(GDS_BGNLIB))
01039 return(false);
01040
01041 int year;
01042 int month;
01043 int day;
01044 int hour;
01045 int minute;
01046 int second;
01047
01048 year = ReadInt();
01049 month = ReadInt() - 1;
01050 day = ReadInt();
01051 hour = ReadInt();
01052 minute = ReadInt();
01053 second = ReadInt();
01054
01055 m_doc->GetModificationTime().Set( day, (wxDateTime::Month)month, year, hour, minute, second );
01056
01057 year = ReadInt();
01058 month = ReadInt() - 1;
01059 day = ReadInt();
01060 hour = ReadInt();
01061 minute = ReadInt();
01062 second = ReadInt();
01063
01064 m_doc->GetAccessTime().Set( day, (wxDateTime::Month)month, year, hour, minute, second );
01065
01066 return(true);
01067 }
01068
01069
01070 bool a2dIOHandlerGDSIn::ReadLibrarySettings()
01071 {
01072 if (!ReadHeader(GDS_LIBNAME))
01073 throw GDS_Error( _("GDS_LIBNAME record missing (in GDSII)"), _("Error"));
01074
01075 wxString libname;
01076 ReadString(libname);
01077
01078 m_doc->SetLibraryName(libname);
01079
01080 if (ReadHeader(GDS_REFLIBS))
01081 SkipData();
01082
01083 if (ReadHeader(GDS_FONTS))
01084 SkipData();
01085
01086 if (ReadHeader(GDS_ATTRTABLE))
01087 SkipData();
01088
01089 if (ReadHeader(GDS_GENERATIONS))
01090 SkipData();
01091
01092 if (ReadHeader(GDS_FORMAT))
01093 SkipData();
01094
01095 if (!ReadHeader(GDS_UNITS))
01096 throw GDS_Error( _("UNITS missing (in GDSII)") );
01097
01098 m_userunits_out = ReadDouble();
01099 m_doc->SetUnitsAccuracy(m_userunits_out);
01100 double value1;
01101 value1 = ReadDouble();
01102 double metersScale = value1/m_userunits_out;
01103 m_doc->SetUnitsScale( metersScale );
01104
01105 a2dDoMu unit = a2dDoMu( 1, 1 );
01106 m_doc->SetUnits( unit.GetMultiplierString() );
01107 unit = a2dDoMu( 1, metersScale );
01108 m_doc->SetUnits( unit.GetMultiplierString() );
01109
01110 return true;
01111 }
01112
01113
01114 bool a2dIOHandlerGDSIn::ReadHeader(int type)
01115 {
01116 if (m_back)
01117 {
01118 if (m_recordtype == type)
01119 {
01120 m_back=false;
01121 return true;
01122 }
01123 }
01124 else
01125 {
01126 if ( Eof() )
01127 throw GDS_Error( _("Unexpected end of GDSII-file!"), _("Driver Error"));
01128
01129 m_recordsize = ReadUnsignedInt();
01130 m_recordtype = GetC();
01131 m_datatype = GetC();
01132
01133 m_recordsize -= (TWO_G_BYTE_UNSIGNED_INTEGER) GDS_HEADERSIZE;
01134
01135 if (m_recordtype == type)
01136 return true;
01137 if (m_recordtype>56)
01138 {
01139
01140 SkipData();
01141 }
01142 m_back=true;
01143 }
01144 return false;
01145 }
01146
01147 void a2dIOHandlerGDSIn::SkipData()
01148 {
01149 for (int i=0;i < m_recordsize; i++)
01150 {
01151 GetC();
01152 }
01153
01154 m_back=false;
01155 m_recordsize =0;
01156 m_recordtype =0;
01157 m_datatype =0;
01158 }
01159
01160 void a2dIOHandlerGDSIn::ReadString(wxString& a_string)
01161 {
01162 wxString header;
01163 char buf[512];
01164 int last_read = a2dIOHandlerStrIn::Read( buf, m_recordsize);
01165
01166 if ( buf[m_recordsize-1] == '\0' )
01167 a_string = wxString(buf, wxConvUTF8, m_recordsize-1 );
01168 else
01169 a_string = wxString(buf, wxConvUTF8, m_recordsize );
01170 }
01171
01172
01173 bool a2dIOHandlerGDSIn::ReadElement( a2dCanvasObject* parent )
01174 {
01175 if ( ReadBoundary( parent ) ||
01176 ReadPath( parent ) ||
01177 ReadStructureReference( parent ) ||
01178 ReadArrayReference( parent ) ||
01179 ReadText( parent ) ||
01180 ReadNode( parent ) ||
01181 ReadBox( parent ) )
01182 {
01183 }
01184 else
01185 return false;
01186
01187 while (ReadProperty())
01188 ;
01189
01190 if (!ReadHeader(GDS_ENDEL))
01191 throw GDS_Error( _("ENDEL missing (in Element)") );
01192
01193 return true;
01194 }
01195
01196
01197
01198 bool a2dIOHandlerGDSIn::ReadProperty()
01199 {
01200 int i;
01201 if (ReadHeader(GDS_PROPATTR))
01202 {
01203
01204 int propattr;
01205 propattr = ReadInt();
01206
01207 if ( Eof() )
01208 throw GDS_Error(_("Unexpected end of GDSII-file!"), _("GDSII Input parsing Error"));
01209
01210 m_back=false;
01211
01212
01213 if (!ReadHeader(GDS_PROPVALUE))
01214 throw GDS_Error( _("PROPVALUE missing (in Property)") );
01215
01216
01217 G_BYTE propval[126];
01218 for (i=0;i < m_recordsize; i++)
01219 {
01220 if ( Eof() )
01221 throw GDS_Error(_("Unexpected end of GDSII-file!"), _("GDSII Input parsing Error"));
01222
01223 propval[i] = GetC();
01224 }
01225 m_back=false;
01226
01227 if (i<=126)
01228 propval[i]=0;
01229
01230 return true;
01231 }
01232 return false;
01233 }
01234
01235
01236
01237 bool a2dIOHandlerGDSIn::ReadBoundary( a2dCanvasObject* parent )
01238 {
01239
01240 if (!ReadHeader(GDS_BOUNDARY))
01241 return false;
01242
01243
01244
01245 a2dSmrtPtr<a2dPolygonL> _Boundary = new a2dPolygonL();
01246
01247 ReadElflags(_Boundary);
01248
01249 if (ReadHeader(GDS_PLEX))
01250 SkipData();
01251
01252 if (!ReadLayer(_Boundary))
01253 throw GDS_Error( _("Boundary: LAYER missing (in GDS-file)") );
01254
01255 if (!ReadHeader(GDS_DATATYPE))
01256 throw GDS_Error( _("Boundary: DATATYPE missing (in GDS-file)") );
01257
01258 SetDataTypeProperty( _Boundary, ReadInt() );
01259
01260 if ( m_doc->GetLayerSetup()->GetRead(_Boundary->GetLayer()))
01261 {
01262 if (!Read( _Boundary ))
01263 throw GDS_Error( _("Header: XY missing (in Boundary)") );
01264
01265 parent->Append( _Boundary );
01266 }
01267 else
01268 {
01269 ReadHeader(GDS_XY);
01270 SkipData();
01271 }
01272
01273 return true;
01274 }
01275
01276
01277 bool a2dIOHandlerGDSIn::ReadPath( a2dCanvasObject* parent )
01278 {
01279
01280
01281
01282 if (!ReadHeader(GDS_PATH))
01283 return false;
01284
01285
01286 a2dSmrtPtr<a2dPolylineL> path = new a2dPolylineL();
01287
01288 ReadElflags( path );
01289
01290 if (ReadHeader(GDS_PLEX))
01291 SkipData();
01292
01293 if (!ReadLayer( path ))
01294 throw GDS_Error( _("record LAYER missing (in Path)") );
01295
01296 if (!ReadHeader(GDS_DATATYPE))
01297 throw GDS_Error( _("record DATATYPE missing (in Path)") );
01298
01299 SetDataTypeProperty( path, ReadInt() );
01300
01301 if (ReadHeader(GDS_PATHTYPE))
01302 path->SetPathType( (a2dPATH_END_TYPE) ReadInt() );
01303
01304 if ( ReadHeader(GDS_WIDTH))
01305 path->SetContourWidth( ReadLong() * m_userunits_out );
01306
01307 if (ReadHeader(GDS_BGNEXTN))
01308 SkipData();
01309
01310 if (ReadHeader(GDS_ENDEXTN))
01311 SkipData();
01312
01313 if ( m_doc->GetLayerSetup()->GetRead( path->GetLayer()))
01314 {
01315 if ( !Read( path->GetSegments() ))
01316 throw GDS_Error( _("Header: XY missing (in Path)") );
01317 parent->Append( path );
01318 path->RemoveRedundantPoints();
01319 }
01320 else
01321 {
01322 ReadHeader(GDS_XY);
01323 SkipData();
01324 }
01325
01326 return true;
01327 }
01328
01329
01330 bool a2dIOHandlerGDSIn::ReadText( a2dCanvasObject* parent )
01331 {
01332
01333
01334
01335
01336
01337
01338 if (!ReadHeader(GDS_TEXT))
01339 return false;
01340
01341
01342
01343
01344 int elflags = 0;
01345 if (ReadHeader(GDS_ELFLAGS))
01346 elflags = ReadInt();
01347
01348 if (ReadHeader(GDS_PLEX))
01349 SkipData();
01350
01351 int layer;
01352 if ( !ReadLayer( layer ) )
01353 throw GDS_Error( _("Text: LAYER is missing (in GDS-file)") );
01354
01355
01356
01357
01358 if (!ReadHeader(GDS_TEXTTYPE))
01359 throw GDS_Error( _("Text: TEXTBODY is missing (in GDS-file)") );
01360
01361 int texttype = ReadInt();
01362 int presentation = 0;
01363 int pathtype = 0;
01364 long textHeight = 0;
01365
01366 if ( ReadHeader(GDS_PRESENTATION) )
01367 presentation = ReadInt();
01368
01369 if (ReadHeader(GDS_PATHTYPE))
01370 pathtype = ReadInt();
01371
01372 if ( ReadHeader(GDS_WIDTH))
01373 {
01374
01375
01376
01377 textHeight = ReadLong();
01378 }
01379
01380 Strans Strans;
01381 ReadStrans( Strans );
01382
01383 if (!ReadHeader(GDS_XY))
01384 throw GDS_Error( _("Text: XY is missing (in GDS-file)") );
01385
01386 a2dPoint2D point;
01387 Read( point);
01388
01389 a2dAffineMatrix relative_matrix;
01390
01391
01392
01393
01394
01395 if (Strans.GetReflection())
01396 relative_matrix.Mirror();
01397
01398
01399 if (Strans.GetAbsAngle() == 0)
01400 relative_matrix.Rotate(Strans.GetAngle(), 0, 0);
01401
01402
01403 if (Strans.GetAbsScale() == 0)
01404 {
01405
01406
01407
01408 }
01409
01410
01411 relative_matrix.Translate(point.m_x, point.m_y);
01412
01413 if (!ReadHeader(GDS_STRING))
01414 throw GDS_Error( _("Text: STRING is missing (in GDS-file)") );
01415
01416 wxString a_string;
01417 ReadString(a_string);
01418 a_string.Replace( wxT("\t"), wxT(" "));
01419
01420
01421 a2dSmrtPtr<a2dTextGDS> Text = new a2dTextGDS( m_fontType, a_string, Strans.GetScale() * a2dTextGDS::GetFontScaleFactor(), presentation );
01422 Text->SetLayer(m_mapping[layer]);
01423 Text->SetTextType( texttype );
01424 Text->SetPathtype((TEXT_PATHTYPE)pathtype);
01425 Text->SetTransformMatrix(relative_matrix);
01426
01427 #ifdef _G_UNIX
01428 Text->SetTemplate((bool) (elflags && 2));
01429 Text->SetExternal((bool) (elflags && 1));
01430 #else
01431 Text->SetTemplate((bool) (elflags && 1));
01432 Text->SetExternal((bool) (elflags && 2));
01433 #endif
01434
01435
01436 if ( m_doc->GetLayerSetup()->GetRead( Text->GetLayer() ))
01437 parent->Append( Text );
01438
01439 return true;
01440 }
01441
01442
01443
01444 bool a2dIOHandlerGDSIn::ReadStructureReference( a2dCanvasObject* parent )
01445 {
01446
01447
01448
01449
01450 if (!ReadHeader(GDS_SREF))
01451 return false;
01452
01453 a2dPoint2D point;
01454 a2dAffineMatrix relative_matrix;
01455 a2dSmrtPtr<class a2dCanvasObjectReference> sref = new a2dCanvasObjectReference();
01456 try
01457 {
01458
01459 ReadElflags(sref);
01460
01461 if (ReadHeader(GDS_PLEX))
01462 SkipData();
01463
01464 if (!ReadHeader(GDS_SNAME))
01465 throw GDS_Error( _("Header: SNAME missing (in Structure Reference)") );
01466
01467 wxString strname;
01468 ReadString(strname);
01469 sref->SetName(strname);
01470
01471 Strans strans;
01472 ReadStrans(strans);
01473
01474 if (!ReadHeader(GDS_XY))
01475 throw GDS_Error( _("Header: XY missing (in Structure Reference)") );
01476
01477 Read( point );
01478
01479
01480
01481
01482
01483 if (strans.GetReflection())
01484 relative_matrix.Mirror();
01485
01486
01487 if (strans.GetAbsAngle() == 0)
01488 relative_matrix.Rotate(strans.GetAngle(), 0, 0);
01489
01490
01491 if (strans.GetAbsScale() == 0)
01492 {
01493 double scale = strans.GetScale();
01494 relative_matrix.Scale(scale, scale, 0, 0);
01495 }
01496
01497
01498 relative_matrix.Translate(point.m_x, point.m_y);
01499
01500 sref->SetTransformMatrix( relative_matrix );
01501
01502 parent->Append( sref );
01503 ResolveOrAddLink( sref.Get(), sref->GetName() );
01504 }
01505 catch (GDS_Error& _error)
01506 {
01507 throw _error;
01508 }
01509
01510 return true;
01511 }
01512
01513
01514
01515 bool a2dIOHandlerGDSIn::ReadArrayReference( a2dCanvasObject* parent )
01516 {
01517
01518
01519
01520 if (!ReadHeader(GDS_AREF))
01521 return false;
01522
01523 a2dPoint2D Point;
01524 a2dAffineMatrix relative_matrix;
01525 a2dPoint2D HorPoint;
01526 a2dPoint2D VerPoint;
01527
01528
01529 a2dSmrtPtr<class a2dCanvasObjectArrayReference> arrayref = new a2dCanvasObjectArrayReference();
01530 try
01531 {
01532 ReadElflags( arrayref );
01533
01534 if (ReadHeader(GDS_PLEX))
01535 SkipData();
01536
01537 if (!ReadHeader(GDS_SNAME))
01538 throw GDS_Error( _("Header: SNAME missing (in Structure Reference)") );
01539
01540 wxString strname;
01541 ReadString(strname);
01542 arrayref->SetName(strname);
01543
01544 Strans strans;
01545 ReadStrans( strans );
01546
01547 if (!ReadHeader(GDS_COLROW))
01548 throw GDS_Error( _("Header: COLROW missing (in Array Reference)") );
01549
01550 int columns = ReadInt();
01551 arrayref->SetColumns( columns );
01552
01553 int rows = ReadInt();
01554 arrayref->SetRows( rows );
01555
01556
01557 if (!ReadHeader(GDS_XY))
01558 throw GDS_Error( _("Header: XY missing (in Array Reference)") );
01559
01560 Read( Point );
01561 Read( HorPoint );
01562 Read( VerPoint );
01563
01564 arrayref->SetHorzSpace( sqrt( pow(HorPoint.m_x - Point.m_x,2) + pow(HorPoint.m_y - Point.m_y,2) )/columns );
01565 arrayref->SetVertSpace( sqrt( pow(VerPoint.m_x - Point.m_x,2) + pow(VerPoint.m_y - Point.m_y,2) )/rows );
01566
01567
01568
01569
01570
01571 if (strans.GetReflection())
01572 relative_matrix.Mirror();
01573
01574
01575 if (strans.GetAbsAngle() == 0)
01576 relative_matrix.Rotate( strans.GetAngle(), 0, 0);
01577
01578
01579 if (strans.GetAbsScale() == 0)
01580 {
01581 EIGHT_G_BYTE_REAL scale = strans.GetScale();
01582 relative_matrix.Scale(scale, scale, 0, 0);
01583 }
01584
01585
01586 relative_matrix.Translate(Point.m_x, Point.m_y);
01587 arrayref->SetTransformMatrix( relative_matrix );
01588
01589 parent->Append( arrayref );
01590 ResolveOrAddLink( arrayref.Get(), arrayref->GetName() );
01591 }
01592 catch (GDS_Error& _error)
01593 {
01594 throw _error;
01595 }
01596
01597 return true;
01598 }
01599
01600
01601 bool a2dIOHandlerGDSIn::ReadNode( a2dCanvasObject* WXUNUSED(parent) )
01602 {
01603
01604 return false;
01605 }
01606
01607
01608
01609 bool a2dIOHandlerGDSIn::ReadBox( a2dCanvasObject* parent )
01610 {
01611
01612 if (!ReadHeader(GDS_BOX))
01613 return false;
01614
01615
01616 a2dRect* Box = new a2dRect();
01617
01618 ReadElflags( Box );
01619
01620 if (ReadHeader(GDS_PLEX))
01621 SkipData();
01622
01623 if (!ReadLayer( Box ))
01624 throw GDS_Error( _("Box: LAYER missing (in GDS-file)") );
01625
01626 if (!ReadHeader(GDS_BOXTYPE))
01627 throw GDS_Error( _("Box: BOXTYPE missing (in GDS-file)") );
01628
01629 Box->SetBoxType( ReadInt() );
01630
01631 if (!ReadHeader(GDS_XY))
01632 return false;
01633
01634 int points = m_recordsize / (2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER));
01635
01636 if (points != 5 )
01637 throw GDS_Error(_("Wrong number of points in BOX XY."), _("Fatal GDSII error"));
01638
01639 a2dPoint2D seg;
01640 Read( seg );
01641 a2dPoint2D seg2;
01642 Read( seg2 );
01643 a2dPoint2D seg3;
01644 Read( seg3 );
01645 a2dPoint2D seg4;
01646 Read( seg4 );
01647 a2dPoint2D seg5;
01648 Read( seg5 );
01649
01650 double minx, miny, maxx, maxy;
01651
01652 minx = maxx = seg.m_x;
01653 miny = maxy = seg.m_y;
01654
01655 minx = wxMin(minx, seg2.m_x);
01656 maxx = wxMax(maxx, seg2.m_x);
01657 miny = wxMin(miny, seg2.m_y);
01658 maxy = wxMax(maxy, seg2.m_y);
01659
01660 minx = wxMin(minx, seg3.m_x);
01661 maxx = wxMax(maxx, seg3.m_x);
01662 miny = wxMin(miny, seg3.m_y);
01663 maxy = wxMax(maxy, seg3.m_y);
01664
01665 minx = wxMin(minx, seg4.m_x);
01666 maxx = wxMax(maxx, seg4.m_x);
01667 miny = wxMin(miny, seg4.m_y);
01668 maxy = wxMax(maxy, seg4.m_y);
01669
01670 Box->SetWidth( fabs( maxx - minx ) );
01671 Box->SetHeight( fabs( maxy - miny ) );
01672 Box->SetPosXY( minx, miny );
01673
01674 if ( m_doc->GetLayerSetup()->GetRead(Box->GetLayer()))
01675 parent->Append( Box );
01676
01677 return true;
01678 }
01679
01680
01681 bool a2dIOHandlerGDSIn::ReadElflags( a2dCanvasObject* object )
01682 {
01683 if (!ReadHeader(GDS_ELFLAGS))
01684 return false;
01685
01686 int value;
01687 value = ReadInt();
01688
01689 #ifdef _G_UNIX
01690 object->SetTemplate((bool) (value && 2));
01691 object->SetExternal((bool) (value && 1));
01692 #else
01693 object->SetTemplate((bool) (value && 1));
01694 object->SetExternal((bool) (value && 2));
01695 #endif
01696
01697 return true;
01698 }
01699
01700
01701 bool a2dIOHandlerGDSIn::ReadLayer( a2dCanvasObject* object )
01702 {
01703 if (!ReadHeader(GDS_LAYER))
01704 return false;
01705
01706 int layer;
01707 layer = ReadInt();
01708 if ( layer < 0 || layer >= wxMAXLAYER )
01709 {
01710 layer = 0;
01711 wxString mes;
01712 mes.Printf( _("Object %s, layer >= wxMAXLAYER put on layer 0 "), object->GetClassInfo()->GetClassName() );
01713 a2dDocviewGlobals->ReportWarningF( a2dError_NotSpecified, _("warning GDSII file \n %s \n"),
01714 mes.c_str() );
01715 }
01716
01717 object->SetLayer(m_mapping[layer]);
01718 return true;
01719 }
01720
01721
01722 bool a2dIOHandlerGDSIn::ReadLayer( int& layer )
01723 {
01724 if (!ReadHeader(GDS_LAYER))
01725 return false;
01726
01727 layer = ReadInt();
01728 if ( layer < 0 || layer >= wxMAXLAYER )
01729 {
01730 layer = 0;
01731 wxString mes;
01732 mes.Printf( wxT("%s"),_("Object layer >= wxMAXLAYER put on layer 0 ") );
01733 a2dDocviewGlobals->ReportWarningF( a2dError_NotSpecified, _("warning GDSII file \n %s \n"),
01734 mes.c_str() );
01735 }
01736 return true;
01737 }
01738
01739
01740 bool a2dIOHandlerGDSIn::Read( a2dPoint2D& Point)
01741 {
01742 FOUR_G_BYTE_SIGNED_INTEGER value;
01743 value = ReadLong();
01744 Point.m_x = value * m_doc->GetUnitsAccuracy();
01745 value = ReadLong();
01746 Point.m_y = value * m_doc->GetUnitsAccuracy();
01747 return true;
01748 }
01749
01750
01751 bool a2dIOHandlerGDSIn::Read(a2dPolygonL* polygon)
01752 {
01753 if (!ReadHeader(GDS_XY))
01754 return false;
01755
01756 int points = m_recordsize / (2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER))-1;
01757
01758 if (points < 2)
01759 {
01760 if ( points == 1 )
01761 {
01762 a2dPoint2D seg;
01763 Read( seg);
01764 a2dDocviewGlobals->ReportErrorF( a2dError_GDSIIparse,
01765 _("GDSII: Structure %s Only one point in Polygon: %f, %f "), m_strucname.c_str(), seg.m_x, seg.m_y );
01766 polygon->AddPoint( seg.m_x, seg.m_y );
01767 a2dPoint2D segend;
01768 Read(segend);
01769 }
01770 else
01771 throw GDS_Error(_("Too few points in Polygon."), _("Fatal GDSII error"));
01772 }
01773 else
01774 {
01775 for (int i = 0; i < points; i++)
01776 {
01777 a2dPoint2D seg;
01778 Read( seg );
01779 polygon->AddPoint( seg.m_x, seg.m_y );
01780 }
01781 a2dPoint2D segend;
01782 Read(segend);
01783 }
01784
01785 return true;
01786 }
01787
01788
01789 bool a2dIOHandlerGDSIn::Read( a2dVertexList* segments)
01790 {
01791 if (!ReadHeader(GDS_XY))
01792 return false;
01793
01794 int points = m_recordsize / (2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER));
01795 if (points < 2 )
01796 {
01797 if ( points == 1 )
01798 {
01799 a2dLineSegment* seg = new a2dLineSegment( 0, 0 );
01800
01801 FOUR_G_BYTE_SIGNED_INTEGER value;
01802 value = ReadLong();
01803 seg->m_x = value * m_doc->GetUnitsAccuracy();
01804 value = ReadLong();
01805 seg->m_y = value * m_doc->GetUnitsAccuracy();
01806
01807 a2dDocviewGlobals->ReportErrorF( a2dError_GDSIIparse,
01808 _("GDSII: Structure %s Only one point in Polyline: %f, %f "), m_strucname.c_str(), seg->m_x, seg->m_y );
01809 segments->push_back(seg);
01810 }
01811 else
01812 throw GDS_Error(_("Too few points in Polyline."), _("Fatal GDSII error"));
01813 }
01814 else
01815 {
01816 a2dLineSegment* seg;
01817 for (int i = 0; i < points; i++)
01818 {
01819 seg = new a2dLineSegment( 0, 0 );
01820
01821 FOUR_G_BYTE_SIGNED_INTEGER value;
01822 value = ReadLong();
01823 seg->m_x = value * m_doc->GetUnitsAccuracy();
01824 value = ReadLong();
01825 seg->m_y = value * m_doc->GetUnitsAccuracy();
01826 segments->push_back(seg);
01827 }
01828 }
01829
01830 return true;
01831 }
01832
01833
01834
01835
01836 bool a2dIOHandlerGDSIn::ReadStrans( Strans& Strans)
01837 {
01838 if (!ReadHeader(GDS_STRANS))
01839 return(false);
01840
01841 EIGHT_G_BYTE_REAL real;
01842
01843 Strans.m_stransflags.total = ReadInt();
01844
01845 if (ReadHeader(GDS_MAG))
01846 {
01847 real = ReadDouble();
01848 Strans.SetScale(real);
01849 }
01850
01851 if (ReadHeader(GDS_ANGLE))
01852 {
01853 real = ReadDouble();
01854 Strans.SetAngle(real);
01855 }
01856
01857 return true;
01858 }
01859
01860
01861
01862 bool a2dIOHandlerGDSIn::ReadStructure( a2dCanvasObject* parent )
01863 {
01864
01865
01866
01867 if (!ReadHeader(GDS_BGNSTR))
01868 return false;
01869
01870 a2dSmrtPtr<class a2dCanvasObject> Structure = new a2dCanvasObject();
01871
01872 Structure->SetIgnoreLayer( true );
01873
01874
01875 wxDateTime m_modificationtime = wxDateTime::Now();
01876 wxDateTime m_accesstime = wxDateTime::Now();
01877
01878 int year;
01879 int month;
01880 int day;
01881 int hour;
01882 int minute;
01883 int second;
01884
01885 year = ReadInt();
01886 month = ReadInt() - 1;
01887 day = ReadInt();
01888 hour = ReadInt();
01889 minute = ReadInt();
01890 second = ReadInt();
01891
01892 m_modificationtime.Set( day, (wxDateTime::Month)month, year, hour, minute, second );
01893 a2dCanvasObject::PROPID_ModificationDateTime->SetPropertyToObject( Structure, m_modificationtime );
01894
01895 year = ReadInt();
01896 month = ReadInt() - 1;
01897 day = ReadInt();
01898 hour = ReadInt();
01899 minute = ReadInt();
01900 second = ReadInt();
01901
01902 m_accesstime.Set( day, (wxDateTime::Month)month, year, hour, minute, second );
01903 a2dCanvasObject::PROPID_AccessDateTime->SetPropertyToObject( Structure, m_accesstime );
01904
01905 if (!ReadHeader(GDS_STRNAME))
01906 throw GDS_Error( _("STRNAME record missing (in Structure)") );
01907
01908 ReadString(m_strucname);
01909 Structure->SetName(m_strucname);
01910
01911
01912 if(ReadHeader(GDS_STRCLASS))
01913 SkipData();
01914
01915 while ( ReadElement( Structure ) )
01916 {
01917 }
01918
01919 if(!ReadHeader(GDS_ENDSTR))
01920 throw GDS_Error( _("ENDSTR record missing (in GDSII)") );
01921
01922
01923 parent->Append(Structure);
01924
01925
01926 GetObjectHashMap()[m_strucname] = Structure;
01927
01928
01929 return true;
01930 }
01931
01932 void a2dIOHandlerGDSIn::SetDataTypeProperty( a2dCanvasObject* toobject, wxUint16 type )
01933 {
01934 if ( type != 0 )
01935 a2dCanvasObject::PROPID_Datatype->SetPropertyToObject( toobject, type );
01936 }
01937
01938
01939
01940
01941
01942 a2dIOHandlerGDSOut::a2dIOHandlerGDSOut()
01943 {
01944 m_scale_out = 1;
01945 m_textAsPath = false;
01946 m_fromViewAsTop = false;
01947 }
01948
01949 a2dIOHandlerGDSOut::~a2dIOHandlerGDSOut()
01950 {
01951 }
01952
01953 bool a2dIOHandlerGDSOut::CanSave( const wxObject* obj )
01954 {
01955 if ( !wxDynamicCast( obj, a2dCanvasDocument) )
01956 return false;
01957 return true;
01958 }
01959
01960 void a2dIOHandlerGDSOut::InitializeSave()
01961 {
01962 a2dIOHandlerStrOut::InitializeSave();
01963 a2dGlobals->SetAberPolyToArc( double(a2dGetCmdh()->GetAberPolyToArc())/m_doc->GetUnitsScale() );
01964 }
01965
01966 void a2dIOHandlerGDSOut::ResetSave( )
01967 {
01968 a2dIOHandlerStrOut::ResetSave();
01969 }
01970
01971 bool a2dIOHandlerGDSOut::Save( a2dDocumentOutputStream& stream, const wxObject* doc )
01972 {
01973 m_doc = (a2dCanvasDocument*) doc;
01974 InitializeSave();
01975
01976 a2dCanvasObject* showobject = m_doc->GetRootObject();
01977
01978 if ( m_fromViewAsTop )
01979 {
01980 a2dCanvasView* drawer = wxDynamicCast( a2dDocviewGlobals->GetDocviewCommandProcessor()->GetCurrentView(),a2dCanvasView );
01981 if ( drawer )
01982 showobject = drawer->GetShowObject();
01983 }
01984
01985 a2dWalker_SetSpecificFlagsCanvasObjects setflags( a2dCanvasOFlags::BIN );
01986 setflags.Start( showobject, false );
01987
01988
01989 unsigned int i;
01990 for (i = 0; i < 999; i++)
01991 m_mapping[i]=-1;
01992 for (i = 0; i < wxMAXLAYER; i++)
01993 if ( m_doc->GetLayerSetup()->GetLayerIndex()[i] != wxNullLayerInfo )
01994 m_mapping[ m_doc->GetLayerSetup()->GetOutMapping(i) ] = i;
01995
01996 for (i = 0; i < 999; i++)
01997 if (m_mapping[i]==-1)
01998 m_mapping[i]=0;
01999
02000 m_streamo = &stream;
02001
02002
02003
02004
02005
02006 a2dBoundingBox drawing = showobject->GetBbox();
02007
02008 m_userunits_out = m_doc->GetUnitsAccuracy();
02009 if ( m_userunits_out == 0 )
02010 {
02011 wxLogWarning( wxT("GDS userunits: 0 was set to 0.01") );
02012 m_userunits_out = 0.01;
02013 }
02014 drawing.SetMin( drawing.GetMinX()/m_userunits_out, drawing.GetMinY()/m_userunits_out );
02015 drawing.SetMax( drawing.GetMaxX()/m_userunits_out, drawing.GetMaxY()/m_userunits_out );
02016 a2dBoundingBox maxint(LONG_MIN,LONG_MIN,LONG_MAX,LONG_MAX);
02017
02018 int l=0;
02019 while (maxint.Intersect(drawing,0) != _IN)
02020 {
02021 drawing.SetMin( drawing.GetMinX()/10.0, drawing.GetMinY()/10.0 );
02022 drawing.SetMax( drawing.GetMaxX()/10.0, drawing.GetMaxY()/10.0 );
02023 l++;
02024 }
02025 m_scale_out = pow(10.,l);
02026
02027 WriteHeader(2, GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER, GDS_HEADER);
02028
02029 WriteInt( m_doc->GetVersion() );
02030
02031 WriteHeader(12 * sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02032 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
02033 GDS_BGNLIB);
02034
02035 WriteInt( m_doc->GetModificationTime().GetYear() );
02036 WriteInt( m_doc->GetModificationTime().GetMonth() + 1 );
02037 WriteInt( m_doc->GetModificationTime().GetDay() );
02038 WriteInt( m_doc->GetModificationTime().GetHour() );
02039 WriteInt( m_doc->GetModificationTime().GetMinute() );
02040 WriteInt( m_doc->GetModificationTime().GetSecond() );
02041
02042 WriteInt( m_doc->GetAccessTime().GetYear() );
02043 WriteInt( m_doc->GetAccessTime().GetMonth() + 1 );
02044 WriteInt( m_doc->GetAccessTime().GetDay() );
02045 WriteInt( m_doc->GetAccessTime().GetHour() );
02046 WriteInt( m_doc->GetAccessTime().GetMinute() );
02047 WriteInt( m_doc->GetAccessTime().GetSecond() );
02048
02049 int value = wxStrlen(m_doc->GetLibraryName());
02050 if (value % 2 != 0)
02051 value++;
02052 WriteHeader(value, GDSTYPE_ASCII_STRING, GDS_LIBNAME);
02053
02054 WriteString( m_doc->GetLibraryName());
02055 WriteHeader(2 * sizeof(EIGHT_G_BYTE_REAL),
02056 GDSTYPE_EIGHT_G_BYTE_REAL,
02057 GDS_UNITS);
02058
02059 WriteDouble( m_userunits_out );
02060 WriteDouble( m_doc->GetUnitsScale()*m_userunits_out*m_scale_out );
02061
02062 a2dCanvasObjectList towrite;
02063 if ( m_fromViewAsTop || !m_doc->GetMultiRoot() )
02064 towrite.push_back( showobject );
02065 else
02066 m_doc->GetRootObject()->GetChildObjectList()->CollectObjects( &towrite );
02067
02068 a2dCanvasObjectList::iterator iter = towrite.begin();
02069 while ( towrite.size() )
02070 {
02071 a2dCanvasObject *obj = *iter;
02072 SaveStructure( obj, &towrite );
02073 obj->SetBin( true );
02074 towrite.erase( iter );
02075 iter = towrite.begin();
02076 }
02077
02078 WriteHeader(0, 0, GDS_ENDLIB);
02079
02080 ResetSave();
02081
02082 return true;
02083 }
02084
02085 void a2dIOHandlerGDSOut::SaveStructure( a2dCanvasObject* object, a2dCanvasObjectList* towrite )
02086 {
02087 SetFlags( object );
02088 if ( !object->GetRelease() && object->GetChildObjectList() != wxNullCanvasObjectList && object->GetChildObjectsCount() )
02089 {
02090 if ( !object->GetBin() )
02091 {
02092
02093
02094
02095 WriteHeader(12 * sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02096 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
02097 GDS_BGNSTR);
02098
02099 wxDateTime modTime = a2dCanvasObject::PROPID_ModificationDateTime->GetPropertyValue( object );
02100
02101 WriteInt( modTime.GetYear() );
02102 WriteInt( modTime.GetMonth() + 1 );
02103 WriteInt( modTime.GetDay() );
02104 WriteInt( modTime.GetHour() );
02105 WriteInt( modTime.GetMinute() );
02106 WriteInt( modTime.GetSecond() );
02107
02108 wxDateTime accesTime = a2dCanvasObject::PROPID_AccessDateTime->GetPropertyValue( object );
02109
02110 WriteInt( accesTime.GetYear() );
02111 WriteInt( accesTime.GetMonth() + 1 );
02112 WriteInt( accesTime.GetDay() );
02113 WriteInt( accesTime.GetHour() );
02114 WriteInt( accesTime.GetMinute() );
02115 WriteInt( accesTime.GetSecond() );
02116
02117
02118 TWO_G_BYTE_UNSIGNED_INTEGER value = (TWO_G_BYTE_UNSIGNED_INTEGER) wxStrlen( object->GetName() );
02119 WriteHeader(value, GDSTYPE_ASCII_STRING, GDS_STRNAME);
02120 WriteString( object->GetName() );
02121
02122 a2dCanvasObjectList* childobjects = object->GetChildObjectList();
02123 if ( childobjects != wxNullCanvasObjectList )
02124 {
02125 forEachIn( a2dCanvasObjectList, childobjects )
02126 {
02127 a2dCanvasObject *obj = *iter;
02128 if ( !obj->GetRelease() && m_doc->GetLayerSetup()->GetVisible( obj->GetLayer() ) || obj->GetIgnoreLayer() )
02129 {
02130 Save( obj, towrite );
02131 }
02132 }
02133 }
02134 WriteHeader(0, 0, GDS_ENDSTR);
02135 }
02136 }
02137 }
02138
02139 void a2dIOHandlerGDSOut::Save( a2dCanvasObject* object, a2dCanvasObjectList* towrite )
02140 {
02141 if( object->IsTemporary_DontSave())
02142 return;
02143
02144
02145 a2dCanvasObjectList* vectorpaths = wxNullCanvasObjectList;
02146
02147 SetFlags( object );
02148
02149 if (0 != wxDynamicCast( object, a2dPolylineL ))
02150 {
02151 a2dPolylineL* obj = wxDynamicCast( object, a2dPolylineL );
02152 DoSave( obj, towrite );
02153 }
02154 else if (0 != wxDynamicCast( object, a2dSurface ))
02155 {
02156
02157 a2dSmrtPtr<a2dSurface> poly = wxDynamicCast( object, a2dSurface );
02158 poly = wxDynamicCast( poly->Clone( a2dObject::clone_deep ), a2dSurface );
02159 if ( poly && poly->GetSegments()->HasArcs() )
02160 poly->GetSegments()->ConvertToLines();
02161
02162 WriteBoundary( poly->GetTransformMatrix(), poly->GetSegments(), poly->GetLayer(), a2dCanvasObject::PROPID_Datatype->GetPropertyValue( poly ), poly->GetSpline() );
02163
02164 a2dListOfa2dVertexList& holes = poly->GetHoles();
02165 if ( holes.size() )
02166 wxLogWarning( _("a2dSurface holes are saved as polygons in contour, better convert to polygons first") );
02167
02168 for( a2dListOfa2dVertexList::iterator iterp = holes.begin(); iterp != holes.end(); iterp++ )
02169 {
02170 a2dVertexListPtr vlist = (*iterp);
02171 if ( vlist->HasArcs() )
02172 vlist->ConvertToLines();
02173
02174 WriteBoundary( poly->GetTransformMatrix(), vlist, poly->GetLayer(), a2dCanvasObject::PROPID_Datatype->GetPropertyValue( poly ), poly->GetSpline() );
02175 }
02176 }
02177 else if (0 != wxDynamicCast( object, a2dPolygonL ))
02178 {
02179 a2dPolygonL* obj = wxDynamicCast( object, a2dPolygonL );
02180 DoSave( obj, towrite );
02181 }
02182 else if (0 != wxDynamicCast( object, a2dVectorPath ))
02183 {
02184 a2dVectorPath* obj = wxDynamicCast( object, a2dVectorPath );
02185 DoSave( obj, towrite );
02186 }
02187 else if (0 != wxDynamicCast( object, a2dCanvasObjectArrayReference ))
02188 {
02189 a2dCanvasObjectArrayReference* obj = wxDynamicCast( object, a2dCanvasObjectArrayReference );
02190 DoSave( obj, towrite );
02191 }
02192 else if (0 != wxDynamicCast( object, a2dCanvasObjectReference ))
02193 {
02194 a2dCanvasObjectReference* obj = wxDynamicCast( object, a2dCanvasObjectReference );
02195 DoSave( obj, towrite );
02196 }
02197 else if (0 != wxDynamicCast( object, a2dTextGDS ))
02198 {
02199 a2dTextGDS* obj = wxDynamicCast( object, a2dTextGDS );
02200
02201 if ( !m_textAsPath )
02202 DoSave( obj, towrite );
02203 else
02204 vectorpaths = obj->GetAsCanvasVpaths( false );
02205 }
02206 else if (0 != wxDynamicCast( object, a2dText ))
02207 {
02208 a2dText* obj = wxDynamicCast( object, a2dText );
02209
02210 if ( !m_textAsPath )
02211 DoSave( obj, towrite );
02212 else
02213 vectorpaths = obj->GetAsCanvasVpaths( false );
02214 }
02215 else if ( ( 0 != wxDynamicCast( object, a2dArrow ) ) ||
02216 ( 0 != wxDynamicCast( object, a2dRectC ) ) ||
02217 ( 0 != wxDynamicCast( object, a2dRect ) ) ||
02218 ( 0 != wxDynamicCast( object, a2dCircle ) ) ||
02219 ( 0 != wxDynamicCast( object, a2dEllipse ) ) ||
02220 ( 0 != wxDynamicCast( object, a2dEllipticArc ) ) ||
02221 ( 0 != wxDynamicCast( object, a2dArc ) ) ||
02222 ( 0 != wxDynamicCast( object, a2dSLine ) )
02223 )
02224 {
02225 vectorpaths = object->GetAsCanvasVpaths( false );
02226 }
02227 else if ( wxString(object->GetClassInfo()->GetClassName()) == wxT("a2dCanvasObject" ) )
02228 {
02229 WriteHeader(0, 0, GDS_SREF);
02230 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02231 GDSTYPE_BIT_ARRAY,
02232 GDS_ELFLAGS);
02233
02234 WriteInt( m_objectFlags );
02235
02236 int value = wxStrlen( object->GetName() );
02237 if (value % 2 != 0)
02238 value++;
02239 WriteHeader(value, GDSTYPE_ASCII_STRING, GDS_SNAME);
02240 WriteString( object->GetName() );
02241
02242
02243 a2dAffineMatrix lworld = object->GetTransformMatrix();
02244 if ( !lworld.IsIdentity() )
02245 {
02246 Strans* strans = new Strans();
02247 strans->MakeStrans( lworld );
02248 if ( strans->GetStrans() )
02249 Write(strans);
02250 }
02251
02252 WriteHeader(2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER),
02253 GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER,
02254 GDS_XY);
02255
02256 WritePoint( object->GetPosX(), object->GetPosY() );
02257
02258 WriteHeader(0, 0, GDS_ENDEL);
02259 towrite->push_back( object );
02260 }
02261 else
02262 {
02263 wxLogWarning(wxT("GDSIO : object %s is not implemented for output"), object->GetClassInfo()->GetClassName() );
02264 }
02265
02266
02267 if ( vectorpaths != wxNullCanvasObjectList )
02268 {
02269 a2dAffineMatrix lworld = object->GetTransformMatrix();
02270
02271 for( a2dCanvasObjectList::iterator iter = vectorpaths->begin(); iter != vectorpaths->end(); ++iter )
02272 {
02273 a2dVectorPath* canpath = (a2dVectorPath*) (*iter).Get();
02274 WriteVpath( lworld, canpath->GetSegments(), canpath->GetLayer(), canpath->GetDataType(), canpath->GetPathType(), canpath->GetContourWidth() );
02275 }
02276 delete vectorpaths;
02277 }
02278
02279 if ( object->GetChildObjectList() != wxNullCanvasObjectList && object->GetChildObjectsCount() )
02280 {
02281 WriteHeader(0, 0, GDS_SREF);
02282 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02283 GDSTYPE_BIT_ARRAY,
02284 GDS_ELFLAGS);
02285
02286 WriteInt( m_objectFlags );
02287
02288 int value = wxStrlen( object->GetName() );
02289 if (value % 2 != 0)
02290 value++;
02291 WriteHeader(value, GDSTYPE_ASCII_STRING, GDS_SNAME);
02292 WriteString( object->GetName() );
02293
02294
02295 a2dAffineMatrix lworld = object->GetTransformMatrix();
02296 if ( !lworld.IsIdentity() )
02297 {
02298 Strans* strans = new Strans();
02299 strans->MakeStrans( lworld );
02300 if ( strans->GetStrans() )
02301 Write(strans);
02302 }
02303
02304 WriteHeader(2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER),
02305 GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER,
02306 GDS_XY);
02307
02308 WritePoint( object->GetPosX(), object->GetPosY() );
02309
02310 WriteHeader(0, 0, GDS_ENDEL);
02311
02312
02313 towrite->push_back( object );
02314 }
02315
02316 }
02317
02318 void a2dIOHandlerGDSOut::DoSave( a2dPolylineL* obj, a2dCanvasObjectList* WXUNUSED(towrite) )
02319 {
02320 a2dVertexList* origpoints = obj->GetSegments();
02321
02322 a2dVertexList* rlist;
02323 if ( obj->GetSpline() || origpoints->HasArcs() )
02324 {
02325
02326 a2dVertexList* lpoints = new a2dVertexList();
02327 *lpoints = *origpoints;
02328 lpoints->ConvertSplinedPolyline(10);
02329 rlist=lpoints;
02330 }
02331 else
02332 rlist=origpoints;
02333
02334 WritePath( obj->GetTransformMatrix(), rlist, obj->GetLayer(),
02335 a2dCanvasObject::PROPID_Datatype->GetPropertyValue( obj ), obj->GetPathType(), obj->GetContourWidth() );
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414 if ( obj->GetSpline() || origpoints->HasArcs() )
02415 delete rlist;
02416 }
02417
02418 void a2dIOHandlerGDSOut::DoSave( a2dPolygonL* obj, a2dCanvasObjectList* WXUNUSED(towrite) )
02419 {
02420 WriteBoundary( obj->GetTransformMatrix(), obj->GetSegments(), obj->GetLayer(), a2dCanvasObject::PROPID_Datatype->GetPropertyValue( obj ), obj->GetSpline() );
02421 }
02422
02423 void a2dIOHandlerGDSOut::DoSave( a2dVectorPath* obj, a2dCanvasObjectList* WXUNUSED(towrite) )
02424 {
02425 WriteVpath( obj->GetTransformMatrix(), obj->GetSegments(), obj->GetLayer(), a2dCanvasObject::PROPID_Datatype->GetPropertyValue( obj ), obj->GetPathType(), obj->GetContourWidth() );
02426 }
02427
02428 void a2dIOHandlerGDSOut::DoSave( a2dText* obj, a2dCanvasObjectList* WXUNUSED(towrite) )
02429 {
02430 WriteHeader(0, 0, GDS_TEXT);
02431 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02432 GDSTYPE_BIT_ARRAY,
02433 GDS_ELFLAGS);
02434
02435 WriteInt( m_objectFlags );
02436
02437 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02438 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
02439 GDS_LAYER);
02440
02441 WriteInt( m_mapping[obj->GetLayer()] );
02442
02443
02444 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02445 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
02446 GDS_TEXTTYPE);
02447
02448 WriteInt( TEXT_PATH_END_SQAURE );
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460 a2dAffineMatrix lworld = obj->GetTransformMatrix();
02461 if ( !lworld.IsIdentity() )
02462 {
02463 Strans strans = Strans();
02464 strans.MakeStrans( lworld );
02465 if( obj->GetTextHeight() != 0 )
02466 strans.SetScale( strans.GetScale() * obj->GetTextHeight() );
02467
02468 if ( strans.GetStrans() )
02469 Write(&strans);
02470 }
02471
02472
02473 WriteHeader(2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER),
02474 GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER,
02475 GDS_XY);
02476
02477 WritePoint( obj->GetPosX(), obj->GetPosY() );
02478
02479
02480 int nrChar = wxStrlen( obj->GetText() );
02481 if (nrChar % 2 != 0)
02482 nrChar++;
02483 WriteHeader(nrChar, GDSTYPE_ASCII_STRING, GDS_STRING);
02484
02485 WriteString(obj->GetText());
02486
02487 WriteHeader(0, 0, GDS_ENDEL);
02488 }
02489
02490 void a2dIOHandlerGDSOut::DoSave( a2dTextGDS* obj, a2dCanvasObjectList* WXUNUSED(towrite) )
02491 {
02492 WriteHeader(0, 0, GDS_TEXT);
02493
02494 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02495 GDSTYPE_BIT_ARRAY,
02496 GDS_ELFLAGS);
02497
02498 WriteInt( m_objectFlags );
02499
02500 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02501 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
02502 GDS_LAYER);
02503
02504 WriteInt( m_mapping[obj->GetLayer()] );
02505
02506
02507 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02508 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
02509 GDS_TEXTTYPE);
02510
02511 WriteInt( obj->GetTextType() );
02512
02513 if ( obj->GetPresentationFlags())
02514 {
02515
02516 if ((obj->GetFont() != DEFAULT_PRESENTATION_FONT) ||
02517 (obj->GetVertical() != DEFAULT_PRESENTATION_VERTICAL) ||
02518 (obj->GetHorizontal() != DEFAULT_PRESENTATION_HORIZONTAL))
02519 {
02520 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02521 GDSTYPE_BIT_ARRAY,
02522 GDS_PRESENTATION);
02523 WriteInt( obj->GetPresentationFlags() );
02524 }
02525 }
02526
02527 if ( obj->GetPathtype())
02528 {
02529 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02530 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
02531 GDS_PATHTYPE);
02532
02533 WriteInt( obj->GetPathtype() );
02534 }
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546 a2dAffineMatrix lworld = obj->GetTransformMatrix();
02547 if ( !lworld.IsIdentity() )
02548 {
02549 Strans strans = Strans();
02550 strans.MakeStrans( lworld );
02551 if( obj->GetTextHeight() != 0 )
02552 strans.SetScale( strans.GetScale() * obj->GetTextHeight() / a2dTextGDS::GetFontScaleFactor() );
02553
02554 if ( strans.GetStrans() )
02555 Write(&strans);
02556 }
02557
02558
02559 WriteHeader(2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER),
02560 GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER,
02561 GDS_XY);
02562
02563 WritePoint( obj->GetPosX(), obj->GetPosY() );
02564
02565
02566 int nrChar = wxStrlen( obj->GetText() );
02567 if (nrChar % 2 != 0)
02568 nrChar++;
02569 WriteHeader(nrChar, GDSTYPE_ASCII_STRING, GDS_STRING);
02570
02571 WriteString(obj->GetText());
02572
02573 WriteHeader(0, 0, GDS_ENDEL);
02574 }
02575
02576 void a2dIOHandlerGDSOut::DoSave( a2dCanvasObjectReference* obj, a2dCanvasObjectList* towrite )
02577 {
02578 WriteHeader(0, 0, GDS_SREF);
02579 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02580 GDSTYPE_BIT_ARRAY,
02581 GDS_ELFLAGS);
02582
02583 WriteInt( m_objectFlags );
02584
02585 int value = wxStrlen( obj->GetName() );
02586 if (value % 2 != 0)
02587 value++;
02588 WriteHeader(value, GDSTYPE_ASCII_STRING, GDS_SNAME);
02589 WriteString( obj->GetName() );
02590
02591
02592 a2dAffineMatrix lworld = obj->GetTransformMatrix();
02593 if ( !lworld.IsIdentity() )
02594 {
02595 Strans* strans = new Strans();
02596 strans->MakeStrans( lworld );
02597 if ( strans->GetStrans() )
02598 Write(strans);
02599 }
02600
02601 WriteHeader(2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER),
02602 GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER,
02603 GDS_XY);
02604
02605 WritePoint( obj->GetPosX(), obj->GetPosY() );
02606
02607 WriteHeader(0, 0, GDS_ENDEL);
02608
02609 if ( obj->GetCanvasObject() )
02610 towrite->push_back( obj->GetCanvasObject() );
02611 }
02612
02613 void a2dIOHandlerGDSOut::DoSave( a2dCanvasObjectArrayReference* obj, a2dCanvasObjectList* towrite )
02614 {
02615 WriteHeader(0, 0, GDS_AREF);
02616 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02617 GDSTYPE_BIT_ARRAY,
02618 GDS_ELFLAGS);
02619
02620 WriteInt( m_objectFlags );
02621
02622 int value = wxStrlen( obj->GetName() );
02623 if (value % 2 != 0)
02624 value++;
02625 WriteHeader(value, GDSTYPE_ASCII_STRING, GDS_SNAME);
02626 WriteString( obj->GetName() );
02627
02628
02629 a2dAffineMatrix lworld = obj->GetTransformMatrix();
02630 if ( !lworld.IsIdentity() )
02631 {
02632 Strans* strans = new Strans();
02633 strans->MakeStrans( lworld );
02634 if ( strans->GetStrans() )
02635 Write(strans);
02636 }
02637
02638 WriteHeader(2 * sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02639 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
02640 GDS_COLROW);
02641
02642 WriteInt( obj->GetColumns() );
02643 WriteInt( obj->GetRows() );
02644
02645 WriteHeader(6 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER),
02646 GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER,
02647 GDS_XY);
02648
02649 WritePoint( obj->GetPosX(), obj->GetPosY() );
02650
02651 WritePoint( obj->GetPosX() + obj->GetHorzSpace() * obj->GetColumns(), obj->GetPosY() );
02652 WritePoint( obj->GetPosX(), obj->GetPosY() + obj->GetVertSpace() * obj->GetRows() );
02653
02654 WriteHeader(0, 0, GDS_ENDEL);
02655
02656 if ( obj->GetCanvasObject() )
02657 towrite->push_back( obj->GetCanvasObject() );
02658 }
02659
02660 void a2dIOHandlerGDSOut::Write(Strans* Strans)
02661 {
02662
02663 if ((Strans->m_stransflags.bits.abs_angle != DEFAULT_STRANS_ABS_ANGLE) ||
02664 (Strans->m_stransflags.bits.abs_scale != DEFAULT_STRANS_ABS_SCALE) ||
02665 (Strans->m_stransflags.bits.reflection != DEFAULT_STRANS_REFLECTION) ||
02666 (Strans->GetScale() != DEFAULT_STRANS_SCALE) ||
02667 (Strans->GetAngle() != DEFAULT_STRANS_ANGLE))
02668 {
02669 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
02670 GDSTYPE_BIT_ARRAY,
02671 GDS_STRANS);
02672 WriteInt( Strans->m_stransflags.total );
02673
02674
02675 if (Strans->GetScale() != DEFAULT_STRANS_SCALE)
02676 {
02677 WriteHeader(sizeof(EIGHT_G_BYTE_REAL),
02678 GDSTYPE_EIGHT_G_BYTE_REAL,
02679 GDS_MAG);
02680 WriteDouble( Strans->GetScale() );
02681
02682 }
02683
02684
02685 if (Strans->GetAngle() != DEFAULT_STRANS_ANGLE)
02686 {
02687 WriteHeader(sizeof(EIGHT_G_BYTE_REAL),
02688 GDSTYPE_EIGHT_G_BYTE_REAL,
02689 GDS_ANGLE);
02690 WriteDouble( Strans->GetAngle() );
02691 }
02692 }
02693 }
02694
02695 void a2dIOHandlerGDSOut::WriteHeader( TWO_G_BYTE_UNSIGNED_INTEGER nw_recordsize, G_BYTE nw_datatype, G_BYTE nw_recordtype)
02696 {
02697
02698 if (nw_datatype == GDSTYPE_ASCII_STRING &&
02699 (nw_recordsize % 2) != 0)
02700 nw_recordsize++;
02701
02702 WriteInt( nw_recordsize + GDS_HEADERSIZE );
02703 WriteByte( nw_recordtype );
02704 WriteByte( nw_datatype );
02705
02706 m_recordsize = (TWO_G_BYTE_UNSIGNED_INTEGER) nw_recordsize;
02707 }
02708
02709
02710
02711 void a2dIOHandlerGDSOut::WriteString(const wxString& a_string)
02712 {
02713 int value = a_string.Len();
02714 for (int i = 0 ; i < value; i++)
02715 WriteByte(a_string[i]);
02716
02717 if (value % 2 != 0)
02718 WriteByte( wxT('\0') );
02719 }
02720
02721
02722
02723 void a2dIOHandlerGDSOut::SetFlags( a2dCanvasObject* Element)
02724 {
02725 if ((Element->GetTemplate() != 0) ||
02726 (Element->GetExternal() != 0))
02727 {
02728 m_objectFlags = 0;
02729
02730 if (Element->GetTemplate())
02731 m_objectFlags += 1<<1;
02732
02733 if (Element->GetExternal())
02734 m_objectFlags += 1<<2;
02735 }
02736 }
02737
02738
02739 void a2dIOHandlerGDSOut::WritePoint( double xi, double yi )
02740 {
02741 long x;
02742 long y;
02743 if ( xi > 0 )
02744 x = (long) (xi / m_userunits_out/m_scale_out + 0.5);
02745 else
02746 x = (long) (xi / m_userunits_out/m_scale_out - 0.5);
02747 if ( yi > 0 )
02748 y = (long) (yi / m_userunits_out/m_scale_out + 0.5);
02749 else
02750 y = (long) (yi / m_userunits_out/m_scale_out - 0.5);
02751
02752 WriteLong( x );
02753 WriteLong( y );
02754 }
02755
02756 void a2dIOHandlerGDSOut::WriteVpath( const a2dAffineMatrix& lworld, const a2dVpath* path, int layer, int datatype, int pathtype, double width )
02757 {
02758 double tstep = 1/ (double) SPLINE_STEP;
02759 unsigned int i;
02760
02761 a2dVertexArray* cpoints = new a2dVertexArray;
02762
02763 double x,y;
02764 bool move = false;
02765 int count = 0;
02766 bool nostrokeparts = false;
02767
02768
02769 for (i = 0; i < path->GetCount(); i++)
02770 {
02771 a2dVpathSegment& seg = path->Item(i);
02772 switch ( seg.GetType() )
02773 {
02774 case a2dPATHSEG_MOVETO:
02775 if ( count == 0 )
02776 {
02777 lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
02778 cpoints->push_back( new a2dLineSegment( x, y ) );
02779 count++;
02780 }
02781 else
02782 {
02783 i--;
02784 move = true;
02785 }
02786 break;
02787
02788 case a2dPATHSEG_LINETO:
02789 lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
02790 cpoints->push_back( new a2dLineSegment( x, y ) );
02791 count++;
02792 break;
02793 case a2dPATHSEG_LINETO_NOSTROKE:
02794 lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
02795 cpoints->push_back( new a2dLineSegment( x, y ) );
02796 count++;
02797 nostrokeparts = true;
02798 break;
02799
02800 case a2dPATHSEG_CBCURVETO_NOSTROKE:
02801 nostrokeparts = true;
02802 case a2dPATHSEG_CBCURVETO:
02803 {
02804 double xw, yw;
02805
02806 double xwl = path->Item(i? i-1: 0).m_x1;
02807 double ywl = path->Item(i? i-1: 0).m_y1;
02808 a2dVpathCBCurveSegment& cseg = (a2dVpathCBCurveSegment&) seg;
02809
02810 int step;
02811 double t = 0;
02812 for ( step=0; step <= SPLINE_STEP; step++ )
02813 {
02814 xw = xwl*pow(1-t,3) + cseg.m_x2*pow(1-t,2)*t*3 + cseg.m_x3*(1-t)*t*t*3 + cseg.m_x1*pow(t,3);
02815 yw = ywl*pow(1-t,3) + cseg.m_y2*pow(1-t,2)*t*3 + cseg.m_y3*(1-t)*t*t*3 + cseg.m_y1*pow(t,3);
02816 lworld.TransformPoint( xw, yw, x, y );
02817 cpoints->push_back( new a2dLineSegment( x, y ) );
02818 count++;
02819 t= t + tstep;
02820 }
02821 }
02822 break;
02823
02824 case a2dPATHSEG_QBCURVETO_NOSTROKE:
02825 nostrokeparts = true;
02826 case a2dPATHSEG_QBCURVETO:
02827 {
02828 double xw, yw;
02829
02830 double xwl = path->Item(i? i-1: 0).m_x1;
02831 double ywl = path->Item(i? i-1: 0).m_y1;
02832 a2dVpathQBCurveSegment& cseg = (a2dVpathQBCurveSegment&) seg;
02833
02834 int step;
02835 double t = 0;
02836 for ( step=0; step <= SPLINE_STEP; step++ )
02837 {
02838 xw = xwl*pow(1-t,2) + cseg.m_x2*(1-t)*t*2 + cseg.m_x1*pow(t,2);
02839 yw = ywl*pow(1-t,2) + cseg.m_y2*(1-t)*t*2 + cseg.m_y1*pow(t,2);
02840 lworld.TransformPoint( xw, yw, x, y );
02841 cpoints->push_back( new a2dLineSegment( x, y ) );
02842 count++;
02843 t= t + tstep;
02844 }
02845 }
02846 break;
02847
02848 case a2dPATHSEG_ARCTO_NOSTROKE:
02849 nostrokeparts = true;
02850 case a2dPATHSEG_ARCTO:
02851 {
02852 a2dVpathArcSegment& cseg = (a2dVpathArcSegment&) seg;
02853
02854 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
02855
02856 if ( cseg.CalcR( path->Item(i? i-1: 0), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
02857 {
02858 double dphi;
02859 unsigned int segments;
02860 a2dGlobals->Aberration( phit, radius , dphi, segments );
02861
02862 double theta = beginrad;
02863 unsigned int step;
02864
02865 for (step = 0; step < segments+1; step++)
02866 {
02867 lworld.TransformPoint( center_x + radius * cos (theta), center_y + radius * sin (theta), x, y );
02868 cpoints->push_back( new a2dLineSegment( x, y ) );
02869 count++;
02870 theta = theta + dphi;
02871 }
02872 }
02873 else
02874 {
02875 lworld.TransformPoint( cseg.m_x1, cseg.m_y1, x, y );
02876 cpoints->push_back( new a2dLineSegment( x, y ) );
02877 count++;
02878 }
02879 }
02880 break;
02881 }
02882
02883 if ( move )
02884 {
02885 WritePath( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width );
02886 move = false;
02887 cpoints->clear();
02888 count = 0;
02889 }
02890 else if ( seg.GetClose() != a2dPATHSEG_END_OPEN )
02891 {
02892 if (nostrokeparts || seg.GetClose() == a2dPATHSEG_END_CLOSED_NOSTROKE )
02893 {
02894 WriteBoundary( a2dIDENTITY_MATRIX, cpoints, layer, datatype );
02895 nostrokeparts = true;
02896 }
02897 else
02898 {
02899 WriteBoundary( a2dIDENTITY_MATRIX, cpoints, layer, datatype );
02900 }
02901
02902 move = false;
02903 cpoints->clear();
02904 count = 0;
02905 }
02906 else if ( i == path->GetCount()-1 )
02907 {
02908 WritePath( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width );
02909 cpoints->clear();
02910 }
02911 }
02912
02913 if (nostrokeparts)
02914 {
02915 move = false;
02916 count = 0;
02917 cpoints->clear();
02918
02919 nostrokeparts = false;
02920
02921 double lastmovex = 0;
02922 double lastmovey = 0;
02923
02924 for (i = 0; i < path->GetCount(); i++)
02925 {
02926 a2dVpathSegment& seg = path->Item(i);
02927 switch ( seg.GetType() )
02928 {
02929 case a2dPATHSEG_MOVETO:
02930 if ( count == 0 )
02931 {
02932 lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
02933 cpoints->push_back( new a2dLineSegment( x, y ) );
02934 lastmovex = x;
02935 lastmovey = y;
02936 count++;
02937 }
02938 else
02939 {
02940 i--;
02941 move = true;
02942 }
02943 break;
02944
02945 case a2dPATHSEG_LINETO:
02946 lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
02947 cpoints->push_back( new a2dLineSegment( x, y ) );
02948 count++;
02949 break;
02950
02951 case a2dPATHSEG_LINETO_NOSTROKE:
02952 case a2dPATHSEG_CBCURVETO_NOSTROKE:
02953 case a2dPATHSEG_QBCURVETO_NOSTROKE:
02954 case a2dPATHSEG_ARCTO_NOSTROKE:
02955 if ( count == 0 )
02956 {
02957 lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
02958 cpoints->push_back( new a2dLineSegment( x, y ) );
02959 count++;
02960 }
02961 else
02962 {
02963 i--;
02964 nostrokeparts = true;
02965 }
02966 break;
02967
02968 case a2dPATHSEG_CBCURVETO:
02969 {
02970 double xw, yw;
02971
02972 double xwl = path->Item(i? i-1: 0).m_x1;
02973 double ywl = path->Item(i? i-1: 0).m_y1;
02974 a2dVpathCBCurveSegment& cseg = (a2dVpathCBCurveSegment&) seg;
02975
02976 int step;
02977 double t = 0;
02978 for ( step=0; step <= SPLINE_STEP; step++ )
02979 {
02980 xw = xwl*pow(1-t,3) + cseg.m_x2*pow(1-t,2)*t*3 + cseg.m_x3*(1-t)*t*t*3 + cseg.m_x1*pow(t,3);
02981 yw = ywl*pow(1-t,3) + cseg.m_y2*pow(1-t,2)*t*3 + cseg.m_y3*(1-t)*t*t*3 + cseg.m_y1*pow(t,3);
02982 lworld.TransformPoint( xw, yw, x, y );
02983 cpoints->push_back( new a2dLineSegment( x, y ) );
02984 count++;
02985 t= t + tstep;
02986 }
02987 }
02988 break;
02989
02990 case a2dPATHSEG_QBCURVETO:
02991 {
02992 double xw, yw;
02993
02994 double xwl = path->Item(i? i-1: 0).m_x1;
02995 double ywl = path->Item(i? i-1: 0).m_y1;
02996 a2dVpathQBCurveSegment& cseg = (a2dVpathQBCurveSegment&) seg;
02997
02998 int step;
02999 double t = 0;
03000 for ( step=0; step <= SPLINE_STEP; step++ )
03001 {
03002 xw = xwl*pow(1-t,2) + cseg.m_x2*(1-t)*t*2 + cseg.m_x1*pow(t,2);
03003 yw = ywl*pow(1-t,2) + cseg.m_y2*(1-t)*t*2 + cseg.m_y1*pow(t,2);
03004 lworld.TransformPoint( xw, yw, x, y );
03005 cpoints->push_back( new a2dLineSegment( x, y ) );
03006 count++;
03007 t= t + tstep;
03008 }
03009 }
03010 break;
03011
03012 case a2dPATHSEG_ARCTO:
03013 {
03014 a2dVpathArcSegment& cseg = (a2dVpathArcSegment&) seg;
03015
03016 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
03017
03018 if ( cseg.CalcR( path->Item(i? i-1: 0), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
03019 {
03020 double dphi;
03021 unsigned int segments;
03022 a2dGlobals->Aberration( phit, radius , dphi, segments );
03023
03024 double theta = beginrad;
03025 unsigned int step;
03026
03027 double x,y;
03028 for (step = 0; step < segments+1; step++)
03029 {
03030 lworld.TransformPoint( center_x + radius * cos (theta), center_y + radius * sin (theta), x, y );
03031 cpoints->push_back( new a2dLineSegment( x, y ) );
03032 count++;
03033 theta = theta + dphi;
03034 }
03035 }
03036 else
03037 {
03038 double x,y;
03039 lworld.TransformPoint( cseg.m_x1, cseg.m_y1, x, y );
03040 cpoints->push_back( new a2dLineSegment( x, y ) );
03041 count++;
03042 }
03043 }
03044 break;
03045 }
03046
03047 if ( move || nostrokeparts )
03048 {
03049 WritePath( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width );
03050 move = false;
03051 nostrokeparts = false;
03052 cpoints->clear();
03053 count = 0;
03054 }
03055 else if ( seg.GetClose() != a2dPATHSEG_END_OPEN )
03056 {
03057 if ( seg.GetClose() == a2dPATHSEG_END_CLOSED )
03058 {
03059 cpoints->push_back( new a2dLineSegment( lastmovex, lastmovey ) );
03060 count++;
03061 }
03062 WritePath( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width );
03063 nostrokeparts = false;
03064 move = false;
03065 cpoints->clear();
03066 count = 0;
03067 }
03068 else if ( i == path->GetCount() )
03069 {
03070 WritePath( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width );
03071 cpoints->clear();
03072 }
03073 }
03074 }
03075
03076 delete cpoints;
03077
03078 }
03079
03080
03081 void a2dIOHandlerGDSOut::WritePath( const a2dAffineMatrix& lworld, a2dVertexArray* points, int layer, int datatype, int pathtype, double width )
03082 {
03083 WriteHeader(0, 0, GDS_PATH);
03084
03085 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03086 GDSTYPE_BIT_ARRAY,
03087 GDS_ELFLAGS);
03088
03089 WriteInt( m_objectFlags );
03090
03091 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03092 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03093 GDS_LAYER);
03094
03095 WriteInt( m_mapping[layer] );
03096
03097 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03098 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03099 GDS_DATATYPE);
03100
03101 WriteInt( datatype );
03102
03103 if (pathtype)
03104 {
03105 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03106 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03107 GDS_PATHTYPE);
03108
03109 WriteInt( pathtype );
03110 }
03111
03112 if ( width )
03113 {
03114 WriteHeader(sizeof(FOUR_G_BYTE_SIGNED_INTEGER),
03115 GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER,
03116 GDS_WIDTH);
03117 WriteLong( Round( width / m_userunits_out/m_scale_out ) );
03118 }
03119
03120 long help;
03121 points->ConvertToLines();
03122 unsigned int n;
03123 n = points->size();
03124
03125 help = 2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER) * n;
03126
03127 if (help > 65530L)
03128 {
03129 wxLogWarning( wxT("%s"), _("to many points in Polyline"));
03130 help = 65530L;
03131 n = help/(2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER));
03132 }
03133 WriteHeader( help, GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER, GDS_XY );
03134
03135 unsigned int i;
03136 for ( i = 0; i < n; i++)
03137 {
03138 double x, y;
03139 lworld.TransformPoint( points->Item(i)->m_x, points->Item(i)->m_y, x, y );
03140 WritePoint( x, y );
03141 }
03142
03143 WriteHeader(0, 0, GDS_ENDEL);
03144 }
03145
03146
03147 void a2dIOHandlerGDSOut::WritePath( const a2dAffineMatrix& lworld, a2dVertexList* points, int layer, int datatype, int pathtype, double width )
03148 {
03149 WriteHeader(0, 0, GDS_PATH);
03150
03151 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03152 GDSTYPE_BIT_ARRAY,
03153 GDS_ELFLAGS);
03154
03155 WriteInt( m_objectFlags );
03156
03157 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03158 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03159 GDS_LAYER);
03160
03161 WriteInt( m_mapping[layer] );
03162
03163 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03164 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03165 GDS_DATATYPE);
03166
03167 WriteInt( datatype );
03168
03169 if (pathtype)
03170 {
03171 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03172 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03173 GDS_PATHTYPE);
03174
03175 WriteInt( pathtype );
03176 }
03177
03178 if ( width )
03179 {
03180 WriteHeader(sizeof(FOUR_G_BYTE_SIGNED_INTEGER),
03181 GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER,
03182 GDS_WIDTH);
03183 WriteLong( Round( width / m_userunits_out/m_scale_out ) );
03184 }
03185
03186 points->ConvertToLines();
03187 unsigned int n = points->size();
03188
03189 long help = 2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER) * n;
03190 if (help > 65530L)
03191 {
03192 wxLogWarning( wxT("%s"),_("to many points in Polyline"));
03193 help = 65530L;
03194 n = help/(2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER));
03195 }
03196 WriteHeader( help, GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER, GDS_XY );
03197
03198 a2dVertexList::iterator iter = points->begin();
03199 unsigned int i=0;
03200 while ( i < n )
03201 {
03202 a2dPoint2D point = (*iter)->GetPoint();
03203 double x, y;
03204 lworld.TransformPoint( point.m_x, point.m_y, x, y );
03205 WritePoint( x, y );
03206 iter++;
03207 i++;
03208 }
03209
03210 WriteHeader(0, 0, GDS_ENDEL);
03211 }
03212
03213
03214 void a2dIOHandlerGDSOut::WriteBoundary( const a2dAffineMatrix& lworld, a2dVertexArray* points, int layer, int datatype )
03215 {
03216 WriteHeader(0, 0, GDS_BOUNDARY);
03217
03218 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03219 GDSTYPE_BIT_ARRAY,
03220 GDS_ELFLAGS);
03221
03222 WriteInt( m_objectFlags );
03223
03224 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03225 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03226 GDS_LAYER);
03227
03228 WriteInt( m_mapping[layer] );
03229
03230 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03231 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03232 GDS_DATATYPE);
03233
03234 WriteInt( datatype );
03235
03236 points->ConvertToLines();
03237 long help;
03238 unsigned int n = points->size();
03239
03240 help = 2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER) * (n + 1);
03241
03242 if (help > 65530L)
03243 {
03244 wxLogWarning( wxT("%s"),_("to many points in Polyline"));
03245
03246
03247 help = 65530L;
03248 n = help/(2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER))-1;
03249 }
03250 WriteHeader( help, GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER, GDS_XY );
03251
03252 double x, y;
03253 unsigned int i;
03254 for ( i = 0; i < n; i++)
03255 {
03256 lworld.TransformPoint( points->Item(i)->m_x, points->Item(i)->m_y, x, y );
03257 WritePoint( x, y );
03258 }
03259 lworld.TransformPoint( points->Item(0)->m_x, points->Item(0)->m_y, x, y );
03260 WritePoint( x, y );
03261
03262 WriteHeader(0, 0, GDS_ENDEL);
03263 }
03264
03265
03266 void a2dIOHandlerGDSOut::WriteBoundary( const a2dAffineMatrix& lworld, a2dVertexList* points, int layer, int datatype, bool spline )
03267 {
03268 a2dVertexList* rlist;
03269
03270 if ( spline || points->HasArcs() )
03271 {
03272 a2dVertexList* lpoints = new a2dVertexList();
03273 *lpoints = *points;
03274 lpoints->ConvertSplinedPolygon(10);
03275 rlist = lpoints;
03276 }
03277 else
03278 rlist = points;
03279
03280 WriteHeader(0, 0, GDS_BOUNDARY);
03281
03282 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03283 GDSTYPE_BIT_ARRAY,
03284 GDS_ELFLAGS);
03285
03286 WriteInt( m_objectFlags );
03287
03288 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03289 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03290 GDS_LAYER);
03291
03292 WriteInt( m_mapping[layer] );
03293
03294 WriteHeader(sizeof(TWO_G_BYTE_SIGNED_INTEGER),
03295 GDSTYPE_TWO_G_BYTE_SIGNED_INTEGER,
03296 GDS_DATATYPE);
03297
03298 WriteInt( datatype );
03299
03300 points->ConvertToLines();
03301 unsigned int n = points->size();
03302
03303 long help = 2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER) * (n + 1);
03304 if (help > 65530L)
03305 {
03306 wxLogWarning( wxT("%s"),_("to many points in Polyline"));
03307 help = 65530L;
03308 n = help/(2 * sizeof(FOUR_G_BYTE_SIGNED_INTEGER))-1;
03309 }
03310 WriteHeader( help, GDSTYPE_FOUR_G_BYTE_SIGNED_INTEGER, GDS_XY );
03311
03312 a2dVertexList::iterator iter = points->begin();
03313 double x, y;
03314 unsigned int i=0;
03315 while ( i < n )
03316 {
03317 a2dPoint2D point = (*iter)->GetPoint();
03318 lworld.TransformPoint( point.m_x, point.m_y, x, y );
03319 WritePoint( x, y );
03320 iter++;
03321 i++;
03322 }
03323 lworld.TransformPoint( points->front()->m_x, points->front()->m_y, x, y );
03324 WritePoint( x, y );
03325
03326 WriteHeader(0, 0, GDS_ENDEL);
03327
03328 if ( spline || points->HasArcs() )
03329 delete rlist;
03330 }
03331
03332
03333
03334
03335 void a2dIOHandlerGDSOut::WriteByte( G_BYTE ch )
03336 {
03337 #if wxUSE_STD_IOSTREAM
03338 m_streamo->put( ch );
03339 #else
03340 m_streamo->PutC( ch );
03341 #endif
03342 }
03343
03344
03345 void a2dIOHandlerGDSOut::WriteUnsignedInt( TWO_G_BYTE_UNSIGNED_INTEGER i )
03346 {
03347 a_union_value a_value;
03348 a_value.two_byte_signed_integer = i;
03349 #if wxBYTE_ORDER == wxBIG_ENDIAN
03350 WriteByte(a_value.array.array[0]);
03351 WriteByte(a_value.array.array[1]);
03352 #else
03353 WriteByte(a_value.array.array[1]);
03354 WriteByte(a_value.array.array[0]);
03355 #endif
03356 }
03357
03358
03359 void a2dIOHandlerGDSOut::WriteInt( TWO_G_BYTE_SIGNED_INTEGER i )
03360 {
03361 a_union_value a_value;
03362 a_value.two_byte_signed_integer = i;
03363 #if wxBYTE_ORDER == wxBIG_ENDIAN
03364 WriteByte(a_value.array.array[0]);
03365 WriteByte(a_value.array.array[1]);
03366 #else
03367 WriteByte(a_value.array.array[1]);
03368 WriteByte(a_value.array.array[0]);
03369 #endif
03370 }
03371
03372
03373
03374 void a2dIOHandlerGDSOut::WriteLong( FOUR_G_BYTE_SIGNED_INTEGER i )
03375 {
03376 a_union_value a_value;
03377 a_value.four_byte_signed_integer = i;
03378
03379
03380
03381
03382
03383 #if wxBYTE_ORDER == wxBIG_ENDIAN
03384 int t;
03385 for( t=0; t<=3; t++)
03386 #else
03387 int t;
03388 for( t=3; t>=0; t--)
03389 #endif
03390 WriteByte(a_value.array.array[t]);
03391 }
03392
03393
03394
03395 void a2dIOHandlerGDSOut::WriteFloat( FOUR_G_BYTE_REAL r )
03396 {
03397 a_union_value a_value;
03398 a_value.four_byte_real = r;
03399
03400
03401
03402
03403 #if wxBYTE_ORDER == wxBIG_ENDIAN
03404 for(short int i=0; i<=3; i++)
03405 #else
03406 for(short int i=3; i>=0; i--)
03407 #endif
03408 WriteByte(a_value.array.array[i]);
03409 }
03410
03411
03412
03413 void a2dIOHandlerGDSOut::WriteDouble( EIGHT_G_BYTE_REAL r )
03414 {
03415 a_union_value a_value;
03416 a_value.eight_byte_real = r;
03417
03418 short int i;
03419
03420
03421 double2gds(a_value.array.array);
03422
03423
03424
03425 for(i=0; i<8; i++)
03426 WriteByte(a_value.array.array[i]);
03427
03428 }
03429
03430
03431
03432
03433
03434 IMPLEMENT_DYNAMIC_CLASS( a2dTextGDS, a2dText )
03435
03436 double a2dTextGDS::m_fontScaleFactor = 1.0;
03437
03438 a2dTextGDS::a2dTextGDS( a2dFontType fontType, const wxString &text, double height, short int presentation )
03439 : a2dText( text, 0.0, 0.0, *a2dNullFONT )
03440 {
03441 m_alignment = 0;
03442 m_presentationflags.total = presentation;
03443 SetHorizontal( m_presentationflags.bits._horizontal );
03444 SetVertical( m_presentationflags.bits._vertical );
03445
03446 m_fontType = fontType;
03447 if ( m_fontType == a2dFONT_STROKED )
03448 {
03449
03450 int weight = 2;
03451 switch( m_presentationflags.bits._font )
03452 {
03453 default:
03454 case 0 : weight = 2;
03455 break;
03456 case 1 : weight = 4;
03457 break;
03458 case 2 : weight = 8;
03459 break;
03460 case 3 : weight = 12;
03461 break;
03462 }
03463 a2dText::SetFont( a2dFont( wxT("nen.chr"), height, m_monoSpaced, weight ) );
03464 }
03465 if ( m_fontType == a2dFONT_WXDC )
03466 {
03467 int FontFamily=wxMODERN;
03468 switch( m_presentationflags.bits._font )
03469 {
03470 case 0 : FontFamily = wxDEFAULT; break;
03471 case 1 : FontFamily = wxROMAN; break;
03472 case 2 : FontFamily = wxSWISS; break;
03473 case 3 : FontFamily = wxDECORATIVE; break;
03474 default: FontFamily = wxMODERN; break;
03475 }
03476 a2dText::SetFont( a2dFont(height,FontFamily,wxNORMAL) );
03477 }
03478
03479
03480
03481
03482
03483
03484 m_texttype = 0;
03485 m_pathtype = TEXT_PATH_END_SQAURE;
03486 m_width = 0;
03487 m_monoSpaced = true;
03488 SetBackGround( false );
03489 }
03490
03491 a2dTextGDS::a2dTextGDS( const a2dTextGDS &other, CloneOptions options )
03492 :a2dText( other, options )
03493 {
03494 m_presentationflags.total = other.m_presentationflags.total;
03495 m_texttype = other.m_texttype;
03496 m_pathtype = other.m_pathtype;
03497 m_monoSpaced = other.m_monoSpaced;
03498 m_width = other.m_width;
03499 }
03500
03501 a2dObject* a2dTextGDS::Clone( CloneOptions options ) const
03502 {
03503 return new a2dTextGDS(*this, options );
03504 };
03505
03506 void a2dTextGDS::SetFont(char nw_font)
03507 {
03508 if ( m_fontType == a2dFONT_STROKED )
03509 {
03510 m_font = a2dFont( wxT("nen.chr"), 0, m_monoSpaced );
03511 m_presentationflags.bits._font = nw_font;
03512
03513 switch( nw_font )
03514 {
03515 default:
03516 case 0 : m_font.SetWeight( 2 );
03517 break;
03518 case 1 : m_font.SetWeight( 4 );
03519 break;
03520 case 2 : m_font.SetWeight( 8 );
03521 break;
03522 case 3 : m_font.SetWeight( 12 );
03523 break;
03524 }
03525 }
03526 if ( m_fontType == a2dFONT_WXDC )
03527 {
03528 int FontFamily=wxMODERN;
03529 switch( nw_font )
03530 {
03531 case 0 : FontFamily = wxDEFAULT; break;
03532 case 1 : FontFamily = wxROMAN; break;
03533 case 2 : FontFamily = wxSWISS; break;
03534 case 3 : FontFamily = wxDECORATIVE; break;
03535 default: FontFamily = wxMODERN; break;
03536 }
03537 a2dText::SetFont( a2dFont(1,FontFamily,wxNORMAL,wxNORMAL) );
03538 }
03539 }
03540
03541 void a2dTextGDS::SetVertical(char nw_vertical)
03542 {
03543 m_presentationflags.bits._vertical = nw_vertical;
03544 switch ( m_presentationflags.bits._horizontal )
03545 {
03546 case 0 :
03547 default:
03548 m_alignment = wxBBOX|wxBOTTOM | m_alignment;
03549 break;
03550 case 1 :
03551 m_alignment = wxBBOX|wxCENTRE | m_alignment;
03552 break;
03553 case 2 :
03554 m_alignment = wxBBOX|wxTOP | m_alignment;
03555 break;
03556 }
03557 }
03558
03559
03560 void a2dTextGDS::SetHorizontal(char nw_horizontal)
03561 {
03562 m_presentationflags.bits._horizontal = nw_horizontal;
03563 switch ( m_presentationflags.bits._horizontal )
03564 {
03565 case 0 :
03566 default:
03567 m_alignment = wxLEFT | m_alignment;
03568 break;
03569 case 1 :
03570 m_alignment = wxCENTRE | m_alignment;
03571 break;
03572 case 2 :
03573 m_alignment = wxRIGHT | m_alignment;
03574 break;
03575 }
03576 }
03577
03578
03579 short int a2dTextGDS::GetFont()
03580 {
03581 return (short int) m_presentationflags.bits._font;
03582 }
03583
03584
03585 short int a2dTextGDS::GetVertical()
03586 {
03587 return (short int) m_presentationflags.bits._vertical;
03588 }
03589
03590
03591 short int a2dTextGDS::GetHorizontal()
03592 {
03593 return (short int) m_presentationflags.bits._horizontal;
03594 }
03595
03596 void a2dTextGDS::SetPresentationFlags( short int the_total)
03597 {
03598 m_presentationflags.total=the_total;
03599 SetHorizontal( m_presentationflags.bits._horizontal );
03600 SetVertical( m_presentationflags.bits._vertical );
03601 SetFont( m_presentationflags.bits._font );
03602 }
03603
03604 short int a2dTextGDS::GetPresentationFlags( )
03605 {
03606 return m_presentationflags.total;
03607 }
03608
03609 #endif //wxART2D_USE_GDSIO