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