KiCad PCB EDA Suite
drawing_sheet_reader.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 1992-2013 Jean-Pierre Charras <jp.charras at wanadoo.fr>.
5  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <eda_item.h>
27 #include <locale_io.h>
28 #include <kicad_string.h>
33 #include <drawing_sheet/drawing_sheet_reader_lexer.h>
34 #include <wx/ffile.h>
35 #include <wx/log.h>
36 
37 #include <wx/file.h>
38 #include <wx/mstream.h>
39 
40 
41 using namespace TB_READER_T;
42 
48 class DRAWING_SHEET_READER_PARSER : public DRAWING_SHEET_READER_LEXER
49 {
50 public:
51  DRAWING_SHEET_READER_PARSER( const char* aLine, const wxString& aSource );
52  void Parse( DS_DATA_MODEL* aLayout );
53 
54 private:
56 
61  void parseHeader( T aHeaderType );
62 
66  int parseInt();
67 
75  int parseInt( int aMin, int aMax );
76 
82  double parseDouble();
83 
84  void parseSetup( DS_DATA_MODEL* aLayout );
85 
89  void parseGraphic( DS_DATA_ITEM * aItem );
90 
94  void parseText( DS_DATA_ITEM_TEXT * aItem );
95 
100  void parsePolygon( DS_DATA_ITEM_POLYGONS * aItem );
101 
105  void parsePolyOutline( DS_DATA_ITEM_POLYGONS * aItem );
106 
107 
111  void parseBitmap( DS_DATA_ITEM_BITMAP * aItem );
112 
113  void parseCoordinate( POINT_COORD& aCoord);
114  void readOption( DS_DATA_ITEM * aItem );
115  void readPngdata( DS_DATA_ITEM_BITMAP * aItem );
116 };
117 
118 // PCB_PLOT_PARAMS_PARSER
119 
121  const wxString& aSource ) :
122  DRAWING_SHEET_READER_LEXER( aLine, aSource ),
123  m_requiredVersion( 0 )
124 {
125 }
126 
127 
128 wxString convertLegacyVariableRefs( const wxString& aTextbase )
129 {
130  wxString msg;
131 
132  /*
133  * Legacy formats
134  * %% = replaced by %
135  * %K = Kicad version
136  * %Z = paper format name (A4, USLetter)
137  * %Y = company name
138  * %D = date
139  * %R = revision
140  * %S = sheet number
141  * %N = number of sheets
142  * %L = layer name
143  * %Cx = comment (x = 0 to 9 to identify the comment)
144  * %F = filename
145  * %P = sheet path (sheet full name)
146  * %T = title
147  */
148 
149  for( unsigned ii = 0; ii < aTextbase.Len(); ii++ )
150  {
151  if( aTextbase[ii] != '%' )
152  {
153  msg << aTextbase[ii];
154  continue;
155  }
156 
157  if( ++ii >= aTextbase.Len() )
158  break;
159 
160  wxChar format = aTextbase[ii];
161 
162  switch( format )
163  {
164  case '%': msg += '%'; break;
165  case 'D': msg += wxT( "${ISSUE_DATE}" ); break;
166  case 'R': msg += wxT( "${REVISION}" ); break;
167  case 'K': msg += wxT( "${KICAD_VERSION}" ); break;
168  case 'Z': msg += wxT( "${PAPER}" ); break;
169  case 'S': msg += wxT( "${#}" ); break;
170  case 'N': msg += wxT( "${##}" ); break;
171  case 'F': msg += wxT( "${FILENAME}" ); break;
172  case 'L': msg += wxT( "${LAYER}" ); break;
173  case 'P': msg += wxT( "${SHEETNAME}" ); break;
174  case 'Y': msg += wxT( "${COMPANY}" ); break;
175  case 'T': msg += wxT( "${TITLE}" ); break;
176  case 'C':
177  format = aTextbase[++ii];
178 
179  switch( format )
180  {
181  case '0': msg += wxT( "${COMMENT1}" ); break;
182  case '1': msg += wxT( "${COMMENT2}" ); break;
183  case '2': msg += wxT( "${COMMENT3}" ); break;
184  case '3': msg += wxT( "${COMMENT4}" ); break;
185  case '4': msg += wxT( "${COMMENT5}" ); break;
186  case '5': msg += wxT( "${COMMENT6}" ); break;
187  case '6': msg += wxT( "${COMMENT7}" ); break;
188  case '7': msg += wxT( "${COMMENT8}" ); break;
189  case '8': msg += wxT( "${COMMENT9}" ); break;
190  }
191  break;
192 
193  default:
194  break;
195  }
196  }
197 
198  return msg;
199 }
200 
201 
203 {
204  DS_DATA_ITEM* item;
205  LOCALE_IO toggle;
206 
207  NeedLEFT();
208  T token = NextTok();
209 
210  parseHeader( token );
212 
213  for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
214  {
215  if( token == T_LEFT )
216  token = NextTok();
217 
218  switch( token )
219  {
220  case T_setup: // Defines default values for graphic items
221  parseSetup( aLayout );
222  break;
223 
224  case T_line:
226  parseGraphic( item );
227  aLayout->Append( item );
228  break;
229 
230  case T_rect:
231  item = new DS_DATA_ITEM( DS_DATA_ITEM::DS_RECT );
232  parseGraphic( item );
233  aLayout->Append( item );
234  break;
235 
236  case T_polygon:
237  item = new DS_DATA_ITEM_POLYGONS();
239  aLayout->Append( item );
240  break;
241 
242  case T_bitmap:
243  item = new DS_DATA_ITEM_BITMAP( NULL );
244  parseBitmap( (DS_DATA_ITEM_BITMAP*) item );
245  aLayout->Append( item );
246  break;
247 
248  case T_tbtext:
249  NeedSYMBOLorNUMBER();
250  item = new DS_DATA_ITEM_TEXT( convertLegacyVariableRefs( FromUTF8() ) );
251  parseText( (DS_DATA_ITEM_TEXT*) item );
252  aLayout->Append( item );
253  break;
254 
255  default:
256  Unexpected( CurText() );
257  break;
258  }
259  }
260 }
261 
263 {
264  // The older files had no versioning and their first token after the initial left parenthesis
265  // was a `page_layout` or `drawing_sheet` token. The newer files have versions and have a
266  // `kicad_wks` token instead.
267 
268  if( aHeaderType == T_kicad_wks )
269  {
270  NeedLEFT();
271 
272  T tok = NextTok();
273 
274  if( tok == T_version )
275  {
277  NeedRIGHT();
278  }
279  else
280  {
281  Expecting( T_version );
282  }
283 
284  // Ignore generator info.
285  NeedLEFT();
286  NeedSYMBOL();
287  NeedSYMBOL();
288  NeedRIGHT();
289  }
290  else
291  {
292  // We assign version 0 to files that were created before there was any versioning of
293  // worksheets. The below line is not strictly necessary, as `m_requiredVersion` is already
294  // initialized to 0 in the constructor.
295  m_requiredVersion = 0;
296  }
297 }
298 
300 {
301  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
302  {
303  switch( token )
304  {
305  case T_LEFT:
306  break;
307 
308  case T_linewidth:
309  aLayout->m_DefaultLineWidth = parseDouble();
310  NeedRIGHT();
311  break;
312 
313  case T_textsize:
314  aLayout->m_DefaultTextSize.x = parseDouble();
315  aLayout->m_DefaultTextSize.y = parseDouble();
316  NeedRIGHT();
317  break;
318 
319  case T_textlinewidth:
320  aLayout->m_DefaultTextThickness = parseDouble();
321  NeedRIGHT();
322  break;
323 
324  case T_left_margin:
325  aLayout->SetLeftMargin( parseDouble() );
326  NeedRIGHT();
327  break;
328 
329  case T_right_margin:
330  aLayout->SetRightMargin( parseDouble() );
331  NeedRIGHT();
332  break;
333 
334  case T_top_margin:
335  aLayout->SetTopMargin( parseDouble() );
336  NeedRIGHT();
337  break;
338 
339  case T_bottom_margin:
340  aLayout->SetBottomMargin( parseDouble() );
341  NeedRIGHT();
342  break;
343 
344  default:
345  Unexpected( CurText() );
346  break;
347  }
348  }
349 
350  // The file is well-formed. If it has no further items, then that's the way the
351  // user wants it.
352  aLayout->AllowVoidList( true );
353 }
354 
355 
357 {
358  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
359  {
360  if( token == T_LEFT )
361  token = NextTok();
362 
363  switch( token )
364  {
365  case T_comment:
366  NeedSYMBOLorNUMBER();
367  aItem->m_Info = FromUTF8();
368  NeedRIGHT();
369  break;
370 
371  case T_pos:
372  parseCoordinate( aItem->m_Pos );
373  break;
374 
375  case T_name:
376  NeedSYMBOLorNUMBER();
377  aItem->m_Name = FromUTF8();
378  NeedRIGHT();
379  break;
380 
381  case T_option:
382  readOption( aItem );
383  break;
384 
385  case T_pts:
386  parsePolyOutline( aItem );
387  aItem->CloseContour();
388  break;
389 
390  case T_rotate:
391  aItem->m_Orient = parseDouble();
392  NeedRIGHT();
393  break;
394 
395  case T_repeat:
396  aItem->m_RepeatCount = parseInt( -1, 100 );
397  NeedRIGHT();
398  break;
399 
400  case T_incrx:
401  aItem->m_IncrementVector.x = parseDouble();
402  NeedRIGHT();
403  break;
404 
405  case T_incry:
406  aItem->m_IncrementVector.y = parseDouble();
407  NeedRIGHT();
408  break;
409 
410  case T_linewidth:
411  aItem->m_LineWidth = parseDouble();
412  NeedRIGHT();
413  break;
414 
415  default:
416  Unexpected( CurText() );
417  break;
418  }
419  }
420 
421  aItem->SetBoundingBox();
422 }
423 
425 {
426  DPOINT corner;
427 
428  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
429  {
430  if( token == T_LEFT )
431  token = NextTok();
432 
433  switch( token )
434  {
435  case T_xy:
436  corner.x = parseDouble();
437  corner.y = parseDouble();
438  aItem->AppendCorner( corner );
439  NeedRIGHT();
440  break;
441 
442  default:
443  Unexpected( CurText() );
444  break;
445  }
446  }
447 }
448 
449 
451 {
453  aItem->m_ImageBitmap = image;
454 
455  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
456  {
457  if( token == T_LEFT )
458  token = NextTok();
459 
460  switch( token )
461  {
462  case T_name:
463  NeedSYMBOLorNUMBER();
464  aItem->m_Name = FromUTF8();
465  NeedRIGHT();
466  break;
467 
468  case T_pos:
469  parseCoordinate( aItem->m_Pos );
470  break;
471 
472  case T_repeat:
473  aItem->m_RepeatCount = parseInt( -1, 100 );
474  NeedRIGHT();
475  break;
476 
477  case T_incrx:
478  aItem->m_IncrementVector.x = parseDouble();
479  NeedRIGHT();
480  break;
481 
482  case T_incry:
483  aItem->m_IncrementVector.y = parseDouble();
484  NeedRIGHT();
485  break;
486 
487  case T_linewidth:
488  aItem->m_LineWidth = parseDouble();
489  NeedRIGHT();
490  break;
491 
492  case T_scale:
493  aItem->m_ImageBitmap->SetScale( parseDouble() );
494  NeedRIGHT();
495  break;
496 
497  case T_pngdata:
498  readPngdata( aItem );
499  break;
500 
501  case T_option:
502  readOption( aItem );
503  break;
504 
505  default:
506  Unexpected( CurText() );
507  break;
508  }
509  }
510 }
511 
513 {
514  std::string tmp;
515 
516  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
517  {
518  if( token == T_LEFT )
519  token = NextTok();
520 
521  switch( token )
522  {
523  case T_data:
524  NeedSYMBOLorNUMBER();
525  tmp += CurStr();
526  tmp += "\n";
527  NeedRIGHT();
528  break;
529 
530  default:
531  Unexpected( CurText() );
532  break;
533  }
534  }
535 
536  tmp += "EndData";
537 
538  wxString msg;
539  STRING_LINE_READER str_reader( tmp, wxT("Png kicad_wks data") );
540 
541  if( ! aItem->m_ImageBitmap->LoadData( str_reader, msg ) )
542  wxLogMessage(msg);
543 }
544 
545 
547 {
548  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
549  {
550  switch( token )
551  {
552  case T_page1only: aItem->SetPage1Option( FIRST_PAGE_ONLY ); break;
553  case T_notonpage1: aItem->SetPage1Option( SUBSEQUENT_PAGES ); break;
554  default: Unexpected( CurText() ); break;
555  }
556  }
557 }
558 
559 
561 {
562  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
563  {
564  if( token == T_LEFT )
565  token = NextTok();
566  else
567  {
568  // If another token than T_LEFT is read here, this is an error
569  // however, due to a old bug in kicad, the token T_end can be found
570  // without T_LEFT in a very few .wks files (perhaps only one in a demo).
571  // So this ugly hack disables the error detection.
572  if( token != T_end )
573  Unexpected( CurText() );
574  }
575 
576  switch( token )
577  {
578  case T_comment:
579  NeedSYMBOLorNUMBER();
580  aItem->m_Info = FromUTF8();
581  NeedRIGHT();
582  break;
583 
584  case T_option:
585  readOption( aItem );
586  break;
587 
588  case T_name:
589  NeedSYMBOLorNUMBER();
590  aItem->m_Name = FromUTF8();
591  NeedRIGHT();
592  break;
593 
594  case T_start:
595  parseCoordinate( aItem->m_Pos );
596  break;
597 
598  case T_end:
599  parseCoordinate( aItem->m_End );
600  break;
601 
602  case T_repeat:
603  aItem->m_RepeatCount = parseInt( -1, 100 );
604  NeedRIGHT();
605  break;
606 
607  case T_incrx:
608  aItem->m_IncrementVector.x = parseDouble();
609  NeedRIGHT();
610  break;
611 
612  case T_incry:
613  aItem->m_IncrementVector.y = parseDouble();
614  NeedRIGHT();
615  break;
616 
617  case T_linewidth:
618  aItem->m_LineWidth = parseDouble();
619  NeedRIGHT();
620  break;
621 
622  default:
623  Unexpected( CurText() );
624  break;
625  }
626  }
627 }
628 
629 
631 {
632  if( m_requiredVersion < 20210606 )
634 
635  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
636  {
637  if( token == T_LEFT )
638  token = NextTok();
639 
640  switch( token )
641  {
642  case T_comment:
643  NeedSYMBOLorNUMBER();
644  aItem->m_Info = FromUTF8();
645  NeedRIGHT();
646  break;
647 
648  case T_option:
649  readOption( aItem );
650  break;
651 
652  case T_name:
653  NeedSYMBOLorNUMBER();
654  aItem->m_Name = FromUTF8();
655  NeedRIGHT();
656  break;
657 
658  case T_pos:
659  parseCoordinate( aItem->m_Pos );
660  break;
661 
662  case T_repeat:
663  aItem->m_RepeatCount = parseInt( -1, 100 );
664  NeedRIGHT();
665  break;
666 
667  case T_incrx:
668  aItem->m_IncrementVector.x = parseDouble();
669  NeedRIGHT();
670  break;
671 
672  case T_incry:
673  aItem->m_IncrementVector.y = parseDouble();
674  NeedRIGHT();
675  break;
676 
677  case T_incrlabel:
678  aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
679  NeedRIGHT();
680  break;
681 
682  case T_maxlen:
683  aItem->m_BoundingBoxSize.x = parseDouble();
684  NeedRIGHT();
685  break;
686 
687  case T_maxheight:
688  aItem->m_BoundingBoxSize.y = parseDouble();
689  NeedRIGHT();
690  break;
691 
692  case T_font:
693  for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
694  {
695  switch( token )
696  {
697  case T_LEFT:
698  break;
699 
700  case T_bold:
701  aItem->m_Bold = true;
702  break;
703 
704  case T_italic:
705  aItem->m_Italic = true;
706  break;
707 
708  case T_size:
709  aItem->m_TextSize.x = parseDouble();
710  aItem->m_TextSize.y = parseDouble();
711  NeedRIGHT();
712  break;
713 
714  case T_linewidth:
715  aItem->m_LineWidth = parseDouble();
716  NeedRIGHT();
717  break;
718 
719  default:
720  Unexpected( CurText() );
721  break;
722  }
723  }
724  break;
725 
726  case T_justify:
727  for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
728  {
729  switch( token )
730  {
731  case T_center:
734  break;
735 
736  case T_left:
738  break;
739 
740  case T_right:
742  break;
743 
744  case T_top:
746  break;
747 
748  case T_bottom:
750  break;
751 
752  default:
753  Unexpected( CurText() );
754  break;
755  }
756  }
757  break;
758 
759  case T_rotate:
760  aItem->m_Orient = parseDouble();
761  NeedRIGHT();
762  break;
763 
764  default:
765  Unexpected( CurText() );
766  break;
767  }
768  }
769 }
770 
771 // parse an expression like " 25 1 ltcorner)"
773 {
774  aCoord.m_Pos.x = parseDouble();
775  aCoord.m_Pos.y = parseDouble();
776 
777  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
778  {
779  switch( token )
780  {
781  case T_ltcorner: aCoord.m_Anchor = LT_CORNER; break;
782  case T_lbcorner: aCoord.m_Anchor = LB_CORNER; break;
783  case T_rbcorner: aCoord.m_Anchor = RB_CORNER; break;
784  case T_rtcorner: aCoord.m_Anchor = RT_CORNER; break;
785  default: Unexpected( CurText() ); break;
786  }
787  }
788 }
789 
791 {
792  T token = NextTok();
793 
794  if( token != T_NUMBER )
795  Expecting( T_NUMBER );
796 
797  return atoi( CurText() );
798 }
799 
800 int DRAWING_SHEET_READER_PARSER::parseInt( int aMin, int aMax )
801 {
802  int val = parseInt();
803 
804  if( val < aMin )
805  val = aMin;
806  else if( val > aMax )
807  val = aMax;
808 
809  return val;
810 }
811 
812 
814 {
815  T token = NextTok();
816 
817  if( token != T_NUMBER )
818  Expecting( T_NUMBER );
819 
820  double val = strtod( CurText(), NULL );
821 
822  return val;
823 }
824 
825 // defaultDrawingSheet is the default drawing sheet using the S expr.
826 extern const char defaultDrawingSheet[];
827 
829 {
830  SetPageLayout( defaultDrawingSheet, false, wxT( "default page" ) );
831 }
832 
833 // Returns defaultDrawingSheet as a string;
835 {
836  return wxString( defaultDrawingSheet );
837 }
838 
839 // emptyDrawingSheet is a "empty" drawing sheet using the S expr.
840 // there is a 0 length line to fool something somewhere.
841 extern const char emptyDrawingSheet[];
842 
844 {
845  SetPageLayout( emptyDrawingSheet, false, wxT( "empty page" ) );
846 }
847 
848 
850 {
851  return wxString( emptyDrawingSheet );
852 }
853 
854 
855 void DS_DATA_MODEL::SetPageLayout( const char* aPageLayout, bool Append, const wxString& aSource )
856 {
857  if( ! Append )
858  ClearList();
859 
860  DRAWING_SHEET_READER_PARSER lp_parser( aPageLayout, wxT( "Sexpr_string" ) );
861 
862  try
863  {
864  lp_parser.Parse( this );
865  }
866  catch( const IO_ERROR& ioe )
867  {
868  wxLogMessage( ioe.What() );
869  }
870 }
871 
872 
873 bool DS_DATA_MODEL::LoadDrawingSheet( const wxString& aFullFileName, bool Append )
874 {
875  wxString fullFileName = aFullFileName;
876 
877  if( !Append )
878  {
879  if( fullFileName.IsEmpty() )
880  wxGetEnv( wxT( "KICAD_WKSFILE" ), &fullFileName );
881 
882  if( fullFileName.IsEmpty() )
883  {
885  return true; // we assume its fine / default init
886  }
887 
888  if( !wxFileExists( fullFileName ) )
889  {
890  wxLogMessage( _( "Drawing sheet '%s' not found." ), fullFileName );
892  return false;
893  }
894  }
895 
896  wxFFile wksFile( fullFileName, "rb" );
897 
898  if( ! wksFile.IsOpened() )
899  {
900  wxLogMessage( _( "Drawing sheet '%s' could not be opened." ), fullFileName );
901 
902  if( !Append )
904 
905  return false;
906  }
907 
908  size_t filelen = wksFile.Length();
909  std::unique_ptr<char[]> buffer = std::make_unique<char[]>(filelen+10);
910 
911  if( wksFile.Read( buffer.get(), filelen ) != filelen )
912  {
913  wxLogMessage( _( "Drawing sheet '%s' was not fully read." ), fullFileName.GetData() );
914  return false;
915  }
916  else
917  {
918  buffer[filelen]=0;
919 
920  if( ! Append )
921  ClearList();
922 
923  DRAWING_SHEET_READER_PARSER pl_parser( buffer.get(), fullFileName );
924 
925  try
926  {
927  pl_parser.Parse( this );
928  }
929  catch( const IO_ERROR& ioe )
930  {
931  wxLogMessage( ioe.What() );
932  return false;
933  }
934  catch( const std::bad_alloc& )
935  {
936  wxLogMessage( "Memory exhaustion reading drawing sheet" );
937  return false;
938  }
939  }
940 
941  return true;
942 }
wxString m_Info
Definition: ds_data_item.h:199
void ClearList()
Erase the list of items.
void parseHeader(T aHeaderType)
Parse the data specified at the very beginning of the file, like version and the application used to ...
Handle the graphic items list to draw/plot the frame and title block.
Definition: ds_data_model.h:38
EDA_TEXT_VJUSTIFY_T m_Vjustify
Definition: ds_data_item.h:339
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
void parsePolygon(DS_DATA_ITEM_POLYGONS *aItem)
Parse a polygon item starting by "( polygon" and read parameters.
static wxString DefaultLayout()
Return a string containing the empty layout shape.
void SetScale(double aScale)
Definition: bitmap_base.h:80
void SetBottomMargin(double aMargin)
Definition: ds_data_model.h:73
void SetBoundingBox()
Calculate the bounding box of the set polygons.
void readOption(DS_DATA_ITEM *aItem)
double m_DefaultLineWidth
DRAWING_SHEET_READER_PARSER holds data and functions pertinent to parsing a S-expression file for a D...
void SetLeftMargin(double aMargin)
Definition: ds_data_model.h:64
void readPngdata(DS_DATA_ITEM_BITMAP *aItem)
POINT_COORD m_End
Definition: ds_data_item.h:201
static double parseDouble(LINE_READER &aReader, const char *aLine, const char **aOutput=nullptr)
Parses an ASCII point string with possible leading whitespace into a double precision floating point ...
void parseText(DS_DATA_ITEM_TEXT *aItem)
Parse a text item starting by "(tbtext" and read parameters.
void parseBitmap(DS_DATA_ITEM_BITMAP *aItem)
Parse a bitmap item starting by "( bitmap" and read parameters.
void SetRightMargin(double aMargin)
Definition: ds_data_model.h:67
double m_DefaultTextThickness
This class handle bitmap images in KiCad.
Definition: bitmap_base.h:51
EDA_TEXT_HJUSTIFY_T m_Hjustify
Definition: ds_data_item.h:338
DPOINT m_IncrementVector
Definition: ds_data_item.h:204
double m_LineWidth
Definition: ds_data_item.h:202
#define NULL
DSIZE m_DefaultTextSize
BITMAP_BASE * m_ImageBitmap
Definition: ds_data_item.h:368
void AllowVoidList(bool Allow)
In KiCad applications, a drawing sheet is needed So if the list is empty, a default drawing sheet is ...
Definition: ds_data_model.h:83
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
DPOINT m_Pos
Definition: ds_data_item.h:80
void CloseContour()
Close the current contour, by storing the index of the last corner of the current polygon in m_polyIn...
Definition: ds_data_item.h:238
void SetTopMargin(double aMargin)
Definition: ds_data_model.h:70
void parseGraphic(DS_DATA_ITEM *aItem)
Parse a graphic item starting by "(line" or "(rect" and read parameters.
int m_IncrementLabel
Definition: ds_data_item.h:205
static wxString EmptyLayout()
Return a string containing the empty layout shape.
#define _(s)
static int parseInt(LINE_READER &aReader, const char *aLine, const char **aOutput=nullptr)
Parse an ASCII integer string with possible leading whitespace into an integer and updates the pointe...
const char defaultDrawingSheet[]
A coordinate point.
Definition: ds_data_item.h:69
void parseCoordinate(POINT_COORD &aCoord)
void SetFileFormatVersionAtLoad(int aVersion)
Definition: ds_data_model.h:61
void Parse(DS_DATA_MODEL *aLayout)
void SetPageLayout(const char *aPageLayout, bool aAppend=false, const wxString &aSource=wxT("Sexpr_string"))
Populate the list from a S expr description stored in a string.
void SetPage1Option(PAGE_OPTION aChoice)
Definition: ds_data_item.h:134
wxString convertLegacyVariableRefs(const wxString &aTextbase)
void parseSetup(DS_DATA_MODEL *aLayout)
POINT_COORD m_Pos
Definition: ds_data_item.h:200
Drawing sheet structure type definitions.
Definition: ds_data_item.h:95
DRAWING_SHEET_READER_PARSER(const char *aLine, const wxString &aSource)
bool LoadData(LINE_READER &aLine, wxString &aErrorMsg)
Load an image data saved by SaveData.
void parsePolyOutline(DS_DATA_ITEM_POLYGONS *aItem)
Parse a list of corners starting by "( pts" and read coordinates.
bool LoadDrawingSheet(const wxString &aFullFileName=wxEmptyString, bool Append=false)
Populates the list with a custom layout or the default layout if no custom layout is available.
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
Definition: string.cpp:44
double parseDouble()
Parse a double.
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:240
const char emptyDrawingSheet[]
wxString m_Name
Definition: ds_data_item.h:198
void AppendCorner(const DPOINT &aCorner)
Add a corner in corner list.
Definition: ds_data_item.h:229
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
void Append(DS_DATA_ITEM *aItem)