KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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 <charconv>
27#include <fmt/format.h>
28#include <wx/base64.h>
29#include <wx/ffile.h>
30#include <wx/log.h>
31
32#include <eda_item.h>
33#include <locale_io.h>
34#include <string_utils.h>
38#include <drawing_sheet/drawing_sheet_lexer.h>
40#include <font/font.h>
41
42using namespace DRAWINGSHEET_T;
43
49class DRAWING_SHEET_PARSER : public DRAWING_SHEET_LEXER
50{
51public:
52 DRAWING_SHEET_PARSER( const char* aLine, const wxString& aSource );
53 void Parse( DS_DATA_MODEL* aLayout );
54
55private:
58
63 void parseHeader( T aHeaderType );
64
68 int parseInt();
69
77 int parseInt( int aMin, int aMax );
78
84 double parseDouble();
85
86 void parseSetup( DS_DATA_MODEL* aLayout );
87
91 void parseGraphic( DS_DATA_ITEM * aItem );
92
96 void parseText( DS_DATA_ITEM_TEXT * aItem );
97
102 void parsePolygon( DS_DATA_ITEM_POLYGONS * aItem );
103
108
109
113 void parseBitmap( DS_DATA_ITEM_BITMAP * aItem );
114
115 void parseCoordinate( POINT_COORD& aCoord);
116 void readOption( DS_DATA_ITEM * aItem );
117 void readPngdata( DS_DATA_ITEM_BITMAP * aItem );
118};
119
120
122 const wxString& aSource ) :
123 DRAWING_SHEET_LEXER( aLine, aSource ),
124 m_requiredVersion( 0 )
125{
126}
127
128
129wxString convertLegacyVariableRefs( const wxString& aTextbase )
130{
131 wxString msg;
132
133 /*
134 * Legacy formats
135 * %% = replaced by %
136 * %K = Kicad version
137 * %Z = paper format name (A4, USLetter)
138 * %Y = company name
139 * %D = date
140 * %R = revision
141 * %S = sheet number
142 * %N = number of sheets
143 * %L = layer name
144 * %Cx = comment (x = 0 to 9 to identify the comment)
145 * %F = filename
146 * %P = sheet path (sheet full name)
147 * %T = title
148 */
149
150 for( unsigned ii = 0; ii < aTextbase.Len(); ii++ )
151 {
152 if( aTextbase[ii] != '%' )
153 {
154 msg << aTextbase[ii];
155 continue;
156 }
157
158 if( ++ii >= aTextbase.Len() )
159 break;
160
161 wxChar format = aTextbase[ii];
162
163 switch( format )
164 {
165 case '%': msg += '%'; break;
166 case 'D': msg += wxT( "${ISSUE_DATE}" ); break;
167 case 'R': msg += wxT( "${REVISION}" ); break;
168 case 'K': msg += wxT( "${KICAD_VERSION}" ); break;
169 case 'Z': msg += wxT( "${PAPER}" ); break;
170 case 'S': msg += wxT( "${#}" ); break;
171 case 'N': msg += wxT( "${##}" ); break;
172 case 'F': msg += wxT( "${FILENAME}" ); break;
173 case 'L': msg += wxT( "${LAYER}" ); break;
174 case 'P': msg += wxT( "${SHEETPATH}" ); break;
175 case 'Y': msg += wxT( "${COMPANY}" ); break;
176 case 'T': msg += wxT( "${TITLE}" ); break;
177 case 'C':
178 format = aTextbase[++ii];
179
180 switch( format )
181 {
182 case '0': msg += wxT( "${COMMENT1}" ); break;
183 case '1': msg += wxT( "${COMMENT2}" ); break;
184 case '2': msg += wxT( "${COMMENT3}" ); break;
185 case '3': msg += wxT( "${COMMENT4}" ); break;
186 case '4': msg += wxT( "${COMMENT5}" ); break;
187 case '5': msg += wxT( "${COMMENT6}" ); break;
188 case '6': msg += wxT( "${COMMENT7}" ); break;
189 case '7': msg += wxT( "${COMMENT8}" ); break;
190 case '8': msg += wxT( "${COMMENT9}" ); break;
191 }
192 break;
193
194 default:
195 break;
196 }
197 }
198
199 return msg;
200}
201
202
204{
205 DS_DATA_ITEM* item;
206 LOCALE_IO toggle;
207
208 NeedLEFT();
209 T token = NextTok();
210
211 parseHeader( token );
213
214 auto checkVersion =
215 [&]()
216 {
218 {
219 throw FUTURE_FORMAT_ERROR( fmt::format( "{}", m_requiredVersion ),
221 }
222 };
223
224 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
225 {
226 if( token == T_LEFT )
227 token = NextTok();
228
229 switch( token )
230 {
231 case T_generator:
232 // (generator "genname"); we don't care about it at the moment.
233 NeedSYMBOL();
234 NeedRIGHT();
235 break;
236
237 case T_generator_version:
238 NextTok();
239 m_generatorVersion = FromUTF8();
240 NeedRIGHT();
241 break;
242
243 case T_setup: // Defines default values for graphic items
244 // Check the version here, because the generator and generator_version (if available)
245 // will have been parsed by now given the order the formatter writes them in
246 checkVersion();
247 parseSetup( aLayout );
248 break;
249
250 case T_line:
252 parseGraphic( item );
253 aLayout->Append( item );
254 break;
255
256 case T_rect:
258 parseGraphic( item );
259 aLayout->Append( item );
260 break;
261
262 case T_polygon:
263 item = new DS_DATA_ITEM_POLYGONS();
265 aLayout->Append( item );
266 break;
267
268 case T_bitmap:
269 item = new DS_DATA_ITEM_BITMAP( NULL );
271
272 // Drop invalid bitmaps
273 if( static_cast<DS_DATA_ITEM_BITMAP*>( item )->m_ImageBitmap->GetOriginalImageData() )
274 {
275 aLayout->Append( item );
276 }
277 else
278 {
279 delete static_cast<DS_DATA_ITEM_BITMAP*>( item )->m_ImageBitmap;
280 delete item;
281 }
282
283 break;
284
285 case T_tbtext:
286 NeedSYMBOLorNUMBER();
287 item = new DS_DATA_ITEM_TEXT( convertLegacyVariableRefs( FromUTF8() ) );
288 parseText( (DS_DATA_ITEM_TEXT*) item );
289 aLayout->Append( item );
290 break;
291
292 default:
293 Unexpected( CurText() );
294 break;
295 }
296 }
297}
298
300{
301 // The older files had no versioning and their first token after the initial left parenthesis
302 // was a `page_layout` or `drawing_sheet` token. The newer files have versions and have a
303 // `kicad_wks` token instead.
304
305 if( aHeaderType == T_kicad_wks || aHeaderType == T_drawing_sheet )
306 {
307 NeedLEFT();
308
309 T tok = NextTok();
310
311 if( tok == T_version )
312 {
314
315 NeedRIGHT();
316 }
317 else
318 {
319 Expecting( T_version );
320 }
321 }
322 else
323 {
324 // We assign version 0 to files that were created before there was any versioning of
325 // worksheets. The below line is not strictly necessary, as `m_requiredVersion` is already
326 // initialized to 0 in the constructor.
328 }
329}
330
332{
333 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
334 {
335 switch( token )
336 {
337 case T_LEFT:
338 break;
339
340 case T_linewidth:
341 aLayout->m_DefaultLineWidth = parseDouble();
342 NeedRIGHT();
343 break;
344
345 case T_textsize:
346 aLayout->m_DefaultTextSize.x = parseDouble();
347 aLayout->m_DefaultTextSize.y = parseDouble();
348 NeedRIGHT();
349 break;
350
351 case T_textlinewidth:
353 NeedRIGHT();
354 break;
355
356 case T_left_margin:
357 aLayout->SetLeftMargin( parseDouble() );
358 NeedRIGHT();
359 break;
360
361 case T_right_margin:
362 aLayout->SetRightMargin( parseDouble() );
363 NeedRIGHT();
364 break;
365
366 case T_top_margin:
367 aLayout->SetTopMargin( parseDouble() );
368 NeedRIGHT();
369 break;
370
371 case T_bottom_margin:
372 aLayout->SetBottomMargin( parseDouble() );
373 NeedRIGHT();
374 break;
375
376 default:
377 Unexpected( CurText() );
378 break;
379 }
380 }
381
382 // The file is well-formed. If it has no further items, then that's the way the
383 // user wants it.
384 aLayout->AllowVoidList( true );
385}
386
387
389{
390 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
391 {
392 if( token == T_LEFT )
393 token = NextTok();
394
395 switch( token )
396 {
397 case T_comment:
398 NeedSYMBOLorNUMBER();
399 aItem->m_Info = FromUTF8();
400 NeedRIGHT();
401 break;
402
403 case T_pos:
404 parseCoordinate( aItem->m_Pos );
405 break;
406
407 case T_name:
408 NeedSYMBOLorNUMBER();
409 aItem->m_Name = FromUTF8();
410 NeedRIGHT();
411 break;
412
413 case T_option:
414 readOption( aItem );
415 break;
416
417 case T_pts:
418 parsePolyOutline( aItem );
419 aItem->CloseContour();
420 break;
421
422 case T_rotate:
424 NeedRIGHT();
425 break;
426
427 case T_repeat:
428 aItem->m_RepeatCount = parseInt( 1, 100 );
429 NeedRIGHT();
430 break;
431
432 case T_incrx:
434 NeedRIGHT();
435 break;
436
437 case T_incry:
439 NeedRIGHT();
440 break;
441
442 case T_linewidth:
443 aItem->m_LineWidth = parseDouble();
444 NeedRIGHT();
445 break;
446
447 default:
448 Unexpected( CurText() );
449 break;
450 }
451 }
452
453 aItem->SetBoundingBox();
454}
455
457{
458 VECTOR2D corner;
459
460 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
461 {
462 if( token == T_LEFT )
463 token = NextTok();
464
465 switch( token )
466 {
467 case T_xy:
468 corner.x = parseDouble();
469 corner.y = parseDouble();
470 aItem->AppendCorner( corner );
471 NeedRIGHT();
472 break;
473
474 default:
475 Unexpected( CurText() );
476 break;
477 }
478 }
479}
480
481
483{
485 aItem->m_ImageBitmap = image;
486
487 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
488 {
489 if( token == T_LEFT )
490 token = NextTok();
491
492 switch( token )
493 {
494 case T_name:
495 NeedSYMBOLorNUMBER();
496 aItem->m_Name = FromUTF8();
497 NeedRIGHT();
498 break;
499
500 case T_pos:
501 parseCoordinate( aItem->m_Pos );
502 break;
503
504 case T_repeat:
505 aItem->m_RepeatCount = parseInt( 1, 100 );
506 NeedRIGHT();
507 break;
508
509 case T_incrx:
511 NeedRIGHT();
512 break;
513
514 case T_incry:
516 NeedRIGHT();
517 break;
518
519 case T_linewidth:
520 aItem->m_LineWidth = parseDouble();
521 NeedRIGHT();
522 break;
523
524 case T_scale:
526 NeedRIGHT();
527 break;
528
529 case T_comment:
530 NeedSYMBOLorNUMBER();
531 aItem->m_Info = FromUTF8();
532 NeedRIGHT();
533 break;
534
535 case T_data:
536 {
537 token = NextTok();
538
539 wxString data;
540
541 // Reserve 512K because most image files are going to be larger than the default
542 // 1K that wxString reserves.
543 data.reserve( 1 << 19 );
544
545 while( token != T_RIGHT )
546 {
547 if( !IsSymbol( token ) )
548 Expecting( "base64 image data" );
549
550 data += FromUTF8();
551 token = NextTok();
552 }
553
554 wxMemoryBuffer buffer = wxBase64Decode( data );
555
556 if( !aItem->m_ImageBitmap->ReadImageFile( buffer ) )
557 THROW_IO_ERROR( _( "Failed to read image data." ) );
558
559 break;
560 }
561
562 case T_pngdata:
563 readPngdata( aItem );
564 break;
565
566 case T_option:
567 readOption( aItem );
568 break;
569
570 default:
571 Unexpected( CurText() );
572 break;
573 }
574 }
575}
576
578{
579 std::string tmp;
580
581 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
582 {
583 if( token == T_LEFT )
584 token = NextTok();
585
586 switch( token )
587 {
588 case T_data:
589 NeedSYMBOLorNUMBER();
590 tmp += CurStr();
591 tmp += "\n";
592 NeedRIGHT();
593 break;
594
595 default:
596 Unexpected( CurText() );
597 break;
598 }
599 }
600
601 tmp += "EndData";
602
603 wxString msg;
604 STRING_LINE_READER str_reader( tmp, wxT("Png kicad_wks data") );
605
606 if( ! aItem->m_ImageBitmap->LoadLegacyData( str_reader, msg ) )
607 wxLogMessage(msg);
608}
609
610
612{
613 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
614 {
615 switch( token )
616 {
617 case T_page1only: aItem->SetPage1Option( FIRST_PAGE_ONLY ); break;
618 case T_notonpage1: aItem->SetPage1Option( SUBSEQUENT_PAGES ); break;
619 default: Unexpected( CurText() ); break;
620 }
621 }
622}
623
624
626{
627 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
628 {
629 if( token == T_LEFT )
630 token = NextTok();
631 else
632 {
633 // If another token than T_LEFT is read here, this is an error
634 // however, due to a old bug in kicad, the token T_end can be found
635 // without T_LEFT in a very few .wks files (perhaps only one in a demo).
636 // So this ugly hack disables the error detection.
637 if( token != T_end )
638 Unexpected( CurText() );
639 }
640
641 switch( token )
642 {
643 case T_comment:
644 NeedSYMBOLorNUMBER();
645 aItem->m_Info = FromUTF8();
646 NeedRIGHT();
647 break;
648
649 case T_option:
650 readOption( aItem );
651 break;
652
653 case T_name:
654 NeedSYMBOLorNUMBER();
655 aItem->m_Name = FromUTF8();
656 NeedRIGHT();
657 break;
658
659 case T_start:
660 parseCoordinate( aItem->m_Pos );
661 break;
662
663 case T_end:
664 parseCoordinate( aItem->m_End );
665 break;
666
667 case T_repeat:
668 aItem->m_RepeatCount = parseInt( 1, 100 );
669 NeedRIGHT();
670 break;
671
672 case T_incrx:
674 NeedRIGHT();
675 break;
676
677 case T_incry:
679 NeedRIGHT();
680 break;
681
682 case T_linewidth:
683 aItem->m_LineWidth = parseDouble();
684 NeedRIGHT();
685 break;
686
687 default:
688 Unexpected( CurText() );
689 break;
690 }
691 }
692}
693
694
696{
697 if( m_requiredVersion < 20210606 )
699
700 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
701 {
702 if( token == T_LEFT )
703 token = NextTok();
704
705 switch( token )
706 {
707 case T_comment:
708 NeedSYMBOLorNUMBER();
709 aItem->m_Info = FromUTF8();
710 NeedRIGHT();
711 break;
712
713 case T_option:
714 readOption( aItem );
715 break;
716
717 case T_name:
718 NeedSYMBOLorNUMBER();
719 aItem->m_Name = FromUTF8();
720 NeedRIGHT();
721 break;
722
723 case T_pos:
724 parseCoordinate( aItem->m_Pos );
725 break;
726
727 case T_repeat:
728 aItem->m_RepeatCount = parseInt( 1, 100 );
729 NeedRIGHT();
730 break;
731
732 case T_incrx:
734 NeedRIGHT();
735 break;
736
737 case T_incry:
739 NeedRIGHT();
740 break;
741
742 case T_incrlabel:
743 aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
744 NeedRIGHT();
745 break;
746
747 case T_maxlen:
749 NeedRIGHT();
750 break;
751
752 case T_maxheight:
754 NeedRIGHT();
755 break;
756
757 case T_font:
758 {
759 wxString faceName;
760
761 aItem->m_TextColor = COLOR4D::UNSPECIFIED;
762
763 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
764 {
765 switch( token )
766 {
767 case T_LEFT:
768 break;
769
770 case T_face:
771 NeedSYMBOL();
772 faceName = FromUTF8();
773 NeedRIGHT();
774 break;
775
776 case T_bold:
777 aItem->m_Bold = true;
778 break;
779
780 case T_italic:
781 aItem->m_Italic = true;
782 break;
783
784 case T_size:
785 aItem->m_TextSize.x = parseDouble();
786 aItem->m_TextSize.y = parseDouble();
787 NeedRIGHT();
788 break;
789
790 case T_color:
791 aItem->m_TextColor.r = parseInt( 0, 255 ) / 255.0;
792 aItem->m_TextColor.g = parseInt( 0, 255 ) / 255.0;
793 aItem->m_TextColor.b = parseInt( 0, 255 ) / 255.0;
794 aItem->m_TextColor.a = Clamp( parseDouble(), 0.0, 1.0 );
795 NeedRIGHT();
796 break;
797
798 case T_linewidth:
799 aItem->m_LineWidth = parseDouble();
800 NeedRIGHT();
801 break;
802
803 default:
804 Unexpected( CurText() );
805 break;
806 }
807 }
808
809 if( !faceName.IsEmpty() )
810 aItem->m_Font = KIFONT::FONT::GetFont( faceName, aItem->m_Bold, aItem->m_Italic );
811
812 break;
813 }
814
815 case T_justify:
816 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
817 {
818 switch( token )
819 {
820 case T_center:
823 break;
824
825 case T_left:
827 break;
828
829 case T_right:
831 break;
832
833 case T_top:
835 break;
836
837 case T_bottom:
839 break;
840
841 default:
842 Unexpected( CurText() );
843 break;
844 }
845 }
846 break;
847
848 case T_rotate:
849 aItem->m_Orient = parseDouble();
850 NeedRIGHT();
851 break;
852
853 default:
854 Unexpected( CurText() );
855 break;
856 }
857 }
858}
859
860// parse an expression like " 25 1 ltcorner)"
862{
863 aCoord.m_Pos.x = parseDouble();
864 aCoord.m_Pos.y = parseDouble();
865
866 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
867 {
868 switch( token )
869 {
870 case T_ltcorner: aCoord.m_Anchor = LT_CORNER; break;
871 case T_lbcorner: aCoord.m_Anchor = LB_CORNER; break;
872 case T_rbcorner: aCoord.m_Anchor = RB_CORNER; break;
873 case T_rtcorner: aCoord.m_Anchor = RT_CORNER; break;
874 default: Unexpected( CurText() ); break;
875 }
876 }
877}
878
880{
881 T token = NextTok();
882
883 if( token != T_NUMBER )
884 Expecting( T_NUMBER );
885
886 return atoi( CurText() );
887}
888
889int DRAWING_SHEET_PARSER::parseInt( int aMin, int aMax )
890{
891 int val = parseInt();
892
893 if( val < aMin )
894 val = aMin;
895 else if( val > aMax )
896 val = aMax;
897
898 return val;
899}
900
901
903{
904 T token = NextTok();
905
906 if( token != T_NUMBER )
907 Expecting( T_NUMBER );
908
909
910 return DSNLEXER::parseDouble();
911}
912
913// defaultDrawingSheet is the default drawing sheet using the S expr.
914extern const char defaultDrawingSheet[];
915
917{
918 SetPageLayout( defaultDrawingSheet, false, wxT( "default page" ) );
919}
920
921// Returns defaultDrawingSheet as a string;
923{
924 return wxString( defaultDrawingSheet );
925}
926
927// emptyDrawingSheet is a "empty" drawing sheet using the S expr.
928// there is a 0 length line to fool something somewhere.
929extern const char emptyDrawingSheet[];
930
932{
933 SetPageLayout( emptyDrawingSheet, false, wxT( "empty page" ) );
934}
935
936
938{
939 return wxString( emptyDrawingSheet );
940}
941
942
943void DS_DATA_MODEL::SetPageLayout( const char* aPageLayout, bool Append, const wxString& aSource )
944{
945 if( ! Append )
946 ClearList();
947
948 DRAWING_SHEET_PARSER parser( aPageLayout, wxT( "Sexpr_string" ) );
949
950 try
951 {
952 parser.Parse( this );
953 }
954 catch( const IO_ERROR& ioe )
955 {
956 wxLogMessage( ioe.What() );
957 }
958 catch( const std::bad_alloc& )
959 {
960 wxLogMessage( wxS( "Memory exhaustion reading drawing sheet" ) );
961 }
962}
963
964
965bool DS_DATA_MODEL::LoadDrawingSheet( const wxString& aFullFileName, bool Append )
966{
967 wxString fullFileName = aFullFileName;
968
969 if( !Append )
970 {
971 if( fullFileName.IsEmpty() )
972 {
974 return true; // we assume its fine / default init
975 }
976
977 if( !wxFileExists( fullFileName ) )
978 {
979 wxLogMessage( _( "Drawing sheet '%s' not found." ), fullFileName );
981 return false;
982 }
983 }
984
985 wxFFile wksFile( fullFileName, wxS( "rb" ) );
986
987 if( ! wksFile.IsOpened() )
988 {
989 wxLogMessage( _( "Drawing sheet '%s' could not be opened." ), fullFileName );
990
991 if( !Append )
993
994 return false;
995 }
996
997 size_t filelen = wksFile.Length();
998 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(filelen+10);
999
1000 if( wksFile.Read( buffer.get(), filelen ) != filelen )
1001 {
1002 wxLogMessage( _( "Drawing sheet '%s' was not fully read." ), fullFileName.GetData() );
1003 return false;
1004 }
1005 else
1006 {
1007 buffer[filelen]=0;
1008
1009 if( ! Append )
1010 ClearList();
1011
1012 DRAWING_SHEET_PARSER parser( buffer.get(), fullFileName );
1013
1014 try
1015 {
1016 parser.Parse( this );
1017 }
1018 catch( const IO_ERROR& ioe )
1019 {
1020 wxLogMessage( ioe.What() );
1021 return false;
1022 }
1023 catch( const std::bad_alloc& )
1024 {
1025 wxLogMessage( wxS( "Memory exhaustion reading drawing sheet" ) );
1026 return false;
1027 }
1028 }
1029
1030 return true;
1031}
This class handle bitmap images in KiCad.
Definition: bitmap_base.h:48
bool LoadLegacyData(LINE_READER &aLine, wxString &aErrorMsg)
Load an image data saved by #SaveData.
bool ReadImageFile(const wxString &aFullFilename)
Reads and stores in memory an image file.
void SetScale(double aScale)
Definition: bitmap_base.h:73
DRAWING_SHEET_PARSER holds data and functions pertinent to parsing a S-expression file for a DS_DATA_...
void parseCoordinate(POINT_COORD &aCoord)
void parseHeader(T aHeaderType)
Parse the data specified at the very beginning of the file, like version and the application used to ...
DRAWING_SHEET_PARSER(const char *aLine, const wxString &aSource)
void parseBitmap(DS_DATA_ITEM_BITMAP *aItem)
Parse a bitmap item starting by "( bitmap" and read parameters.
void readPngdata(DS_DATA_ITEM_BITMAP *aItem)
void parsePolygon(DS_DATA_ITEM_POLYGONS *aItem)
Parse a polygon item starting by "( polygon" and read parameters.
void parseText(DS_DATA_ITEM_TEXT *aItem)
Parse a text item starting by "(tbtext" and read parameters.
void Parse(DS_DATA_MODEL *aLayout)
int parseInt()
Parse an integer.
void readOption(DS_DATA_ITEM *aItem)
double parseDouble()
Parse a double.
void parseSetup(DS_DATA_MODEL *aLayout)
void parseGraphic(DS_DATA_ITEM *aItem)
Parse a graphic item starting by "(line" or "(rect" and read parameters.
void parsePolyOutline(DS_DATA_ITEM_POLYGONS *aItem)
Parse a list of corners starting by "( pts" and read coordinates.
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
Definition: dsnlexer.cpp:824
BITMAP_BASE * m_ImageBitmap
Definition: ds_data_item.h:370
void SetBoundingBox()
Calculate the bounding box of the set polygons.
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 AppendCorner(const VECTOR2D &aCorner)
Add a corner in corner list.
Definition: ds_data_item.h:229
KIFONT::FONT * m_Font
Definition: ds_data_item.h:342
GR_TEXT_H_ALIGN_T m_Hjustify
Definition: ds_data_item.h:338
KIGFX::COLOR4D m_TextColor
Definition: ds_data_item.h:344
VECTOR2D m_BoundingBoxSize
Definition: ds_data_item.h:345
GR_TEXT_V_ALIGN_T m_Vjustify
Definition: ds_data_item.h:339
Drawing sheet structure type definitions.
Definition: ds_data_item.h:96
void SetPage1Option(PAGE_OPTION aChoice)
Definition: ds_data_item.h:134
wxString m_Name
Definition: ds_data_item.h:198
VECTOR2D m_IncrementVector
Definition: ds_data_item.h:204
POINT_COORD m_Pos
Definition: ds_data_item.h:200
wxString m_Info
Definition: ds_data_item.h:199
double m_LineWidth
Definition: ds_data_item.h:202
POINT_COORD m_End
Definition: ds_data_item.h:201
int m_IncrementLabel
Definition: ds_data_item.h:205
Handle the graphic items list to draw/plot the frame and title block.
Definition: ds_data_model.h:39
void SetBottomMargin(double aMargin)
Definition: ds_data_model.h:73
VECTOR2D m_DefaultTextSize
void SetRightMargin(double aMargin)
Definition: ds_data_model.h:67
double m_DefaultLineWidth
static wxString DefaultLayout()
Return a string containing the empty layout shape.
static wxString EmptyLayout()
Return a string containing the empty layout shape.
void SetLeftMargin(double aMargin)
Definition: ds_data_model.h:64
double m_DefaultTextThickness
void Append(DS_DATA_ITEM *aItem)
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
void ClearList()
Erase the list of items.
void SetTopMargin(double aMargin)
Definition: ds_data_model.h:70
void SetFileFormatVersionAtLoad(int aVersion)
Definition: ds_data_model.h:61
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.
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.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:146
double r
Red component.
Definition: color4d.h:376
double g
Green component.
Definition: color4d.h:377
double a
Alpha component.
Definition: color4d.h:379
double b
Blue component.
Definition: color4d.h:378
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
A coordinate point.
Definition: ds_data_item.h:70
VECTOR2D m_Pos
Definition: ds_data_item.h:80
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:253
const char emptyDrawingSheet[]
const char defaultDrawingSheet[]
const char emptyDrawingSheet[]
wxString convertLegacyVariableRefs(const wxString &aTextbase)
const char defaultDrawingSheet[]
@ FIRST_PAGE_ONLY
Definition: ds_data_item.h:58
@ SUBSEQUENT_PAGES
Definition: ds_data_item.h:59
@ RB_CORNER
Definition: ds_data_item.h:49
@ RT_CORNER
Definition: ds_data_item.h:50
@ LT_CORNER
Definition: ds_data_item.h:52
@ LB_CORNER
Definition: ds_data_item.h:51
#define SEXPR_WORKSHEET_FILE_VERSION
This file contains the file format version information for the s-expression drawing sheet file format...
#define _(s)
@ DEGREES_T
Definition: eda_angle.h:31
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
Variant of PARSE_ERROR indicating that a syntax or related error was likely caused by a file generate...
Definition: ki_exception.h:176
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
constexpr T Clamp(const T &lower, const T &value, const T &upper)
Limit value within the range lower <= value <= upper.
Definition: util.h:64