KiCad PCB EDA Suite
drawing_sheet_parser.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-2022 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 <wx/ffile.h>
27 #include <wx/log.h>
28 #include <eda_item.h>
29 #include <locale_io.h>
30 #include <string_utils.h>
34 #include <drawing_sheet/drawing_sheet_lexer.h>
36 
37 using namespace DRAWINGSHEET_T;
38 
44 class DRAWING_SHEET_PARSER : public DRAWING_SHEET_LEXER
45 {
46 public:
47  DRAWING_SHEET_PARSER( const char* aLine, const wxString& aSource );
48  void Parse( DS_DATA_MODEL* aLayout );
49 
50 private:
52 
57  void parseHeader( T aHeaderType );
58 
62  int parseInt();
63 
71  int parseInt( int aMin, int aMax );
72 
78  double parseDouble();
79 
80  void parseSetup( DS_DATA_MODEL* aLayout );
81 
85  void parseGraphic( DS_DATA_ITEM * aItem );
86 
90  void parseText( DS_DATA_ITEM_TEXT * aItem );
91 
96  void parsePolygon( DS_DATA_ITEM_POLYGONS * aItem );
97 
101  void parsePolyOutline( DS_DATA_ITEM_POLYGONS * aItem );
102 
103 
107  void parseBitmap( DS_DATA_ITEM_BITMAP * aItem );
108 
109  void parseCoordinate( POINT_COORD& aCoord);
110  void readOption( DS_DATA_ITEM * aItem );
111  void readPngdata( DS_DATA_ITEM_BITMAP * aItem );
112 };
113 
114 // PCB_PLOT_PARAMS_PARSER
115 
117  const wxString& aSource ) :
118  DRAWING_SHEET_LEXER( aLine, aSource ),
119  m_requiredVersion( 0 )
120 {
121 }
122 
123 
124 wxString convertLegacyVariableRefs( const wxString& aTextbase )
125 {
126  wxString msg;
127 
128  /*
129  * Legacy formats
130  * %% = replaced by %
131  * %K = Kicad version
132  * %Z = paper format name (A4, USLetter)
133  * %Y = company name
134  * %D = date
135  * %R = revision
136  * %S = sheet number
137  * %N = number of sheets
138  * %L = layer name
139  * %Cx = comment (x = 0 to 9 to identify the comment)
140  * %F = filename
141  * %P = sheet path (sheet full name)
142  * %T = title
143  */
144 
145  for( unsigned ii = 0; ii < aTextbase.Len(); ii++ )
146  {
147  if( aTextbase[ii] != '%' )
148  {
149  msg << aTextbase[ii];
150  continue;
151  }
152 
153  if( ++ii >= aTextbase.Len() )
154  break;
155 
156  wxChar format = aTextbase[ii];
157 
158  switch( format )
159  {
160  case '%': msg += '%'; break;
161  case 'D': msg += wxT( "${ISSUE_DATE}" ); break;
162  case 'R': msg += wxT( "${REVISION}" ); break;
163  case 'K': msg += wxT( "${KICAD_VERSION}" ); break;
164  case 'Z': msg += wxT( "${PAPER}" ); break;
165  case 'S': msg += wxT( "${#}" ); break;
166  case 'N': msg += wxT( "${##}" ); break;
167  case 'F': msg += wxT( "${FILENAME}" ); break;
168  case 'L': msg += wxT( "${LAYER}" ); break;
169  case 'P': msg += wxT( "${SHEETNAME}" ); break;
170  case 'Y': msg += wxT( "${COMPANY}" ); break;
171  case 'T': msg += wxT( "${TITLE}" ); break;
172  case 'C':
173  format = aTextbase[++ii];
174 
175  switch( format )
176  {
177  case '0': msg += wxT( "${COMMENT1}" ); break;
178  case '1': msg += wxT( "${COMMENT2}" ); break;
179  case '2': msg += wxT( "${COMMENT3}" ); break;
180  case '3': msg += wxT( "${COMMENT4}" ); break;
181  case '4': msg += wxT( "${COMMENT5}" ); break;
182  case '5': msg += wxT( "${COMMENT6}" ); break;
183  case '6': msg += wxT( "${COMMENT7}" ); break;
184  case '7': msg += wxT( "${COMMENT8}" ); break;
185  case '8': msg += wxT( "${COMMENT9}" ); break;
186  }
187  break;
188 
189  default:
190  break;
191  }
192  }
193 
194  return msg;
195 }
196 
197 
199 {
200  DS_DATA_ITEM* item;
201  LOCALE_IO toggle;
202 
203  NeedLEFT();
204  T token = NextTok();
205 
206  parseHeader( token );
208 
209  for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
210  {
211  if( token == T_LEFT )
212  token = NextTok();
213 
214  switch( token )
215  {
216  case T_setup: // Defines default values for graphic items
217  parseSetup( aLayout );
218  break;
219 
220  case T_line:
222  parseGraphic( item );
223  aLayout->Append( item );
224  break;
225 
226  case T_rect:
227  item = new DS_DATA_ITEM( DS_DATA_ITEM::DS_RECT );
228  parseGraphic( item );
229  aLayout->Append( item );
230  break;
231 
232  case T_polygon:
233  item = new DS_DATA_ITEM_POLYGONS();
235  aLayout->Append( item );
236  break;
237 
238  case T_bitmap:
239  item = new DS_DATA_ITEM_BITMAP( NULL );
240  parseBitmap( (DS_DATA_ITEM_BITMAP*) item );
241  aLayout->Append( item );
242  break;
243 
244  case T_tbtext:
245  NeedSYMBOLorNUMBER();
246  item = new DS_DATA_ITEM_TEXT( convertLegacyVariableRefs( FromUTF8() ) );
247  parseText( (DS_DATA_ITEM_TEXT*) item );
248  aLayout->Append( item );
249  break;
250 
251  default:
252  Unexpected( CurText() );
253  break;
254  }
255  }
256 }
257 
259 {
260  // The older files had no versioning and their first token after the initial left parenthesis
261  // was a `page_layout` or `drawing_sheet` token. The newer files have versions and have a
262  // `kicad_wks` token instead.
263 
264  if( aHeaderType == T_kicad_wks || aHeaderType == T_drawing_sheet )
265  {
266  NeedLEFT();
267 
268  T tok = NextTok();
269 
270  if( tok == T_version )
271  {
273 
275  throw FUTURE_FORMAT_ERROR( FromUTF8() );
276 
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_comment:
498  NeedSYMBOLorNUMBER();
499  aItem->m_Info = FromUTF8();
500  NeedRIGHT();
501  break;
502 
503  case T_pngdata:
504  readPngdata( aItem );
505  break;
506 
507  case T_option:
508  readOption( aItem );
509  break;
510 
511  default:
512  Unexpected( CurText() );
513  break;
514  }
515  }
516 }
517 
519 {
520  std::string tmp;
521 
522  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
523  {
524  if( token == T_LEFT )
525  token = NextTok();
526 
527  switch( token )
528  {
529  case T_data:
530  NeedSYMBOLorNUMBER();
531  tmp += CurStr();
532  tmp += "\n";
533  NeedRIGHT();
534  break;
535 
536  default:
537  Unexpected( CurText() );
538  break;
539  }
540  }
541 
542  tmp += "EndData";
543 
544  wxString msg;
545  STRING_LINE_READER str_reader( tmp, wxT("Png kicad_wks data") );
546 
547  if( ! aItem->m_ImageBitmap->LoadData( str_reader, msg ) )
548  wxLogMessage(msg);
549 }
550 
551 
553 {
554  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
555  {
556  switch( token )
557  {
558  case T_page1only: aItem->SetPage1Option( FIRST_PAGE_ONLY ); break;
559  case T_notonpage1: aItem->SetPage1Option( SUBSEQUENT_PAGES ); break;
560  default: Unexpected( CurText() ); break;
561  }
562  }
563 }
564 
565 
567 {
568  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
569  {
570  if( token == T_LEFT )
571  token = NextTok();
572  else
573  {
574  // If another token than T_LEFT is read here, this is an error
575  // however, due to a old bug in kicad, the token T_end can be found
576  // without T_LEFT in a very few .wks files (perhaps only one in a demo).
577  // So this ugly hack disables the error detection.
578  if( token != T_end )
579  Unexpected( CurText() );
580  }
581 
582  switch( token )
583  {
584  case T_comment:
585  NeedSYMBOLorNUMBER();
586  aItem->m_Info = FromUTF8();
587  NeedRIGHT();
588  break;
589 
590  case T_option:
591  readOption( aItem );
592  break;
593 
594  case T_name:
595  NeedSYMBOLorNUMBER();
596  aItem->m_Name = FromUTF8();
597  NeedRIGHT();
598  break;
599 
600  case T_start:
601  parseCoordinate( aItem->m_Pos );
602  break;
603 
604  case T_end:
605  parseCoordinate( aItem->m_End );
606  break;
607 
608  case T_repeat:
609  aItem->m_RepeatCount = parseInt( -1, 100 );
610  NeedRIGHT();
611  break;
612 
613  case T_incrx:
614  aItem->m_IncrementVector.x = parseDouble();
615  NeedRIGHT();
616  break;
617 
618  case T_incry:
619  aItem->m_IncrementVector.y = parseDouble();
620  NeedRIGHT();
621  break;
622 
623  case T_linewidth:
624  aItem->m_LineWidth = parseDouble();
625  NeedRIGHT();
626  break;
627 
628  default:
629  Unexpected( CurText() );
630  break;
631  }
632  }
633 }
634 
635 
637 {
638  if( m_requiredVersion < 20210606 )
640 
641  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
642  {
643  if( token == T_LEFT )
644  token = NextTok();
645 
646  switch( token )
647  {
648  case T_comment:
649  NeedSYMBOLorNUMBER();
650  aItem->m_Info = FromUTF8();
651  NeedRIGHT();
652  break;
653 
654  case T_option:
655  readOption( aItem );
656  break;
657 
658  case T_name:
659  NeedSYMBOLorNUMBER();
660  aItem->m_Name = FromUTF8();
661  NeedRIGHT();
662  break;
663 
664  case T_pos:
665  parseCoordinate( aItem->m_Pos );
666  break;
667 
668  case T_repeat:
669  aItem->m_RepeatCount = parseInt( -1, 100 );
670  NeedRIGHT();
671  break;
672 
673  case T_incrx:
674  aItem->m_IncrementVector.x = parseDouble();
675  NeedRIGHT();
676  break;
677 
678  case T_incry:
679  aItem->m_IncrementVector.y = parseDouble();
680  NeedRIGHT();
681  break;
682 
683  case T_incrlabel:
684  aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
685  NeedRIGHT();
686  break;
687 
688  case T_maxlen:
689  aItem->m_BoundingBoxSize.x = parseDouble();
690  NeedRIGHT();
691  break;
692 
693  case T_maxheight:
694  aItem->m_BoundingBoxSize.y = parseDouble();
695  NeedRIGHT();
696  break;
697 
698  case T_font:
699  for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
700  {
701  switch( token )
702  {
703  case T_LEFT:
704  break;
705 
706  case T_bold:
707  aItem->m_Bold = true;
708  break;
709 
710  case T_italic:
711  aItem->m_Italic = true;
712  break;
713 
714  case T_size:
715  aItem->m_TextSize.x = parseDouble();
716  aItem->m_TextSize.y = parseDouble();
717  NeedRIGHT();
718  break;
719 
720  case T_linewidth:
721  aItem->m_LineWidth = parseDouble();
722  NeedRIGHT();
723  break;
724 
725  default:
726  Unexpected( CurText() );
727  break;
728  }
729  }
730  break;
731 
732  case T_justify:
733  for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
734  {
735  switch( token )
736  {
737  case T_center:
740  break;
741 
742  case T_left:
744  break;
745 
746  case T_right:
748  break;
749 
750  case T_top:
752  break;
753 
754  case T_bottom:
756  break;
757 
758  default:
759  Unexpected( CurText() );
760  break;
761  }
762  }
763  break;
764 
765  case T_rotate:
766  aItem->m_Orient = parseDouble();
767  NeedRIGHT();
768  break;
769 
770  default:
771  Unexpected( CurText() );
772  break;
773  }
774  }
775 }
776 
777 // parse an expression like " 25 1 ltcorner)"
779 {
780  aCoord.m_Pos.x = parseDouble();
781  aCoord.m_Pos.y = parseDouble();
782 
783  for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
784  {
785  switch( token )
786  {
787  case T_ltcorner: aCoord.m_Anchor = LT_CORNER; break;
788  case T_lbcorner: aCoord.m_Anchor = LB_CORNER; break;
789  case T_rbcorner: aCoord.m_Anchor = RB_CORNER; break;
790  case T_rtcorner: aCoord.m_Anchor = RT_CORNER; break;
791  default: Unexpected( CurText() ); break;
792  }
793  }
794 }
795 
797 {
798  T token = NextTok();
799 
800  if( token != T_NUMBER )
801  Expecting( T_NUMBER );
802 
803  return atoi( CurText() );
804 }
805 
806 int DRAWING_SHEET_PARSER::parseInt( int aMin, int aMax )
807 {
808  int val = parseInt();
809 
810  if( val < aMin )
811  val = aMin;
812  else if( val > aMax )
813  val = aMax;
814 
815  return val;
816 }
817 
818 
820 {
821  T token = NextTok();
822 
823  if( token != T_NUMBER )
824  Expecting( T_NUMBER );
825 
826  double val = strtod( CurText(), NULL );
827 
828  return val;
829 }
830 
831 // defaultDrawingSheet is the default drawing sheet using the S expr.
832 extern const char defaultDrawingSheet[];
833 
835 {
836  SetPageLayout( defaultDrawingSheet, false, wxT( "default page" ) );
837 }
838 
839 // Returns defaultDrawingSheet as a string;
841 {
842  return wxString( defaultDrawingSheet );
843 }
844 
845 // emptyDrawingSheet is a "empty" drawing sheet using the S expr.
846 // there is a 0 length line to fool something somewhere.
847 extern const char emptyDrawingSheet[];
848 
850 {
851  SetPageLayout( emptyDrawingSheet, false, wxT( "empty page" ) );
852 }
853 
854 
856 {
857  return wxString( emptyDrawingSheet );
858 }
859 
860 
861 void DS_DATA_MODEL::SetPageLayout( const char* aPageLayout, bool Append, const wxString& aSource )
862 {
863  if( ! Append )
864  ClearList();
865 
866  DRAWING_SHEET_PARSER lp_parser( aPageLayout, wxT( "Sexpr_string" ) );
867 
868  try
869  {
870  lp_parser.Parse( this );
871  }
872  catch( const IO_ERROR& ioe )
873  {
874  wxLogMessage( ioe.What() );
875  }
876 }
877 
878 
879 bool DS_DATA_MODEL::LoadDrawingSheet( const wxString& aFullFileName, bool Append )
880 {
881  wxString fullFileName = aFullFileName;
882 
883  if( !Append )
884  {
885  if( fullFileName.IsEmpty() )
886  wxGetEnv( wxT( "KICAD_WKSFILE" ), &fullFileName );
887 
888  if( fullFileName.IsEmpty() )
889  {
891  return true; // we assume its fine / default init
892  }
893 
894  if( !wxFileExists( fullFileName ) )
895  {
896  wxLogMessage( _( "Drawing sheet '%s' not found." ), fullFileName );
898  return false;
899  }
900  }
901 
902  wxFFile wksFile( fullFileName, wxT( "rb" ) );
903 
904  if( ! wksFile.IsOpened() )
905  {
906  wxLogMessage( _( "Drawing sheet '%s' could not be opened." ), fullFileName );
907 
908  if( !Append )
910 
911  return false;
912  }
913 
914  size_t filelen = wksFile.Length();
915  std::unique_ptr<char[]> buffer = std::make_unique<char[]>(filelen+10);
916 
917  if( wksFile.Read( buffer.get(), filelen ) != filelen )
918  {
919  wxLogMessage( _( "Drawing sheet '%s' was not fully read." ), fullFileName.GetData() );
920  return false;
921  }
922  else
923  {
924  buffer[filelen]=0;
925 
926  if( ! Append )
927  ClearList();
928 
929  DRAWING_SHEET_PARSER pl_parser( buffer.get(), fullFileName );
930 
931  try
932  {
933  pl_parser.Parse( this );
934  }
935  catch( const IO_ERROR& ioe )
936  {
937  wxLogMessage( ioe.What() );
938  return false;
939  }
940  catch( const std::bad_alloc& )
941  {
942  wxLogMessage( wxT( "Memory exhaustion reading drawing sheet" ) );
943  return false;
944  }
945  }
946 
947  return true;
948 }
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
wxString m_Info
Definition: ds_data_item.h:199
void ClearList()
Erase the list of items.
Handle the graphic items list to draw/plot the frame and title block.
Definition: ds_data_model.h:38
void parseGraphic(DS_DATA_ITEM *aItem)
Parse a graphic item starting by "(line" or "(rect" and read parameters.
const char emptyDrawingSheet[]
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 parseHeader(T aHeaderType)
Parse the data specified at the very beginning of the file, like version and the application used to ...
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.
double m_DefaultLineWidth
void readOption(DS_DATA_ITEM *aItem)
void SetLeftMargin(double aMargin)
Definition: ds_data_model.h:64
int parseInt()
Parse an integer.
void parseText(DS_DATA_ITEM_TEXT *aItem)
Parse a text item starting by "(tbtext" and read parameters.
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 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
DRAWING_SHEET_PARSER holds data and functions pertinent to parsing a S-expression file for a DS_DATA_...
DPOINT m_IncrementVector
Definition: ds_data_item.h:204
double m_LineWidth
Definition: ds_data_item.h:202
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
wxString convertLegacyVariableRefs(const wxString &aTextbase)
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
int m_IncrementLabel
Definition: ds_data_item.h:205
static wxString EmptyLayout()
Return a string containing the empty layout shape.
#define SEXPR_WORKSHEET_FILE_VERSION
This file contains the file format version information for the s-expression drawing sheet file format...
#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...
A coordinate point.
Definition: ds_data_item.h:69
void parseBitmap(DS_DATA_ITEM_BITMAP *aItem)
Parse a bitmap item starting by "( bitmap" and read parameters.
void parseCoordinate(POINT_COORD &aCoord)
void parseSetup(DS_DATA_MODEL *aLayout)
const char defaultDrawingSheet[]
void SetFileFormatVersionAtLoad(int aVersion)
Definition: ds_data_model.h:61
void parsePolyOutline(DS_DATA_ITEM_POLYGONS *aItem)
Parse a list of corners starting by "( pts" and read coordinates.
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
void readPngdata(DS_DATA_ITEM_BITMAP *aItem)
POINT_COORD m_Pos
Definition: ds_data_item.h:200
Drawing sheet structure type definitions.
Definition: ds_data_item.h:95
double parseDouble()
Parse a double.
bool LoadData(LINE_READER &aLine, wxString &aErrorMsg)
Load an image data saved by SaveData.
void parsePolygon(DS_DATA_ITEM_POLYGONS *aItem)
Parse a polygon item starting by "( polygon" and read parameters.
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.
DRAWING_SHEET_PARSER(const char *aLine, const wxString &aSource)
Variant of PARSE_ERROR indicating that a syntax or related error was likely caused by a file generate...
Definition: ki_exception.h:174
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:240
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)
void Parse(DS_DATA_MODEL *aLayout)