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, 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
47class DRAWING_SHEET_PARSER : public DRAWING_SHEET_LEXER
48{
49public:
50 DRAWING_SHEET_PARSER( const char* aLine, const wxString& aSource );
51 void Parse( DS_DATA_MODEL* aLayout );
52
53private:
56
61 void parseHeader( T aHeaderType );
62
66 int parseInt();
67
75 int parseInt( int aMin, int aMax );
76
82 double parseDouble();
83
84 void parseSetup( DS_DATA_MODEL* aLayout );
85
89 void parseGraphic( DS_DATA_ITEM * aItem );
90
94 void parseText( DS_DATA_ITEM_TEXT * aItem );
95
100 void parsePolygon( DS_DATA_ITEM_POLYGONS * aItem );
101
106
107
111 void parseBitmap( DS_DATA_ITEM_BITMAP * aItem );
112
113 void parseCoordinate( POINT_COORD& aCoord);
114 void readOption( DS_DATA_ITEM * aItem );
115 void readPngdata( DS_DATA_ITEM_BITMAP * aItem );
116};
117
118
120 const wxString& aSource ) :
121 DRAWING_SHEET_LEXER( aLine, aSource ),
122 m_requiredVersion( 0 )
123{
124}
125
126
127wxString convertLegacyVariableRefs( const wxString& aTextbase )
128{
129 wxString msg;
130
131 /*
132 * Legacy formats
133 * %% = replaced by %
134 * %K = Kicad version
135 * %Z = paper format name (A4, USLetter)
136 * %Y = company name
137 * %D = date
138 * %R = revision
139 * %S = sheet number
140 * %N = number of sheets
141 * %L = layer name
142 * %Cx = comment (x = 0 to 9 to identify the comment)
143 * %F = filename
144 * %P = sheet path (sheet full name)
145 * %T = title
146 */
147
148 for( unsigned ii = 0; ii < aTextbase.Len(); ii++ )
149 {
150 if( aTextbase[ii] != '%' )
151 {
152 msg << aTextbase[ii];
153 continue;
154 }
155
156 if( ++ii >= aTextbase.Len() )
157 break;
158
159 wxChar format = aTextbase[ii];
160
161 switch( format )
162 {
163 case '%': msg += '%'; break;
164 case 'D': msg += wxT( "${ISSUE_DATE}" ); break;
165 case 'R': msg += wxT( "${REVISION}" ); break;
166 case 'K': msg += wxT( "${KICAD_VERSION}" ); break;
167 case 'Z': msg += wxT( "${PAPER}" ); break;
168 case 'S': msg += wxT( "${#}" ); break;
169 case 'N': msg += wxT( "${##}" ); break;
170 case 'F': msg += wxT( "${FILENAME}" ); break;
171 case 'L': msg += wxT( "${LAYER}" ); break;
172 case 'P': msg += wxT( "${SHEETPATH}" ); break;
173 case 'Y': msg += wxT( "${COMPANY}" ); break;
174 case 'T': msg += wxT( "${TITLE}" ); break;
175 case 'C':
176 format = aTextbase[++ii];
177
178 switch( format )
179 {
180 case '0': msg += wxT( "${COMMENT1}" ); break;
181 case '1': msg += wxT( "${COMMENT2}" ); break;
182 case '2': msg += wxT( "${COMMENT3}" ); break;
183 case '3': msg += wxT( "${COMMENT4}" ); break;
184 case '4': msg += wxT( "${COMMENT5}" ); break;
185 case '5': msg += wxT( "${COMMENT6}" ); break;
186 case '6': msg += wxT( "${COMMENT7}" ); break;
187 case '7': msg += wxT( "${COMMENT8}" ); break;
188 case '8': msg += wxT( "${COMMENT9}" ); break;
189 }
190 break;
191
192 default:
193 break;
194 }
195 }
196
197 return msg;
198}
199
200
202{
203 DS_DATA_ITEM* item;
204 LOCALE_IO toggle;
205
206 NeedLEFT();
207 T token = NextTok();
208
209 parseHeader( token );
211
212 auto checkVersion =
213 [&]()
214 {
216 {
217 throw FUTURE_FORMAT_ERROR( fmt::format( "{}", m_requiredVersion ),
219 }
220 };
221
222 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
223 {
224 if( token == T_LEFT )
225 token = NextTok();
226
227 switch( token )
228 {
229 case T_generator:
230 // (generator "genname"); we don't care about it at the moment.
231 NeedSYMBOL();
232 NeedRIGHT();
233 break;
234
235 case T_generator_version:
236 NextTok();
237 m_generatorVersion = FromUTF8();
238 NeedRIGHT();
239 break;
240
241 case T_setup: // Defines default values for graphic items
242 // Check the version here, because the generator and generator_version (if available)
243 // will have been parsed by now given the order the formatter writes them in
244 checkVersion();
245 parseSetup( aLayout );
246 break;
247
248 case T_line:
250 parseGraphic( item );
251 aLayout->Append( item );
252 break;
253
254 case T_rect:
256 parseGraphic( item );
257 aLayout->Append( item );
258 break;
259
260 case T_polygon:
261 item = new DS_DATA_ITEM_POLYGONS();
263 aLayout->Append( item );
264 break;
265
266 case T_bitmap:
267 item = new DS_DATA_ITEM_BITMAP( NULL );
269
270 // Drop invalid bitmaps
271 if( static_cast<DS_DATA_ITEM_BITMAP*>( item )->m_ImageBitmap->GetOriginalImageData() )
272 {
273 aLayout->Append( item );
274 }
275 else
276 {
277 delete static_cast<DS_DATA_ITEM_BITMAP*>( item )->m_ImageBitmap;
278 delete item;
279 }
280
281 break;
282
283 case T_tbtext:
284 NeedSYMBOLorNUMBER();
285 item = new DS_DATA_ITEM_TEXT( convertLegacyVariableRefs( FromUTF8() ) );
286 parseText( (DS_DATA_ITEM_TEXT*) item );
287 aLayout->Append( item );
288 break;
289
290 default:
291 Unexpected( CurText() );
292 break;
293 }
294 }
295}
296
297
299{
300 // The older files had no versioning and their first token after the initial left parenthesis
301 // was a `page_layout` or `drawing_sheet` token. The newer files have versions and have a
302 // `kicad_wks` token instead.
303
304 if( aHeaderType == T_kicad_wks || aHeaderType == T_drawing_sheet )
305 {
306 NeedLEFT();
307
308 T tok = NextTok();
309
310 if( tok == T_version )
311 {
313
314 NeedRIGHT();
315 }
316 else
317 {
318 Expecting( T_version );
319 }
320 }
321 else
322 {
323 // We assign version 0 to files that were created before there was any versioning of
324 // worksheets. The below line is not strictly necessary, as `m_requiredVersion` is already
325 // initialized to 0 in the constructor.
327 }
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
456
458{
459 VECTOR2D corner;
460
461 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
462 {
463 if( token == T_LEFT )
464 token = NextTok();
465
466 switch( token )
467 {
468 case T_xy:
469 corner.x = parseDouble();
470 corner.y = parseDouble();
471 aItem->AppendCorner( corner );
472 NeedRIGHT();
473 break;
474
475 default:
476 Unexpected( CurText() );
477 break;
478 }
479 }
480}
481
482
484{
486 aItem->m_ImageBitmap = image;
487
488 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
489 {
490 if( token == T_LEFT )
491 token = NextTok();
492
493 switch( token )
494 {
495 case T_name:
496 NeedSYMBOLorNUMBER();
497 aItem->m_Name = FromUTF8();
498 NeedRIGHT();
499 break;
500
501 case T_pos:
502 parseCoordinate( aItem->m_Pos );
503 break;
504
505 case T_repeat:
506 aItem->m_RepeatCount = parseInt( 1, 100 );
507 NeedRIGHT();
508 break;
509
510 case T_incrx:
512 NeedRIGHT();
513 break;
514
515 case T_incry:
517 NeedRIGHT();
518 break;
519
520 case T_linewidth:
521 aItem->m_LineWidth = parseDouble();
522 NeedRIGHT();
523 break;
524
525 case T_scale:
527 NeedRIGHT();
528 break;
529
530 case T_comment:
531 NeedSYMBOLorNUMBER();
532 aItem->m_Info = FromUTF8();
533 NeedRIGHT();
534 break;
535
536 case T_data:
537 {
538 token = NextTok();
539
540 wxString data;
541
542 // Reserve 512K because most image files are going to be larger than the default
543 // 1K that wxString reserves.
544 data.reserve( 1 << 19 );
545
546 while( token != T_RIGHT )
547 {
548 if( !IsSymbol( token ) )
549 Expecting( "base64 image data" );
550
551 data += FromUTF8();
552 token = NextTok();
553 }
554
555 wxMemoryBuffer buffer = wxBase64Decode( data );
556
557 if( !aItem->m_ImageBitmap->ReadImageFile( buffer ) )
558 THROW_IO_ERROR( _( "Failed to read image data." ) );
559
560 break;
561 }
562
563 case T_pngdata:
564 readPngdata( aItem );
565 break;
566
567 case T_option:
568 readOption( aItem );
569 break;
570
571 default:
572 Unexpected( CurText() );
573 break;
574 }
575 }
576}
577
578
580{
581 std::string tmp;
582
583 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
584 {
585 if( token == T_LEFT )
586 token = NextTok();
587
588 switch( token )
589 {
590 case T_data:
591 NeedSYMBOLorNUMBER();
592 tmp += CurStr();
593 tmp += "\n";
594 NeedRIGHT();
595 break;
596
597 default:
598 Unexpected( CurText() );
599 break;
600 }
601 }
602
603 tmp += "EndData";
604
605 wxString msg;
606 STRING_LINE_READER str_reader( tmp, wxT("Png kicad_wks data") );
607
608 aItem->m_ImageBitmap->LoadLegacyData( str_reader, msg );
609}
610
611
613{
614 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
615 {
616 switch( token )
617 {
618 case T_page1only: aItem->SetPage1Option( FIRST_PAGE_ONLY ); break;
619 case T_notonpage1: aItem->SetPage1Option( SUBSEQUENT_PAGES ); break;
620 default: Unexpected( CurText() ); break;
621 }
622 }
623}
624
625
627{
628 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
629 {
630 if( token == T_LEFT )
631 {
632 token = NextTok();
633 }
634 else
635 {
636 // If another token than T_LEFT is read here, this is an error
637 // however, due to a old bug in kicad, the token T_end can be found
638 // without T_LEFT in a very few .wks files (perhaps only one in a demo).
639 // So this ugly hack disables the error detection.
640 if( token != T_end )
641 Unexpected( CurText() );
642 }
643
644 switch( token )
645 {
646 case T_comment:
647 NeedSYMBOLorNUMBER();
648 aItem->m_Info = FromUTF8();
649 NeedRIGHT();
650 break;
651
652 case T_option:
653 readOption( aItem );
654 break;
655
656 case T_name:
657 NeedSYMBOLorNUMBER();
658 aItem->m_Name = FromUTF8();
659 NeedRIGHT();
660 break;
661
662 case T_start:
663 parseCoordinate( aItem->m_Pos );
664 break;
665
666 case T_end:
667 parseCoordinate( aItem->m_End );
668 break;
669
670 case T_repeat:
671 aItem->m_RepeatCount = parseInt( 1, 100 );
672 NeedRIGHT();
673 break;
674
675 case T_incrx:
677 NeedRIGHT();
678 break;
679
680 case T_incry:
682 NeedRIGHT();
683 break;
684
685 case T_linewidth:
686 aItem->m_LineWidth = parseDouble();
687 NeedRIGHT();
688 break;
689
690 default:
691 Unexpected( CurText() );
692 break;
693 }
694 }
695}
696
697
699{
700 if( m_requiredVersion < 20210606 )
702
703 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
704 {
705 if( token == T_LEFT )
706 token = NextTok();
707
708 switch( token )
709 {
710 case T_comment:
711 NeedSYMBOLorNUMBER();
712 aItem->m_Info = FromUTF8();
713 NeedRIGHT();
714 break;
715
716 case T_option:
717 readOption( aItem );
718 break;
719
720 case T_name:
721 NeedSYMBOLorNUMBER();
722 aItem->m_Name = FromUTF8();
723 NeedRIGHT();
724 break;
725
726 case T_pos:
727 parseCoordinate( aItem->m_Pos );
728 break;
729
730 case T_repeat:
731 aItem->m_RepeatCount = parseInt( 1, 100 );
732 NeedRIGHT();
733 break;
734
735 case T_incrx:
737 NeedRIGHT();
738 break;
739
740 case T_incry:
742 NeedRIGHT();
743 break;
744
745 case T_incrlabel:
746 aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
747 NeedRIGHT();
748 break;
749
750 case T_maxlen:
752 NeedRIGHT();
753 break;
754
755 case T_maxheight:
757 NeedRIGHT();
758 break;
759
760 case T_font:
761 {
762 wxString faceName;
763
764 aItem->m_TextColor = COLOR4D::UNSPECIFIED;
765
766 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
767 {
768 switch( token )
769 {
770 case T_LEFT:
771 break;
772
773 case T_face:
774 NeedSYMBOL();
775 faceName = FromUTF8();
776 NeedRIGHT();
777 break;
778
779 case T_bold:
780 aItem->m_Bold = true;
781 break;
782
783 case T_italic:
784 aItem->m_Italic = true;
785 break;
786
787 case T_size:
788 aItem->m_TextSize.x = parseDouble();
789 aItem->m_TextSize.y = parseDouble();
790 NeedRIGHT();
791 break;
792
793 case T_color:
794 aItem->m_TextColor.r = parseInt( 0, 255 ) / 255.0;
795 aItem->m_TextColor.g = parseInt( 0, 255 ) / 255.0;
796 aItem->m_TextColor.b = parseInt( 0, 255 ) / 255.0;
797 aItem->m_TextColor.a = std::clamp( parseDouble(), 0.0, 1.0 );
798 NeedRIGHT();
799 break;
800
801 case T_linewidth:
802 aItem->m_LineWidth = parseDouble();
803 NeedRIGHT();
804 break;
805
806 default:
807 Unexpected( CurText() );
808 break;
809 }
810 }
811
812 if( !faceName.IsEmpty() )
813 aItem->m_Font = KIFONT::FONT::GetFont( faceName, aItem->m_Bold, aItem->m_Italic );
814
815 break;
816 }
817
818 case T_justify:
819 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
820 {
821 switch( token )
822 {
823 case T_center:
826 break;
827
828 case T_left:
830 break;
831
832 case T_right:
834 break;
835
836 case T_top:
838 break;
839
840 case T_bottom:
842 break;
843
844 default:
845 Unexpected( CurText() );
846 break;
847 }
848 }
849 break;
850
851 case T_rotate:
852 aItem->m_Orient = parseDouble();
853 NeedRIGHT();
854 break;
855
856 default:
857 Unexpected( CurText() );
858 break;
859 }
860 }
861}
862
863
865{
866 aCoord.m_Pos.x = parseDouble();
867 aCoord.m_Pos.y = parseDouble();
868
869 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
870 {
871 switch( token )
872 {
873 case T_ltcorner: aCoord.m_Anchor = LT_CORNER; break;
874 case T_lbcorner: aCoord.m_Anchor = LB_CORNER; break;
875 case T_rbcorner: aCoord.m_Anchor = RB_CORNER; break;
876 case T_rtcorner: aCoord.m_Anchor = RT_CORNER; break;
877 default: Unexpected( CurText() ); break;
878 }
879 }
880}
881
882
884{
885 T token = NextTok();
886
887 if( token != T_NUMBER )
888 Expecting( T_NUMBER );
889
890 return atoi( CurText() );
891}
892
893
894int DRAWING_SHEET_PARSER::parseInt( int aMin, int aMax )
895{
896 int val = parseInt();
897
898 if( val < aMin )
899 val = aMin;
900 else if( val > aMax )
901 val = aMax;
902
903 return val;
904}
905
906
908{
909 T token = NextTok();
910
911 if( token != T_NUMBER )
912 Expecting( T_NUMBER );
913
914
915 return DSNLEXER::parseDouble();
916}
917
918
919// defaultDrawingSheet is the default drawing sheet using the S expr.
920extern const char defaultDrawingSheet[];
921
922
924{
925 SetPageLayout( defaultDrawingSheet, false, wxT( "default page" ) );
926}
927
928
930{
931 return wxString( defaultDrawingSheet );
932}
933
934
935// emptyDrawingSheet is a "empty" drawing sheet using the S expr.
936// there is a 0 length line to fool something somewhere.
937extern const char emptyDrawingSheet[];
938
939
941{
942 SetPageLayout( emptyDrawingSheet, false, wxT( "empty page" ) );
943}
944
945
947{
948 return wxString( emptyDrawingSheet );
949}
950
951
952void DS_DATA_MODEL::SetPageLayout( const char* aPageLayout, bool Append, const wxString& aSource )
953{
954 if( ! Append )
955 ClearList();
956
957 DRAWING_SHEET_PARSER parser( aPageLayout, wxT( "Sexpr_string" ) );
958
959 try
960 {
961 parser.Parse( this );
962 }
963 catch( ... )
964 {
965 // best efforts
966 }
967}
968
969
970bool DS_DATA_MODEL::LoadDrawingSheet( const wxString& aFullFileName, wxString* aMsg, bool aAppend )
971{
972 if( !aAppend )
973 {
974 if( aFullFileName.IsEmpty() )
975 {
977 return true; // we assume its fine / default init
978 }
979
980 if( !wxFileExists( aFullFileName ) )
981 {
982 if( aMsg )
983 *aMsg = _( "File not found." );
984
986 return false;
987 }
988 }
989
990 wxFFile wksFile( aFullFileName, wxS( "rb" ) );
991
992 if( ! wksFile.IsOpened() )
993 {
994 if( aMsg )
995 *aMsg = _( "File could not be opened." );
996
997 if( !aAppend )
999
1000 return false;
1001 }
1002
1003 size_t filelen = wksFile.Length();
1004 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(filelen+10);
1005
1006 if( wksFile.Read( buffer.get(), filelen ) != filelen )
1007 {
1008 if( aMsg )
1009 *aMsg = _( "Drawing sheet was not fully read." );
1010
1011 return false;
1012 }
1013 else
1014 {
1015 buffer[filelen]=0;
1016
1017 if( ! aAppend )
1018 ClearList();
1019
1020 DRAWING_SHEET_PARSER parser( buffer.get(), aFullFileName );
1021
1022 try
1023 {
1024 parser.Parse( this );
1025 }
1026 catch( const IO_ERROR& ioe )
1027 {
1028 if( aMsg )
1029 *aMsg = ioe.What();
1030
1031 return false;
1032 }
1033 catch( const std::bad_alloc& )
1034 {
1035 if( aMsg )
1036 *aMsg = _( "Ran out of memory." );
1037
1038 return false;
1039 }
1040 }
1041
1042 return true;
1043}
This class handle bitmap images in KiCad.
Definition: bitmap_base.h:49
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:74
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:844
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
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)
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.
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, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition: font.cpp:146
double r
Red component.
Definition: color4d.h:392
double g
Green component.
Definition: color4d.h:393
double a
Alpha component.
Definition: color4d.h:395
double b
Blue component.
Definition: color4d.h:394
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