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:
58 void parseHeader( T aHeaderType );
59
63 int parseInt();
64
72 int parseInt( int aMin, int aMax );
73
79 double parseDouble();
80
81 void parseSetup( DS_DATA_MODEL* aLayout );
82
86 void parseGraphic( DS_DATA_ITEM * aItem );
87
91 void parseText( DS_DATA_ITEM_TEXT * aItem );
92
97 void parsePolygon( DS_DATA_ITEM_POLYGONS * aItem );
98
103
104
108 void parseBitmap( DS_DATA_ITEM_BITMAP * aItem );
109
110 void parseCoordinate( POINT_COORD& aCoord);
111 void readOption( DS_DATA_ITEM * aItem );
112 void readPngdata( DS_DATA_ITEM_BITMAP * aItem );
113
114private:
117};
118
119
121 const wxString& aSource ) :
122 DRAWING_SHEET_LEXER( aLine, aSource ),
123 m_requiredVersion( 0 )
124{
125}
126
127
128wxString convertLegacyVariableRefs( const wxString& aTextbase )
129{
130 wxString msg;
131
132 /*
133 * Legacy formats
134 * %% = replaced by %
135 * %K = Kicad version
136 * %Z = paper format name (A4, USLetter)
137 * %Y = company name
138 * %D = date
139 * %R = revision
140 * %S = sheet number
141 * %N = number of sheets
142 * %L = layer name
143 * %Cx = comment (x = 0 to 9 to identify the comment)
144 * %F = filename
145 * %P = sheet path (sheet full name)
146 * %T = title
147 */
148
149 for( unsigned ii = 0; ii < aTextbase.Len(); ii++ )
150 {
151 if( aTextbase[ii] != '%' )
152 {
153 msg << aTextbase[ii];
154 continue;
155 }
156
157 if( ++ii >= aTextbase.Len() )
158 break;
159
160 wxChar format = aTextbase[ii];
161
162 switch( format )
163 {
164 case '%': msg += '%'; break;
165 case 'D': msg += wxT( "${ISSUE_DATE}" ); break;
166 case 'R': msg += wxT( "${REVISION}" ); break;
167 case 'K': msg += wxT( "${KICAD_VERSION}" ); break;
168 case 'Z': msg += wxT( "${PAPER}" ); break;
169 case 'S': msg += wxT( "${#}" ); break;
170 case 'N': msg += wxT( "${##}" ); break;
171 case 'F': msg += wxT( "${FILENAME}" ); break;
172 case 'L': msg += wxT( "${LAYER}" ); break;
173 case 'P': msg += wxT( "${SHEETPATH}" ); break;
174 case 'Y': msg += wxT( "${COMPANY}" ); break;
175 case 'T': msg += wxT( "${TITLE}" ); break;
176 case 'C':
177 format = aTextbase[++ii];
178
179 switch( format )
180 {
181 case '0': msg += wxT( "${COMMENT1}" ); break;
182 case '1': msg += wxT( "${COMMENT2}" ); break;
183 case '2': msg += wxT( "${COMMENT3}" ); break;
184 case '3': msg += wxT( "${COMMENT4}" ); break;
185 case '4': msg += wxT( "${COMMENT5}" ); break;
186 case '5': msg += wxT( "${COMMENT6}" ); break;
187 case '6': msg += wxT( "${COMMENT7}" ); break;
188 case '7': msg += wxT( "${COMMENT8}" ); break;
189 case '8': msg += wxT( "${COMMENT9}" ); break;
190 }
191 break;
192
193 default:
194 break;
195 }
196 }
197
198 return msg;
199}
200
201
203{
204 DS_DATA_ITEM* item;
205 LOCALE_IO toggle;
206
207 NeedLEFT();
208 T token = NextTok();
209
210 parseHeader( token );
212
213 auto checkVersion =
214 [&]()
215 {
217 {
218 throw FUTURE_FORMAT_ERROR( fmt::format( "{}", m_requiredVersion ),
220 }
221 };
222
223 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
224 {
225 if( token == T_LEFT )
226 token = NextTok();
227
228 switch( token )
229 {
230 case T_generator:
231 // (generator "genname"); we don't care about it at the moment.
232 NeedSYMBOL();
233 NeedRIGHT();
234 break;
235
236 case T_generator_version:
237 NextTok();
238 m_generatorVersion = FromUTF8();
239 NeedRIGHT();
240 break;
241
242 case T_setup: // Defines default values for graphic items
243 // Check the version here, because the generator and generator_version (if available)
244 // will have been parsed by now given the order the formatter writes them in
245 checkVersion();
246 parseSetup( aLayout );
247 break;
248
249 case T_line:
251 parseGraphic( item );
252 aLayout->Append( item );
253 break;
254
255 case T_rect:
257 parseGraphic( item );
258 aLayout->Append( item );
259 break;
260
261 case T_polygon:
262 item = new DS_DATA_ITEM_POLYGONS();
264 aLayout->Append( item );
265 break;
266
267 case T_bitmap:
268 item = new DS_DATA_ITEM_BITMAP( NULL );
270
271 // Drop invalid bitmaps
272 if( static_cast<DS_DATA_ITEM_BITMAP*>( item )->m_ImageBitmap->GetOriginalImageData() )
273 {
274 aLayout->Append( item );
275 }
276 else
277 {
278 delete static_cast<DS_DATA_ITEM_BITMAP*>( item )->m_ImageBitmap;
279 delete item;
280 }
281
282 break;
283
284 case T_tbtext:
285 NeedSYMBOLorNUMBER();
286 item = new DS_DATA_ITEM_TEXT( convertLegacyVariableRefs( FromUTF8() ) );
287 parseText( (DS_DATA_ITEM_TEXT*) item );
288 aLayout->Append( item );
289 break;
290
291 default:
292 Unexpected( CurText() );
293 break;
294 }
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
331
333{
334 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
335 {
336 switch( token )
337 {
338 case T_LEFT:
339 break;
340
341 case T_linewidth:
342 aLayout->m_DefaultLineWidth = parseDouble();
343 NeedRIGHT();
344 break;
345
346 case T_textsize:
347 aLayout->m_DefaultTextSize.x = parseDouble();
348 aLayout->m_DefaultTextSize.y = parseDouble();
349 NeedRIGHT();
350 break;
351
352 case T_textlinewidth:
354 NeedRIGHT();
355 break;
356
357 case T_left_margin:
358 aLayout->SetLeftMargin( parseDouble() );
359 NeedRIGHT();
360 break;
361
362 case T_right_margin:
363 aLayout->SetRightMargin( parseDouble() );
364 NeedRIGHT();
365 break;
366
367 case T_top_margin:
368 aLayout->SetTopMargin( parseDouble() );
369 NeedRIGHT();
370 break;
371
372 case T_bottom_margin:
373 aLayout->SetBottomMargin( parseDouble() );
374 NeedRIGHT();
375 break;
376
377 default:
378 Unexpected( CurText() );
379 break;
380 }
381 }
382
383 // The file is well-formed. If it has no further items, then that's the way the
384 // user wants it.
385 aLayout->AllowVoidList( true );
386}
387
388
390{
391 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
392 {
393 if( token == T_LEFT )
394 token = NextTok();
395
396 switch( token )
397 {
398 case T_comment:
399 NeedSYMBOLorNUMBER();
400 aItem->m_Info = FromUTF8();
401 NeedRIGHT();
402 break;
403
404 case T_pos:
405 parseCoordinate( aItem->m_Pos );
406 break;
407
408 case T_name:
409 NeedSYMBOLorNUMBER();
410 aItem->m_Name = FromUTF8();
411 NeedRIGHT();
412 break;
413
414 case T_option:
415 readOption( aItem );
416 break;
417
418 case T_pts:
419 parsePolyOutline( aItem );
420 aItem->CloseContour();
421 break;
422
423 case T_rotate:
425 NeedRIGHT();
426 break;
427
428 case T_repeat:
429 aItem->m_RepeatCount = parseInt( 1, 100 );
430 NeedRIGHT();
431 break;
432
433 case T_incrx:
435 NeedRIGHT();
436 break;
437
438 case T_incry:
440 NeedRIGHT();
441 break;
442
443 case T_linewidth:
444 aItem->m_LineWidth = parseDouble();
445 NeedRIGHT();
446 break;
447
448 default:
449 Unexpected( CurText() );
450 break;
451 }
452 }
453
454 aItem->SetBoundingBox();
455}
456
457
459{
460 VECTOR2D corner;
461
462 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
463 {
464 if( token == T_LEFT )
465 token = NextTok();
466
467 switch( token )
468 {
469 case T_xy:
470 corner.x = parseDouble();
471 corner.y = parseDouble();
472 aItem->AppendCorner( corner );
473 NeedRIGHT();
474 break;
475
476 default:
477 Unexpected( CurText() );
478 break;
479 }
480 }
481}
482
483
485{
487 aItem->m_ImageBitmap = image;
488
489 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
490 {
491 if( token == T_LEFT )
492 token = NextTok();
493
494 switch( token )
495 {
496 case T_name:
497 NeedSYMBOLorNUMBER();
498 aItem->m_Name = FromUTF8();
499 NeedRIGHT();
500 break;
501
502 case T_pos:
503 parseCoordinate( aItem->m_Pos );
504 break;
505
506 case T_repeat:
507 aItem->m_RepeatCount = parseInt( 1, 100 );
508 NeedRIGHT();
509 break;
510
511 case T_incrx:
513 NeedRIGHT();
514 break;
515
516 case T_incry:
518 NeedRIGHT();
519 break;
520
521 case T_linewidth:
522 aItem->m_LineWidth = parseDouble();
523 NeedRIGHT();
524 break;
525
526 case T_scale:
528 NeedRIGHT();
529 break;
530
531 case T_comment:
532 NeedSYMBOLorNUMBER();
533 aItem->m_Info = FromUTF8();
534 NeedRIGHT();
535 break;
536
537 case T_data:
538 {
539 token = NextTok();
540
541 wxString data;
542
543 // Reserve 512K because most image files are going to be larger than the default
544 // 1K that wxString reserves.
545 data.reserve( 1 << 19 );
546
547 while( token != T_RIGHT )
548 {
549 if( !IsSymbol( token ) )
550 Expecting( "base64 image data" );
551
552 data += FromUTF8();
553 token = NextTok();
554 }
555
556 wxMemoryBuffer buffer = wxBase64Decode( data );
557
558 if( !aItem->m_ImageBitmap->ReadImageFile( buffer ) )
559 THROW_IO_ERROR( _( "Failed to read image data." ) );
560
561 break;
562 }
563
564 case T_pngdata:
565 readPngdata( aItem );
566 break;
567
568 case T_option:
569 readOption( aItem );
570 break;
571
572 default:
573 Unexpected( CurText() );
574 break;
575 }
576 }
577}
578
579
581{
582 std::string tmp;
583
584 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
585 {
586 if( token == T_LEFT )
587 token = NextTok();
588
589 switch( token )
590 {
591 case T_data:
592 NeedSYMBOLorNUMBER();
593 tmp += CurStr();
594 tmp += "\n";
595 NeedRIGHT();
596 break;
597
598 default:
599 Unexpected( CurText() );
600 break;
601 }
602 }
603
604 tmp += "EndData";
605
606 wxString msg;
607 STRING_LINE_READER str_reader( tmp, wxT("Png kicad_wks data") );
608
609 aItem->m_ImageBitmap->LoadLegacyData( str_reader, msg );
610}
611
612
614{
615 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
616 {
617 switch( token )
618 {
619 case T_page1only: aItem->SetPage1Option( FIRST_PAGE_ONLY ); break;
620 case T_notonpage1: aItem->SetPage1Option( SUBSEQUENT_PAGES ); break;
621 default: Unexpected( CurText() ); break;
622 }
623 }
624}
625
626
628{
629 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
630 {
631 if( token == T_LEFT )
632 {
633 token = NextTok();
634 }
635 else
636 {
637 // If another token than T_LEFT is read here, this is an error
638 // however, due to a old bug in kicad, the token T_end can be found
639 // without T_LEFT in a very few .wks files (perhaps only one in a demo).
640 // So this ugly hack disables the error detection.
641 if( token != T_end )
642 Unexpected( CurText() );
643 }
644
645 switch( token )
646 {
647 case T_comment:
648 NeedSYMBOLorNUMBER();
649 aItem->m_Info = FromUTF8();
650 NeedRIGHT();
651 break;
652
653 case T_option:
654 readOption( aItem );
655 break;
656
657 case T_name:
658 NeedSYMBOLorNUMBER();
659 aItem->m_Name = FromUTF8();
660 NeedRIGHT();
661 break;
662
663 case T_start:
664 parseCoordinate( aItem->m_Pos );
665 break;
666
667 case T_end:
668 parseCoordinate( aItem->m_End );
669 break;
670
671 case T_repeat:
672 aItem->m_RepeatCount = parseInt( 1, 100 );
673 NeedRIGHT();
674 break;
675
676 case T_incrx:
678 NeedRIGHT();
679 break;
680
681 case T_incry:
683 NeedRIGHT();
684 break;
685
686 case T_linewidth:
687 aItem->m_LineWidth = parseDouble();
688 NeedRIGHT();
689 break;
690
691 default:
692 Unexpected( CurText() );
693 break;
694 }
695 }
696}
697
698
700{
701 if( m_requiredVersion < 20210606 )
703
704 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
705 {
706 if( token == T_LEFT )
707 token = NextTok();
708
709 switch( token )
710 {
711 case T_comment:
712 NeedSYMBOLorNUMBER();
713 aItem->m_Info = FromUTF8();
714 NeedRIGHT();
715 break;
716
717 case T_option:
718 readOption( aItem );
719 break;
720
721 case T_name:
722 NeedSYMBOLorNUMBER();
723 aItem->m_Name = FromUTF8();
724 NeedRIGHT();
725 break;
726
727 case T_pos:
728 parseCoordinate( aItem->m_Pos );
729 break;
730
731 case T_repeat:
732 aItem->m_RepeatCount = parseInt( 1, 100 );
733 NeedRIGHT();
734 break;
735
736 case T_incrx:
738 NeedRIGHT();
739 break;
740
741 case T_incry:
743 NeedRIGHT();
744 break;
745
746 case T_incrlabel:
747 aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
748 NeedRIGHT();
749 break;
750
751 case T_maxlen:
753 NeedRIGHT();
754 break;
755
756 case T_maxheight:
758 NeedRIGHT();
759 break;
760
761 case T_font:
762 {
763 wxString faceName;
764
765 aItem->m_TextColor = COLOR4D::UNSPECIFIED;
766
767 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
768 {
769 switch( token )
770 {
771 case T_LEFT:
772 break;
773
774 case T_face:
775 NeedSYMBOL();
776 faceName = FromUTF8();
777 NeedRIGHT();
778 break;
779
780 case T_bold:
781 aItem->m_Bold = true;
782 break;
783
784 case T_italic:
785 aItem->m_Italic = true;
786 break;
787
788 case T_size:
789 aItem->m_TextSize.x = parseDouble();
790 aItem->m_TextSize.y = parseDouble();
791 NeedRIGHT();
792 break;
793
794 case T_color:
795 aItem->m_TextColor.r = parseInt( 0, 255 ) / 255.0;
796 aItem->m_TextColor.g = parseInt( 0, 255 ) / 255.0;
797 aItem->m_TextColor.b = parseInt( 0, 255 ) / 255.0;
798 aItem->m_TextColor.a = std::clamp( parseDouble(), 0.0, 1.0 );
799 NeedRIGHT();
800 break;
801
802 case T_linewidth:
803 aItem->m_LineWidth = parseDouble();
804 NeedRIGHT();
805 break;
806
807 default:
808 Unexpected( CurText() );
809 break;
810 }
811 }
812
813 if( !faceName.IsEmpty() )
814 aItem->m_Font = KIFONT::FONT::GetFont( faceName, aItem->m_Bold, aItem->m_Italic );
815
816 break;
817 }
818
819 case T_justify:
820 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
821 {
822 switch( token )
823 {
824 case T_center:
827 break;
828
829 case T_left:
831 break;
832
833 case T_right:
835 break;
836
837 case T_top:
839 break;
840
841 case T_bottom:
843 break;
844
845 default:
846 Unexpected( CurText() );
847 break;
848 }
849 }
850 break;
851
852 case T_rotate:
853 aItem->m_Orient = parseDouble();
854 NeedRIGHT();
855 break;
856
857 default:
858 Unexpected( CurText() );
859 break;
860 }
861 }
862}
863
864
866{
867 aCoord.m_Pos.x = parseDouble();
868 aCoord.m_Pos.y = parseDouble();
869
870 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
871 {
872 switch( token )
873 {
874 case T_ltcorner: aCoord.m_Anchor = LT_CORNER; break;
875 case T_lbcorner: aCoord.m_Anchor = LB_CORNER; break;
876 case T_rbcorner: aCoord.m_Anchor = RB_CORNER; break;
877 case T_rtcorner: aCoord.m_Anchor = RT_CORNER; break;
878 default: Unexpected( CurText() ); break;
879 }
880 }
881}
882
883
885{
886 T token = NextTok();
887
888 if( token != T_NUMBER )
889 Expecting( T_NUMBER );
890
891 return atoi( CurText() );
892}
893
894
895int DRAWING_SHEET_PARSER::parseInt( int aMin, int aMax )
896{
897 int val = parseInt();
898
899 if( val < aMin )
900 val = aMin;
901 else if( val > aMax )
902 val = aMax;
903
904 return val;
905}
906
907
909{
910 T token = NextTok();
911
912 if( token != T_NUMBER )
913 Expecting( T_NUMBER );
914
915
916 return DSNLEXER::parseDouble();
917}
918
919
920// defaultDrawingSheet is the default drawing sheet using the S expr.
921extern const char defaultDrawingSheet[];
922
923
925{
926 SetPageLayout( defaultDrawingSheet, false, wxT( "default page" ) );
927}
928
929
931{
932 return wxString( defaultDrawingSheet );
933}
934
935
936// emptyDrawingSheet is a "empty" drawing sheet using the S expr.
937// there is a 0 length line to fool something somewhere.
938extern const char emptyDrawingSheet[];
939
940
942{
943 SetPageLayout( emptyDrawingSheet, false, wxT( "empty page" ) );
944}
945
946
948{
949 return wxString( emptyDrawingSheet );
950}
951
952
953void DS_DATA_MODEL::SetPageLayout( const char* aPageLayout, bool Append, const wxString& aSource )
954{
955 if( ! Append )
956 ClearList();
957
958 DRAWING_SHEET_PARSER parser( aPageLayout, wxT( "Sexpr_string" ) );
959
960 try
961 {
962 parser.Parse( this );
963 }
964 catch( ... )
965 {
966 // best efforts
967 }
968}
969
970
971bool DS_DATA_MODEL::LoadDrawingSheet( const wxString& aFullFileName, wxString* aMsg, bool aAppend )
972{
973 if( !aAppend )
974 {
975 if( aFullFileName.IsEmpty() )
976 {
978 return true; // we assume its fine / default init
979 }
980
981 if( !wxFileExists( aFullFileName ) )
982 {
983 if( aMsg )
984 *aMsg = _( "File not found." );
985
987 return false;
988 }
989 }
990
991 wxFFile wksFile( aFullFileName, wxS( "rb" ) );
992
993 if( ! wksFile.IsOpened() )
994 {
995 if( aMsg )
996 *aMsg = _( "File could not be opened." );
997
998 if( !aAppend )
1000
1001 return false;
1002 }
1003
1004 size_t filelen = wksFile.Length();
1005 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(filelen+10);
1006
1007 if( wksFile.Read( buffer.get(), filelen ) != filelen )
1008 {
1009 if( aMsg )
1010 *aMsg = _( "Drawing sheet was not fully read." );
1011
1012 return false;
1013 }
1014 else
1015 {
1016 buffer[filelen]=0;
1017
1018 if( ! aAppend )
1019 ClearList();
1020
1021 DRAWING_SHEET_PARSER parser( buffer.get(), aFullFileName );
1022
1023 try
1024 {
1025 parser.Parse( this );
1026 }
1027 catch( const IO_ERROR& ioe )
1028 {
1029 if( aMsg )
1030 *aMsg = ioe.What();
1031
1032 return false;
1033 }
1034 catch( const std::bad_alloc& )
1035 {
1036 if( aMsg )
1037 *aMsg = _( "Ran out of memory." );
1038
1039 return false;
1040 }
1041 }
1042
1043 return true;
1044}
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:861
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:147
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:41
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