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 The 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, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <charconv>
23#include <fmt/format.h>
24#include <wx/base64.h>
25#include <wx/ffile.h>
26#include <wx/log.h>
27
28#include <eda_item.h>
29#include <filename_resolver.h>
30#include <locale_io.h>
31#include <pgm_base.h>
32#include <string_utils.h>
36#include <drawing_sheet/drawing_sheet_lexer.h>
38#include <font/font.h>
39
40using namespace DRAWINGSHEET_T;
41
45class DRAWING_SHEET_PARSER : public DRAWING_SHEET_LEXER
46{
47public:
48 DRAWING_SHEET_PARSER( const char* aLine, const wxString& aSource );
49 void Parse( DS_DATA_MODEL* aLayout );
50
51private:
56 void parseHeader( T aHeaderType );
57
61 int parseInt();
62
70 int parseInt( int aMin, int aMax );
71
77 double parseDouble();
78
79 void parseSetup( DS_DATA_MODEL* aLayout );
80
84 void parseGraphic( DS_DATA_ITEM * aItem );
85
89 void parseText( DS_DATA_ITEM_TEXT * aItem );
90
95 void parsePolygon( DS_DATA_ITEM_POLYGONS * aItem );
96
101
102
106 void parseBitmap( DS_DATA_ITEM_BITMAP * aItem );
107
108 void parseCoordinate( POINT_COORD& aCoord);
109 void readOption( DS_DATA_ITEM * aItem );
110 void readPngdata( DS_DATA_ITEM_BITMAP * aItem );
111
112private:
115};
116
117
119 const wxString& aSource ) :
120 DRAWING_SHEET_LEXER( aLine, aSource ),
122{
123}
124
125
126wxString convertLegacyVariableRefs( const wxString& aTextbase )
127{
128 wxString msg;
129
130 /*
131 * Legacy formats
132 * %% = replaced by %
133 * %K = Kicad version
134 * %Z = paper format name (A4, USLetter)
135 * %Y = company name
136 * %D = date
137 * %R = revision
138 * %S = sheet number
139 * %N = number of sheets
140 * %L = layer name
141 * %Cx = comment (x = 0 to 9 to identify the comment)
142 * %F = filename
143 * %P = sheet path (sheet full name)
144 * %T = title
145 */
146
147 for( unsigned ii = 0; ii < aTextbase.Len(); ii++ )
148 {
149 if( aTextbase[ii] != '%' )
150 {
151 msg << aTextbase[ii];
152 continue;
153 }
154
155 if( ++ii >= aTextbase.Len() )
156 break;
157
158 wxChar format = aTextbase[ii];
159
160 switch( format )
161 {
162 case '%': msg += '%'; break;
163 case 'D': msg += wxT( "${ISSUE_DATE}" ); break;
164 case 'R': msg += wxT( "${REVISION}" ); break;
165 case 'K': msg += wxT( "${KICAD_VERSION}" ); break;
166 case 'Z': msg += wxT( "${PAPER}" ); break;
167 case 'S': msg += wxT( "${#}" ); break;
168 case 'N': msg += wxT( "${##}" ); break;
169 case 'F': msg += wxT( "${FILENAME}" ); break;
170 case 'L': msg += wxT( "${LAYER}" ); break;
171 case 'P': msg += wxT( "${SHEETPATH}" ); break;
172 case 'Y': msg += wxT( "${COMPANY}" ); break;
173 case 'T': msg += wxT( "${TITLE}" ); break;
174 case 'C':
175 format = aTextbase[++ii];
176
177 switch( format )
178 {
179 case '0': msg += wxT( "${COMMENT1}" ); break;
180 case '1': msg += wxT( "${COMMENT2}" ); break;
181 case '2': msg += wxT( "${COMMENT3}" ); break;
182 case '3': msg += wxT( "${COMMENT4}" ); break;
183 case '4': msg += wxT( "${COMMENT5}" ); break;
184 case '5': msg += wxT( "${COMMENT6}" ); break;
185 case '6': msg += wxT( "${COMMENT7}" ); break;
186 case '7': msg += wxT( "${COMMENT8}" ); break;
187 case '8': msg += wxT( "${COMMENT9}" ); break;
188 }
189 break;
190
191 default:
192 break;
193 }
194 }
195
196 return msg;
197}
198
199
201{
202 DS_DATA_ITEM* item;
203 LOCALE_IO toggle;
204
205 NeedLEFT();
206 T token = NextTok();
207
208 parseHeader( token );
210
211 // Sheets predating the generator token, or a reused model, must not inherit a stale generator.
212 aLayout->SetGenerator( wxT( "pl_editor" ) );
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 NeedSYMBOL();
233 aLayout->SetGenerator( FromUTF8() );
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
299
301{
302 // The older files had no versioning and their first token after the initial left parenthesis
303 // was a `page_layout` or `drawing_sheet` token. The newer files have versions and have a
304 // `kicad_wks` token instead.
305
306 if( aHeaderType == T_kicad_wks || aHeaderType == T_drawing_sheet )
307 {
308 NeedLEFT();
309
310 T tok = NextTok();
311
312 if( tok == T_version )
313 {
315
316 NeedRIGHT();
317 }
318 else
319 {
320 Expecting( T_version );
321 }
322 }
323 else
324 {
325 // We assign version 0 to files that were created before there was any versioning of
326 // worksheets. The below line is not strictly necessary, as `m_requiredVersion` is already
327 // initialized to 0 in the constructor.
329 }
330}
331
332
334{
335 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
336 {
337 switch( token )
338 {
339 case T_LEFT:
340 break;
341
342 case T_linewidth:
343 aLayout->m_DefaultLineWidth = parseDouble();
344 NeedRIGHT();
345 break;
346
347 case T_textsize:
348 aLayout->m_DefaultTextSize.x = parseDouble();
349 aLayout->m_DefaultTextSize.y = parseDouble();
350 NeedRIGHT();
351 break;
352
353 case T_textlinewidth:
355 NeedRIGHT();
356 break;
357
358 case T_left_margin:
359 aLayout->SetLeftMargin( parseDouble() );
360 NeedRIGHT();
361 break;
362
363 case T_right_margin:
364 aLayout->SetRightMargin( parseDouble() );
365 NeedRIGHT();
366 break;
367
368 case T_top_margin:
369 aLayout->SetTopMargin( parseDouble() );
370 NeedRIGHT();
371 break;
372
373 case T_bottom_margin:
374 aLayout->SetBottomMargin( parseDouble() );
375 NeedRIGHT();
376 break;
377
378 default:
379 Unexpected( CurText() );
380 break;
381 }
382 }
383
384 // The file is well-formed. If it has no further items, then that's the way the
385 // user wants it.
386 aLayout->AllowVoidList( true );
387}
388
389
391{
392 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
393 {
394 if( token == T_LEFT )
395 token = NextTok();
396
397 switch( token )
398 {
399 case T_comment:
400 NeedSYMBOLorNUMBER();
401 aItem->m_Info = FromUTF8();
402 NeedRIGHT();
403 break;
404
405 case T_pos:
406 parseCoordinate( aItem->m_Pos );
407 break;
408
409 case T_name:
410 NeedSYMBOLorNUMBER();
411 aItem->m_Name = FromUTF8();
412 NeedRIGHT();
413 break;
414
415 case T_option:
416 readOption( aItem );
417 break;
418
419 case T_pts:
420 parsePolyOutline( aItem );
421 aItem->CloseContour();
422 break;
423
424 case T_rotate:
426 NeedRIGHT();
427 break;
428
429 case T_repeat:
431 NeedRIGHT();
432 break;
433
434 case T_incrx:
436 NeedRIGHT();
437 break;
438
439 case T_incry:
441 NeedRIGHT();
442 break;
443
444 case T_linewidth:
445 aItem->m_LineWidth = parseDouble();
446 NeedRIGHT();
447 break;
448
449 default:
450 Unexpected( CurText() );
451 break;
452 }
453 }
454
455 aItem->SetBoundingBox();
456}
457
458
460{
461 VECTOR2D corner;
462
463 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
464 {
465 if( token == T_LEFT )
466 token = NextTok();
467
468 switch( token )
469 {
470 case T_xy:
471 corner.x = parseDouble();
472 corner.y = parseDouble();
473 aItem->AppendCorner( corner );
474 NeedRIGHT();
475 break;
476
477 default:
478 Unexpected( CurText() );
479 break;
480 }
481 }
482}
483
484
486{
488 aItem->m_ImageBitmap = image;
489
490 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
491 {
492 if( token == T_LEFT )
493 token = NextTok();
494
495 switch( token )
496 {
497 case T_name:
498 NeedSYMBOLorNUMBER();
499 aItem->m_Name = FromUTF8();
500 NeedRIGHT();
501 break;
502
503 case T_pos:
504 parseCoordinate( aItem->m_Pos );
505 break;
506
507 case T_repeat:
509 NeedRIGHT();
510 break;
511
512 case T_incrx:
514 NeedRIGHT();
515 break;
516
517 case T_incry:
519 NeedRIGHT();
520 break;
521
522 case T_linewidth:
523 aItem->m_LineWidth = parseDouble();
524 NeedRIGHT();
525 break;
526
527 case T_scale:
529 NeedRIGHT();
530 break;
531
532 case T_comment:
533 NeedSYMBOLorNUMBER();
534 aItem->m_Info = FromUTF8();
535 NeedRIGHT();
536 break;
537
538 case T_data:
539 {
540 token = NextTok();
541
542 wxString data;
543
544 // Reserve 512K because most image files are going to be larger than the default
545 // 1K that wxString reserves.
546 data.reserve( 1 << 19 );
547
548 while( token != T_RIGHT )
549 {
550 if( !IsSymbol( token ) )
551 Expecting( "base64 image data" );
552
553 data += FromUTF8();
554 token = NextTok();
555 }
556
557 wxMemoryBuffer buffer = wxBase64Decode( data );
558
559 if( !aItem->m_ImageBitmap->ReadImageFile( buffer ) )
560 THROW_IO_ERROR( _( "Failed to read image data." ) );
561
562 break;
563 }
564
565 case T_pngdata:
566 readPngdata( aItem );
567 break;
568
569 case T_option:
570 readOption( aItem );
571 break;
572
573 default:
574 Unexpected( CurText() );
575 break;
576 }
577 }
578}
579
580
582{
583 std::string tmp;
584
585 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
586 {
587 if( token == T_LEFT )
588 token = NextTok();
589
590 switch( token )
591 {
592 case T_data:
593 NeedSYMBOLorNUMBER();
594 tmp += CurStr();
595 tmp += "\n";
596 NeedRIGHT();
597 break;
598
599 default:
600 Unexpected( CurText() );
601 break;
602 }
603 }
604
605 tmp += "EndData";
606
607 wxString msg;
608 STRING_LINE_READER str_reader( tmp, wxT("Png kicad_wks data") );
609
610 aItem->m_ImageBitmap->LoadLegacyData( str_reader, msg );
611}
612
613
615{
616 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
617 {
618 switch( token )
619 {
620 case T_page1only: aItem->SetPage1Option( FIRST_PAGE_ONLY ); break;
621 case T_notonpage1: aItem->SetPage1Option( SUBSEQUENT_PAGES ); break;
622 default: Unexpected( CurText() ); break;
623 }
624 }
625}
626
627
629{
630 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
631 {
632 if( token == T_LEFT )
633 {
634 token = NextTok();
635 }
636 else
637 {
638 // If another token than T_LEFT is read here, this is an error
639 // however, due to a old bug in kicad, the token T_end can be found
640 // without T_LEFT in a very few .wks files (perhaps only one in a demo).
641 // So this ugly hack disables the error detection.
642 if( token != T_end )
643 Unexpected( CurText() );
644 }
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_start:
665 parseCoordinate( aItem->m_Pos );
666 break;
667
668 case T_end:
669 parseCoordinate( aItem->m_End );
670 break;
671
672 case T_repeat:
674 NeedRIGHT();
675 break;
676
677 case T_incrx:
679 NeedRIGHT();
680 break;
681
682 case T_incry:
684 NeedRIGHT();
685 break;
686
687 case T_linewidth:
688 aItem->m_LineWidth = parseDouble();
689 NeedRIGHT();
690 break;
691
692 default:
693 Unexpected( CurText() );
694 break;
695 }
696 }
697}
698
699
701{
702 if( m_requiredVersion < 20210606 )
704
705 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
706 {
707 if( token == T_LEFT )
708 token = NextTok();
709
710 switch( token )
711 {
712 case T_comment:
713 NeedSYMBOLorNUMBER();
714 aItem->m_Info = FromUTF8();
715 NeedRIGHT();
716 break;
717
718 case T_option:
719 readOption( aItem );
720 break;
721
722 case T_name:
723 NeedSYMBOLorNUMBER();
724 aItem->m_Name = FromUTF8();
725 NeedRIGHT();
726 break;
727
728 case T_pos:
729 parseCoordinate( aItem->m_Pos );
730 break;
731
732 case T_repeat:
734 NeedRIGHT();
735 break;
736
737 case T_incrx:
739 NeedRIGHT();
740 break;
741
742 case T_incry:
744 NeedRIGHT();
745 break;
746
747 case T_incrlabel:
748 aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
749 NeedRIGHT();
750 break;
751
752 case T_maxlen:
754 NeedRIGHT();
755 break;
756
757 case T_maxheight:
759 NeedRIGHT();
760 break;
761
762 case T_font:
763 {
764 wxString faceName;
765
767
768 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
769 {
770 switch( token )
771 {
772 case T_LEFT:
773 break;
774
775 case T_face:
776 NeedSYMBOL();
777 faceName = FromUTF8();
778 NeedRIGHT();
779 break;
780
781 case T_bold:
782 aItem->m_Bold = true;
783 break;
784
785 case T_italic:
786 aItem->m_Italic = true;
787 break;
788
789 case T_size:
790 aItem->m_TextSize.x = parseDouble();
791 aItem->m_TextSize.y = parseDouble();
792 NeedRIGHT();
793 break;
794
795 case T_color:
796 aItem->m_TextColor.r = parseInt( 0, 255 ) / 255.0;
797 aItem->m_TextColor.g = parseInt( 0, 255 ) / 255.0;
798 aItem->m_TextColor.b = parseInt( 0, 255 ) / 255.0;
799 aItem->m_TextColor.a = std::clamp( parseDouble(), 0.0, 1.0 );
800 NeedRIGHT();
801 break;
802
803 case T_linewidth:
804 aItem->m_LineWidth = parseDouble();
805 NeedRIGHT();
806 break;
807
808 default:
809 Unexpected( CurText() );
810 break;
811 }
812 }
813
814 if( !faceName.IsEmpty() )
815 aItem->m_Font = KIFONT::FONT::GetFont( faceName, aItem->m_Bold, aItem->m_Italic );
816
817 break;
818 }
819
820 case T_justify:
821 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
822 {
823 switch( token )
824 {
825 case T_center:
828 break;
829
830 case T_left:
832 break;
833
834 case T_right:
836 break;
837
838 case T_top:
840 break;
841
842 case T_bottom:
844 break;
845
846 default:
847 Unexpected( CurText() );
848 break;
849 }
850 }
851 break;
852
853 case T_rotate:
854 aItem->m_Orient = parseDouble();
855 NeedRIGHT();
856 break;
857
858 default:
859 Unexpected( CurText() );
860 break;
861 }
862 }
863}
864
865
867{
868 aCoord.m_Pos.x = parseDouble();
869 aCoord.m_Pos.y = parseDouble();
870
871 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
872 {
873 switch( token )
874 {
875 case T_ltcorner: aCoord.m_Anchor = LT_CORNER; break;
876 case T_lbcorner: aCoord.m_Anchor = LB_CORNER; break;
877 case T_rbcorner: aCoord.m_Anchor = RB_CORNER; break;
878 case T_rtcorner: aCoord.m_Anchor = RT_CORNER; break;
879 default: Unexpected( CurText() ); break;
880 }
881 }
882}
883
884
886{
887 T token = NextTok();
888
889 if( token != T_NUMBER )
890 Expecting( T_NUMBER );
891
892 return atoi( CurText() );
893}
894
895
896int DRAWING_SHEET_PARSER::parseInt( int aMin, int aMax )
897{
898 int val = parseInt();
899
900 if( val < aMin )
901 val = aMin;
902 else if( val > aMax )
903 val = aMax;
904
905 return val;
906}
907
908
910{
911 T token = NextTok();
912
913 if( token != T_NUMBER )
914 Expecting( T_NUMBER );
915
916
917 return DSNLEXER::parseDouble();
918}
919
920
921// defaultDrawingSheet is the default drawing sheet using the S expr.
922extern const char defaultDrawingSheet[];
923
924
926{
927 SetPageLayout( defaultDrawingSheet, false, wxT( "default page" ) );
928}
929
930
932{
933 return wxString( defaultDrawingSheet );
934}
935
936
937// emptyDrawingSheet is a "empty" drawing sheet using the S expr.
938// there is a 0 length line to fool something somewhere.
939extern const char emptyDrawingSheet[];
940
941
943{
944 SetPageLayout( emptyDrawingSheet, false, wxT( "empty page" ) );
945}
946
947
949{
950 return wxString( emptyDrawingSheet );
951}
952
953
955{
956 static const wxString name( wxS( "empty.kicad_wks" ) );
957
958 return name;
959}
960
961
962bool DS_DATA_MODEL::LoadFromName( const wxString& aSheetName, const wxString& aBasePath, PROJECT* aProject,
963 std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack, wxString* aMsg )
964{
965 if( aSheetName == EmptyLayoutName() )
966 {
968 return true;
969 }
970
972 resolver.SetProject( aProject );
973 resolver.SetProgramBase( &Pgm() );
974
975 return LoadDrawingSheet( resolver.ResolvePath( aSheetName, aBasePath, std::move( aEmbeddedFilesStack ) ), aMsg );
976}
977
978
979void DS_DATA_MODEL::SetPageLayout( const char* aPageLayout, bool Append, const wxString& aSource )
980{
981 if( ! Append )
982 ClearList();
983
984 DRAWING_SHEET_PARSER parser( aPageLayout, wxT( "Sexpr_string" ) );
985
986 try
987 {
988 parser.Parse( this );
989 }
990 catch( ... )
991 {
992 // best efforts
993 }
994}
995
996
997bool DS_DATA_MODEL::LoadDrawingSheet( const wxString& aFullFileName, wxString* aMsg, bool aAppend )
998{
999 if( !aAppend )
1000 {
1001 if( aFullFileName.IsEmpty() )
1002 {
1004 return true; // we assume its fine / default init
1005 }
1006
1007 if( !wxFileExists( aFullFileName ) )
1008 {
1009 if( aMsg )
1010 *aMsg = _( "File not found." );
1011
1013 return false;
1014 }
1015 }
1016
1017 wxFFile wksFile( aFullFileName, wxS( "rb" ) );
1018
1019 if( ! wksFile.IsOpened() )
1020 {
1021 if( aMsg )
1022 *aMsg = _( "File could not be opened." );
1023
1024 if( !aAppend )
1026
1027 return false;
1028 }
1029
1030 size_t filelen = wksFile.Length();
1031 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(filelen+10);
1032
1033 if( wksFile.Read( buffer.get(), filelen ) != filelen )
1034 {
1035 if( aMsg )
1036 *aMsg = _( "Drawing sheet was not fully read." );
1037
1038 return false;
1039 }
1040 else
1041 {
1042 buffer[filelen]=0;
1043
1044 if( ! aAppend )
1045 ClearList();
1046
1047 DRAWING_SHEET_PARSER parser( buffer.get(), aFullFileName );
1048
1049 try
1050 {
1051 parser.Parse( this );
1052 }
1053 catch( const IO_ERROR& ioe )
1054 {
1055 if( aMsg )
1056 *aMsg = ioe.What();
1057
1058 return false;
1059 }
1060 catch( const std::bad_alloc& )
1061 {
1062 if( aMsg )
1063 *aMsg = _( "Ran out of memory." );
1064
1065 return false;
1066 }
1067 }
1068
1069 return true;
1070}
const char * name
This class handle bitmap images in KiCad.
Definition bitmap_base.h:45
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:70
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:399
Hold data and functions pertinent to parsing a S-expression file for a DS_DATA_MODEL.
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:860
BITMAP_BASE * m_ImageBitmap
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...
void AppendCorner(const VECTOR2D &aCorner)
Add a corner in corner list.
KIFONT::FONT * m_Font
GR_TEXT_H_ALIGN_T m_Hjustify
KIGFX::COLOR4D m_TextColor
VECTOR2D m_BoundingBoxSize
GR_TEXT_V_ALIGN_T m_Vjustify
Drawing sheet structure type definitions.
void SetPage1Option(PAGE_OPTION aChoice)
wxString m_Name
VECTOR2D m_IncrementVector
POINT_COORD m_Pos
wxString m_Info
double m_LineWidth
POINT_COORD m_End
Handle the graphic items list to draw/plot the frame and title block.
bool LoadDrawingSheet(const wxString &aFullFileName, wxString *aMsg, bool aAppend=false)
Populate the list with a custom layout or the default layout if no custom layout is available.
void SetBottomMargin(double aMargin)
VECTOR2D m_DefaultTextSize
void SetRightMargin(double aMargin)
void SetGenerator(const wxString &aGenerator)
bool LoadFromName(const wxString &aSheetName, const wxString &aBasePath, PROJECT *aProject, std::vector< const EMBEDDED_FILES * > aEmbeddedFilesStack, wxString *aMsg)
Populate the list from aSheetName, which is either EmptyLayoutName, an embedded file reference or a p...
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)
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 ...
void ClearList()
Erase the list of items.
void SetTopMargin(double aMargin)
static const wxString & EmptyLayoutName()
Return the reserved drawing-sheet name that marks a design as deliberately having no sheet,...
void SetFileFormatVersionAtLoad(int aVersion)
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.
Provide an extensible class to resolve 3D model paths.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition font.cpp:143
double r
Red component.
Definition color4d.h:390
double g
Green component.
Definition color4d.h:391
double a
Alpha component.
Definition color4d.h:393
double b
Blue component.
Definition color4d.h:392
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
A coordinate point.
VECTOR2D m_Pos
Container for project specific data.
Definition project.h:63
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition richio.h:225
const char emptyDrawingSheet[]
const char defaultDrawingSheet[]
wxString convertLegacyVariableRefs(const wxString &aTextbase)
@ FIRST_PAGE_ONLY
@ SUBSEQUENT_PAGES
@ RB_CORNER
@ RT_CORNER
@ LT_CORNER
@ LB_CORNER
constexpr int DS_MAX_REPEAT_COUNT
Upper bound on DS_DATA_ITEM::m_RepeatCount.
#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
static FILENAME_RESOLVER * resolver
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
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...
@ 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
VECTOR2< double > VECTOR2D
Definition vector2d.h:682