wxArt2D
keyio.cpp
Go to the documentation of this file.
1 /*! \file keyio/src/keyio.cpp
2  \brief KEY parser
3  \author Probably Klaas Holwerda
4 
5  Copyright: 2001-2004 (C) Probably Klaas Holwerda
6 
7  Licence: wxWidgets Licence
8 
9  RCS-ID: $Id: keyio.cpp,v 1.64 2009/05/15 16:34:28 titato Exp $
10 */
11 
12 #include "a2dprec.h"
13 
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17 
18 #ifndef WX_PRECOMP
19 #include "wx/wx.h"
20 #endif
21 
22 #ifdef new
23 #undef new
24 #endif
25 
26 #include "a2dprivate.h"
27 
28 #if wxART2D_USE_KEYIO
29 
30 #include "wx/docview/doccom.h"
31 #include "wx/canvas/canglob.h"
32 #include "wx/canvas/algos.h"
33 #include "wx/canvas/canobj.h"
34 #include "wx/canvas/vpath.h"
35 #include "wx/editor/candoc.h"
36 #include "wx/canvas/layerinf.h"
37 #include "wx/canvas/recur.h"
38 #include "wx/canvas/drawer.h"
39 #include "wx/canvas/cameleon.h"
40 #include "wx/canvas/polygon.h"
41 #include "wx/keyio/keyio.h"
42 #include "wx/gdsio/gdserr.h"
43 
44 #include <wx/datetime.h>
45 #include <limits.h>
46 
47 /*
48 Purpose Used by GDS driver for conversions and read en write
49  GDSII elements
50 */
51 
52 // ----------------------------------------------------------------------------
53 // a2dIOHandlerKeyIn
54 // ----------------------------------------------------------------------------
55 
56 // strips all the spaces and tabs from the left of the string
57 // <blanks> ::= { TAB | SPACE }*
58 bool a2dIOHandlerKeyIn::Blanks()
59 {
60  int i = 0;
61  // delete blanks at the beginning
62  while ( a == wxT( ' ' ) || a == wxT( '\t' ) || a == wxT( '\\' ) || a == 0xd )
63  {
64  if ( a == wxT( '\\' ) )
65  {
66  if ( PeekNextC() != wxT( '\n' ) )
67  break;
68  else
69  IncC(); i++;
70  }
71  IncC(); i++;
72  }
73 
74  return ( i != 0 );
75 }
76 
77 // <comment> ::= # {CHAR}*
78 bool a2dIOHandlerKeyIn::Comment()
79 {
80  if( a != wxT( '#' ) ) //quote must be there
81  {
82  m_error_mes = wxT( "wrong comment" );
83  return false;
84  }
85  m_b.Empty();
86 
87  m_b += a;
88  IncC();
89 
90  while( a != wxT( '\0' ) )
91  {
92  if ( a == wxT( '\\' ) )
93  {
94  IncC();
95  if ( a == wxT( '\n' ) )
96  {
97  m_b += wxT( ' ' );
98  IncC();
99  continue;
100  }
101  }
102  if ( a == wxT( '\n' ) )
103  break; //end of comment
104 
105  m_b += a;
106  IncC();
107  }
108  return true;
109 }
110 
111 // <word> ::= { <quotedstring> | <bracedstring> | <normalword> }
112 bool a2dIOHandlerKeyIn::Word()
113 {
114  Blanks();
115  m_b.Empty();
116 
117  if ( a == wxT( '"' ) )
118  {
119  if ( !QuotedString() )
120  return false;
121  }
122  else if ( a == wxT( '{' ) )
123  {
124  if ( !BracedString() )
125  return false;
126  }
127  else
128  {
129  if ( !NormalWord() )
130  return false;
131  }
132 
133  return true;
134 }
135 
136 //<multipartword> ::= {CHAR}*
137 bool a2dIOHandlerKeyIn::NormalWord()
138 {
139  while( a != wxT( ' ' ) && a != wxT( '\t' ) && a != wxT( '\0' ) && a != wxT( '\n' ) && a != wxT( ';' ) )
140  {
141  if ( a == wxT( '\\' ) ) //take the next character
142  {
143  IncC();
144 
145  if ( a == wxT( ' ' ) || a == wxT( '\t' ) || a == wxT( '\0' ) || a == wxT( ';' ) )
146  break; //treat it as word seperator
147 
148  //all other backslash character take them
149  m_b += a;
150  IncC();
151  continue;
152  }
153 
154  //all other characters
155  m_b += a;
156  IncC();
157  }
158  return true;
159 }
160 
161 //<quotedstring> ::= ('"') {CHAR | '\"' | '\\n' }* ('"')
162 bool a2dIOHandlerKeyIn::QuotedString()
163 {
164  if( a != wxT( '"' ) ) //quote must be there
165  {
166  m_error_mes = wxT( "wrong quotedstring, begin quote missing" );
167  return false;
168  }
169 
170  IncC();
171 
172  while( a != wxT( '"' ) && a != wxT( '\0' ) )
173  {
174  if ( a == wxT( '\\' ) ) //take the next character
175  {
176  IncC();
177  if ( a == wxT( '\0' ) )
178  break; //error handled later
179 
180  m_b += a;
181  IncC();
182  continue;
183  }
184 
185  //all other characters
186  m_b += a;
187  IncC();
188  }
189 
190  if( a != wxT( '"' ) ) //quote must be there
191  {
192  m_error_mes = wxT( "wrong quotedstring, end quote missing" );
193  return false;
194  }
195  IncC();
196 
197  return true;
198 }
199 
200 
201 //<bracedstring> ::= ('{') {CHAR | '\{' | '\}' | '\\n'}* ('}')
202 bool a2dIOHandlerKeyIn::BracedString()
203 {
204  if( a != wxT( '{' ) ) //quote must be there
205  {
206  m_error_mes = wxT( "wrong bracedstring, begin brace missing" );
207  return false;
208  }
209 
210  IncC();
211 
212  int brnr = 0;
213  while( ( a != wxT( '}' ) || brnr ) && a != wxT( '\0' ) )
214  {
215  if ( a == '\\' ) //take the next character
216  {
217  IncC();
218  if ( a == wxT( '\0' ) )
219  break; //error handled later
220 
221  m_b += a;
222  IncC();
223  continue;
224  }
225 
226  //nested braces are allowed
227  if ( a == wxT( '{' ) ) //nested brace
228  brnr++;
229 
230  if ( a == wxT( '}' ) ) //nested brace
231  brnr--;
232 
233  //all other characters
234  m_b += a;
235  IncC();
236  }
237 
238 
239  if( a != wxT( '}' ) ) //quote must be there
240  {
241  m_error_mes = wxT( "wrong bracedstring, end brace missing" );
242  return false;
243  }
244  IncC();
245 
246  return true;
247 }
248 
249 bool a2dIOHandlerKeyIn::GetCommand()
250 {
251  m_keyword.Empty();
252  m_value.Empty();
253  m_error_mes.Empty();
254 
255  if ( !m_linenumber ) //the very first lien will be parsed
256  m_linenumber++;
257 
258 
259  // already skip blanks in front of next command
260  Blanks();
261 
262  while( a == wxT( '\0' ) || a == wxT( '\n' ) || a == wxT( ';' ) ) //skip empty command
263  {
264  if ( a == wxT( '\0' ) ) //end of file no error will be set
265  {
266  return false;
267  }
268  IncC();
269  Blanks();
270  }
271 
272  if ( a == wxT( '\0' ) ) //end of file no error will be set
273  return false;
274  else if ( a == wxT( '#' ) )
275  {
276  if ( !Comment() ) //it is comment
277  {
278  m_error_mes = wxT( "comment wrong" );
279  return false;
280  }
281 
282  m_keyword = _T( "comment" );
283  return true;
284  }
285  else
286  {
287  m_b.Empty();
288 
289  if ( !NormalWord() )
290  return false;
291 
292  m_keyword = m_b;
293 
294  Word();
295 
296  if ( m_error_mes.Len() )
297  return false;
298 
299  Blanks();
300 
301  // <endcommand> ::= '\0' | ';'
302  if( a == wxT( '\0' ) || a == wxT( '\n' ) || a == wxT( ';' ) ) //not at end of m_command
303  IncC();
304  else
305  {
306  m_error_mes = wxT( "; or EOL expected" );
307  return false;
308  }
309 
310  //skip empty commands
311  Blanks();
312 
313  if( a == wxT( '\0' ) || a == wxT( '\n' ) || a == wxT( ';' ) )
314  IncC();
315 
316  m_value = m_b;
317  }
318 
319  return true;
320 }
321 
322 // ReadItem (parser) --------------------------------------------------------
323 bool a2dIOHandlerKeyIn::ReadItem( const wxString& type )
324 {
325 // <item> ::= KEYWORD VALUE
326  if ( m_back )
327  {
328  if ( ! m_keyword.CmpNoCase( type ) )
329  m_back = false;
330  else
331  m_back = true;
332  return bool( !m_back );
333  }
334 
335  wxString buf;
336  bool Next = true;
337  do
338  {
339  if( !GetCommand() )
340  {
341  if ( !m_error_mes.IsEmpty() )
342  {
343  m_b.Printf( _T( "Could not Parse line %d: \n Error: %s" ),
344  m_linenumber, m_error_mes.c_str() );
345 
346  throw GDS_Error( m_b, wxT( "Command Parsing Error" ) );
347 
348  }
349  return false;
350  }
351  if ( m_keyword == wxT( "comment" ) )
352  Next = true;
353  else if ( m_keyword == wxT( "" ) )
354  Next = true;
355  else
356  Next = false;
357  }
358  while ( Next );
359 
360  if ( m_value.IsEmpty() )
361  {
362  wxString buf;
363  buf = wxT( "Argument missing (in " );
364  if ( !m_keyword.CmpNoCase( type ) )
365  {
366  // These commands don't have arguments...
367  if ( !m_keyword.CmpNoCase( wxT( "BGNLIB" ) ) );
368  //else if (!m_keyword.CmpNoCase(wxT("UNITS")));
369  else if ( !m_keyword.CmpNoCase( wxT( "BGNSTR" ) ) );
370  else if ( !m_keyword.CmpNoCase( wxT( "BOUNDARY" ) ) );
371  else if ( !m_keyword.CmpNoCase( wxT( "SURFACE" ) ) );
372  else if ( !m_keyword.CmpNoCase( wxT( "LINE" ) ) );
373  else if ( !m_keyword.CmpNoCase( wxT( "CIRCLE" ) ) );
374  else if ( !m_keyword.CmpNoCase( wxT( "BOX" ) ) );
375  else if ( !m_keyword.CmpNoCase( wxT( "PATH" ) ) );
376  else if ( !m_keyword.CmpNoCase( wxT( "TEXT" ) ) );
377  else if ( !m_keyword.CmpNoCase( wxT( "AREF" ) ) );
378  else if ( !m_keyword.CmpNoCase( wxT( "SREF" ) ) );
379  else if ( !m_keyword.CmpNoCase( wxT( "ARC" ) ) );
380  else if ( !m_keyword.CmpNoCase( wxT( "ENDEL" ) ) );
381  else if ( !m_keyword.CmpNoCase( wxT( "ENDLIB" ) ) );
382  else if ( !m_keyword.CmpNoCase( wxT( "ENDMASKS" ) ) );
383  else
384  {
385  buf += m_keyword;
386  buf += wxT( ")" );
387  throw GDS_Error( buf ); // There is no argument, so throw an error...
388  }
389  }
390  }
391 
392  if ( !m_keyword.CmpNoCase( type ) )
393  m_back = false;
394  else
395  m_back = true;
396  return bool( !m_back );
397 }
398 
399 bool a2dIOHandlerKeyIn::SkipXYData()
400 {
401  if ( !ReadItem( wxT( "xy" ) ) )
402  return false;
403 
404  while ( 1 )
405  {
406  if ( ( ReadItem( wxT( "x" ) ) ) ||
407  ( ReadItem( wxT( "y" ) ) ) ||
408  ( ReadItem( wxT( "xm" ) ) ) ||
409  ( ReadItem( wxT( "ym" ) ) ) ||
410  ( ReadItem( wxT( "xo" ) ) ) ||
411  ( ReadItem( wxT( "yo" ) ) )
412  )
413  continue;
414  else
415  break;
416  }
417 
418  return true;
419 }
420 
421 double a2dIOHandlerKeyIn::ReadDouble()
422 {
423  return m_scale_in * wxAtof( m_value );
424 }
425 
426 wxChar a2dIOHandlerKeyIn::PeekNextC()
427 {
428  wxChar p = ( wxChar ) Peek();
429  return p;
430 }
431 
432 void a2dIOHandlerKeyIn::IncC()
433 {
434  a = ( wxChar ) GetC();
435 
436  if ( a == wxT( '\0' ) || a == wxT( '\n' ) )
437  m_linenumber++;
438 
439 
440  if ( Eof() )
441  a = wxT( '\0' );
442  if ( a == wxChar( EOF ) )
443  a = wxT( '\0' );
444  if ( a == wxT( '\r' ) )
445  a = wxT( ' ' );
446 }
447 
448 // -------------- use it -----------------
449 
450 a2dIOHandlerKeyIn::a2dIOHandlerKeyIn()
451 {
452  m_scale_in = 1;
453  m_back = false;
454  m_asCameleons = false;
455  m_keyword.Clear();
456  m_value.Clear();
457  m_lastElementLayer = 0;
458 
459  m_docClassInfo = &a2dCanvasDocument::ms_classInfo;
460  m_refMaxx = 10;
461  m_dx = m_dy = 0;
462 }
463 
464 a2dIOHandlerKeyIn::~a2dIOHandlerKeyIn()
465 {
466 }
467 
469 {
470  m_linenumber = 0;
472  IncC(); //get the first character;
473  if ( m_doc )
474  a2dCanvasGlobals->GetHabitat()->SetAberPolyToArc( double( a2dCanvasGlobals->GetHabitat()->GetAberPolyToArc() ) / m_doc->GetUnitsScale() );
475 }
476 
478 {
480 }
481 
482 bool a2dIOHandlerKeyIn::CanLoad( a2dDocumentInputStream& stream, const wxObject* obj, wxClassInfo* docClassInfo )
483 {
484  if ( obj && !wxDynamicCast( obj, a2dCanvasDocument ) )
485  return false;
486 
487  if ( docClassInfo && m_docClassInfo && !docClassInfo->IsKindOf( m_docClassInfo ) )
488  return false;
489 
490  m_streami = &stream;
491  m_doc = 0;
492 
493  SeekI( 0 );
494  InitializeLoad();
495 
496  m_recordsize = 0;
497  m_recordtype = 0;
498  m_back = false;
499 
500  try
501  {
502  if ( !ReadItem( wxT( "header" ) ) ) // Header expected here
503  {
504  SeekI( 0 );
505  return false;
506  }
507  }
508  catch ( GDS_Error& WXUNUSED( error ) )
509  {
510  ResetLoad();
511  SeekI( 0 );
512  return false;
513  }
514  SeekI( 0 );
515 
516  return true;
517 }
518 
519 bool a2dIOHandlerKeyIn::LinkReferences()
520 {
521  bool res = a2dIOHandler::LinkReferences();
522 
523  //search in the root object for the childs that have the bin flag set,
524  //which means they are referenced, and can be deleted.
525  //All others are top structures.
527  a2dCanvasObjectList::iterator rootchild = root->GetChildObjectList()->begin();
528  while ( rootchild != root->GetChildObjectList()->end() )
529  {
530  a2dCanvasObjectList::iterator delnode = rootchild;
531  rootchild++;
532  if ( ( *delnode )->GetCheck() )
533  {
534  root->GetChildObjectList()->erase( delnode );
535  }
536  }
537  return res;
538 }
539 
540 bool a2dIOHandlerKeyIn::Load( a2dDocumentInputStream& stream, wxObject* doc )
541 {
542  m_streami = &stream;
543 
545  InitializeLoad();
546 
547  wxString path;
548  path = m_doc->GetFilename().GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR ) + m_doc->GetFilename().GetName() + wxT( ".cvg" );
549  if ( wxFileExists( path ) )
550  m_doc->LoadLayers( path );
551 
553 
554  m_recordsize = 0;
555  m_recordtype = 0;
556  m_back = false;
557 
558  m_mapping.resize( wxMAXLAYER );
559 
560  unsigned int i;
561  for ( i = 0; i < wxMAXLAYER; i++ )
562  m_mapping[i] = -1;
563  for ( i = 0; i < wxMAXLAYER; i++ )
564  {
565  if ( m_doc->GetLayerSetup()->GetLayerIndex()[i] != wxNullLayerInfo )
566  {
567  int layerIndex = m_doc->GetLayerSetup()->GetInMapping( i );
568  wxASSERT_MSG( layerIndex >= 0 && layerIndex < wxMAXLAYER, wxT( "InMap must be > wxMAXLAYER" ) );
569  m_mapping[ layerIndex ] = i;
570  }
571  }
572  for ( i = 0; i < wxMAXLAYER; i++ )
573  if ( m_mapping[i] == -1 )
574  m_mapping[i] = 0;
575 
576  try
577  {
578  ReadKey();
579  }
580  catch ( GDS_Error& error )
581  {
582  ResetLoad();
583  a2dDocviewGlobals->ReportErrorF( a2dError_NotSpecified, wxT( "error in KEY file \n %s \n %d \n" ), error.GetErrorMessage().c_str(), m_linenumber );
584  return false;
585  }
586 
587  ResetLoad();
588  return true;
589 }
590 
591 // GdsII --------------------------------------------------------------------
592 void a2dIOHandlerKeyIn::ReadKey()
593 {
594  //The a2dObject::m_check is used for removing structure from the rootobject after resolving references.
595  //when a new document is filled this would not be needed, sine all m_check flags are default set false.
596  //But maybe for the future import it is important to do.
597  a2dWalker_SetCheck setp( false );
598  setp.Start( m_doc->GetDrawing() );
599 
601 
602  // Grammar: HEADER BGNLIB LIBNAME [REFLIBS] [FONTS]
603  // [ATTRTABLE] [GENERATION] [<FormatType>]
604  // UNITS {<Structure>}* ENDLIB
605  //
606 
607 // <stream format> ::= HEADER
608 // BGNLIB
609 // <LibrarySettings>
610 // {<Structure>}*
611 // ENDLIB
612 
613  if ( !ReadItem( wxT( "header" ) ) ) // Header expected here
614  throw GDS_Error( wxT( "HEADER is missing (in KEY-file)" ) );
615 
617  if ( !ReadBgnlib() )
618  throw GDS_Error( wxT( "BGNLIB is missing (in KEY-file)" ) );
619  if ( !ReadLibrarySettings() )
620  throw GDS_Error( wxT( "LIBNAME is missing (in KEY-file)" ) );
621  if ( m_asCameleons )
622  {
623  while ( ReadCameleonStructure( m_doc->GetDrawing()->GetRootObject() ) )
624  {
625  }
626  }
627  else
628  {
629  while ( ReadStructure( m_doc->GetDrawing()->GetRootObject() ) )
630  {
631  }
632  }
633  if ( !ReadItem( wxT( "endlib" ) ) )
634  throw GDS_Error( wxT( "ENDLIB is missing (in KEY-file)" ) );
635 
636  //references to other structure are known
637  //by name now. Set the pointers in those references
638  //to the right structures
639  LinkReferences(); //GDS links on Name
640 
641  if ( m_asCameleons )
642  {
643  m_dx = m_dy = 0;
644 
645  m_doc->GetDrawing()->SetDrawingId( a2dDrawing::sm_cameleonrefs );
647  throw GDS_Error( wxT( "no structures found" ) );
648 
650 
651  a2dCameleon* topcam = NULL;
652  a2dCanvasObjectList::iterator rootchild = m_doc->GetDrawing()->GetRootObject()->GetChildObjectList()->begin();
653  while ( rootchild != m_doc->GetDrawing()->GetRootObject()->GetChildObjectList()->end() )
654  {
655  a2dCameleon* ref = wxDynamicCast( (*rootchild).Get(), a2dCameleon );
656  if ( ref )
657  {
658  a2dLayout* layout = ref->GetAppearance<a2dDiagram>();
659  layout->GetDrawing()->SetRootRecursive();
660  if ( ! layout->GetCheck() )
661  {
662  topcam = ref;
663  m_doc->SetTopCameleon( topcam );
664  m_doc->SetShowObject( layout->GetDrawing()->GetRootObject() );
665  }
666  }
667  rootchild++;
668  }
669  }
670  else
671  {
673  m_doc->SetMultiRoot();
674  else
677  }
678 }
679 
680 // Bgnlib -------------------------------------------------------------------
681 bool a2dIOHandlerKeyIn::ReadBgnlib()
682 {
683  if( !ReadItem( wxT( "bgnlib" ) ) ) // BgnLib expected here
684  return false;
685  if( !ReadItem( wxT( "lastmod" ) ) )
686  throw GDS_Error( wxT( "BGNLIB: LASTMOD is missing (in KEY-file)" ) );
687 
688  wxString _int_str_ptr = m_value;
689 
690  int year;
691  int month;
692  int day;
693  int hour;
694  int minute;
695  int second;
696 
697  year = wxAtoi( _int_str_ptr );
698  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
699  month = wxAtoi( _int_str_ptr ) - 1;
700  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
701  day = wxAtoi( _int_str_ptr );
702  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( " " ) ) + 2;
703  hour = wxAtoi( _int_str_ptr );
704  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
705  minute = wxAtoi( _int_str_ptr );
706  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
707  second = wxAtoi( _int_str_ptr );
708 
709  m_doc->GetModificationTime().Set( day, ( wxDateTime::Month )month, year, hour, minute, second );
710 
711  if( !ReadItem( wxT( "lastacc" ) ) )
712  throw GDS_Error( wxT( "BGNLIB: LASTACC is missing (in KEY-file)" ) );
713 
714  _int_str_ptr = m_value;
715 
716  year = wxAtoi( _int_str_ptr );
717  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
718  month = wxAtoi( _int_str_ptr ) - 1;
719  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
720  day = wxAtoi( _int_str_ptr );
721  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( " " ) ) + 2;
722  hour = wxAtoi( _int_str_ptr );
723  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
724  minute = wxAtoi( _int_str_ptr );
725  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
726  second = wxAtoi( _int_str_ptr );
727 
728  m_doc->GetAccessTime().Set( day, ( wxDateTime::Month )month, year, hour, minute, second );
729 
730  return( true );
731 }
732 
733 // Library ------------------------------------------------------------------
734 bool a2dIOHandlerKeyIn::ReadLibrarySettings()
735 {
736  if( !ReadItem( wxT( "libname" ) ) ) // BgnLib expected here
737  throw GDS_Error( wxT( "libname record missing (in KEY)" ), wxT( "Error" ) );
738 
740  m_doc->SetTitle( m_value, false );
741 
742  ReadItem( wxT( "reflibs" ) ); // RefLibs optional
743  ReadItem( wxT( "fonts" ) );
744  ReadItem( wxT( "attrtable" ) );
745  ReadItem( wxT( "generations" ) );
746  if ( ReadItem( wxT( "format" ) ) )
747  {
748  //skip rest for the moment
749  while( !ReadItem( wxT( "endmasks" ) ) )
750  {
751  if ( ReadItem( wxT( "mask" ) ) )
752  {
753  wxString layerstr = m_value;
754  wxInt16 layernr = 0;
755  a2dLayerInfo* info = NULL;
756 
757  a2dFill layerfill;
758  a2dStroke layerstroke;
759 
760  while( 1 )
761  {
762  if ( ReadItem( wxT( "layernr" ) ) )
763  {
764  layernr = wxAtoi( m_value );
765  wxInt16 internalMappedTo = m_mapping[ layernr ];
766  info = m_doc->GetLayerSetup()->GetLayerIndex()[ internalMappedTo ];
767  if ( info != wxNullLayerInfo )
768  {
769  info->SetName( layerstr );
770  layerfill = info->GetFill();
771  layerstroke = info->GetStroke();
772  }
773  }
774  else if ( ReadItem( wxT( "color" ) ) )
775  {
776  wxColour fill;
777  wxString fillColour = m_value;
778  if ( !fillColour.IsEmpty() )
779  {
780  if ( fillColour.GetChar( 0 ) == wxT( '#' ) )
781  fill = HexToColour( fillColour.After( wxT( '#' ) ) );
782  else
783  {
784  fill = wxTheColourDatabase->Find( fillColour );
785  if ( !fill.Ok() )
786  fill = *wxBLACK;
787  }
788  layerfill.SetColour( fill );
789  layerstroke.SetColour( fill );
790  }
791  }
792  else if ( ReadItem( wxT( "trans" ) ) )
793  {
794  }
795  else if ( ReadItem( wxT( "binding" ) ) )
796  {
797  }
798  else if ( ReadItem( wxT( "linestyle" ) ) )
799  {
801  layerstroke.SetStyle( style );
802  }
803  else if ( ReadItem( wxT( "stream" ) ) )
804  {
805  }
806  else if ( ReadItem( wxT( "iges" ) ) )
807  {
808  }
809  else if ( ReadItem( wxT( "type" ) ) )
810  {
811  }
812  else if ( ReadItem( wxT( "dxf" ) ) )
813  {
814  }
815  else if ( ReadItem( wxT( "plotmode" ) ) )
816  {
817  wxUint16 shapestyle = wxAtoi( m_value );
818  switch( shapestyle )
819  {
820  case 0:
821  layerfill.SetFilling( false );
822  break;
823  case 1:
824  layerfill.SetFilling( true );
825  break;
826  case 2:
827  layerfill.SetFilling( true );
828  break;
829  default:
830  layerfill.SetFilling( true );;
831  }
832  }
833  else if ( ReadItem( wxT( "protected" ) ) )
834  {
835  }
836  else if ( ReadItem( wxT( "visible" ) ) )
837  {
838  }
839  else if ( ReadItem( wxT( "patternnr" ) ) )
840  {
841  }
842  else if ( m_keyword.CmpNoCase( wxT( "mask" ) ) == 0 || m_keyword.CmpNoCase( wxT( "endmasks" ) ) == 0 )
843  break;
844  else
845  m_back = false; //skip this
846  }
847  if ( info != wxNullLayerInfo )
848  {
849  info->SetFill( layerfill );
850  info->SetStroke( layerstroke );
851  }
852  }
853  }
854  }
855 
856  if( !ReadItem( wxT( "units" ) ) ) // Units expected here
857  return false;
858  m_doc->SetUnits( m_value );
859 
860  if( !ReadItem( wxT( "userunits" ) ) )
861  throw GDS_Error( wxT( "USERUNITS missing (in KEY-file)" ) );
862  m_userunits_out = ( double )wxAtof( m_value );
863  m_doc->SetUnitsAccuracy( m_userunits_out );
864  if( !ReadItem( wxT( "physunits" ) ) )
865  throw GDS_Error( wxT( "PHYSUNITS missing (in KEY-file)" ) );
866 
867  double metersScale = ( ( double )wxAtof( m_value ) ) / m_userunits_out;
868  m_doc->SetUnitsScale( metersScale );
869 
870  a2dDoMu unit = a2dDoMu( 1, 1 );
872  unit = a2dDoMu( 1, metersScale );
874 
875  return true;
876 }
877 
878 // Read Element -------------------------------------------------------------
879 bool a2dIOHandlerKeyIn::ReadElement( a2dCanvasObject* parent )
880 {
881 // <element> ::= {<boundary> | <path> | <SREF> | <AREF> | <text> | <node> | <box>}
882 // /* {<property>}* */
883 // ENDEL
884 
885  if ( ReadBoundary( parent ) ||
886  ReadSurface( parent ) ||
887  ReadPath( parent ) ||
888  ReadStructureReference( parent ) ||
889  ReadArrayReference( parent ) ||
890  ReadText( parent ) ||
891  ReadNode( parent ) ||
892  ReadBox( parent ) ||
893  ReadArc( parent ) ||
894  ReadCircle( parent ) ||
895  ReadLine( parent ) ||
896  ReadImage( parent )
897  )
898  {
899  }
900  else
901  return false;
902 
903  while ( ReadProperties( parent->GetChildObjectList()->back() ) );
904  while ( ReadParameters( parent->GetChildObjectList()->back() ) );
905 
906  if ( !ReadItem( wxT( "endel" ) ) )
907  throw GDS_Error( wxT( "ENDEL is missing (in KEY-file) (too many points in element?)" ) );
908  return true;
909 }
910 
911 
912 // Property -----------------------------------------------------------------
913 bool a2dIOHandlerKeyIn::ReadProperties( a2dCanvasObject* parent )
914 {
915  if ( !ReadItem( wxT( "property" ) ) )
916  return false;
917 
918  do
919  {
920  wxString name;
921  wxString value;
922  wxString type;
923  name = m_value;
924 
925  if ( ReadItem( wxT( "proptype" ) ) )
926  type = m_value;
927  if ( ReadItem( wxT( "propvalue" ) ) )
928  value = m_value;
929 
930  if ( m_doc->GetLayerSetup()->GetRead( m_lastElementLayer ) )
931  {
932  if ( type == wxT( "string" ) )
933  {
934  a2dPropertyIdString* propid = ( a2dPropertyIdString* ) parent->HasPropertyId( name );
935  if ( !propid )
936  {
937  propid = new a2dPropertyIdString( name, wxT( "" ), a2dPropertyId::flag_userDefined );
938  parent->AddPropertyId( propid );
939  }
940  propid->SetPropertyToObject( parent, value );
941  }
942  else if ( type == wxT( "integer" ) )
943  {
944  a2dPropertyIdInt32* propid = ( a2dPropertyIdInt32* ) parent->HasPropertyId( name );
945  if ( !propid )
946  {
947  propid = new a2dPropertyIdInt32( name, 0, a2dPropertyId::flag_userDefined );
948  parent->AddPropertyId( propid );
949  }
950  propid->SetPropertyToObject( parent, wxAtoi( value ) );
951  }
952  else if ( type == wxT( "real" ) )
953  {
954  a2dPropertyIdDouble* propid = ( a2dPropertyIdDouble* ) parent->HasPropertyId( name );
955  if ( !propid )
956  {
957  propid = new a2dPropertyIdDouble( name, 0, a2dPropertyId::flag_userDefined );
958  parent->AddPropertyId( propid );
959  }
960  double doubleval;
961  value.ToDouble( &doubleval );
962  propid->SetPropertyToObject( parent, doubleval );
963  }
964  else if ( type == wxT( "bool" ) )
965  {
966  a2dPropertyIdBool* propid = ( a2dPropertyIdBool* ) parent->HasPropertyId( name );
967  if ( !propid )
968  {
969  propid = new a2dPropertyIdBool( name, false, a2dPropertyId::flag_userDefined );
970  parent->AddPropertyId( propid );
971  }
972  propid->SetPropertyToObject( parent, value.IsSameAs( wxT( "true" ), true ) ? true : false );
973  }
974  else
975  wxLogWarning( wxT( "KEYIO : property type: %s is not implemented" ), type.c_str() );
976 
977  }
978  }
979  while ( ReadItem( wxT( "property" ) ) );
980  return true;
981 }
982 
983 // Property -----------------------------------------------------------------
984 bool a2dIOHandlerKeyIn::ReadParameters( a2dCanvasObject* parent )
985 {
986  if ( !ReadItem( wxT( "parameter" ) ) )
987  return false;
988 
989  do
990  {
991  wxString name;
992  wxString value;
993  wxString type;
994  name = m_value;
995 
996  if ( ReadItem( wxT( "parametertype" ) ) )
997  type = m_value;
998  if ( ReadItem( wxT( "parametervalue" ) ) )
999  value = m_value;
1000 
1001  if ( m_doc->GetLayerSetup()->GetRead( m_lastElementLayer ) )
1002  {
1003  if ( type == wxT( "string" ) )
1004  {
1005  a2dPropertyIdString* propid = ( a2dPropertyIdString* ) parent->HasPropertyId( name );
1006  if ( !propid )
1007  {
1008  propid = new a2dPropertyIdString( name, wxT( "" ), a2dPropertyId::flag_userDefined );
1009  parent->AddPropertyId( propid );
1010  }
1011  propid->SetPropertyToObject( parent, value );
1012  }
1013  else if ( type == wxT( "integer" ) )
1014  {
1015  a2dPropertyIdInt32* propid = ( a2dPropertyIdInt32* ) parent->HasPropertyId( name );
1016  if ( !propid )
1017  {
1018  propid = new a2dPropertyIdInt32( name, 0, a2dPropertyId::flag_userDefined );
1019  parent->AddPropertyId( propid );
1020  }
1021  propid->SetPropertyToObject( parent, wxAtoi( value ) );
1022  }
1023  else if ( type == wxT( "real" ) )
1024  {
1025  a2dPropertyIdDouble* propid = ( a2dPropertyIdDouble* ) parent->HasPropertyId( name );
1026  if ( !propid )
1027  {
1028  propid = new a2dPropertyIdDouble( name, 0, a2dPropertyId::flag_userDefined );
1029  parent->AddPropertyId( propid );
1030  }
1031  double doubleval;
1032  value.ToDouble( &doubleval );
1033  propid->SetPropertyToObject( parent, doubleval );
1034  }
1035  else if ( type == wxT( "bool" ) )
1036  {
1037  a2dPropertyIdBool* propid = ( a2dPropertyIdBool* ) parent->HasPropertyId( name );
1038  if ( !propid )
1039  {
1040  propid = new a2dPropertyIdBool( name, false, a2dPropertyId::flag_userDefined );
1041  parent->AddPropertyId( propid );
1042  }
1043  propid->SetPropertyToObject( parent, value.IsSameAs( wxT( "true" ), true ) ? true : false );
1044  }
1045  else
1046  wxLogWarning( wxT( "KEYIO : parameter type: %s is not implemented" ), type.c_str() );
1047 
1048  }
1049  }
1050  while ( ReadItem( wxT( "parameter" ) ) );
1051  return true;
1052 }
1053 
1054 // Surface -----------------------------------------------------------------
1055 bool a2dIOHandlerKeyIn::ReadSurface( a2dCanvasObject* parent )
1056 {
1057 // <Surface> ::= SURFACE [ELFLAGS] [PLEX] LAYER DATATYPE [WIDTH] XY
1058 
1059  if ( !ReadItem( wxT( "surface" ) ) )
1060  return false;
1061 
1062  // Create a new Boundary
1063  a2dSmrtPtr<a2dSurface> Surface = new a2dSurface();
1064 
1065  ReadElflags( Surface );
1066 
1067  ReadItem( wxT( "plex" ) );
1068 
1069  if ( !ReadLayer( Surface ) )
1070  throw GDS_Error( wxT( "Surface: LAYER missing (in KEY-file)" ) );
1071 
1072  ReadItem( wxT( "datatype" ) );
1073  SetDataTypeProperty( Surface, wxAtoi( m_value ) );
1074 
1075  if ( ReadItem( wxT( "spline" ) ) )
1076  Surface->SetSpline( wxAtoi( m_value ) > 0 );
1077 
1078  if ( ReadItem( wxT( "width" ) ) )
1079  Surface->SetContourWidth( ReadDouble() );
1080 
1081  if ( m_doc->GetLayerSetup()->GetRead( Surface->GetLayer() ) )
1082  {
1083  if ( !ReadPolygon( Surface->GetSegments() ) )
1084  throw GDS_Error( wxT( "Header: XY missing (in Boundary)" ) );
1085 
1086  while ( ReadItem( wxT( "hole" ) ) )
1087  {
1088  a2dVertexList* rlist = new a2dVertexList();
1089  if ( !ReadPolygon( rlist ) )
1090  throw GDS_Error( wxT( "Header: XY missing (in Surface Hole)" ) );
1091  Surface->AddHole( rlist );
1092  }
1093  parent->Append( Surface );
1094  }
1095  else
1096  {
1097  SkipXYData();
1098  while ( ReadItem( wxT( "hole" ) ) )
1099  {
1100  a2dVertexList* rlist = new a2dVertexList();
1101  SkipXYData();
1102  }
1103  }
1104  return true;
1105 }
1106 
1107 // Boundary -----------------------------------------------------------------
1108 bool a2dIOHandlerKeyIn::ReadBoundary( a2dCanvasObject* parent )
1109 {
1110 // <boundary> ::= BOUNDARY [ELFLAGS] [PLEX] LAYER DATATYPE [WIDTH] XY
1111 
1112  if ( !ReadItem( wxT( "boundary" ) ) )
1113  return false;
1114 
1115  // Create a new Boundary
1116  a2dSmrtPtr<a2dPolygonL> Boundary = new a2dPolygonL();
1117 
1118  ReadElflags( Boundary );
1119 
1120  ReadItem( wxT( "plex" ) );
1121 
1122  if ( !ReadLayer( Boundary ) )
1123  throw GDS_Error( wxT( "Boundary: LAYER missing (in KEY-file)" ) );
1124 
1125  ReadItem( wxT( "datatype" ) );
1126  SetDataTypeProperty( Boundary, wxAtoi( m_value ) );
1127 
1128  if ( ReadItem( wxT( "spline" ) ) )
1129  Boundary->SetSpline( wxAtoi( m_value ) > 0 );
1130 
1131  if ( ReadItem( wxT( "width" ) ) )
1132  Boundary->SetContourWidth( ReadDouble() );
1133 
1134  if ( m_doc->GetLayerSetup()->GetRead( Boundary->GetLayer() ) )
1135  {
1136  if ( !ReadPolygon( Boundary->GetSegments() ) )
1137  throw GDS_Error( wxT( "Header: XY missing (in Boundary)" ) );
1138 
1139  parent->Append( Boundary );
1140  }
1141  else
1142  SkipXYData();
1143 
1144  return true;
1145 }
1146 
1147 // Path ---------------------------------------------------------------------
1148 bool a2dIOHandlerKeyIn::ReadPath( a2dCanvasObject* parent )
1149 {
1150 // <path> ::= PATH [ELFLAGS] [PLEX] LAYER
1151 // DATATYPE [PATHTYPE] [WIDTH]
1152 // [BGNEXTN] [ENDEXTN] XY
1153 
1154  if ( !ReadItem( wxT( "path" ) ) )
1155  return false;
1156 
1157  // Create a new Path
1159 
1160  ReadElflags( path );
1161  ReadItem( wxT( "plex" ) );
1162 
1163  if ( !ReadLayer( path ) )
1164  throw GDS_Error( wxT( "record LAYER missing (in Path)" ) );
1165 
1166  if ( ReadItem( wxT( "datatype" ) ) )
1167  SetDataTypeProperty( path, wxAtoi( m_value ) );
1168 
1169  if ( ReadItem( wxT( "pathtype" ) ) )
1170  path->SetPathType( ( a2dPATH_END_TYPE )wxAtoi( m_value ) );
1171 
1172  if ( ReadItem( wxT( "spline" ) ) )
1173  path->SetSpline( wxAtoi( m_value ) > 0 );
1174 
1175  if ( ReadItem( wxT( "width" ) ) )
1176  path->SetContourWidth( ReadDouble() );
1177 
1178  ReadItem( wxT( "bgnextn" ) );
1179  ReadItem( wxT( "endextn" ) );
1180 
1181  if ( m_doc->GetLayerSetup()->GetRead( path->GetLayer() ) )
1182  {
1183  if ( !ReadPolyline( path->GetSegments() ) )
1184  throw GDS_Error( wxT( "Header: XY missing (in Path)" ) );
1185  parent->Append( path );
1186  }
1187  else
1188  SkipXYData();
1189 
1190  return true;
1191 }
1192 
1193 
1194 // Text ---------------------------------------------------------------------
1195 bool a2dIOHandlerKeyIn::ReadText( a2dCanvasObject* parent )
1196 {
1197  // Grammar: TEXT [ELFLAGS] [PLEX] LAYER
1198  // TEXTTYPE [PRESENTATION] [PATHTYPE] [WIDTH]
1199  // [<strans>] XY STRING
1200  //
1201  // <strans> = STRANS [MAG] [ANGLE]
1202 
1203  if ( !ReadItem( wxT( "text" ) ) )
1204  return false;
1205 
1206  // Create a new Text
1207  a2dSmrtPtr<a2dTextGDS> Text = new a2dTextGDS( a2dFONT_STROKED );
1208 
1209  ReadElflags( Text );
1210  ReadItem( wxT( "plex" ) );
1211  if ( !ReadLayer( Text ) )
1212  throw GDS_Error( wxT( "Text: LAYER is missing (in GDS-file)" ) );
1213 
1214  if ( !ReadItem( wxT( "texttype" ) ) )
1215  throw GDS_Error( wxT( "Text: TEXTBODY is missing (in GDS-file)" ) );
1216  Text->SetTextType( wxAtoi( m_value ) );
1217 
1218  if ( ReadItem( wxT( "presentation" ) ) )
1219  {
1220  //now that we know the size, in order to set font stroke weight based on size.
1221  wxString _int_str_ptr = m_value;
1222  Text->SetHorizontal( wxAtoi( _int_str_ptr ) % 4 );
1223  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "," ) ) + 1;
1224  Text->SetVertical( wxAtoi( _int_str_ptr ) % 4 );
1225  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "," ) ) + 1;
1226  Text->SetFontGDS( wxAtoi( _int_str_ptr ) % 4 );
1227  }
1228 
1229  if ( ReadItem( wxT( "pathtype" ) ) )
1230  {
1231  Text->SetPathtype( ( TEXT_PATHTYPE )wxAtoi( m_value ) );
1232  }
1233 
1234  if ( ReadItem( wxT( "width" ) ) )
1235  Text->SetTextHeight( ReadDouble() * m_userunits_out );
1236  else
1237  Text->SetTextHeight( 1.0 );
1238 
1239  Strans Strans;
1240  ReadStrans( Strans );
1241 
1242  // this is line to line height in ADS.
1243  double lineheight = Strans.GetScale();
1244  double factHeightSize = Text->GetTextHeight()/Text->GetLineHeight();
1245  Text->SetTextHeight( factHeightSize * lineheight );
1246 
1247  if ( !ReadItem( wxT( "xy" ) ) )
1248  throw GDS_Error( wxT( "Text: XY is missing (in KEY-file)" ) );
1249 
1250  a2dPoint2D point;
1251  Read( point );
1252 
1253  a2dAffineMatrix relative_matrix;
1254 
1255  // Ok, now we have a strans, but we want to work with a matrix,
1256  // so let's convert it to one:
1257 
1258  // Mirror in X if necessary
1259  if ( Strans.GetReflection() )
1260  relative_matrix.Mirror();
1261 
1262  // Rotate if necessary
1263  if ( Strans.GetAbsAngle() == 0 )
1264  relative_matrix.Rotate( Strans.GetAngle(), 0, 0 );
1265 
1266  // Scale if necessary
1267  if ( Strans.GetAbsScale() == 0 )
1268  {
1269  //WE DIRECTLY SET IT TO TEXT HEIGHT
1270  //double scale = Strans.GetScale();
1271  //relative_matrix.Scale(scale, scale, 0, 0);
1272  }
1273 
1274  // Translate2D over XY from the structrereference
1275  relative_matrix.Translate( point.m_x, point.m_y );
1276 
1277  Text->SetTransformMatrix( relative_matrix );
1278  //Text->SetLineSpacing( Text->GetLineHeight() / );
1279  double textheight = Text->GetLineHeight();
1280  //Text->SetLineSpacing( textheight * -0.37 );
1281  Text->SetLineSpacing( 0 );
1282 
1283  if ( !ReadItem( wxT( "string" ) ) )
1284  throw GDS_Error( wxT( "Text: STRING is missing (in KEY-file)" ) );
1285 
1286  Text->SetText( m_value );
1287 
1288  if ( m_doc->GetLayerSetup()->GetRead( Text->GetLayer() ) )
1289  parent->Append( Text );
1290 
1291  return true;
1292 }
1293 
1294 
1295 // StructureReference -------------------------------------------------------
1296 bool a2dIOHandlerKeyIn::ReadStructureReference( a2dCanvasObject* parent )
1297 {
1298 // <SREF> ::= SREF [ELFLAGS] [PLEX] SNAME
1299 // [<strans>] XY
1300 // <strans> ::= STRANS [MAG] [ANGLE]
1301 
1302  if ( m_asCameleons )
1303  return ReadStructureCameleonReference( parent );
1304 
1305 
1306  if ( !ReadItem( wxT( "sref" ) ) )
1307  return false;
1308 
1309  a2dPoint2D point;
1310  a2dAffineMatrix relative_matrix;
1312  try
1313  {
1314  ReadElflags( sref );
1315  ReadItem( wxT( "plex" ) );
1316 
1317  if ( !ReadItem( wxT( "sname" ) ) )
1318  throw GDS_Error( wxT( "Sref: SNAME is missing (in KEY-file)" ) );
1319  sref->SetName( m_value );
1320  //wxLogDebug(wxT("structure reference= %s"), m_value.c_str() );
1321 
1322  Strans strans;
1323  ReadStrans( strans );
1324 
1325  if ( !ReadItem( wxT( "xy" ) ) )
1326  throw GDS_Error( wxT( "Sref: XY is missing (in Structure Reference)" ) );
1327 
1328  Read( point );
1329 
1330  // Ok, now we have a strans, but we want to work with a matrix,
1331  // so let's convert it to one:
1332 
1333  // Mirror in X if necessary
1334  if ( strans.GetReflection() )
1335  relative_matrix.Mirror();
1336 
1337  // Rotate if necessary
1338  if ( strans.GetAbsAngle() == 0 )
1339  relative_matrix.Rotate( strans.GetAngle(), 0, 0 );
1340 
1341  // Scale if necessary
1342  if ( strans.GetAbsScale() == 0 )
1343  {
1344  double scale = strans.GetScale();
1345  relative_matrix.Scale( scale, scale, 0, 0 );
1346  }
1347 
1348  // Translate2D over XY from the structure reference
1349  relative_matrix.Translate( point.m_x, point.m_y );
1350 
1351  sref->SetTransformMatrix( relative_matrix );
1352 
1353  parent->Append( sref );
1354  ResolveOrAddLink( sref.Get(), sref->GetName() );
1355  }
1356  catch ( GDS_Error& _error )
1357  {
1358  throw _error;
1359  }
1360 
1361  return true;
1362 }
1363 
1364 // StructureReference -------------------------------------------------------
1365 bool a2dIOHandlerKeyIn::ReadStructureCameleonReference( a2dCanvasObject* parent )
1366 {
1367 // <SREF> ::= SREF [ELFLAGS] [PLEX] SNAME
1368 // [<strans>] XY
1369 // <strans> ::= STRANS [MAG] [ANGLE]
1370 
1371 
1372  if ( !ReadItem( wxT( "sref" ) ) )
1373  return false;
1374 
1375  a2dPoint2D point;
1376  a2dAffineMatrix relative_matrix;
1378  try
1379  {
1380  ReadElflags( sref );
1381  ReadItem( wxT( "plex" ) );
1382 
1383  if ( !ReadItem( wxT( "sname" ) ) )
1384  throw GDS_Error( wxT( "Sref: SNAME is missing (in KEY-file)" ) );
1385  sref->SetAppearanceName( m_value + wxT(":layout") );
1386 
1387  sref->SetName( m_value );
1388  //wxLogDebug(wxT("structure reference= %s"), m_value.c_str() );
1389 
1390  Strans strans;
1391  ReadStrans( strans );
1392 
1393  if ( !ReadItem( wxT( "xy" ) ) )
1394  throw GDS_Error( wxT( "Sref: XY is missing (in Structure Reference)" ) );
1395 
1396  Read( point );
1397 
1398  // Ok, now we have a strans, but we want to work with a matrix,
1399  // so let's convert it to one:
1400 
1401  // Mirror in X if necessary
1402  if ( strans.GetReflection() )
1403  relative_matrix.Mirror();
1404 
1405  // Rotate if necessary
1406  if ( strans.GetAbsAngle() == 0 )
1407  relative_matrix.Rotate( strans.GetAngle(), 0, 0 );
1408 
1409  // Scale if necessary
1410  if ( strans.GetAbsScale() == 0 )
1411  {
1412  double scale = strans.GetScale();
1413  relative_matrix.Scale( scale, scale, 0, 0 );
1414  }
1415 
1416  // Translate2D over XY from the structure reference
1417  relative_matrix.Translate( point.m_x, point.m_y );
1418 
1419  sref->SetTransformMatrix( relative_matrix );
1420 
1421  parent->Append( sref );
1422  ResolveOrAddLink( sref.Get(), sref->GetName() );
1423  }
1424  catch ( GDS_Error& _error )
1425  {
1426  throw _error;
1427  }
1428 
1429  return true;
1430 }
1431 
1432 // Arrayreference -----------------------------------------------------------
1433 bool a2dIOHandlerKeyIn::ReadArrayReference( a2dCanvasObject* parent )
1434 {
1435  // Grammar: AREF [ELFLAGS] [PLEX] SNAME [<strans>]
1436  // COLROW XY
1437 
1438  if ( !ReadItem( wxT( "aref" ) ) )
1439  return false;
1440 
1441  a2dPoint2D Point;
1442  a2dAffineMatrix relative_matrix;
1443  a2dPoint2D HorPoint;
1444  a2dPoint2D VerPoint;
1445 
1446  // Create a new Aref
1448  try
1449  {
1450  ReadElflags( arrayref );
1451 
1452  ReadItem( wxT( "plex" ) );
1453 
1454  if ( !ReadItem( wxT( "sname" ) ) )
1455  throw GDS_Error( wxT( "Aref: SNAME missing (in Structure Reference)" ) );
1456 
1457  arrayref->SetName( m_value );
1458  //wxLogDebug(wxT("structure reference= %s"), m_value.c_str() );
1459 
1460  Strans strans;
1461  ReadStrans( strans );
1462 
1463  if ( !ReadItem( wxT( "colrow" ) ) )
1464  throw GDS_Error( wxT( "Aref: COLROW is missing (in Array Reference)" ) );
1465 
1466  wxString _int_str_ptr = m_value;
1467  arrayref->SetColumns( wxAtoi( _int_str_ptr ) );
1468  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "," ) ) + 1;
1469  arrayref->SetRows( wxAtoi( _int_str_ptr ) );
1470 
1471  if ( !ReadItem( wxT( "xy" ) ) )
1472  throw GDS_Error( wxT( "Aref: XY missing (in Array Reference)" ) );
1473 
1474  Read( Point );
1475  Read( HorPoint );
1476  Read( VerPoint );
1477 
1478  arrayref->SetHorzSpace( sqrt( pow( HorPoint.m_x - Point.m_x, 2 ) + pow( HorPoint.m_y - Point.m_y, 2 ) ) / arrayref->GetColumns() );
1479  arrayref->SetVertSpace( sqrt( pow( VerPoint.m_x - Point.m_x, 2 ) + pow( VerPoint.m_y - Point.m_y, 2 ) ) / arrayref->GetRows() );
1480 
1481  // Ok, now we have a strans, but we want to work with a matrix,
1482  // so let's convert it to one:
1483 
1484  // Mirror in X if necessary
1485  if ( strans.GetReflection() )
1486  relative_matrix.Mirror();
1487 
1488  // Rotate if necessary
1489  if ( strans.GetAbsAngle() == 0 )
1490  relative_matrix.Rotate( strans.GetAngle(), 0, 0 );
1491 
1492  // Scale if necessary
1493  if ( strans.GetAbsScale() == 0 )
1494  {
1495  EIGHT_G_BYTE_REAL scale = strans.GetScale();
1496  relative_matrix.Scale( scale, scale, 0, 0 );
1497  }
1498 
1499  // Translate2D over XY from the structurereference
1500  relative_matrix.Translate( Point.m_x, Point.m_y );
1501  arrayref->SetTransformMatrix( relative_matrix );
1502 
1503  parent->Append( arrayref );
1504  ResolveOrAddLink( arrayref.Get(), arrayref->GetName() );
1505  }
1506  catch ( GDS_Error& _error )
1507  {
1508  throw _error;
1509  }
1510 
1511  return true;
1512 }
1513 
1514 
1515 bool a2dIOHandlerKeyIn::ReadNode( a2dCanvasObject* WXUNUSED( parent ) )
1516 {
1517 // <node> ::= NODE [ELFLAGS] [PLEX] LAYER NODETYPE [WIDTH] XY
1518 
1519  // not implemented
1520  if ( ReadItem( wxT( "node" ) ) )
1521  throw GDS_Error( wxT( "Node: NODE not implemented yet! (in KEY-file)" ) );
1522  return false;
1523 }
1524 
1525 
1526 // Box ----------------------------------------------------------------------
1527 bool a2dIOHandlerKeyIn::ReadBox( a2dCanvasObject* parent )
1528 {
1529 // <box> ::= BOX [ELFLAGS] [PLEX] LAYER BOXTYPE [WIDTH] XY
1530 
1531  if ( !ReadItem( wxT( "box" ) ) )
1532  return false;
1533 
1534  // Create a new Boundary
1535  a2dSmrtPtr<class a2dRect> Box = new a2dRect();
1536 
1537  // Optional
1538  ReadElflags( Box );
1539  ReadItem( wxT( "plex" ) );
1540 
1541  // Must be there
1542  if ( !ReadLayer( Box ) )
1543  throw GDS_Error( wxT( "Box: LAYER is missing (in KEY-file)" ) );
1544 
1545  if ( !ReadItem( wxT( "boxtype" ) ) )
1546  throw GDS_Error( wxT( "Box: boxtype is missing (in KEY-file)" ) );
1547  Box->SetBoxType( wxAtoi( m_value ) );
1548 
1549  if ( ReadItem( wxT( "width" ) ) )
1550  Box->SetContourWidth( ReadDouble() );
1551 
1552  if ( !ReadItem( wxT( "xy" ) ) )
1553  return false;
1554 
1555  int points = wxAtoi( m_value );
1556 
1557  if ( points != 5 )
1558  throw GDS_Error( wxT( "Wrong number of points in BOX XY." ), wxT( "Fatal GDSII error" ) );
1559 
1560 
1561  a2dPoint2D seg;
1562  Read( seg );
1563  a2dPoint2D seg2;
1564  Read( seg2 );
1565  a2dPoint2D seg3;
1566  Read( seg3 );
1567  a2dPoint2D seg4;
1568  Read( seg4 );
1569  a2dPoint2D seg5;
1570  Read( seg5 ); // Last point matches first one read
1571 
1572  double minx, miny, maxx, maxy;
1573 
1574  minx = maxx = seg.m_x;
1575  miny = maxy = seg.m_y;
1576 
1577  minx = wxMin( minx, seg2.m_x );
1578  maxx = wxMax( maxx, seg2.m_x );
1579  miny = wxMin( miny, seg2.m_y );
1580  maxy = wxMax( maxy, seg2.m_y );
1581 
1582  minx = wxMin( minx, seg3.m_x );
1583  maxx = wxMax( maxx, seg3.m_x );
1584  miny = wxMin( miny, seg3.m_y );
1585  maxy = wxMax( maxy, seg3.m_y );
1586 
1587  minx = wxMin( minx, seg4.m_x );
1588  maxx = wxMax( maxx, seg4.m_x );
1589  miny = wxMin( miny, seg4.m_y );
1590  maxy = wxMax( maxy, seg4.m_y );
1591 
1592  Box->SetWidth( fabs( maxx - minx ) );
1593  Box->SetHeight( fabs( maxy - miny ) );
1594  Box->SetPosXY( minx, miny );
1595 
1596  if ( m_doc->GetLayerSetup()->GetRead( Box->GetLayer() ) )
1597  parent->Append( Box );
1598 
1599  return true;
1600 }
1601 
1602 bool a2dIOHandlerKeyIn::ReadLine( a2dCanvasObject* parent )
1603 {
1604  if ( !ReadItem( wxT( "line" ) ) )
1605  return false;
1606 
1607  a2dSmrtPtr<class a2dSLine> line = new a2dSLine();
1608 
1609  // Optional
1610  ReadElflags( line );
1611  ReadItem( wxT( "plex" ) );
1612 
1613  // Must be there
1614  if ( !ReadLayer( line ) )
1615  throw GDS_Error( wxT( "Line: LAYER is missing (in KEY-file)" ) );
1616 
1617  if ( ReadItem( wxT( "width" ) ) )
1618  line->SetContourWidth( ReadDouble() );
1619 
1620  if ( !ReadItem( wxT( "xy" ) ) )
1621  return false;
1622 
1623  a2dPoint2D p1;
1624  Read( p1 );
1625  a2dPoint2D p2;
1626  Read( p2 );
1627  line->SetPosXY12( p1.m_x, p1.m_y, p2.m_x, p2.m_y );
1628 
1629  if ( m_doc->GetLayerSetup()->GetRead( line->GetLayer() ) )
1630  parent->Append( line );
1631 
1632  return true;
1633 }
1634 
1635 bool a2dIOHandlerKeyIn::ReadImage( a2dCanvasObject* parent )
1636 {
1637  if ( !ReadItem( wxT( "image" ) ) )
1638  return false;
1639 
1640  a2dSmrtPtr<class a2dImage> image = new a2dImage();
1641 
1642  // Optional
1643  ReadElflags( image );
1644  ReadItem( wxT( "plex" ) );
1645 
1646  // Must be there
1647  if ( !ReadLayer( image ) )
1648  throw GDS_Error( wxT( "Line: LAYER is missing (in KEY-file)" ) );
1649 
1650  ReadItem( wxT( "width" ) );
1651 
1652  if ( ReadItem( wxT( "w" ) ) )
1653  image->SetWidth( ReadDouble() * m_userunits_out );
1654 
1655  if ( ReadItem( wxT( "h" ) ) )
1656  image->SetHeight( ReadDouble() * m_userunits_out );
1657 
1658  wxBitmapType type = wxBITMAP_TYPE_INVALID;
1659  if ( ReadItem( wxT( "type" ) ) )
1660  {
1661  if ( m_value.CmpNoCase( wxT( "gif" ) ) == 0 )
1662  type = wxBITMAP_TYPE_GIF;
1663  else if ( m_value.CmpNoCase( wxT( "png" ) ) == 0 )
1664  type = wxBITMAP_TYPE_PNG;
1665  else if ( m_value.CmpNoCase( wxT( "bmp" ) ) == 0 )
1666  type = wxBITMAP_TYPE_BMP;
1667  else if ( m_value.CmpNoCase( wxT( "jpeg" ) ) == 0 )
1668  type = wxBITMAP_TYPE_JPEG;
1669  else
1670  throw GDS_Error( wxT( "Image: not supported type" ) );
1671  }
1672 
1673  if ( ReadItem( wxT( "path" ) ) )
1674  image->SetFilename( m_value, type, true );
1675 
1676 
1677  a2dPoint2D point;
1678  a2dAffineMatrix relative_matrix;
1679  Strans strans;
1680  ReadStrans( strans );
1681 
1682  if ( !ReadItem( wxT( "xy" ) ) )
1683  throw GDS_Error( wxT( "Sref: XY is missing (in Structure Reference)" ) );
1684 
1685  Read( point );
1686 
1687  // Ok, now we have a strans, but we want to work with a matrix,
1688  // so let's convert it to one:
1689 
1690  // Mirror in X if necessary
1691  if ( strans.GetReflection() )
1692  relative_matrix.Mirror();
1693 
1694  // Rotate if necessary
1695  if ( strans.GetAbsAngle() == 0 )
1696  relative_matrix.Rotate( strans.GetAngle(), 0, 0 );
1697 
1698  // Scale if necessary
1699  if ( strans.GetAbsScale() == 0 )
1700  {
1701  double scale = strans.GetScale();
1702  relative_matrix.Scale( scale, scale, 0, 0 );
1703  }
1704 
1705  // Translate2D over XY from the structure reference
1706  relative_matrix.Translate( point.m_x, point.m_y );
1707 
1708  image->SetTransformMatrix( relative_matrix );
1709 
1710  if ( m_doc->GetLayerSetup()->GetRead( image->GetLayer() ) )
1711  parent->Append( image );
1712 
1713  return true;
1714 }
1715 
1716 // Elflags ------------------------------------------------------------------
1717 bool a2dIOHandlerKeyIn::ReadElflags( a2dCanvasObject* object )
1718 {
1719  if ( !ReadItem( wxT( "elflags" ) ) )
1720  return false;
1721 
1722  object->SetTemplate( ( bool )( wxAtoi( m_value ) && 1 ) );
1723  object->SetExternal( ( bool )( wxAtoi( m_value ) && 2 ) );
1724 
1725  return true;
1726 }
1727 
1728 // Layer --------------------------------------------------------------------
1729 bool a2dIOHandlerKeyIn::ReadLayer( a2dCanvasObject* object )
1730 {
1731  if ( !ReadItem( wxT( "layer" ) ) )
1732  return false;
1733 
1734  m_lastElementLayer = wxAtoi( m_value );
1735  object->SetLayer( m_mapping[ m_lastElementLayer ] );
1736  return true;
1737 }
1738 
1739 // Point --------------------------------------------------------------------
1740 bool a2dIOHandlerKeyIn::Read( a2dPoint2D& Point )
1741 {
1742  if ( !ReadItem( wxT( "x" ) ) )
1743  throw GDS_Error( wxT( "Point: X is missing (in KEY-file)" ) );
1744  Point.m_x = ReadDouble();
1745  if ( !ReadItem( wxT( "y" ) ) )
1746  throw GDS_Error( wxT( "Point: Y is missing (in KEY-file)" ) );
1747  Point.m_y = ReadDouble();
1748  return true;
1749 }
1750 
1751 // Strans -------------------------------------------------------------------
1752 bool a2dIOHandlerKeyIn::ReadStrans( Strans& Strans )
1753 {
1754 // <strans> ::= STRANS [MAG] [ANGLE]
1755  if ( !ReadItem( wxT( "strans" ) ) )
1756  return false;
1757 
1758  wxString _int_str_ptr = m_value;
1759 
1760  Strans.m_stransflags.bits.reflection = wxAtoi( _int_str_ptr );
1761  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "," ) ) + 1;
1762  Strans.m_stransflags.bits.abs_angle = wxAtoi( _int_str_ptr );
1763  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "," ) ) + 1;
1764  Strans.m_stransflags.bits.abs_scale = wxAtoi( _int_str_ptr );
1765 
1766  if ( ReadItem( wxT( "mag" ) ) )
1767  Strans.SetScale( ReadDouble() );
1768 
1769  if ( ReadItem( wxT( "angle" ) ) )
1770  Strans.SetAngle( ReadDouble() );
1771 
1772  return true;
1773 }
1774 
1775 // Structure ----------------------------------------------------------------
1776 bool a2dIOHandlerKeyIn::ReadStructure( a2dCanvasObject* parent )
1777 {
1778  // Grammar: BGNSTR STRNAME [STRCLASS] {<element>}*
1779  // ENDSTR
1780 
1781  if( !ReadItem( wxT( "bgnstr" ) ) ) // BgnStr expected here
1782  return false;
1783 
1784  if( !ReadItem( wxT( "creation" ) ) )
1785  throw GDS_Error( wxT( "Structure: CREATION is missing (in KEY-file)" ) );
1786 
1787  wxString _int_str_ptr = m_value;
1788 
1790  //structures contains object on layers, but is itself just an abstract object without layer
1791  Structure->SetIgnoreLayer( true );
1792 
1793  //TODO store as property on current object????
1794  wxDateTime m_modificationtime = wxDateTime::Now();
1795  wxDateTime m_accesstime = wxDateTime::Now();
1796 
1797  int year;
1798  int month;
1799  int day;
1800  int hour;
1801  int minute;
1802  int second;
1803 
1804  year = wxAtoi( _int_str_ptr );
1805  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
1806  month = wxAtoi( _int_str_ptr ) - 1;
1807  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
1808  day = wxAtoi( _int_str_ptr );
1809  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( " " ) ) + 2;
1810  hour = wxAtoi( _int_str_ptr );
1811  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
1812  minute = wxAtoi( _int_str_ptr );
1813  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
1814  second = wxAtoi( _int_str_ptr );
1815 
1816  m_modificationtime.Set( day, ( wxDateTime::Month )month, year, hour, minute, second );
1817  a2dCanvasObject::PROPID_ModificationDateTime->SetPropertyToObject( Structure, m_modificationtime );
1818 
1819  if( !ReadItem( wxT( "lastmod" ) ) )
1820  throw GDS_Error( wxT( "Structure: LASTACC is missing (in KEY-file)" ) );
1821 
1822  _int_str_ptr = m_value;
1823 
1824  year = wxAtoi( _int_str_ptr );
1825  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
1826  month = wxAtoi( _int_str_ptr ) - 1;
1827  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
1828  day = wxAtoi( _int_str_ptr );
1829  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( " " ) ) + 2;
1830  hour = wxAtoi( _int_str_ptr );
1831  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
1832  minute = wxAtoi( _int_str_ptr );
1833  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
1834  second = wxAtoi( _int_str_ptr );
1835 
1836  m_accesstime.Set( day, ( wxDateTime::Month )month, year, hour, minute, second );
1837  a2dCanvasObject::PROPID_AccessDateTime->SetPropertyToObject( Structure, m_accesstime );
1838 
1839  if ( !ReadItem( wxT( "strname" ) ) )
1840  throw GDS_Error( wxT( "Structure: STRNAME missing (in KEY-file)" ) );
1841 
1842  Structure->SetName( m_value );
1843 
1844  ReadItem( wxT( "strclass" ) ); // Just read it
1845 
1846  while ( ReadParameters( Structure ) );
1847 
1848  while ( ReadElement( Structure ) )
1849  ;
1850 
1851  //wxLogDebug(wxT("structure = %s"), Structure->GetName().c_str() );
1852 
1853  if ( !ReadItem( wxT( "endstr" ) ) )
1854  {
1855  wxString errbuf;
1856  errbuf.Printf( wxT( "Unknown Element: %s (in KEY-file)" ), m_keyword.c_str() );
1857  throw GDS_Error( errbuf );
1858  }
1859 
1860  parent->Append( Structure );
1861  // this one needs to be resolved later
1862  GetObjectHashMap()[ Structure->GetName() ] = Structure;
1863  //wxLogDebug(wxT("structure= %s"), strucname.c_str() );
1864 
1865  return true;
1866 }
1867 
1868 // Structure ----------------------------------------------------------------
1869 bool a2dIOHandlerKeyIn::ReadCameleonStructure( a2dCanvasObject* parent )
1870 {
1871  // Grammar: BGNSTR STRNAME [STRCLASS] {<element>}*
1872  // ENDSTR
1873 
1874  if( !ReadItem( wxT( "bgnstr" ) ) ) // BgnStr expected here
1875  return false;
1876 
1877  if( !ReadItem( wxT( "creation" ) ) )
1878  throw GDS_Error( wxT( "Structure: CREATION is missing (in KEY-file)" ) );
1879 
1880  wxString _int_str_ptr = m_value;
1881 
1883  a2dLayout* layout = new a2dLayout( cam, 0,0 );
1884  cam->AddAppearance( layout );
1885  a2dSmrtPtr<a2dDrawing> Structure = layout->GetDrawing();
1886  Structure->SetLayerSetup( m_doc->GetLayerSetup() );
1887 
1888  //TODO store as property on current object????
1889  wxDateTime m_modificationtime = wxDateTime::Now();
1890  wxDateTime m_accesstime = wxDateTime::Now();
1891 
1892  int year;
1893  int month;
1894  int day;
1895  int hour;
1896  int minute;
1897  int second;
1898 
1899  year = wxAtoi( _int_str_ptr );
1900  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
1901  month = wxAtoi( _int_str_ptr ) - 1;
1902  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
1903  day = wxAtoi( _int_str_ptr );
1904  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( " " ) ) + 2;
1905  hour = wxAtoi( _int_str_ptr );
1906  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
1907  minute = wxAtoi( _int_str_ptr );
1908  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
1909  second = wxAtoi( _int_str_ptr );
1910 
1911  m_modificationtime.Set( day, ( wxDateTime::Month )month, year, hour, minute, second );
1912  a2dCanvasObject::PROPID_ModificationDateTime->SetPropertyToObject( Structure, m_modificationtime );
1913 
1914  if( !ReadItem( wxT( "lastmod" ) ) )
1915  throw GDS_Error( wxT( "Structure: LASTACC is missing (in KEY-file)" ) );
1916 
1917  _int_str_ptr = m_value;
1918 
1919  year = wxAtoi( _int_str_ptr );
1920  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
1921  month = wxAtoi( _int_str_ptr ) - 1;
1922  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( "-" ) ) + 1;
1923  day = wxAtoi( _int_str_ptr );
1924  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( " " ) ) + 2;
1925  hour = wxAtoi( _int_str_ptr );
1926  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
1927  minute = wxAtoi( _int_str_ptr );
1928  _int_str_ptr = wxStrstr( _int_str_ptr, wxT( ":" ) ) + 1;
1929  second = wxAtoi( _int_str_ptr );
1930 
1931  m_accesstime.Set( day, ( wxDateTime::Month )month, year, hour, minute, second );
1932  a2dCanvasObject::PROPID_AccessDateTime->SetPropertyToObject( Structure, m_accesstime );
1933 
1934  if ( !ReadItem( wxT( "strname" ) ) )
1935  throw GDS_Error( wxT( "Structure: STRNAME missing (in KEY-file)" ) );
1936 
1937  cam->SetName( m_value );
1938  layout->SetName( m_value + wxT(":layout") );
1939 
1940  ReadItem( wxT( "strclass" ) ); // Just read it
1941 
1942  while ( ReadParameters( Structure->GetRootObject() ) );
1943 
1944  while ( ReadElement( Structure->GetRootObject() ) )
1945  ;
1946 
1947  //wxLogDebug(wxT("structure = %s"), Structure->GetName().c_str() );
1948 
1949  if ( !ReadItem( wxT( "endstr" ) ) )
1950  {
1951  wxString errbuf;
1952  errbuf.Printf( wxT( "Unknown Element: %s (in KEY-file)" ), m_keyword.c_str() );
1953  throw GDS_Error( errbuf );
1954  }
1955 
1956  cam->AddToRoot();
1957  int px = m_dx * 30 * 1.5;
1958  int py = -m_dy * 10 * 1.5;
1959  cam->SetPosXY( px, py );
1960  m_dx++;
1961  if ( m_dx > m_refMaxx )
1962  { m_dy++; m_dx =0; }
1963 
1964  // this one needs to be resolved later
1965  GetObjectHashMap()[ Structure->GetName() ] = cam;
1966  //wxLogDebug(wxT("structure= %s"), strucname.c_str() );
1967 
1968  return true;
1969 }
1970 
1971 // Circle -----------------------------------------------------------------
1972 bool a2dIOHandlerKeyIn::ReadCircle( a2dCanvasObject* parent )
1973 {
1974 // <circle> ::= CIRCLE [ELFLAGS] [PLEX] LAYER [WIDTH] XY
1975 
1976  if ( !ReadItem( wxT( "circle" ) ) )
1977  return false;
1978 
1979  a2dSmrtPtr<class a2dCircle> circle = new a2dCircle();
1980 
1981  // Optional
1982  ReadElflags( circle );
1983  ReadItem( wxT( "plex" ) );
1984  // Must be there
1985  if ( !ReadLayer( circle ) )
1986  throw GDS_Error( wxT( "Circle: LAYER is missing (in KEY-file)" ) );
1987 
1988  if ( ReadItem( wxT( "datatype" ) ) )
1989  SetDataTypeProperty( circle, wxAtoi( m_value ) );
1990 
1991  if ( ReadItem( wxT( "width" ) ) )
1992  circle->SetContourWidth( ReadDouble() );
1993 
1994  if ( !ReadItem( wxT( "xy" ) ) )
1995  throw GDS_Error( wxT( "Circle: XY is missing (in KEY-file)" ) );
1996 
1997  a2dPoint2D point;
1998  Read( point );
1999  circle->SetPosXY( point.m_x, point.m_y );
2000  if ( !ReadItem( wxT( "radius" ) ) )
2001  throw GDS_Error( wxT( "Circle: RADIUS is missing (in KEY-file)" ) );
2002  circle->SetRadius( ReadDouble() );
2003 
2004  if ( m_doc->GetLayerSetup()->GetRead( circle->GetLayer() ) )
2005  parent->Append( circle );
2006 
2007  return true;
2008 }
2009 
2010 bool a2dIOHandlerKeyIn::ReadArc( a2dCanvasObject* parent )
2011 {
2012 // <arc> ::= ARC [ELFLAGS] [PLEX] LAYER [WIDTH] XY
2013 
2014  if ( !ReadItem( wxT( "arc" ) ) )
2015  return false;
2016 
2017  a2dSmrtPtr<class a2dArc> arc = new a2dArc();
2018  //no NON chords in KEY
2019  arc->SetChord( true );
2020 
2021  // Optional
2022  ReadElflags( arc );
2023  ReadItem( wxT( "plex" ) );
2024  // Must be there
2025  if ( !ReadLayer( arc ) )
2026  throw GDS_Error( wxT( "Arc: LAYER is missing (in KEY-file)" ) );
2027 
2028  if ( ReadItem( wxT( "datatype" ) ) )
2029  SetDataTypeProperty( arc, wxAtoi( m_value ) );
2030 
2031  if ( ReadItem( wxT( "width" ) ) )
2032  arc->SetContourWidth( ReadDouble() );
2033 
2034  if ( m_doc->GetLayerSetup()->GetRead( arc->GetLayer() ) )
2035  {
2036  if ( !ReadItem( wxT( "xy" ) ) )
2037  throw GDS_Error( wxT( "Polyline: XY is missing (in KEY-file)" ) );
2038 
2039  double xs, ys, xe, ye, xm, ym;
2040  xm = ym = 0.0;
2041 
2042  if ( !ReadItem( wxT( "x" ) ) ) //read x
2043  throw GDS_Error( wxT( "Polygon: X is missing (in KEY-file)" ) );
2044 
2045  xs = ReadDouble();
2046 
2047  if ( !ReadItem( wxT( "y" ) ) ) //read y
2048  throw GDS_Error( wxT( "Polygon: Y is missing (in KEY-file)" ) );
2049 
2050  ys = ReadDouble();
2051 
2052  // Read XM or X
2053  if ( ReadItem( wxT( "xm" ) ) ) //an arc segment is coming
2054  {
2055  xm = ReadDouble();
2056  if ( !ReadItem( wxT( "ym" ) ) ) //read ym of arc
2057  throw GDS_Error( wxT( "Polygon: YM is missing (in KEY-file)" ) );
2058  ym = ReadDouble();
2059 
2060  double xo, yo;
2061  if ( !ReadItem( wxT( "xo" ) ) ) //read xo of arc
2062  throw GDS_Error( wxT( "Polygon: XO is missing (in KEY-file)" ) );
2063  xo = ReadDouble();
2064 
2065  if ( !ReadItem( wxT( "yo" ) ) ) //read yo of arc
2066  throw GDS_Error( wxT( "Polygon: YO is missing (in KEY-file)" ) );
2067  yo = ReadDouble();
2068  }
2069 
2070  if ( !ReadItem( wxT( "x" ) ) ) //read x
2071  throw GDS_Error( wxT( "Polygon: X is missing (in KEY-file)" ) );
2072  xe = ReadDouble();
2073 
2074  if ( !ReadItem( wxT( "y" ) ) ) //read y
2075  throw GDS_Error( wxT( "Polygon: Y is missing (in KEY-file)" ) );
2076  ye = ReadDouble();
2077 
2078  arc->Set( xs, ys, xm, ym, xe, ye );
2079 
2080  if ( m_doc->GetLayerSetup()->GetRead( arc->GetLayer() ) )
2081  parent->Append( arc );
2082  }
2083  else
2084  {
2085  SkipXYData();
2086  }
2087  return true;
2088 }
2089 
2090 bool a2dIOHandlerKeyIn::ReadPolygon( a2dVertexList* poly )
2091 {
2092  if ( !ReadItem( wxT( "xy" ) ) )
2093  return false;
2094 
2095  int j = wxAtoi( m_value );
2096  int i;
2097 
2098  double x, y, xp, yp, xm, ym, xo, yo;
2099  a2dSegType tprev;
2100  bool lastWasArc = false;
2101  bool firstRead = false;
2102 
2103  for ( i = 0; i < j - 1; i++ )
2104  {
2106  if ( ReadItem( wxT( "st" ) ) ) //read segtype
2107  {
2108  if ( m_value.CmpNoCase( wxT( "N" ) ) == 0 )
2109  t = a2dNORMAL_SEG;
2110  else if ( m_value.CmpNoCase( wxT( "H" ) ) == 0 )
2111  {
2112  t = a2dHOLE_SEG;
2113  }
2114  else if ( m_value.CmpNoCase( wxT( "L" ) ) == 0 )
2115  t = a2dLINK_SEG;
2116  }
2117 
2118  if ( !ReadItem( wxT( "x" ) ) ) //read x
2119  throw GDS_Error( wxT( "Polygon: X is missing (in KEY-file)" ) );
2120 
2121  x = ReadDouble();
2122 
2123  if ( !ReadItem( wxT( "y" ) ) ) //read y
2124  throw GDS_Error( wxT( "Polygon: Y is missing (in KEY-file)" ) );
2125 
2126  y = ReadDouble();
2127 
2128  if ( firstRead )
2129  {
2130  if ( lastWasArc )
2131  {
2132  lastWasArc = false;
2133 
2134  a2dArcSegment* sega = new a2dArcSegment();
2135  sega->m_x = x;
2136  sega->m_y = y;
2137  sega->m_x2 = xm;
2138  sega->m_y2 = ym;
2139  sega->SetSegType( tprev );
2140  poly->push_back( sega );
2141  }
2142  else
2143  {
2144  a2dLineSegment* seg = new a2dLineSegment();
2145  seg->m_x = x;
2146  seg->m_y = y;
2147  seg->SetSegType( tprev );
2148  poly->push_back( seg );
2149  }
2150  }
2151  else
2152  {
2153  a2dLineSegment* seg = new a2dLineSegment();
2154  seg->m_x = x;
2155  seg->m_y = y;
2156  poly->push_back( seg );
2157 
2158  firstRead = true;
2159  }
2160 
2161  // Read XM or X
2162  if ( ReadItem( wxT( "xm" ) ) ) //an arc segment is coming towards next point
2163  {
2164  lastWasArc = true;
2165 
2166  xp = x;
2167  yp = y;
2168  xm = ReadDouble();
2169 
2170  if ( !ReadItem( wxT( "ym" ) ) ) //read ym of arc
2171  throw GDS_Error( wxT( "Polygon: YM is missing (in KEY-file)" ) );
2172  ym = ReadDouble();
2173 
2174  if ( !ReadItem( wxT( "xo" ) ) ) //read xo of arc
2175  throw GDS_Error( wxT( "Polygon: XO is missing (in KEY-file)" ) );
2176  xo = ReadDouble();
2177 
2178  if ( !ReadItem( wxT( "yo" ) ) ) //read yo of arc
2179  throw GDS_Error( wxT( "Polygon: YO is missing (in KEY-file)" ) );
2180  yo = ReadDouble();
2181  tprev = t;
2182  }
2183  else if ( !m_keyword.CmpNoCase( wxT( "endel" ) ) || !m_keyword.CmpNoCase( wxT( "x" ) ) || !m_keyword.CmpNoCase( wxT( "st" ) ) ) // Read is already done
2184  {
2185  xp = x;
2186  yp = y;
2187  tprev = t;
2188  }
2189  else
2190  throw GDS_Error( wxT( "Polygon: X or XM missing (in KEY-file)" ) );
2191  }
2192 
2193  //last POINT must be eqaul first.
2194 
2195  if ( !ReadItem( wxT( "x" ) ) ) //read x
2196  throw GDS_Error( wxT( "Polygon: X is missing (in KEY-file)" ) );
2197 
2198  x = ReadDouble();
2199 
2200  if ( !ReadItem( wxT( "y" ) ) ) //read y
2201  throw GDS_Error( wxT( "Polygon: Y is missing (in KEY-file)" ) );
2202 
2203  y = ReadDouble();
2204 
2205  if ( ReadItem( wxT( "xm" ) ) ) //last point may not be arc
2206  throw GDS_Error( wxT( "Polygon: expected ENDEL found XM (in KEY-file)" ) );
2207 
2208  // if previous segment was an arc, the closing point (being eqaul to the start),
2209  // defines the end of the arc.
2210  if ( lastWasArc )
2211  {
2212  lastWasArc = false;
2213 
2214  a2dArcSegment* sega = new a2dArcSegment();
2215  sega->m_x = x;
2216  sega->m_y = y;
2217  sega->m_x2 = xm;
2218  sega->m_y2 = ym;
2219  poly->push_back( sega );
2220  }
2221  /*
2222  else //don't need it, is same as first point
2223  {
2224  a2dLineSegment* seg = new a2dLineSegment();
2225  seg->m_x = x;
2226  seg->m_y = y;
2227  poly->push_back(seg);
2228  }
2229  */
2230  return true;
2231 }
2232 
2233 bool a2dIOHandlerKeyIn::ReadPolyline( a2dVertexList* poly )
2234 {
2235  if ( !ReadItem( wxT( "xy" ) ) )
2236  throw GDS_Error( wxT( "Polyline: XY is missing (in KEY-file)" ) );
2237 
2238  int j = wxAtoi( m_value );
2239  int i;
2240  double x, y, xp, yp, xm, ym, xo, yo;
2241  bool lastWasArc = false;
2242  bool firstRead = false;
2243 
2244  for ( i = 0; i < j; i++ )
2245  {
2246  if ( !ReadItem( wxT( "x" ) ) ) //read x
2247  throw GDS_Error( wxT( "Polyline: X is missing (in KEY-file)" ) );
2248  x = ReadDouble();
2249 
2250  if ( !ReadItem( wxT( "y" ) ) ) //read y
2251  throw GDS_Error( wxT( "Polyline: Y is missing (in KEY-file)" ) );
2252  y = ReadDouble();
2253 
2254  if ( firstRead )
2255  {
2256  if ( lastWasArc )
2257  {
2258  lastWasArc = false;
2259 
2260  a2dArcSegment* sega = new a2dArcSegment();
2261  sega->m_x = x; //current segment
2262  sega->m_y = y;
2263  sega->m_x2 = xm; //as stored when read from the previous segment in the key file
2264  sega->m_y2 = ym;
2265  poly->push_back( sega );
2266  }
2267  else
2268  {
2269  a2dLineSegment* seg = new a2dLineSegment();
2270  seg->m_x = x;
2271  seg->m_y = y;
2272  poly->push_back( seg );
2273  }
2274  }
2275  else
2276  {
2277  // even if Arc, we will store that info at the next segment.
2278  a2dLineSegment* seg = new a2dLineSegment();
2279  seg->m_x = x;
2280  seg->m_y = y;
2281  poly->push_back( seg );
2282 
2283  firstRead = true;
2284  }
2285 
2286  // Read XM or X
2287  if ( ReadItem( wxT( "xm" ) ) ) //an arc segment is coming towards next point
2288  {
2289  // arcs in wxArt2D are stored at the next segment.
2290  lastWasArc = true;
2291 
2292  xp = x;
2293  yp = y;
2294  xm = ReadDouble();
2295 
2296  if ( !ReadItem( wxT( "ym" ) ) ) //read ym of arc
2297  throw GDS_Error( wxT( "Polygon: YM is missing (in KEY-file)" ) );
2298  ym = ReadDouble();
2299 
2300  if ( !ReadItem( wxT( "xo" ) ) ) //read xo of arc
2301  throw GDS_Error( wxT( "Polygon: XO is missing (in KEY-file)" ) );
2302  xo = ReadDouble();
2303 
2304  if ( !ReadItem( wxT( "yo" ) ) ) //read yo of arc
2305  throw GDS_Error( wxT( "Polygon: YO is missing (in KEY-file)" ) );
2306  yo = ReadDouble();
2307  }
2308  else if ( !m_keyword.CmpNoCase( wxT( "endel" ) ) || !m_keyword.CmpNoCase( wxT( "x" ) )
2309  || !m_keyword.CmpNoCase( wxT( "st" ) ) || !m_keyword.CmpNoCase( wxT( "property" ) ) ) // Read is already done
2310  {
2311  //remember previous segment x,y
2312  xp = x;
2313  yp = y;
2314  }
2315  else
2316  throw GDS_Error( wxT( "Polyline: X, XM, ST, PROPERTY or ENDEL missing (in KEY-file)" ) );
2317  }
2318  // DO NOT: Skip last coordinate (is not always same as 1st)
2319  if ( lastWasArc )
2320  {
2321  throw GDS_Error( wxT( "Last Segment Should not be an Arc segment (in KEY-file)" ) );
2322  }
2323 
2324  //poly->RemoveRedundant();
2325  return true;
2326 }
2327 
2328 // Elflags ------------------------------------------------------------------
2329 void a2dIOHandlerKeyIn::SetFlags( a2dCanvasObject* Element )
2330 {
2331  if ( ( Element->GetTemplate() != 0 ) ||
2332  ( Element->GetExternal() != 0 ) )
2333  {
2334  m_objectFlags = 0;
2335 
2336  if ( Element->GetTemplate() != 0 )
2337  m_objectFlags += 1 << 1;
2338 
2339  if ( Element->GetExternal() != 0 )
2340  m_objectFlags += 1 << 2;
2341  }
2342 }
2343 
2345 {
2346  if ( type != 0 )
2348 }
2349 
2350 // ----------------------------------------------------------------------------
2351 // a2dIOHandlerKeyOut
2352 // ----------------------------------------------------------------------------
2353 
2354 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( const wxChar* string )
2355 {
2356  WriteString( wxString( string ) );
2357  return *this;
2358 }
2359 
2360 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( const wxString& string )
2361 {
2362  WriteString( string );
2363  return *this;
2364 }
2365 
2366 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( char c )
2367 {
2368  WriteString( wxString::FromAscii( c ) );
2369 
2370  return *this;
2371 }
2372 
2373 #if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
2374 
2375 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( wchar_t wc )
2376 {
2377  WriteString( wxString( &wc, m_conv, 1 ) );
2378 
2379  return *this;
2380 }
2381 
2382 #endif // wxUSE_UNICODE
2383 
2384 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( wxInt16 c )
2385 {
2386  wxString str;
2387  str.Printf( wxT( "%d" ), ( signed int )c );
2388  WriteString( str );
2389 
2390  return *this;
2391 }
2392 
2393 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( wxInt32 c )
2394 {
2395  wxString str;
2396  str.Printf( wxT( "%ld" ), ( signed long )c );
2397  WriteString( str );
2398 
2399  return *this;
2400 }
2401 
2402 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( wxUint16 c )
2403 {
2404  wxString str;
2405  str.Printf( wxT( "%u" ), ( unsigned int )c );
2406  WriteString( str );
2407 
2408  return *this;
2409 }
2410 
2411 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( wxUint32 c )
2412 {
2413  wxString str;
2414  str.Printf( wxT( "%lu" ), ( unsigned long )c );
2415  WriteString( str );
2416 
2417  return *this;
2418 }
2419 
2420 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( double f )
2421 {
2422  WriteDouble( f );
2423  return *this;
2424 }
2425 
2426 a2dIOHandlerKeyOut& a2dIOHandlerKeyOut::operator<<( float f )
2427 {
2428  WriteDouble( ( double )f );
2429  return *this;
2430 }
2431 
2432 const wxChar a2dIOHandlerKeyOut::Endl()
2433 {
2434  return wxT( '\n' );
2435 }
2436 
2437 // -------------- use it -----------------
2438 
2439 a2dIOHandlerKeyOut::a2dIOHandlerKeyOut()
2440 {
2441  m_scale_out = 1;
2442  m_lastElementLayer = 0;
2443  m_textAsPath = false;
2444  m_format = wxT( "%g" );
2445  m_fromViewAsTop = false;
2446  m_asCameleons = false;
2447 }
2448 
2449 a2dIOHandlerKeyOut::~a2dIOHandlerKeyOut()
2450 {
2451 }
2452 
2453 bool a2dIOHandlerKeyOut::CanSave( const wxObject* obj )
2454 {
2455  if ( !wxDynamicCast( obj, a2dCanvasDocument ) )
2456  return false;
2457  return true;
2458 }
2459 
2461 {
2462  m_points_written = 0;
2463 
2465  a2dCanvasGlobals->GetHabitat()->SetAberPolyToArc( double( a2dCanvasGlobals->GetHabitat()->GetAberPolyToArc() ) / m_doc->GetUnitsScale() );
2466 }
2467 
2469 {
2471 }
2472 
2473 bool a2dIOHandlerKeyOut::LinkReferences()
2474 {
2475  bool res = a2dIOHandler::LinkReferences();
2476 
2477  //search in the root object for the childs that have the bin flag set,
2478  //which means they are referenced, and can be deleted.
2479  //All othere are top structures.
2480  a2dCanvasObjectList::iterator rootchild = m_doc->GetDrawing()->GetRootObject()->GetChildObjectList()->begin();
2481  while ( rootchild != m_doc->GetDrawing()->GetRootObject()->GetChildObjectList()->end() )
2482  {
2483  a2dCanvasObjectList::iterator delnode = rootchild;
2484  rootchild++;
2485  if ( ( *delnode )->GetCheck() )
2486  {
2487  m_doc->GetDrawing()->GetRootObject()->GetChildObjectList()->erase( delnode );
2488  }
2489  }
2490  return res;
2491 }
2492 
2493 bool a2dIOHandlerKeyOut::Save( a2dDocumentOutputStream& stream, const wxObject* doc )
2494 {
2495  m_doc = ( a2dCanvasDocument* ) doc;
2496  InitializeSave();
2497 
2498  m_streamo = &stream;
2499 
2500  a2dCanvasObject* showobject = m_doc->GetDrawing()->GetRootObject();
2501 
2502  if ( m_fromViewAsTop )
2503  {
2505  if ( drawer )
2506  showobject = drawer->GetDrawingPart()->GetShowObject();
2507  }
2508 
2509  m_layers = m_doc->GetDrawing()->GetLayerSetup();
2510 
2511 
2513  setflags.Start( showobject, false );
2514 
2515  m_mapping.resize( wxMAXLAYER );
2516 
2517  unsigned int i;
2518  for ( i = 0; i < wxMAXLAYER; i++ )
2519  m_mapping[i] = -1;
2520  for ( i = 0; i < wxMAXLAYER; i++ )
2521  if ( m_layers->GetLayerIndex()[i] != wxNullLayerInfo )
2522  m_mapping[ m_layers->GetOutMapping( i ) ] = i;
2523 
2524  for ( i = 0; i < wxMAXLAYER; i++ )
2525  if ( m_mapping[i] == -1 )
2526  m_mapping[i] = 0;
2527 
2528  //first check if the dat is not to big to fit in four byte integers
2529  //this is the maximum for vertexes in GDSII data
2530 
2531  a2dBoundingBox drawing = showobject->GetBbox();
2532 
2533  m_userunits_out = m_doc->GetUnitsAccuracy();
2534  drawing.SetMin( drawing.GetMinX() / m_userunits_out, drawing.GetMinY() / m_userunits_out );
2535  drawing.SetMax( drawing.GetMaxX() / m_userunits_out, drawing.GetMaxY() / m_userunits_out );
2536  a2dBoundingBox maxint( LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX );
2537 
2538  int l = 0;
2539  while ( maxint.Intersect( drawing, 0 ) != _IN )
2540  {
2541  drawing.SetMin( drawing.GetMinX() / 10.0, drawing.GetMinY() / 10.0 );
2542  drawing.SetMax( drawing.GetMaxX() / 10.0, drawing.GetMaxY() / 10.0 );
2543  l++;
2544  }
2545  m_scale_out = pow( 10.0, l );
2546 
2547  *this << wxT( "# KEY file for GDS-II postprocessing tool" ) << Endl();
2548  *this << wxT( "# File = " ) << m_doc->GetTitle() << Endl();
2549  *this << wxT( "# ====================================================================" ) << Endl() << Endl();
2550 
2551  *this << wxT( "HEADER " ) << m_doc->GetVersion() << wxT( "; # version " ) << Endl();
2552  *this << wxT( "BGNLIB; " ) << Endl();
2553  *this << wxT( "LASTMOD {" )
2554  << m_doc->GetModificationTime().GetYear() << wxT( "-" )
2555  << m_doc->GetModificationTime().GetMonth() + 1 << wxT( "-" )
2556  << m_doc->GetModificationTime().GetDay() << wxT( " " )
2557  << m_doc->GetModificationTime().GetHour() << wxT( ":" )
2558  << m_doc->GetModificationTime().GetMinute() << wxT( ":" )
2559  << m_doc->GetModificationTime().GetSecond() << wxT( "}; # last modification time" ) << Endl();
2560  *this << wxT( "LASTACC {" )
2561  << m_doc->GetAccessTime().GetYear() << wxT( "-" )
2562  << m_doc->GetAccessTime().GetMonth() + 1 << wxT( "-" )
2563  << m_doc->GetAccessTime().GetDay() << wxT( " " )
2564  << m_doc->GetAccessTime().GetHour() << wxT( ":" )
2565  << m_doc->GetAccessTime().GetMinute() << wxT( ":" )
2566  << m_doc->GetAccessTime().GetSecond() << wxT( "}; # last access time" ) << Endl();
2567 
2568  *this << wxT( "LIBNAME \"" ) << m_doc->GetLibraryName() << wxT( "\"; " ) << Endl();
2569 
2570  //start writing
2571 
2572  if ( m_layers )
2573  {
2574  *this << wxT( "FORMAT 1; " ) << Endl();
2575 
2576  unsigned int j;
2577  for ( j = 0; j < wxMAXLAYER; j++ )
2578  {
2579  a2dLayerInfo* layerobj;
2580  if ( 0 )
2581  layerobj = m_layers->GetReverseOrderIndex()[j];
2582  else
2583  layerobj = m_layers->GetOrderIndex()[j];
2584 
2585  if ( a2dLayerInfo::PROPID_TemporaryObject->GetPropertyValue( layerobj ) )
2586  continue;
2587 
2588  // non defined layers, being those that where not in the layer setup, are sorted to the end of the indexes.
2589  // So the can be skipped.
2590  if ( layerobj == wxNullLayerInfo )
2591  break;
2592 
2593  //wxLogDebug( wxT("index %d layername %s, layer %d order %d"), j, layerobj->GetName(), layerobj->GetLayer(), layerobj->GetOrder() );
2594 
2595  //important!
2596  //if layer is visible it will be rendered
2597  if ( layerobj->GetAvailable() && layerobj->GetVisible() )
2598  {
2599  //wxLogDebug( "layer %d", layerobj->GetLayer() );
2600  *this << wxT( "MASK \"" ) << layerobj->GetName() << wxT( "\"; " );
2601  *this << wxT( "layernr " ) << layerobj->GetLayer() << wxT( "; " );
2602 
2603  wxString brushColour = wxTheColourDatabase->FindName( layerobj->GetFill().GetColour() );
2604 
2605  if ( brushColour.IsEmpty() )
2606  *this << wxT( "color \"" ) << wxT( "#" ) + ColourToHex( layerobj->GetFill().GetColour() ) << wxT( "\"; " );
2607  else
2608  *this << wxT( "color \"" ) << brushColour << wxT( "\"; " );
2609  if ( layerobj->GetFill().GetStyle() != a2dFILL_TRANSPARENT )
2610  *this << wxT( "trans " ) << layerobj->GetFill().GetAlpha() << wxT( "; " );
2611  else
2612  *this << wxT( "trans " ) << 0 << wxT( "; " );
2613  *this << wxT( "linestyle " ) << StrokeStyle2String( layerobj->GetStroke().GetStyle() ) << wxT( "; " );
2614 
2615  *this << wxT( "binding {*}; " );
2616  *this << wxT( "stream " ) << j << wxT( "; " );
2617  *this << wxT( "iges " ) << j << wxT( "; " );
2618  *this << wxT( "type " ) << 1 << wxT( "; " );
2619  *this << wxT( "dxf " ) << 1 << wxT( "; " );
2620  if ( !layerobj->GetFill().GetFilling() ) //OUTLINE 0 FILL 1 BOTH 2
2621  *this << wxT( "plotmode " ) << 0 << wxT( "; " );
2622  else
2623  *this << wxT( "plotmode " ) << 1 << wxT( "; " );
2624  *this << wxT( "protected " ) << 0 << wxT( "; " );
2625  *this << wxT( "visible " ) << 1 << wxT( "; " );
2626  *this << wxT( "patternnr " ) << 0 << wxT( "; " );
2627  *this << Endl();
2628  }
2629  }
2630 
2631  *this << wxT( "ENDMASKS" ) << Endl();
2632  *this << Endl();
2633  }
2634 
2635  *this << wxT( "UNITS " ) << m_doc->GetUnits() << wxT( "; " ) << Endl()
2636  << wxT( "USERUNITS " ) << m_userunits_out << wxT( "; " )
2637  << wxT( "PHYSUNITS " ) << m_doc->GetUnitsScale()*m_userunits_out* m_scale_out << wxT( "; " ) << Endl();
2638 
2639 
2640  a2dCanvasObjectList towrite;
2641  if ( m_doc->GetDrawing()->GetDrawingId() == a2dDrawing::sm_cameleonrefs )
2642  {
2643  if ( m_fromViewAsTop )
2644  towrite.push_back( showobject );
2645  else
2646  {
2647  a2dCanvasObjectList::iterator rootchild = m_doc->GetDrawing()->GetRootObject()->GetChildObjectList()->begin();
2648  while ( rootchild != m_doc->GetDrawing()->GetRootObject()->GetChildObjectList()->end() )
2649  {
2650  a2dCameleon* ref = wxDynamicCast( (*rootchild).Get(), a2dCameleon );
2651  if ( ref )
2652  {
2653  //a2dLayout* layout = ref->GetCameleon()->GetAppearance<a2dDiagram>();
2654  //towrite.push_back( layout->GetDrawing() );
2655  //layout->SetBin( false );
2656  towrite.push_back( ref );
2657  ref->SetBin( false );
2658  }
2659  rootchild++;
2660  }
2661  }
2662  }
2663  else
2664  {
2665  if ( m_fromViewAsTop || !m_doc->GetMultiRoot() )
2666  towrite.push_back( showobject );
2667  else
2668  {
2670  }
2671  }
2672 
2673  a2dCanvasObjectList::iterator iter = towrite.begin();
2674  while ( towrite.size() )
2675  {
2676  a2dCanvasObject* obj = *iter;
2677  SaveStructure( obj, &towrite );
2678  obj->SetBin( true );
2679  towrite.erase( iter );
2680  iter = towrite.begin();
2681  }
2682 
2683  *this << wxT( "ENDLIB; " ) << Endl();
2684 
2685  ResetSave();
2686 
2687  return true;
2688 }
2689 
2690 void a2dIOHandlerKeyOut::SaveStructure( a2dCanvasObject* object, a2dCanvasObjectList* towrite )
2691 {
2692  SetFlags( object );
2693 
2694  if ( !object->GetRelease() )
2695  {
2696  if ( !object->GetBin() )
2697  {
2698  //write a struture BEGIN
2699 
2700  // BGNSTR
2701  *this << Endl() << wxT( "BGNSTR; # Begin of structure " ) << Endl();
2702  *this << wxT( "CREATION {" )
2703  << m_doc->GetModificationTime().GetYear() << wxT( "-" )
2704  << m_doc->GetModificationTime().GetMonth() + 1 << wxT( "-" )
2705  << m_doc->GetModificationTime().GetDay() << wxT( " " )
2706  << m_doc->GetModificationTime().GetHour() << wxT( ":" )
2707  << m_doc->GetModificationTime().GetMinute() << wxT( ":" )
2708  << m_doc->GetModificationTime().GetSecond() << wxT( "}; # creation time" ) << Endl();
2709  *this << wxT( "LASTMOD {" )
2710  << m_doc->GetAccessTime().GetYear() << wxT( "-" )
2711  << m_doc->GetAccessTime().GetMonth() + 1 << wxT( "-" )
2712  << m_doc->GetAccessTime().GetDay() << wxT( " " )
2713  << m_doc->GetAccessTime().GetHour() << wxT( ":" )
2714  << m_doc->GetAccessTime().GetMinute() << wxT( ":" )
2715  << m_doc->GetAccessTime().GetSecond() << wxT( "}; # last modification time" ) << Endl();
2716 
2717  *this << wxT( "STRNAME " ) << object->GetName() << wxT( "; " ) << Endl();
2718 
2719  if ( 0 != wxDynamicCast( object, a2dCameleon ) )
2720  {
2721  a2dCameleon* cam = wxDynamicCast( object, a2dCameleon );
2722  //a2dDiagram* dia = wxDynamicCast( cam->GetAppearanceByName( cam->GetName() ), a2dDiagram );
2724  if ( dia )
2725  {
2726  a2dCanvasObjectList* childobjects = dia->GetDrawing()->GetRootObject()->GetChildObjectList();
2727  if ( childobjects != wxNullCanvasObjectList )
2728  {
2729  forEachIn( a2dCanvasObjectList, childobjects )
2730  {
2731  a2dCanvasObject* obj = *iter;
2732  if ( !obj->GetRelease() && m_layers->GetVisible( obj->GetLayer() ) || obj->GetIgnoreLayer() )
2733  {
2734  Save( obj, towrite );
2735  }
2736  }
2737  }
2738  }
2739  }
2740  else
2741  {
2742  a2dCanvasObjectList* childobjects = object->GetChildObjectList();
2743  if ( childobjects != wxNullCanvasObjectList )
2744  {
2745  forEachIn( a2dCanvasObjectList, childobjects )
2746  {
2747  a2dCanvasObject* obj = *iter;
2748  if ( !obj->GetRelease() && m_layers->GetVisible( obj->GetLayer() ) || obj->GetIgnoreLayer() )
2749  {
2750  Save( obj, towrite );
2751  }
2752  }
2753  }
2754  }
2755  *this << Endl() << wxT( "ENDSTR " ) << object->GetName() << wxT( "; " ) << Endl();
2756  }
2757  }
2758 }
2759 
2761 {
2762  if( object->IsTemporary_DontSave() )
2763  return;
2764 
2765  bool skip = false;
2766 
2767  //in case an object can not be written as is, and need to be converted to vector paths, and written that as childs.
2769 
2770  SetFlags( object );
2771  //write the object itself as part of the structure (which is the parent )
2772  if ( 0 != wxDynamicCast( object, a2dPolylineL ) )
2773  {
2774  a2dPolylineL* obj = wxDynamicCast( object, a2dPolylineL );
2775  DoSave( obj, towrite );
2776  }
2777  else if ( 0 != wxDynamicCast( object, a2dSurface ) )
2778  {
2779  a2dSurface* obj = wxDynamicCast( object, a2dSurface );
2780  DoSave( obj, towrite );
2781  }
2782  else if ( 0 != wxDynamicCast( object, a2dPolygonL ) )
2783  {
2784  a2dPolygonL* obj = wxDynamicCast( object, a2dPolygonL );
2785  DoSave( obj, towrite );
2786  }
2787  else if ( 0 != wxDynamicCast( object, a2dVectorPath ) )
2788  {
2789  a2dVectorPath* obj = wxDynamicCast( object, a2dVectorPath );
2790  vectorpaths = obj->GetAsCanvasVpaths( false );
2791  }
2792  else if ( 0 != wxDynamicCast( object, a2dCanvasObjectArrayReference ) )
2793  {
2795  DoSave( obj, towrite );
2796  }
2797  else if ( 0 != wxDynamicCast( object, a2dCanvasObjectReference ) )
2798  {
2800  DoSave( obj, towrite );
2801  }
2802  else if ( 0 != wxDynamicCast( object, a2dCameleonInst ) )
2803  {
2804  a2dCameleonInst* obj = wxDynamicCast( object, a2dCameleonInst );
2805  DoSave( obj, towrite );
2806  }
2807  else if ( 0 != wxDynamicCast( object, a2dCameleon ) )
2808  {
2809  a2dCameleon* obj = wxDynamicCast( object, a2dCameleon );
2810  DoSave( obj, towrite );
2811  }
2812  else if ( 0 != wxDynamicCast( object, a2dTextGDS ) )
2813  {
2814  a2dTextGDS* obj = wxDynamicCast( object, a2dTextGDS );
2815 
2816  if ( !m_textAsPath )
2817  DoSave( obj, towrite );
2818  else
2819  vectorpaths = obj->GetAsCanvasVpaths( false );
2820  }
2821  else if ( 0 != wxDynamicCast( object, a2dText ) )
2822  {
2823  a2dText* obj = wxDynamicCast( object, a2dText );
2824 
2825  if ( !m_textAsPath )
2826  DoSave( obj, towrite );
2827  else
2828  vectorpaths = obj->GetAsCanvasVpaths( false );
2829  }
2830  else if ( 0 != wxDynamicCast( object, a2dCircle ) )
2831  {
2832  a2dCircle* obj = wxDynamicCast( object, a2dCircle );
2833 
2834  DoSave( obj, towrite );
2835  }
2836  else if ( 0 != wxDynamicCast( object, a2dRect ) )
2837  {
2838  vectorpaths = object->GetAsCanvasVpaths( false );
2839  }
2840  else if ( ( 0 != wxDynamicCast( object, a2dArrow ) ) ||
2841  ( 0 != wxDynamicCast( object, a2dRectC ) ) ||
2842  ( 0 != wxDynamicCast( object, a2dEllipse ) ) ||
2843  ( 0 != wxDynamicCast( object, a2dEllipticArc ) ) ||
2844  ( 0 != wxDynamicCast( object, a2dArc ) ) ||
2845  ( 0 != wxDynamicCast( object, a2dSLine ) )
2846  )
2847  {
2848  vectorpaths = object->GetAsCanvasVpaths( false );
2849  }
2850  else if ( wxString( object->GetClassInfo()->GetClassName() ) == wxT( "a2dCanvasObject" ) )
2851  {
2852  *this << Endl() << wxT( "SREF; " ) << Endl();
2853 
2854  WriteFlags( m_objectFlags );
2855 
2856  *this << wxT( "SNAME " ) << object->GetName() << wxT( "; " ) << Endl();
2857 
2858  //write a structure reference in the parent object
2859  a2dAffineMatrix lworld = object->GetTransformMatrix();
2860  if ( !lworld.IsIdentity() )
2861  {
2862  Strans strans = Strans();
2863  strans.MakeStrans( lworld );
2864  if ( strans.GetStrans() )
2865  Write( &strans );
2866  }
2867 
2868  *this << Endl() << wxT( " XY 1; " ) << Endl();
2869 
2870  WritePoint( object->GetPosX(), object->GetPosY() );
2871 
2872  *this << Endl() << wxT( "ENDEL; " ) << Endl();
2873  towrite->push_back( object );
2874 
2875  skip = true;
2876  }
2877  else
2878  {
2879  wxLogWarning( wxT( "KEYIO : object %s is not implemented for output" ), object->GetClassInfo()->GetClassName() );
2880  skip = true;
2881  }
2882 
2883  if ( !skip )
2884  {
2885  //remark properties are lost when the object is converted into vectorpaths
2886 
2887  //now write extra vector paths ( e.g. as a result of a converted object )
2888  if ( vectorpaths != wxNullCanvasObjectList )
2889  {
2890  a2dAffineMatrix lworld = object->GetTransformMatrix();
2891 
2892  for( a2dCanvasObjectList::iterator iter = vectorpaths->begin(); iter != vectorpaths->end(); ++iter )
2893  {
2894  a2dVectorPath* canpath = ( a2dVectorPath* ) ( *iter ).Get();
2895  WriteVpath( lworld, canpath->GetSegments(), canpath->GetLayer(), canpath->GetDataType(), canpath->GetPathType(), canpath->GetContourWidth() );
2896  }
2897  delete vectorpaths;
2898  }
2899  else
2900  {
2901  WriteProperties( object->GetPropertyList() );
2902  *this << Endl() << wxT( "ENDEL; " ) << Endl();
2903  }
2904 
2905  //write normal childs.
2906  if ( object->GetChildObjectList() != wxNullCanvasObjectList && object->GetChildObjectsCount() )
2907  {
2908  *this << Endl() << wxT( "SREF; " ) << Endl();
2909 
2910  WriteFlags( m_objectFlags );
2911 
2912  *this << wxT( "SNAME " ) << object->GetName() << wxT( "; " ) << Endl();
2913 
2914  //write a structure reference in the parent object
2915  a2dAffineMatrix lworld = object->GetTransformMatrix();
2916  if ( !lworld.IsIdentity() )
2917  {
2918  Strans strans = Strans();
2919  strans.MakeStrans( lworld );
2920  if ( strans.GetStrans() )
2921  Write( &strans );
2922  }
2923 
2924  *this << Endl() << wxT( " XY 1; " ) << Endl();
2925 
2926  WritePoint( object->GetPosX(), object->GetPosY() );
2927 
2928  *this << Endl() << wxT( "ENDEL; " ) << Endl();
2929  towrite->push_back( object );
2930  }
2931  }
2932 }
2933 
2934 void a2dIOHandlerKeyOut::DoSave( a2dPolylineL* obj, a2dCanvasObjectList* WXUNUSED( towrite ) )
2935 {
2936  WriteVertexListPolyline( obj->GetTransformMatrix(), obj->GetSegments(),
2938  obj->GetPathType(),
2939  obj->GetContourWidth(), obj->GetSpline(), false );
2940 
2941  /*
2942  double xscale = obj->GetEndScaleX();
2943  double yscale = obj->GetEndScaleY();
2944 
2945  if ( obj->GetBegin() )
2946  {
2947  a2dVertexList::compatibility_iterator node = rlist->GetFirst();
2948  a2dLineSegment* point1 = (a2dLineSegment*)node->GetData();
2949  node = node->GetNext();
2950  a2dLineSegment* point2 = (a2dLineSegment*)node->GetData();
2951 
2952  double dx, dy;
2953  dx=point2->m_x-point1->m_x;
2954  dy=point2->m_y-point1->m_y;
2955 
2956  double ang1;
2957  if (!dx && !dy)
2958  ang1=0;
2959  else
2960  ang1 = wxRadToDeg(atan2(dy,dx));
2961 
2962  a2dAffineMatrix lworld;
2963  //clockwise rotation so minus
2964  lworld.Scale(xscale,yscale,0,0);
2965  lworld.Rotate(-ang1);
2966  lworld.Translate(point1->m_x,point1->m_y);
2967 
2968  WriteStartElementAttributes( wxT("g") );
2969  s.Printf ( wxT("matrix( %f %f %f %f %f %f )"),
2970  lworld.GetValue(0,0), lworld.GetValue(0,1),
2971  lworld.GetValue(1,0), lworld.GetValue(1,1),
2972  lworld.GetValue(2,0), lworld.GetValue(2,1)
2973  );
2974  WriteAttribute( wxT("transform"), s );
2975  WriteEndAttributes();
2976 
2977  Save( obj->GetBegin(), layer );
2978 
2979  WriteEndElement();
2980  }
2981 
2982  if ( obj->GetEnd() )
2983  {
2984  a2dVertexList::compatibility_iterator node = rlist->GetLast();
2985  a2dLineSegment* point1 = (a2dLineSegment*)node->GetData();
2986  node = node->GetPrevious();
2987  a2dLineSegment* point2 = (a2dLineSegment*)node->GetData();
2988 
2989  double dx, dy;
2990  dx=point2->m_x-point1->m_x;
2991  dy=point2->m_y-point1->m_y;
2992  double ang2;
2993  if (!dx && !dy)
2994  ang2=0;
2995  else
2996  ang2 = wxRadToDeg(atan2(dy,dx));
2997 
2998  a2dAffineMatrix lworld;
2999  //clockwise rotation so minus
3000  lworld.Scale(xscale,yscale,0,0);
3001  lworld.Rotate(-ang2);
3002  lworld.Translate(point1->m_x,point1->m_y);
3003 
3004  WriteStartElementAttributes( wxT("g") );
3005  s.Printf ( wxT("matrix( %f %f %f %f %f %f )"),
3006  lworld.GetValue(0,0), lworld.GetValue(0,1),
3007  lworld.GetValue(1,0), lworld.GetValue(1,1),
3008  lworld.GetValue(2,0), lworld.GetValue(2,1)
3009  );
3010  WriteAttribute( wxT("transform"), s );
3011  WriteEndAttributes();
3012 
3013  Save( obj->GetEnd(), layer );
3014 
3015  WriteEndElement();
3016  }
3017  */
3018 
3019 }
3020 
3021 void a2dIOHandlerKeyOut::DoSave( a2dPolygonL* obj, a2dCanvasObjectList* WXUNUSED( towrite ) )
3022 {
3023  WriteVertexListPolygon( obj->GetTransformMatrix(), obj->GetSegments(), obj->GetLayer(), a2dCanvasObject::PROPID_Datatype->GetPropertyValue( obj ), obj->GetContourWidth(), obj->GetSpline(), false );
3024 }
3025 
3026 void a2dIOHandlerKeyOut::DoSave( a2dSurface* surface, a2dCanvasObjectList* WXUNUSED( towrite ) )
3027 {
3028  a2dAffineMatrix lworld = surface->GetTransformMatrix();
3029  a2dVertexList* points = surface->GetSegments();
3030 
3031  m_points_written = 0;
3032 
3033  *this << Endl() << wxT( "SURFACE; " );
3034 
3035  WriteFlags( m_objectFlags );
3036 
3037  *this << wxT( "LAYER " ) << m_mapping[ surface->GetLayer() ] << wxT( "; " );
3038  *this << wxT( "DATATYPE " ) << a2dCanvasObject::PROPID_Datatype->GetPropertyValue( surface ) << wxT( "; " );
3039 
3040  WritePoly( lworld, points, true );
3041 
3042  a2dListOfa2dVertexList& holes = surface->GetHoles();
3043  for( a2dListOfa2dVertexList::iterator iterp = holes.begin(); iterp != holes.end(); iterp++ )
3044  {
3045  *this << Endl() << wxT( "HOLE; " );
3046  a2dVertexListPtr vlist = ( *iterp );
3047  if ( vlist->HasArcs() )
3048  vlist->ConvertToLines();
3049  m_points_written = 0;
3050  WritePoly( lworld, vlist, true );
3051  }
3052 }
3053 
3054 void a2dIOHandlerKeyOut::DoSave( a2dText* obj, a2dCanvasObjectList* WXUNUSED( towrite ) )
3055 {
3056  *this << Endl() << wxT( "TEXT; " );
3057 
3058  WriteFlags( m_objectFlags );
3059 
3060  *this << wxT( "LAYER " ) << m_mapping[obj->GetLayer()] << wxT( "; " ) << Endl();
3061 
3062  *this << wxT( "TEXTTYPE " ) << TEXT_PATH_END_SQAURE << wxT( "; " );
3063 
3064  // for the moment this is in the strans together with matrix
3065  //if( obj->GetTextHeight() != 0 )
3066  // *this << wxT("WIDTH ") << obj->GetTextHeight() / m_scale_out << wxT("; ");
3067 
3068  a2dAffineMatrix lworld = obj->GetTransformMatrix();
3069  if ( !lworld.IsIdentity() )
3070  {
3071  Strans strans = Strans();
3072  strans.MakeStrans( lworld );
3073 
3074  if( obj->GetTextHeight() != 0 )
3075  strans.SetScale( strans.GetScale() * obj->GetTextHeight() );
3076 
3077  if ( strans.GetStrans() )
3078  Write( &strans );
3079  }
3080  *this << Endl() << wxT( " XY 1; " ) << Endl();
3081 
3082  WritePoint( obj->GetPosX(), obj->GetPosY() );
3083 
3084  *this << Endl() << wxT( "STRING {" ) << obj->GetText() << wxT( "}; " );
3085 }
3086 
3087 void a2dIOHandlerKeyOut::DoSave( a2dTextGDS* obj, a2dCanvasObjectList* WXUNUSED( towrite ) )
3088 {
3089  *this << Endl() << wxT( "TEXT; " );
3090 
3091  WriteFlags( m_objectFlags );
3092 
3093  *this << wxT( "LAYER " ) << m_mapping[obj->GetLayer()] << wxT( "; " ) << Endl();
3094 
3095  *this << wxT( "TEXTTYPE " ) << obj->GetTextType() << wxT( "; " );
3096 
3097  if ( obj->GetPresentationFlags() )
3098  {
3099  // write only when a_presentation isn't default
3100  if ( ( obj->GetFontGDS() != DEFAULT_PRESENTATION_FONT ) ||
3101  ( obj->GetVertical() != DEFAULT_PRESENTATION_VERTICAL ) ||
3102  ( obj->GetHorizontal() != DEFAULT_PRESENTATION_HORIZONTAL ) )
3103  {
3104  *this << wxT( "PRESENTATION " ) <<
3105  ( int )obj->GetHorizontal() << wxT( "," ) <<
3106  ( int )obj->GetVertical() << wxT( "," ) <<
3107  ( int )obj->GetFontGDS() << wxT( "; " );
3108  }
3109  }
3110  if ( obj->GetPathtype() )
3111  *this << wxT( "PATHTYPE " ) << obj->GetPathtype() << wxT( "; " );
3112 
3113  // for the moment this is in the strans together with matrix
3114  //if( obj->GetTextHeight() != 0 )
3115  // *this << wxT("WIDTH ") << obj->GetTextHeight() / m_scale_out << wxT("; ");
3116 
3117  a2dAffineMatrix lworld = obj->GetTransformMatrix();
3118  if ( !lworld.IsIdentity() )
3119  {
3120  Strans strans = Strans();
3121  strans.MakeStrans( lworld );
3122 
3123  if( obj->GetTextHeight() != 0 )
3124  strans.SetScale( strans.GetScale() * obj->GetTextHeight() );
3125 
3126  if ( strans.GetStrans() )
3127  Write( &strans );
3128  }
3129  *this << Endl() << wxT( " XY 1; " ) << Endl();
3130 
3131  WritePoint( obj->GetPosX(), obj->GetPosY() );
3132 
3133  *this << Endl() << wxT( "STRING {" ) << obj->GetText() << wxT( "}; " );
3134 }
3135 
3136 void a2dIOHandlerKeyOut::DoSave( a2dCanvasObjectReference* obj, a2dCanvasObjectList* towrite )
3137 {
3138  *this << Endl() << wxT( "SREF; " ) << Endl();
3139 
3140  WriteFlags( m_objectFlags );
3141 
3142  *this << wxT( "SNAME " ) << obj->GetName() << wxT( "; " ) << Endl();
3143 
3144  //write a structure reference in the parent object
3145  a2dAffineMatrix lworld = obj->GetTransformMatrix();
3146  if ( !lworld.IsIdentity() )
3147  {
3148  Strans strans = Strans();
3149  strans.MakeStrans( lworld );
3150  if ( strans.GetStrans() )
3151  Write( &strans );
3152  }
3153 
3154  *this << Endl() << wxT( " XY 1; " ) << Endl();
3155 
3156  WritePoint( obj->GetPosX(), obj->GetPosY() );
3157 
3158  if ( obj->GetCanvasObject() )
3159  towrite->push_back( obj->GetCanvasObject() );
3160 }
3161 
3162 void a2dIOHandlerKeyOut::DoSave( a2dCanvasObjectArrayReference* obj, a2dCanvasObjectList* towrite )
3163 {
3164  *this << Endl() << wxT( "AREF; " ) << Endl();
3165 
3166  WriteFlags( m_objectFlags );
3167 
3168  *this << wxT( "SNAME " ) << obj->GetName() << wxT( "; " );
3169 
3170  a2dAffineMatrix lworld = obj->GetTransformMatrix();
3171  if ( !lworld.IsIdentity() )
3172  {
3173  Strans strans = Strans();
3174  strans.MakeStrans( lworld );
3175  if ( strans.GetStrans() )
3176  Write( &strans );
3177  }
3178 
3179  *this << wxT( "COLROW {" )
3180  << obj->GetColumns() << wxT( " , " )
3181  << obj->GetRows() << wxT( "}; " );
3182 
3183  m_points_written = 0;
3184 
3185  *this << Endl() << wxT( " XY 3; " ) << Endl();
3186 
3187  WritePoint( obj->GetPosX(), obj->GetPosY() );
3188  WritePoint( obj->GetPosX() + obj->GetHorzSpace() * obj->GetColumns(), obj->GetPosY() );
3189  WritePoint( obj->GetPosX(), obj->GetPosY() + obj->GetVertSpace() * obj->GetRows() );
3190 
3191  if ( obj->GetCanvasObject() )
3192  towrite->push_back( obj->GetCanvasObject() );
3193 }
3194 
3195 void a2dIOHandlerKeyOut::DoSave( a2dCameleonInst* obj, a2dCanvasObjectList* towrite )
3196 {
3198  if ( ! dia )
3199  return;
3200 
3201  *this << Endl() << wxT( "SREF; " ) << Endl();
3202 
3203  WriteFlags( m_objectFlags );
3204 
3205  *this << wxT( "SNAME " ) << dia->GetCameleon()->GetName() << wxT( "; " ) << Endl();
3206 
3207  //write a structure reference in the parent object
3208  a2dAffineMatrix lworld = obj->GetTransformMatrix();
3209  if ( !lworld.IsIdentity() )
3210  {
3211  Strans strans = Strans();
3212  strans.MakeStrans( lworld );
3213  if ( strans.GetStrans() )
3214  Write( &strans );
3215  }
3216 
3217  *this << Endl() << wxT( " XY 1; " ) << Endl();
3218 
3219  WritePoint( obj->GetPosX(), obj->GetPosY() );
3220 
3221  if ( m_asCameleons && dia->GetCameleon() )
3222  towrite->push_back( dia->GetCameleon() );
3223 }
3224 
3225 void a2dIOHandlerKeyOut::DoSave( a2dCameleon* obj, a2dCanvasObjectList* towrite )
3226 {
3227  SaveStructure( obj, towrite );
3228 }
3229 
3230 // Circle -----------------------------------------------------------------
3231 void a2dIOHandlerKeyOut::DoSave( a2dCircle* Circle, a2dCanvasObjectList* WXUNUSED( towrite ) )
3232 {
3233  *this << Endl() << wxT( "CIRCLE; " );
3234 
3235  WriteFlags( m_objectFlags );
3236 
3237  *this << wxT( "LAYER " ) << m_mapping[Circle->GetLayer()] << wxT( "; " );
3238  *this << wxT( "DATATYPE " ) << a2dCanvasObject::PROPID_Datatype->GetPropertyValue( Circle ) << wxT( "; " );
3239 
3240  if ( Circle->GetContourWidth() )
3241  *this << wxT( "WIDTH " ) << Circle->GetContourWidth() / m_scale_out << wxT( "; " );
3242 
3243  // write the coordinate to the outputstream
3244  m_points_written = 0;
3245 
3246  *this << Endl() << wxT( " XY 1; " ) << Endl();
3247 
3248  WritePoint( Circle->GetPosX(), Circle->GetPosY() );
3249 
3250  *this << wxT( "RADIUS " ) << Circle->GetRadius() / m_scale_out << wxT( "; " ) << Endl();
3251 }
3252 
3253 void a2dIOHandlerKeyOut::Write( Strans* Strans )
3254 {
3255  // writes only when strans isn't default
3256  if ( ( Strans->m_stransflags.bits.abs_angle != DEFAULT_STRANS_ABS_ANGLE ) ||
3257  ( Strans->m_stransflags.bits.abs_scale != DEFAULT_STRANS_ABS_SCALE ) ||
3258  ( Strans->m_stransflags.bits.reflection != DEFAULT_STRANS_REFLECTION ) ||
3259  ( Strans->GetScale() != DEFAULT_STRANS_SCALE ) ||
3260  ( Strans->GetAngle() != DEFAULT_STRANS_ANGLE ) )
3261  {
3262 
3263  *this << wxT( "STRANS " )
3264  << Strans->m_stransflags.bits.reflection << wxT( "," )
3265  << Strans->m_stransflags.bits.abs_angle << wxT( "," )
3266  << Strans->m_stransflags.bits.abs_scale << wxT( "; " );
3267 
3268  // writes only the scale when different from default
3269  if ( Strans->GetScale() != DEFAULT_STRANS_SCALE )
3270  *this << wxT( "MAG " ) << Strans->GetScale() << wxT( "; " );
3271 
3272  // writes only the angle when different from default
3273  if ( Strans->GetAngle() != DEFAULT_STRANS_ANGLE )
3274  *this << wxT( "ANGLE " ) << Strans->GetAngle() << wxT( "; " );
3275  }
3276 }
3277 
3278 // Elflags ------------------------------------------------------------------
3279 void a2dIOHandlerKeyOut::SetFlags( a2dCanvasObject* Element )
3280 {
3281  if ( ( Element->GetTemplate() != 0 ) ||
3282  ( Element->GetExternal() != 0 ) )
3283  {
3284  m_objectFlags = 0;
3285 
3286  if ( Element->GetTemplate() != 0 )
3287  m_objectFlags += 1 << 1;
3288 
3289  if ( Element->GetExternal() != 0 )
3290  m_objectFlags += 1 << 2;
3291  }
3292 }
3293 
3294 void a2dIOHandlerKeyOut::WriteFlags( int flags )
3295 {
3296  if ( ( flags && 2 != 0 ) ||
3297  ( flags && 1 != 0 ) )
3298  {
3299  int value = 0;
3300 
3301 #ifdef _G_UNIX
3302  if ( ( bool ) ( flags && 2 ) )
3303  value += 2 ^ 1;
3304  if ( ( bool ) ( flags && 1 ) )
3305  value += 2 ^ 2;
3306 #else
3307  if ( ( bool ) ( flags && 1 ) )
3308  value += 2 ^ 2;
3309  if ( ( bool ) ( flags && 2 ) )
3310  value += 2 ^ 1;
3311 #endif
3312 
3313  *this << wxT( "ELFLAGS " ) << value << wxT( "; " );
3314  }
3315 }
3316 
3317 // Point --------------------------------------------------------------------
3318 void a2dIOHandlerKeyOut::WritePoint( double xi, double yi )
3319 {
3320  if ( !( m_points_written % 2 ) )
3321  *this << Endl() << wxT( " " );
3322 
3323  m_points_written++;
3324 
3325  double x;
3326  double y;
3327  if ( xi > 0 )
3328  x = xi / m_scale_out;
3329  else
3330  x = xi / m_scale_out;
3331  if ( yi > 0 )
3332  y = yi / m_scale_out;
3333  else
3334  y = yi / m_scale_out;
3335 
3336  wxString buf;
3337  buf.Printf( wxT( "%18.6lf" ), x );
3338 
3339  *this << wxT( "X " ) << buf << wxT( "; " );
3340 
3341  buf.Printf( wxT( "%18.6lf" ), y );
3342 
3343  *this << wxT( "Y " ) << buf << wxT( "; " );
3344 }
3345 
3346 // Segment -----------------------------------------------------------------
3347 void a2dIOHandlerKeyOut::WriteSegment( const a2dAffineMatrix& lworld, a2dLineSegment* Segment, a2dLineSegment* nextSegment )
3348 {
3349  if ( !( m_points_written % 2 ) )
3350  *this << Endl() << wxT( " " );
3351 
3352  m_points_written++;
3353 
3354  switch ( Segment->GetSegType() )
3355  {
3356  case a2dNORMAL_SEG:break;
3357  case a2dLINK_SEG: *this << wxT( "ST L; " ); break;
3358  case a2dHOLE_SEG: *this << wxT( "ST H; " ); break;
3359  }
3360 
3361  double x, y;
3362  lworld.TransformPoint( Segment->m_x, Segment->m_y, x, y );
3363 
3364  wxString buf;
3365  buf.Printf( wxT( "%18.6f" ), x / m_scale_out );
3366  *this << wxT( "X " ) << buf << wxT( "; " );
3367  buf.Printf( wxT( "%18.6f" ), y / m_scale_out );
3368  *this << wxT( "Y " ) << buf << wxT( "; " );
3369 
3370  if ( nextSegment->GetArc() )
3371  {
3372  if ( !( m_points_written % 2 ) )
3373  *this << Endl() << wxT( " " );
3374  m_points_written++;
3375  a2dArcSegment* aseg = ( a2dArcSegment* ) nextSegment;
3376  lworld.TransformPoint( aseg->m_x2, aseg->m_y2, x, y );
3377 
3378  buf.Printf( wxT( "%18.6f" ), x / m_scale_out );
3379  *this << wxT( "XM " ) << buf << wxT( "; " );
3380  buf.Printf( wxT( "%18.6f" ), y / m_scale_out );
3381  *this << wxT( "YM " ) << buf << wxT( "; " );
3382  if ( !( m_points_written % 2 ) )
3383  *this << Endl() << wxT( " " );
3384  m_points_written++;
3385 
3386  lworld.TransformPoint( aseg->GetOx( *Segment ), aseg->GetOy( *Segment ), x, y );
3387 
3388  buf.Printf( wxT( "%15.3f" ), x / m_scale_out );
3389  *this << wxT( "XO " ) << buf << wxT( "; " );
3390  buf.Printf( wxT( "%15.3f" ), y / m_scale_out );
3391  *this << wxT( "YO " ) << buf << wxT( "; " );
3392  }
3393 }
3394 
3395 void a2dIOHandlerKeyOut::WriteVpath( const a2dAffineMatrix& lworld, const a2dVpath* path, int layer, int datatype, int pathtype, double width )
3396 {
3397  double tstep = 1 / ( double ) SPLINE_STEP;
3398  unsigned int i;
3399 
3400  a2dVertexArray* cpoints = new a2dVertexArray;
3401 
3402  double x, y;
3403  bool move = false;
3404  int count = 0;
3405  bool nostrokeparts = false;
3406 
3407  //first draw as much as possible ( nostroke parts may stop this first round )
3408  for ( i = 0; i < path->size(); i++ )
3409  {
3410  a2dVpathSegment* seg = path->Item( i );
3411  switch ( seg->GetType() )
3412  {
3413  case a2dPATHSEG_MOVETO:
3414  if ( count == 0 )
3415  {
3416  lworld.TransformPoint( seg->m_x1, seg->m_y1, x, y );
3417  cpoints->push_back( new a2dLineSegment( x, y ) );
3418  count++;
3419  }
3420  else
3421  {
3422  i--;
3423  move = true;
3424  }
3425  break;
3426 
3427  case a2dPATHSEG_LINETO:
3428  lworld.TransformPoint( seg->m_x1, seg->m_y1, x, y );
3429  cpoints->push_back( new a2dLineSegment( x, y ) );
3430  count++;
3431  break;
3433  lworld.TransformPoint( seg->m_x1, seg->m_y1, x, y );
3434  cpoints->push_back( new a2dLineSegment( x, y ) );
3435  count++;
3436  nostrokeparts = true;
3437  break;
3438 
3440  nostrokeparts = true;
3441  case a2dPATHSEG_CBCURVETO:
3442  {
3443  double xw, yw;
3444 
3445  double xwl = path->Item( i ? i - 1 : 0 )->m_x1;
3446  double ywl = path->Item( i ? i - 1 : 0 )->m_y1;
3448 
3449  int step;
3450  double t = 0;
3451  for ( step = 0; step <= SPLINE_STEP; step++ )
3452  {
3453  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 );
3454  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 );
3455  lworld.TransformPoint( xw, yw, x, y );
3456  cpoints->push_back( new a2dLineSegment( x, y ) );
3457  count++;
3458  t = t + tstep;
3459  }
3460  }
3461  break;
3462 
3464  nostrokeparts = true;
3465  case a2dPATHSEG_QBCURVETO:
3466  {
3467  double xw, yw;
3468 
3469  double xwl = path->Item( i ? i - 1 : 0 )->m_x1;
3470  double ywl = path->Item( i ? i - 1 : 0 )->m_y1;
3472 
3473  int step;
3474  double t = 0;
3475  for ( step = 0; step <= SPLINE_STEP; step++ )
3476  {
3477  xw = xwl * pow( 1 - t, 2 ) + cseg->m_x2 * ( 1 - t ) * t * 2 + cseg->m_x1 * pow( t, 2 );
3478  yw = ywl * pow( 1 - t, 2 ) + cseg->m_y2 * ( 1 - t ) * t * 2 + cseg->m_y1 * pow( t, 2 );
3479  lworld.TransformPoint( xw, yw, x, y );
3480  cpoints->push_back( new a2dLineSegment( x, y ) );
3481  count++;
3482  t = t + tstep;
3483  }
3484  }
3485  break;
3486 
3488  nostrokeparts = true;
3489  case a2dPATHSEG_ARCTO:
3490  {
3491  a2dVpathArcSegment* cseg = ( a2dVpathArcSegment* ) seg;
3492 
3493  double radius, center_x, center_y, beginrad, midrad, endrad, phit;
3494 
3495  if ( cseg->CalcR( path->Item( i ? i - 1 : 0 ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
3496  {
3497  double dphi;
3498  unsigned int segments;
3499  a2dGlobals->Aberration( phit, radius , dphi, segments );
3500 
3501  double theta = beginrad;
3502  unsigned int step;
3503 
3504  for ( step = 0; step < segments + 1; step++ )
3505  {
3506  lworld.TransformPoint( center_x + radius * cos ( theta ), center_y + radius * sin ( theta ), x, y );
3507  cpoints->push_back( new a2dLineSegment( x, y ) );
3508  count++;
3509  theta = theta + dphi;
3510  }
3511  }
3512  else
3513  {
3514  lworld.TransformPoint( cseg->m_x1, cseg->m_y1, x, y );
3515  cpoints->push_back( new a2dLineSegment( x, y ) );
3516  count++;
3517  }
3518  }
3519  break;
3520  }
3521 
3522  if ( move )
3523  {
3524  WriteVertexArrayPolyline( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width, false, true );
3525  cpoints->clear();
3526  move = false;
3527  count = 0;
3528  }
3529  else if ( seg->GetClose() != a2dPATHSEG_END_OPEN )
3530  {
3531  if ( nostrokeparts || seg->GetClose() == a2dPATHSEG_END_CLOSED_NOSTROKE )
3532  {
3533  WriteVertexArrayPolygon( a2dIDENTITY_MATRIX, cpoints, layer, datatype, 0, false, true );
3534  nostrokeparts = true;
3535  }
3536  else
3537  {
3538  WriteVertexArrayPolygon( a2dIDENTITY_MATRIX, cpoints, layer, datatype, 0, false, true );
3539  }
3540 
3541  cpoints->clear();
3542 
3543  move = false;
3544  count = 0;
3545  }
3546  else if ( i == path->size() - 1 ) //last segment?
3547  {
3548  WriteVertexArrayPolyline( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width, false, true );
3549  cpoints->clear();
3550  }
3551  }
3552 
3553  if ( nostrokeparts )
3554  {
3555  move = false;
3556  count = 0;
3557  cpoints->clear();
3558 
3559  nostrokeparts = false;
3560 
3561  double lastmovex = 0;
3562  double lastmovey = 0;
3563 
3564  for ( i = 0; i < path->size(); i++ )
3565  {
3566  a2dVpathSegment* seg = path->Item( i );
3567  switch ( seg->GetType() )
3568  {
3569  case a2dPATHSEG_MOVETO:
3570  if ( count == 0 )
3571  {
3572  lworld.TransformPoint( seg->m_x1, seg->m_y1, x, y );
3573  cpoints->push_back( new a2dLineSegment( x, y ) );
3574  lastmovex = x;
3575  lastmovey = y;
3576  count++;
3577  }
3578  else
3579  {
3580  i--;
3581  move = true;
3582  }
3583  break;
3584 
3585  case a2dPATHSEG_LINETO:
3586  lworld.TransformPoint( seg->m_x1, seg->m_y1, x, y );
3587  cpoints->push_back( new a2dLineSegment( x, y ) );
3588  count++;
3589  break;
3590 
3595  if ( count == 0 )
3596  {
3597  lworld.TransformPoint( seg->m_x1, seg->m_y1, x, y );
3598  cpoints->push_back( new a2dLineSegment( x, y ) );
3599  count++;
3600  }
3601  else
3602  {
3603  i--;
3604  nostrokeparts = true;
3605  }
3606  break;
3607 
3608  case a2dPATHSEG_CBCURVETO:
3609  {
3610  double xw, yw;
3611 
3612  double xwl = path->Item( i ? i - 1 : 0 )->m_x1;
3613  double ywl = path->Item( i ? i - 1 : 0 )->m_y1;
3615 
3616  int step;
3617  double t = 0;
3618  for ( step = 0; step <= SPLINE_STEP; step++ )
3619  {
3620  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 );
3621  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 );
3622  lworld.TransformPoint( xw, yw, x, y );
3623  cpoints->push_back( new a2dLineSegment( x, y ) );
3624  count++;
3625  t = t + tstep;
3626  }
3627  }
3628  break;
3629 
3630  case a2dPATHSEG_QBCURVETO:
3631  {
3632  double xw, yw;
3633 
3634  double xwl = path->Item( i ? i - 1 : 0 )->m_x1;
3635  double ywl = path->Item( i ? i - 1 : 0 )->m_y1;
3637 
3638  int step;
3639  double t = 0;
3640  for ( step = 0; step <= SPLINE_STEP; step++ )
3641  {
3642  xw = xwl * pow( 1 - t, 2 ) + cseg->m_x2 * ( 1 - t ) * t * 2 + cseg->m_x1 * pow( t, 2 );
3643  yw = ywl * pow( 1 - t, 2 ) + cseg->m_y2 * ( 1 - t ) * t * 2 + cseg->m_y1 * pow( t, 2 );
3644  lworld.TransformPoint( xw, yw, x, y );
3645  cpoints->push_back( new a2dLineSegment( x, y ) );
3646  count++;
3647  t = t + tstep;
3648  }
3649  }
3650  break;
3651 
3652  case a2dPATHSEG_ARCTO:
3653  {
3654  a2dVpathArcSegment* cseg = ( a2dVpathArcSegment* ) seg;
3655 
3656  double radius, center_x, center_y, beginrad, midrad, endrad, phit;
3657 
3658  if ( cseg->CalcR( path->Item( i ? i - 1 : 0 ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
3659  {
3660  double dphi;
3661  unsigned int segments;
3662  a2dGlobals->Aberration( phit, radius , dphi, segments );
3663 
3664  double theta = beginrad;
3665  unsigned int step;
3666 
3667  for ( step = 0; step < segments + 1; step++ )
3668  {
3669  lworld.TransformPoint( center_x + radius * cos ( theta ), center_y + radius * sin ( theta ), x, y );
3670  cpoints->push_back( new a2dLineSegment( x, y ) );
3671  count++;
3672  theta = theta + dphi;
3673  }
3674  }
3675  else
3676  {
3677  lworld.TransformPoint( cseg->m_x1, cseg->m_y1, x, y );
3678  cpoints->push_back( new a2dLineSegment( x, y ) );
3679  count++;
3680  }
3681  }
3682  break;
3683  }
3684 
3685  if ( move || nostrokeparts )
3686  {
3687  WriteVertexArrayPolyline( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width, true );
3688  cpoints->clear();
3689  move = false;
3690  nostrokeparts = false;
3691  count = 0;
3692  }
3693  else if ( seg->GetClose() != a2dPATHSEG_END_OPEN )
3694  {
3695  if ( seg->GetClose() == a2dPATHSEG_END_CLOSED )
3696  {
3697  cpoints->push_back( new a2dLineSegment( lastmovex, lastmovey ) );
3698  count++;
3699  }
3700  WriteVertexArrayPolyline( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width, true );
3701  cpoints->clear();
3702  nostrokeparts = false;
3703  move = false;
3704  count = 0;
3705  }
3706  else if ( i == path->size() )
3707  {
3708  WriteVertexArrayPolyline( a2dIDENTITY_MATRIX, cpoints, layer, datatype, pathtype, width, true );
3709  cpoints->clear();
3710  }
3711  }
3712  }
3713 
3714  delete cpoints;
3715 
3716 }
3717 
3718 // Path ---------------------------------------------------------------------
3719 void a2dIOHandlerKeyOut::WriteVertexArrayPolyline( const a2dAffineMatrix& lworld, a2dVertexArray* points, int layer, int datatype, int pathtype, double width, bool spline, bool close )
3720 {
3721  m_points_written = 0;
3722  *this << Endl() << wxT( "PATH; " );
3723 
3724  WriteFlags( m_objectFlags );
3725 
3726  *this << wxT( "LAYER " ) << m_mapping[layer] << wxT( "; " );
3727  *this << wxT( "DATATYPE " ) << datatype << wxT( "; " );
3728 
3729  if ( pathtype )
3730  *this << wxT( "PATHTYPE " ) << pathtype << wxT( "; " );
3731 
3732  if ( spline )
3733  *this << wxT( "SPLINE 1 ;" );
3734 
3735  if( width )
3736  *this << wxT( "WIDTH " ) << width / m_scale_out << wxT( "; " );
3737 
3738  unsigned int n = points->size();
3739 
3740  *this << Endl() << wxT( " XY " ) << n << wxT( "; " ) << Endl();
3741 
3742  a2dLineSegment* prevseg = 0;
3743  unsigned int i;
3744  a2dLineSegment* nextseg = 0;
3745  for ( i = 0; i < n; i++ )
3746  {
3747  if ( i != n - 1 )
3748  nextseg = points->Item( i + 1 ).Get();
3749  else
3750  nextseg = points->Item( 0 ).Get();
3751  WriteSegment( lworld, points->Item( i ).Get(), nextseg );
3752  }
3753 
3754  if ( close )
3755  *this << Endl() << wxT( "ENDEL; " ) << Endl();
3756 }
3757 
3758 // Path ---------------------------------------------------------------------
3759 void a2dIOHandlerKeyOut::WriteVertexListPolyline( const a2dAffineMatrix& lworld, a2dVertexList* points, int layer, int datatype, int pathtype, double width, bool spline, bool close )
3760 {
3761  m_points_written = 0;
3762 
3763  *this << Endl() << wxT( "PATH; " );
3764 
3765  WriteFlags( m_objectFlags );
3766 
3767  *this << wxT( "LAYER " ) << m_mapping[layer] << wxT( "; " );
3768  *this << wxT( "DATATYPE " ) << datatype << wxT( "; " );
3769 
3770  if ( pathtype )
3771  *this << wxT( "PATHTYPE " ) << pathtype << wxT( "; " );
3772 
3773  if ( spline )
3774  *this << wxT( "SPLINE 1 ;" );
3775 
3776  if( width )
3777  *this << wxT( "WIDTH " ) << width / m_scale_out << wxT( "; " );
3778 
3779  unsigned int n = points->size();
3780 
3781  WritePoly( lworld , points, false );
3782 
3783  if ( close )
3784  *this << Endl() << wxT( "ENDEL; " ) << Endl();
3785 }
3786 
3787 // Boundary------------------------------------------------------------------
3788 void a2dIOHandlerKeyOut::WriteVertexArrayPolygon( const a2dAffineMatrix& lworld, a2dVertexArray* points, int layer, int datatype, double width, bool spline, bool close )
3789 {
3790  m_points_written = 0;
3791 
3792  *this << Endl() << wxT( "BOUNDARY; " );
3793 
3794  WriteFlags( m_objectFlags );
3795 
3796  *this << wxT( "LAYER " ) << m_mapping[layer] << wxT( "; " );
3797  *this << wxT( "DATATYPE " ) << datatype << wxT( "; " );
3798 
3799  if ( spline )
3800  *this << wxT( "SPLINE 1 ;" );
3801 
3802  if( width )
3803  *this << wxT( "WIDTH " ) << width / m_scale_out << wxT( "; " );
3804 
3805  unsigned int n = points->size();
3806 
3807  //last point is repeated so + 1
3808  *this << Endl() << wxT( "XY " ) << n + 1 << wxT( "; " ) << Endl();
3809 
3810  unsigned int i;
3811  a2dLineSegment* nextseg = 0;
3812  for ( i = 0; i < n; i++ )
3813  {
3814  if ( i != n - 1 )
3815  nextseg = points->Item( i + 1 ).Get();
3816  else
3817  nextseg = points->Item( 0 ).Get();
3818  WriteSegment( lworld, points->Item( i ).Get(), nextseg );
3819  }
3820  // not a curve!
3821  //WriteSegment( lworld, points->Item(0).Get(), nextseg );
3822 
3823  WritePoint( points->Item( 0 )->m_x, points->Item( 0 )->m_y );
3824 
3825  if ( close )
3826  {
3827  *this << Endl() << wxT( "ENDEL; " ) << Endl();
3828  }
3829 }
3830 
3831 // Boundary------------------------------------------------------------------
3832 void a2dIOHandlerKeyOut::WriteVertexListPolygon( const a2dAffineMatrix& lworld, a2dVertexList* points, int layer, int datatype, double width, bool spline, bool close )
3833 {
3834  m_points_written = 0;
3835 
3836  *this << Endl() << wxT( "BOUNDARY; " );
3837 
3838  WriteFlags( m_objectFlags );
3839 
3840  *this << wxT( "LAYER " ) << m_mapping[layer] << wxT( "; " );
3841  *this << wxT( "DATATYPE " ) << datatype << wxT( "; " );
3842 
3843  if ( spline )
3844  *this << wxT( "SPLINE 1 ;" );
3845 
3846  if( width )
3847  *this << wxT( "WIDTH " ) << width / m_scale_out << wxT( "; " );
3848 
3849  unsigned int n = points->size();
3850 
3851  WritePoly( lworld , points, true );
3852 
3853  if ( close )
3854  {
3855  *this << Endl() << wxT( "ENDEL; " ) << Endl();
3856  }
3857 }
3858 
3859 void a2dIOHandlerKeyOut::WritePoly( const a2dAffineMatrix& lworld , a2dVertexList* vlist, bool close )
3860 {
3861  unsigned int n = vlist->size();
3862 
3863  //last point is repeated so + 1
3864  *this << Endl() << wxT( "XY " ) << ( close ? n + 1 : n ) << wxT( "; " );
3865 
3866  a2dLineSegment* nextseg = 0;
3867  a2dVertexList::iterator iter = vlist->begin();
3868  unsigned int i = 0;
3869  a2dLineSegment* point;
3870  while ( i < n )
3871  {
3872  point = *iter;
3873  iter++;
3874  if ( i != n - 1 )
3875  nextseg = *iter;
3876  else
3877  nextseg = vlist->front();
3878 
3879  WriteSegment( lworld, point, nextseg );
3880  i++;
3881  }
3882  if ( close )
3883  WritePoint( vlist->front()->m_x, vlist->front()->m_y );
3884 }
3885 
3886 void a2dIOHandlerKeyOut::WriteProperties( const a2dNamedPropertyList& props )
3887 {
3888  *this << Endl();
3889  a2dNamedPropertyList::const_iterator iter;
3890  for( iter = props.begin(); iter != props.end(); ++iter )
3891  {
3892  const a2dNamedProperty* prop = *iter;
3893  if ( prop->GetId()->IsUserDefined() )
3894  {
3895  *this << wxT( "PROPERTY {" ) << prop->GetName() << wxT( "}; " );
3896  if ( wxDynamicCast( prop, a2dStringProperty ) )
3897  {
3898  *this << wxT( "PROPTYPE string; " );
3899  *this << wxT( "PROPVALUE {" ) << prop->StringValueRepresentation() << wxT( "}; " ) << Endl();
3900  }
3901  else if ( wxDynamicCast( prop, a2dInt32Property ) )
3902  {
3903  *this << wxT( "PROPTYPE integer; " );
3904  *this << wxT( "PROPVALUE " ) << prop->StringValueRepresentation() << wxT( "; " ) << Endl();
3905  }
3906  else if ( wxDynamicCast( prop, a2dDoubleProperty ) )
3907  {
3908  *this << wxT( "PROPTYPE real; " );
3909  *this << wxT( "PROPVALUE " ) << prop->StringValueRepresentation() << wxT( "; " ) << Endl();
3910  }
3911  else if ( wxDynamicCast( prop, a2dBoolProperty ) )
3912  {
3913  *this << wxT( "PROPTYPE bool; " );
3914  *this << wxT( "PROPVALUE " ) << prop->StringValueRepresentation() << wxT( "; " ) << Endl();
3915  }
3916  }
3917  }
3918 }
3919 
3920 
3921 
3922 #endif //wxART2D_USE_KEYIO
a2dCanvasObject * GetCanvasObject()
Definition: recur.cpp:104
set check on a2dObject flag false or true
Definition: algos.h:665
a2dCircle at x,y, and with radius
Definition: canprim.h:554
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
Definition: artglob.h:47
a2dAffineMatrix & Mirror(bool y=true, bool x=false)
mirror a matrix in x, y
Definition: afmatrix.cpp:396
a2dPATH_END_TYPE
defines the way a polyline with a contour width is ended.
Definition: polyver.h:31
static const a2dCanvasObjectFlagsMask BIN
Definition: candefs.h:192
(In) Visible property that can be added to Docview Objects.
Definition: gen.h:1785
void SetBoxType(int type)
GDSII compatible to sub identify types of rectangles.
Definition: canprim.h:498
#define wxDynamicCast(obj, className)
Define wxDynamicCast so that it will give a compiler error for unrelated types.
Definition: gen.h:75
Base class for all types of strokes, understood by a2dDrawer2D classes.
Definition: stylebase.h:378
a2dCanvasObjectReference is a reference to any a2dCanvasObject derived class.
Definition: recur.h:53
void SetSegType(a2dSegType type)
Set the type of the segment.
Definition: polyver.h:224
Quadratic Bezier curve.
Definition: polyver.h:984
virtual void InitializeLoad()
Inits the handler for reading.
Definition: gen.cpp:4971
void SetVersion(wxString version)
set version of library or document
Definition: candoc.h:447
diagram is an appearance for a2dCameleon
Definition: cameleon.h:382
bool GetMultiRoot()
Definition: candoc.h:566
wxColour A2DGENERALDLLEXP HexToColour(const wxString &hex)
3-digit hex to wxColour
Definition: gen.cpp:5279
virtual bool IsTemporary_DontSave() const
Check if this is a temporary object, which should not be saved.
Definition: canobj.cpp:6365
a2dSegType GetSegType()
get the type of the segment
Definition: polyver.h:227
virtual wxString GetName() const
Returns the name of this object, if no name is given the internal id will be returned.
Definition: gen.cpp:1310
void Set(double xs, double ys, double xm, double ym, double xe, double ye)
set arc using begin, end and middle point.
Definition: canprim.cpp:3012
double m_x2
control point
Definition: polyver.h:1025
void SetUnitsScale(double scale)
this is the number that defines the physical dimension in meters / inch/ etc.
Definition: candoc.h:608
void MakeStrans(const a2dAffineMatrix &matrix)
create an Strans record for GDSII file
Definition: gdsio.cpp:813
const a2dAffineMatrix & GetTransformMatrix() const
get the matrix used to position the object
Definition: canobj.h:500
wxString m_keyword
keyword for record in KEY data
Definition: keyio.h:129
a2dDrawingId GetDrawingId()
set special id to differentiate drawings
Definition: drawing.h:721
a2dTextGDS text based on wxDC text drawing.
Definition: cantext.h:467
void SetMultiRoot(bool multiRoot=true)
Set true if the document read from a file did not have on erootobject but several.
Definition: candoc.h:563
void ConvertToLines(double aberation=0)
Convert complex segments to line segments.
Definition: polyver.cpp:1948
const int SPLINE_STEP
number of steps when converting a spline to lines.
Definition: artglob.h:334
void SetPosXY12(double x1, double y1, double x2, double y2, bool afterinversion=true)
sets both positions of line
Definition: canprim.cpp:3932
View on a a2dCanvasDocument.
Definition: candoc.h:212
void SetContourWidth(double width)
set the Contour width of the shape
Definition: canprim.h:921
a2dPropertyIdTyped< wxString, a2dStringProperty > a2dPropertyIdString
property of this type
Definition: id.h:665
union Strans::@12 m_stransflags
Strans bit flags for reading and writing to binary file.
unsigned int GetChildObjectsCount() const
get number of child objects
Definition: canobj.cpp:2570
bool GetAvailable()
are there objects on this layer
Definition: layerinf.h:108
void SetRadius(double radius)
set radius
Definition: canprim.h:578
double GetRadius() const
return radius
Definition: canprim.h:581
void SetContourWidth(double width)
set a contour width
Definition: canprim.h:1105
virtual void InitializeSave()
Inits the handler for writing.
Definition: gen.cpp:5095
OVERLAP Intersect(const a2dBoundingBox &, double Marge=0) const
Definition: bbox.cpp:205
virtual void ResetSave()
Reset the object after saving.
Definition: gen.cpp:5101
a2dCanvasObject * GetRootObject() const
get the root object, which holds the objects in the document
Definition: drawing.h:521
Cubic Bezier curve.
Definition: polyver.h:1045
double GetContourWidth() const
get the Contour width of the shape
Definition: vpath.h:158
polygon defined with list of points.
Definition: polygon.h:45
void SetTransformMatrix(const a2dAffineMatrix &mat=a2dIDENTITY_MATRIX)
Returns the matrix used to position the object.
Definition: canobj.h:509
bool Rotate(double angle)
Rotate clockwise by the given number of degrees:
Definition: afmatrix.cpp:432
a2dCanvasObjectList * GetAsCanvasVpaths(bool transform=true) const
when implemented the object without its children, is converted to
Definition: vpath.cpp:67
wxOutputStream a2dDocumentOutputStream
output stream based wxStreams
Definition: gen.h:3458
void SetContourWidth(double width)
set the Contour width of the shape
Definition: polygon.h:564
double m_y2
control point
Definition: polyver.h:1027
void SetSpline(bool on)
set to true, the polygon will be drawn as a spline
Definition: polygon.h:232
property to hold a double type variable to be associated with a a2dObject
Definition: gen.h:2503
double m_y3
control point 2
Definition: polyver.h:1100
double GetUnitsScale()
this is the number that defines the physical dimension in meters / inch/ etc.
Definition: candoc.h:601
a2dDocumentInputStream * m_streami
file or other string stream containing the format to parse.
Definition: gen.h:3734
Arc Segment.
Definition: polyver.h:1112
a2dPropertyIdTyped< wxInt32, a2dInt32Property > a2dPropertyIdInt32
property of this type
Definition: id.h:649
virtual void SetName(const wxString &name)
Set name for layer.
Definition: layerinf.cpp:253
property to hold a bool type variable to be associated with a a2dObject
Definition: gen.h:2004
bool IsIdentity(void) const
Is the matrix the identity matrix?
Definition: afmatrix.h:147
double m_x3
control point 2
Definition: polyver.h:1098
double m_x2
x2 x of arc midpoint
Definition: polyver.h:471
void SetChord(bool chord)
if true draw as a chord ( no fill end no lines to center )
Definition: canprim.cpp:3006
wxString A2DGENERALDLLEXP ColourToHex(const wxColour &colour)
RGB to 3-digit hex.
Definition: gen.cpp:5295
a2dGlobal * a2dGlobals
global a2dCanvasGlobal to have easy access to global settings
Definition: artglob.cpp:34
a2dPropertyIdTyped< bool, a2dBoolProperty > a2dPropertyIdBool
property of this type
Definition: id.h:655
a2dDrawing * GetDrawing() const
get the root object, which holds the objects in the document.
Definition: candoc.h:418
a2dRectC is a centered rectangle
Definition: canprim.h:99
virtual void InitializeSave()
Inits the handler for writing.
Definition: keyio.cpp:2460
int GetDataType()
GDSII compatible to sub identify this object.
Definition: vpath.h:166
The base class for all drawable objects in a a2dCanvasDocument.
void SetFilename(const wxString filename, wxBitmapType type, bool doread=true)
set filename and type of image for saving.
Definition: canimage.cpp:249
wxString GetName() const
Get the name of the a2dPropertyId object.
Definition: gen.h:1864
list of a2dNamedProperty objects
Definition: gen.h:804
void SetLibraryName(const wxString &libraryname)
to name the document as a library (independent of a path and filename )
Definition: candoc.h:441
Arc Segment in a2dVertexList.
Definition: polyver.h:371
vertex array of line and arc segments.
Definition: polyver.h:494
object to show several appearance views on what it contains
Definition: cameleon.h:630
void SetDrawingId(a2dDrawingId id)
get special id to differentiate drawings
Definition: drawing.h:723
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
this segmnet is part of a hole
Definition: polyver.h:152
std::vector< a2dLayerInfoPtr > & GetLayerIndex()
return array index on Layer
Definition: layerinf.cpp:555
a2dAffineMatrix a2dIDENTITY_MATRIX
global a2dAffineMatrix to set/pass the identity matrix.
Definition: afmatrix.cpp:51
double m_y2
control point 1
Definition: polyver.h:1095
Docview framework its controlling class.
a2dCanvasObjectArrayReference is an array of a reference to any a2dCanvasObject derived class...
Definition: recur.h:131
Holds an error message.
KEY input and output.
a2dPATHSEG_END GetClose() const
is this segment the closing a part since the last move
Definition: polyver.h:910
not specific or part of outer contour
Definition: polyver.h:148
a2dLayers * GetLayerSetup()
Get the layersettings for the canvas.
Definition: candoc.h:555
void SetWidth(double w)
set width of rectangle
Definition: canprim.h:328
a2dLayers * GetLayerSetup()
Get the layersettings for the canvas.
Definition: drawing.h:506
a2dCanvasObjectList * GetChildObjectList()
get the list where the child objects are stored in.
Definition: canobj.cpp:2551
vertex list of line and arc segments.
Definition: polyver.h:600
a2dPATH_END_TYPE GetPathType()
get when m_contourwidth != 0 what is the end of the lines looks like.
Definition: vpath.h:172
void TransformPoint(double x, double y, double &tx, double &ty) const
Transform a point.
Definition: afmatrix.cpp:559
a2dCanvasDocument * m_doc
the document to store/load the data found into
Definition: keyio.h:293
special a2dCanvasObject which are used to create hierarchy different from the standard a2dCanvasObjec...
bool GetVisible()
is the layer visible
Definition: layerinf.cpp:341
virtual void SetName(const wxString &name)
Creates the a2dStringProperty PROPID_Name.
Definition: gen.cpp:1305
wxUint32 m_linenumber
last read line in DATA
Definition: keyio.h:137
store and convert number to number with unit and visa versa. e.g. 1.23e-6 =&gt; 1.23 * 1e-6 ...
Definition: artglob.h:208
a2dPATH_END_TYPE GetPathType()
get when m_contourwidth != 0 what is the end of the line looks like.
Definition: polygon.h:404
virtual bool CanLoad(a2dDocumentInputStream &stream, const wxObject *obj=NULL, wxClassInfo *docClassInfo=NULL)
Should return true if the handler can read from the stream.
Definition: keyio.cpp:482
void SetBin(bool bin)
general flag use at will.
Definition: canobj.h:2259
void SetUnitsAccuracy(double accuracy)
this is the number that defines the number of decimal places in the fraction
Definition: candoc.h:595
void SetContourWidth(double width)
set the Contour width of the shape
Definition: polygon.h:237
void AddToRoot(bool autoPlace=true)
add this to ms_centralCameleonRoot at a suitable position
Definition: cameleon.cpp:1260
vector path a2dVectorPath derived from a2dCanvasObject
GDSII format input and output.
Definition: gdserr.h:23
a2dIOHandlerStrIn & SeekI(wxFileOffset pos)
set stream at a position
Definition: gen.cpp:5021
property to hold a 2 byte integer type variable to be associated with a a2dObject ...
Definition: gen.h:2401
void SetHeight(double h)
set height of rectangle
Definition: canprim.h:334
bool GetCheck() const
general flag use at will.
Definition: gen.h:1342
a2dStrokeStyle StrokeString2Style(const wxString &stylestr)
convert a string to a style enum
Definition: stylebase.cpp:5258
void SetRootRecursive()
set a2dDrawing to its nested a2dCanvasObject&#39;s recursive for whole tree
Definition: drawing.cpp:913
a2dText is an abstract base class.
Definition: cantext.h:93
a2dCanvasObjectList * wxNullCanvasObjectList
define a NON a2dCanvasObjectList
Definition: objlist.cpp:53
void SetPathType(a2dPATH_END_TYPE pathtype)
Set when m_contourwidth != 0 what is the end of the line should be.
Definition: polygon.h:401
wxUint16 GetTextType()
GDSII compatible to sub identify types of rectangles.
Definition: cantext.h:497
bool HasArcs() const
return true if there are a2dArcSegment segments.
Definition: polyver.cpp:1761
virtual wxString GetName() const
Get name for layer.
Definition: layerinf.cpp:248
wxString GetVersion()
get version of library or document
Definition: candoc.h:450
double GetMinX() const
get minimum X of the boundingbox
Definition: bbox.cpp:304
a2dCameleon * GetCameleon()
this appearance is for the returned a2dCameleon here.
Definition: cameleon.h:229
void SetColour(const wxColour &col)
set colour used for gradient and wxSTROKE_MASK_OPAQUE filling.
Definition: stylebase.cpp:6112
virtual void InitializeLoad()
Inits the handler for reading.
Definition: keyio.cpp:468
#define forEachIn(listtype, list)
easy iteration for a2dlist
Definition: a2dlist.h:111
bool IsUserDefined() const
true if this property is user defined
Definition: id.h:277
a2dEllipse centered at x,y.
Definition: canprim.h:635
polyline defined with list of points.
Definition: polygon.h:332
void SetPropertyToObject(a2dObject *obj, const basetype &value, SetFlags setflags=set_none) const
Set the property in obj to value.
Definition: id.inl:238
a2dCameleonInst to show one appearance of an a2dCameleon.
Definition: cameleon.h:272
double GetPosX() const
get x position from affine matrix
Definition: canobj.h:527
layer settings for a a2dCanvasDocument Holds layers settings classes
void SetTextType(wxUint16 type)
GDSII compatible to sub identify types of rectangles.
Definition: cantext.h:493
wxString GetUnits()
this string defines the unit e.g. meters / inch/ etc.
Definition: candoc.h:632
Definition: bbox.h:26
Normal straight line segment in a2dVpath.
Definition: polyver.h:878
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
Definition: gen.h:123
a2dVertexListPtr GetSegments()
Get the list of points ( this is not a copy! )
Definition: polygon.h:219
static a2dPropertyIdBool * PROPID_TemporaryObject
set for objects that do not have to be saved
Definition: canobj.h:2681
a2dCanvasObject * GetShowObject() const
return pointer of then currently shown object on the drawer.
Definition: drawer.h:680
a2dImage (will scale/rotate image when needed)
Definition: canimage.h:33
Normal straight line segment in a2dVertexList and a2dVertexArray.
Definition: polyver.h:163
a2dSLine
Definition: canprim.h:987
bool CalcR(a2dVpathSegmentPtr prev, double &radius, double &center_x, double &center_y, double &beginrad, double &midrad, double &endrad, double &phit)
Calculation of center for the Arc.
Definition: polyver.cpp:3820
void SetTextHeight(double height)
set text height in world coordinates
Definition: cantext.h:173
a2dCanvasObjectList * GetAsCanvasVpaths(bool transform=true) const
return text as a vector path, where text outline is converted to polyline or polygons.
Definition: cantext.cpp:247
TWO_G_BYTE_UNSIGNED_INTEGER m_recordsize
size of the last read record
Definition: keyio.h:144
double GetLineHeight() const
Height in world coordinates of one line.
Definition: cantext.h:179
virtual void ResetSave()
Reset the object after saving.
Definition: keyio.cpp:2468
const a2dPropertyId * GetId() const
Get the a2dPropertyId object identifying this property.
Definition: gen.h:1858
wxUint16 GetLayer() const
Returns the layer index where this object is drawn upon.
Definition: canobj.h:2368
int CollectObjects(a2dCanvasObjectList *total, const wxString &type=wxT(""), a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL, const a2dPropertyId *id=NULL, const a2dBoundingBox &bbox=wxNonValidBbox)
Copy objects fitting the given filter to the total list.
Definition: objlist.cpp:663
void SetColour(const wxColour &col)
set colour used for gradient and wxSTIPPLE_MASK_OPAQUE filling.
Definition: stylebase.cpp:4988
void SetMin(double px, double py)
set the bounding box its maximum
Definition: bbox.cpp:340
contains the layer properties for one layer,
Definition: layerinf.h:41
bool GetBin() const
general flag use at will.
Definition: canobj.h:2262
double GetTextHeight() const
get text height in world coordinates
Definition: cantext.h:176
Tappear * GetAppearance(bool autoCreate=false)
Get a specific a2dAppear derived class instance from here.
Definition: cameleon.h:666
bool GetSpline()
Get the polygon spline setting.
Definition: polygon.h:235
a2dArrow is used for having line begin and ends on specific objects.
Definition: canprim.h:198
a2dHashMapIntToObject & GetObjectHashMap()
This is used to find multiple referenced objects by id.
Definition: gen.h:3479
set a2dCanvasObjects flags in a hierarchy of a a2dCanvasDocument
Definition: algos.h:486
wxDateTime & GetModificationTime()
Returns the time of last modification when the document was saved.
Definition: docviewref.h:1410
std::vector< int > m_mapping
mapping of GDSII layers to internal layers
Definition: keyio.h:290
void SetWidth(double width)
set width
Definition: canimage.h:118
property to hold a wxString type variable to be associated with a a2dObject
Definition: gen.h:2066
wxFileName GetFilename() const
Get the file name in use for this document.
Definition: docviewref.h:1103
double m_x2
control point 1
Definition: polyver.h:1093
double GetContourWidth() const
get the Contour width of the shape
Definition: polygon.h:240
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
a2dView * GetCurrentView() const
return the one that is active right now (e.g. has focus in case of a wxWindow), or NULL ...
Definition: doccom.cpp:1185
double GetOy(const a2dLineSegment &prev) const
Get origin Y of arc.
Definition: polyver.cpp:449
bool CanSave(const wxObject *obj=NULL)
Should return true if the handler can write this document to a stream.
Definition: keyio.cpp:2453
wxClassInfo * m_docClassInfo
Run-time class information that allows document instances to be constructed dynamically.
Definition: gen.h:3737
double GetMaxX() const
get maximum X of the boundingbox
Definition: bbox.cpp:316
double m_y2
y2 y of arc midpoint
Definition: polyver.h:473
double GetPosY() const
get y position from affine matrix
Definition: canobj.h:530
bool LoadLayers(const wxString &filename)
load layers from another file
Definition: candoc.cpp:1010
bool GetFilling() const
if true, filling is on else filling is transparent.
Definition: stylebase.cpp:5069
void Aberration(double angle, double radius, double &dphi, unsigned int &segments)
based on angle and radius and m_displayaberration calculate a proper delta phi and number of segments...
Definition: artglob.cpp:154
void SetMax(double px, double py)
set the bounding box its minimum
Definition: bbox.cpp:352
a2dSegType
defines the type of a segment in a a2dLineSegment
Definition: polyver.h:145
double GetOx(const a2dLineSegment &prev) const
Get origin X of arc.
Definition: polyver.cpp:417
wxInputStream a2dDocumentInputStream
input stream based wxStreams
Definition: gen.h:3456
virtual void WriteDouble(double d)
write a double number.
Definition: keyio.h:219
double m_x
x endpoint of line
Definition: polyver.h:232
polygon defined with list of points for outer contour plus a list of hole polygons ...
Definition: polygon.h:502
a2dWalker based algorithms
wxString m_value
value for record in KEY data
Definition: keyio.h:131
a2dVertexListPtr GetSegments()
Get the list of points ( this is not a copy! )
Definition: polygon.h:546
a2dCanvasDocument * m_doc
the document to store/load the data found into
Definition: keyio.h:150
special a2dCanvasObject to make a multi view hierachy.
double m_y
y endpoint of line
Definition: polyver.h:235
a2dDocviewGlobal * a2dDocviewGlobals
a global pointer to get to global instance of important classes.
Definition: doccom.cpp:2348
a2dPATHSEG GetType() const
easy way to test type of segment
Definition: polyver.h:901
Output driver for KEY files.
Definition: keyio.h:175
void SetStroke(const wxColour &strokecolor, double width=0, a2dStrokeStyle style=a2dSTROKE_SOLID)
Set a stroke for the object which will be used instead of the layer stroke.
Definition: canobj.cpp:2924
std::vector< a2dLayerInfoPtr > & GetReverseOrderIndex()
return array index on ReverseOrder
Definition: layerinf.cpp:569
void SetHeight(double height)
set height
Definition: canimage.h:122
virtual bool Load(a2dDocumentInputStream &stream, wxObject *doc)
override to read the stream and store (part of) the contents in to a specific a2dDocument or othere o...
Definition: keyio.cpp:540
double GetUnitsAccuracy()
this is the number that defines the number of decimal places in the fraction
Definition: candoc.h:586
void SetText(const wxString &text)
set the text for the object &#39; &#39; in string means new line
Definition: cantext.h:165
bool m_textAsPath
if true, vonvert text to a2dVpath
Definition: keyio.h:306
Each a2dCanvasView needs to have a a2dCanvasDocument set in order to render data. ...
Definition: candoc.h:374
bool GetRelease() const
get release flag
Definition: gen.h:1350
void SetAberPolyToArc(const a2dDoMu &aber)
Polygon/polyline to Arc Maximum abberation.
Definition: canglob.cpp:815
double m_y1
y endpoint of line
Definition: polyver.h:922
class to hold GDS-II transformation info, only used within the GDSII reader
Definition: gdsio.h:168
wxString StrokeStyle2String(a2dStrokeStyle style)
convert a style enum to a string
Definition: stylebase.cpp:5224
double GetMaxY() const
get maximum Y of the boundingbox
Definition: bbox.cpp:322
int m_recordtype
type of the record in KEY data
Definition: keyio.h:134
wxString GetMultiplierString() const
get the number 1.1 um -&gt; &quot;um&quot;
Definition: artglob.cpp:353
bool m_back
last read record is stored
Definition: keyio.h:126
void SetUnits(const wxString &unitString)
this string defines the unit e.g. meters / inch/ etc.
Definition: candoc.h:643
wxColour GetColour() const
return colour
Definition: stylebase.cpp:5012
a2dAppear * GetAppearance()
get referenced a2dCameleon
Definition: cameleon.h:293
void SetPosXY(double x, double y, bool restrict=false)
set position to x,y
Definition: canobj.cpp:1624
bool Scale(double scale)
Scale by scale (isotropic scaling i.e. the same in x and y):
Definition: afmatrix.cpp:270
bool Start(a2dCanvasObject *object, bool setTo)
start removing properties from the object given, and down.
Definition: algos.cpp:784
bool Translate(double x, double y)
Translate by dx, dy:
Definition: afmatrix.cpp:420
virtual void ReportErrorF(const a2dError &error, const wxChar *Format,...)
concatenate to the the error report the given error.
Definition: comevt.cpp:1312
const a2dError a2dError_NotSpecified
a2dDocumentCommandProcessor * GetDocviewCommandProcessor() const
Gets a2dDocumentCommandProcessor pointer.
Definition: doccom.h:1034
virtual wxString StringValueRepresentation() const
Definition: gen.h:1905
a2dRect
Definition: canprim.h:440
const a2dNamedPropertyList & GetPropertyList() const
Get the Property List.
Definition: gen.h:1510
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
Definition: bbox.h:39
std::vector< a2dLayerInfoPtr > & GetOrderIndex()
return array index on Order
Definition: layerinf.cpp:562
void SetTitle(const wxString &title, bool notifyViews=false)
Sets the title for this document.
void SetLayerSetup(a2dLayers *layersetup)
set the layersettings for the canvas.
Definition: drawing.cpp:280
all polygon and polyline a2dCanvasObject are here.
A property id defined by user.
Definition: id.h:207
double GetMinY() const
get minimum Y of the boundingbox
Definition: bbox.cpp:310
void SetFilling(bool OnOff)
Definition: stylebase.cpp:5060
a2dArc centered at x,y
Definition: canprim.h:823
the a2dDrawingPart is a a2dView specially designed for displaying parts of a a2dDrawing. It uses a a2dDrawer2D to actually redraw things from the document, by giving that a2dDrawer2D as drawing context to the document, and telling the document to redraw a certain rectangular area. At that last is what this class is for. It optimizes the areas to be redrawn after object in the document were changed. To do that it combines redraw areas to a minimal set of redrawing areas. All the administration for this and the way things will be redrawn is from this view.
virtual void ResetLoad()
Reset the handler after loading.
Definition: keyio.cpp:477
double m_x1
x endpoint of line
Definition: polyver.h:919
virtual bool Save(a2dDocumentOutputStream &stream, const wxObject *doc)
Override to write to the stream and store (part of) of the document contents in the stream...
Definition: keyio.cpp:2493
basetype GetPropertyValue(const a2dObject *obj) const
Get the property value in obj.
Definition: id.inl:325
a2dVpath * GetSegments()
modify point at index to x,y
Definition: vpath.h:117
a2dCanvasGlobal * a2dCanvasGlobals
global a2dCanvasGlobal to have easy access to global settings
Definition: canglob.cpp:1234
a2dCanvasObject for a Vector Path
Definition: vpath.h:55
This template class is for property ids with a known data type.
Definition: id.h:477
Vector Path.
Definition: polyver.h:1211
wxMBConv & m_conv
unicode conversion
Definition: gen.h:3822
links an outside contour with a hole
Definition: polyver.h:150
const a2dDoMu & GetAberPolyToArc() const
Polygon/polyline to Arc Maximum abberation.
Definition: canglob.h:727
void SetLineSpacing(double linespace)
Set Space in world coordinates between two lines.
Definition: cantext.h:187
static void SetCameleonRoot(a2dCanvasObject *cameleonRoot)
set the root where all a2dCameleon&#39;s are stored
Definition: cameleon.h:714
void Append(a2dCanvasObject *obj)
append a a2dCanvasObject to the childobjects
Definition: canobj.cpp:6224
a2dStrokeStyle
stroke styles for a2dStroke
Definition: stylebase.h:298
wxDateTime & GetAccessTime()
Returns the time of last access.
Definition: candoc.h:652
static a2dPropertyIdUint16 * PROPID_Datatype
used in GDSII and KEY format to specify the DATATYPE of elements
Definition: canobj.h:2700
wxString GetText() const
get the text of the object &#39; &#39; in string means new line
Definition: cantext.h:168
void SetContourWidth(double width)
set the Contour width of the shape
Definition: canprim.h:482
void SetShowObject(a2dCanvasObject *show)
what to display when document is openened
Definition: candoc.h:576
void SetContourWidth(double width)
set the Contour width of the shape
Definition: canprim.h:584
void SetTopCameleon(a2dCameleon *root)
what is the top a2dcameleon in the drawing to display after opening a document, when m_show is not se...
Definition: candoc.h:571
virtual bool LinkReferences(bool ignoreNonResolved=false)
link references to their destination
Definition: gen.cpp:4862
A pointer class, that automatically calls SmrtPtrOwn/SmrtPtrRelease.
Definition: a2dlist.h:20
a2dDocumentOutputStream * m_streamo
file or other string stream containing the format to output to.
Definition: gen.h:3825
wxString GetTitle() const
Returns the title for this document.
Definition: docviewref.h:1118
virtual void WriteString(const wxString &string)
write a string
Definition: gen.cpp:5107
double GetContourWidth() const
get the Contour width of the shape
Definition: canprim.h:587
virtual void ResetLoad()
Reset the handler after loading.
Definition: gen.cpp:4977
bool ResolveOrAddLink(a2dObject *obj, const wxString &id=wxT(""))
try to resolve an object referenced by obj using the LinkReference function
Definition: gen.cpp:4808
void SetDataTypeProperty(a2dCanvasObject *toobject, wxUint16 type)
set datatype of elements as a property
Definition: keyio.cpp:2344
a2dBoundingBox & GetBbox()
get boundingbox in world coordinates exclusive stroke width relative to its parent ...
Definition: canobj.cpp:3175
wxString & GetLibraryName()
Get name the document as a library (independent of a path and filename )
Definition: candoc.h:444
void SetFill(const a2dFill &fill)
Set a fill for the object which will be used instead of the layer fill.
Definition: canobj.cpp:2874
std::vector< int > m_mapping
mapping of GDSII layers to internal layers
Definition: keyio.h:147
a2dEllipticArc centered at x,y
Definition: canprim.h:697
a2dPropertyIdTyped< double, a2dDoubleProperty > a2dPropertyIdDouble
property of this type
Definition: id.h:657
general canvas module declarations and classes
keyio.cpp Source File -- Sun Oct 12 2014 17:04:21 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation