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-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 <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_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_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_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_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 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)