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 aItem->m_ImageBitmap->LoadLegacyData( str_reader, msg );
607}
608
609
611{
612 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
613 {
614 switch( token )
615 {
616 case T_page1only: aItem->SetPage1Option( FIRST_PAGE_ONLY ); break;
617 case T_notonpage1: aItem->SetPage1Option( SUBSEQUENT_PAGES ); break;
618 default: Unexpected( CurText() ); break;
619 }
620 }
621}
622
623
625{
626 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
627 {
628 if( token == T_LEFT )
629 {
630 token = NextTok();
631 }
632 else
633 {
634 // If another token than T_LEFT is read here, this is an error
635 // however, due to a old bug in kicad, the token T_end can be found
636 // without T_LEFT in a very few .wks files (perhaps only one in a demo).
637 // So this ugly hack disables the error detection.
638 if( token != T_end )
639 Unexpected( CurText() );
640 }
641
642 switch( token )
643 {
644 case T_comment:
645 NeedSYMBOLorNUMBER();
646 aItem->m_Info = FromUTF8();
647 NeedRIGHT();
648 break;
649
650 case T_option:
651 readOption( aItem );
652 break;
653
654 case T_name:
655 NeedSYMBOLorNUMBER();
656 aItem->m_Name = FromUTF8();
657 NeedRIGHT();
658 break;
659
660 case T_start:
661 parseCoordinate( aItem->m_Pos );
662 break;
663
664 case T_end:
665 parseCoordinate( aItem->m_End );
666 break;
667
668 case T_repeat:
669 aItem->m_RepeatCount = parseInt( 1, 100 );
670 NeedRIGHT();
671 break;
672
673 case T_incrx:
675 NeedRIGHT();
676 break;
677
678 case T_incry:
680 NeedRIGHT();
681 break;
682
683 case T_linewidth:
684 aItem->m_LineWidth = parseDouble();
685 NeedRIGHT();
686 break;
687
688 default:
689 Unexpected( CurText() );
690 break;
691 }
692 }
693}
694
695
697{
698 if( m_requiredVersion < 20210606 )
700
701 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
702 {
703 if( token == T_LEFT )
704 token = NextTok();
705
706 switch( token )
707 {
708 case T_comment:
709 NeedSYMBOLorNUMBER();
710 aItem->m_Info = FromUTF8();
711 NeedRIGHT();
712 break;
713
714 case T_option:
715 readOption( aItem );
716 break;
717
718 case T_name:
719 NeedSYMBOLorNUMBER();
720 aItem->m_Name = FromUTF8();
721 NeedRIGHT();
722 break;
723
724 case T_pos:
725 parseCoordinate( aItem->m_Pos );
726 break;
727
728 case T_repeat:
729 aItem->m_RepeatCount = parseInt( 1, 100 );
730 NeedRIGHT();
731 break;
732
733 case T_incrx:
735 NeedRIGHT();
736 break;
737
738 case T_incry:
740 NeedRIGHT();
741 break;
742
743 case T_incrlabel:
744 aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
745 NeedRIGHT();
746 break;
747
748 case T_maxlen:
750 NeedRIGHT();
751 break;
752
753 case T_maxheight:
755 NeedRIGHT();
756 break;
757
758 case T_font:
759 {
760 wxString faceName;
761
762 aItem->m_TextColor = COLOR4D::UNSPECIFIED;
763
764 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
765 {
766 switch( token )
767 {
768 case T_LEFT:
769 break;
770
771 case T_face:
772 NeedSYMBOL();
773 faceName = FromUTF8();
774 NeedRIGHT();
775 break;
776
777 case T_bold:
778 aItem->m_Bold = true;
779 break;
780
781 case T_italic:
782 aItem->m_Italic = true;
783 break;
784
785 case T_size:
786 aItem->m_TextSize.x = parseDouble();
787 aItem->m_TextSize.y = parseDouble();
788 NeedRIGHT();
789 break;
790
791 case T_color:
792 aItem->m_TextColor.r = parseInt( 0, 255 ) / 255.0;
793 aItem->m_TextColor.g = parseInt( 0, 255 ) / 255.0;
794 aItem->m_TextColor.b = parseInt( 0, 255 ) / 255.0;
795 aItem->m_TextColor.a = Clamp( parseDouble(), 0.0, 1.0 );
796 NeedRIGHT();
797 break;
798
799 case T_linewidth:
800 aItem->m_LineWidth = parseDouble();
801 NeedRIGHT();
802 break;
803
804 default:
805 Unexpected( CurText() );
806 break;
807 }
808 }
809
810 if( !faceName.IsEmpty() )
811 aItem->m_Font = KIFONT::FONT::GetFont( faceName, aItem->m_Bold, aItem->m_Italic );
812
813 break;
814 }
815
816 case T_justify:
817 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
818 {
819 switch( token )
820 {
821 case T_center:
824 break;
825
826 case T_left:
828 break;
829
830 case T_right:
832 break;
833
834 case T_top:
836 break;
837
838 case T_bottom:
840 break;
841
842 default:
843 Unexpected( CurText() );
844 break;
845 }
846 }
847 break;
848
849 case T_rotate:
850 aItem->m_Orient = parseDouble();
851 NeedRIGHT();
852 break;
853
854 default:
855 Unexpected( CurText() );
856 break;
857 }
858 }
859}
860
861// parse an expression like " 25 1 ltcorner)"
863{
864 aCoord.m_Pos.x = parseDouble();
865 aCoord.m_Pos.y = parseDouble();
866
867 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
868 {
869 switch( token )
870 {
871 case T_ltcorner: aCoord.m_Anchor = LT_CORNER; break;
872 case T_lbcorner: aCoord.m_Anchor = LB_CORNER; break;
873 case T_rbcorner: aCoord.m_Anchor = RB_CORNER; break;
874 case T_rtcorner: aCoord.m_Anchor = RT_CORNER; break;
875 default: Unexpected( CurText() ); break;
876 }
877 }
878}
879
881{
882 T token = NextTok();
883
884 if( token != T_NUMBER )
885 Expecting( T_NUMBER );
886
887 return atoi( CurText() );
888}
889
890int DRAWING_SHEET_PARSER::parseInt( int aMin, int aMax )
891{
892 int val = parseInt();
893
894 if( val < aMin )
895 val = aMin;
896 else if( val > aMax )
897 val = aMax;
898
899 return val;
900}
901
902
904{
905 T token = NextTok();
906
907 if( token != T_NUMBER )
908 Expecting( T_NUMBER );
909
910
911 return DSNLEXER::parseDouble();
912}
913
914// defaultDrawingSheet is the default drawing sheet using the S expr.
915extern const char defaultDrawingSheet[];
916
918{
919 SetPageLayout( defaultDrawingSheet, false, wxT( "default page" ) );
920}
921
922// Returns defaultDrawingSheet as a string;
924{
925 return wxString( defaultDrawingSheet );
926}
927
928// emptyDrawingSheet is a "empty" drawing sheet using the S expr.
929// there is a 0 length line to fool something somewhere.
930extern const char emptyDrawingSheet[];
931
933{
934 SetPageLayout( emptyDrawingSheet, false, wxT( "empty page" ) );
935}
936
937
939{
940 return wxString( emptyDrawingSheet );
941}
942
943
944void DS_DATA_MODEL::SetPageLayout( const char* aPageLayout, bool Append, const wxString& aSource )
945{
946 if( ! Append )
947 ClearList();
948
949 DRAWING_SHEET_PARSER parser( aPageLayout, wxT( "Sexpr_string" ) );
950
951 try
952 {
953 parser.Parse( this );
954 }
955 catch( ... )
956 {
957 // best efforts
958 }
959}
960
961
962bool DS_DATA_MODEL::LoadDrawingSheet( const wxString& aFullFileName, wxString* aMsg, bool aAppend )
963{
964 if( !aAppend )
965 {
966 if( aFullFileName.IsEmpty() )
967 {
969 return true; // we assume its fine / default init
970 }
971
972 if( !wxFileExists( aFullFileName ) )
973 {
974 if( aMsg )
975 *aMsg = _( "File not found." );
976
978 return false;
979 }
980 }
981
982 wxFFile wksFile( aFullFileName, wxS( "rb" ) );
983
984 if( ! wksFile.IsOpened() )
985 {
986 if( aMsg )
987 *aMsg = _( "File could not be opened." );
988
989 if( !aAppend )
991
992 return false;
993 }
994
995 size_t filelen = wksFile.Length();
996 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(filelen+10);
997
998 if( wksFile.Read( buffer.get(), filelen ) != filelen )
999 {
1000 if( aMsg )
1001 *aMsg = _( "Drawing sheet was not fully read." );
1002
1003 return false;
1004 }
1005 else
1006 {
1007 buffer[filelen]=0;
1008
1009 if( ! aAppend )
1010 ClearList();
1011
1012 DRAWING_SHEET_PARSER parser( buffer.get(), aFullFileName );
1013
1014 try
1015 {
1016 parser.Parse( this );
1017 }
1018 catch( const IO_ERROR& ioe )
1019 {
1020 if( aMsg )
1021 *aMsg = ioe.What();
1022
1023 return false;
1024 }
1025 catch( const std::bad_alloc& )
1026 {
1027 if( aMsg )
1028 *aMsg = _( "Ran out of memory." );
1029
1030 return false;
1031 }
1032 }
1033
1034 return true;
1035}
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: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)
Populates 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)
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
constexpr T Clamp(const T &lower, const T &value, const T &upper)
Limit value within the range lower <= value <= upper.
Definition: util.h:65