KiCad PCB EDA Suite
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-2022 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 <wx/ffile.h>
28#include <wx/log.h>
29#include <eda_item.h>
30#include <locale_io.h>
31#include <string_utils.h>
35#include <drawing_sheet/drawing_sheet_lexer.h>
37#include <font/font.h>
38
39using namespace DRAWINGSHEET_T;
40
46class DRAWING_SHEET_PARSER : public DRAWING_SHEET_LEXER
47{
48public:
49 DRAWING_SHEET_PARSER( const char* aLine, const wxString& aSource );
50 void Parse( DS_DATA_MODEL* aLayout );
51
52private:
54
59 void parseHeader( T aHeaderType );
60
64 int parseInt();
65
73 int parseInt( int aMin, int aMax );
74
80 double parseDouble();
81
82 void parseSetup( DS_DATA_MODEL* aLayout );
83
87 void parseGraphic( DS_DATA_ITEM * aItem );
88
92 void parseText( DS_DATA_ITEM_TEXT * aItem );
93
98 void parsePolygon( DS_DATA_ITEM_POLYGONS * aItem );
99
104
105
109 void parseBitmap( DS_DATA_ITEM_BITMAP * aItem );
110
111 void parseCoordinate( POINT_COORD& aCoord);
112 void readOption( DS_DATA_ITEM * aItem );
113 void readPngdata( DS_DATA_ITEM_BITMAP * aItem );
114};
115
116// PCB_PLOT_PARAMS_PARSER
117
119 const wxString& aSource ) :
120 DRAWING_SHEET_LEXER( aLine, aSource ),
121 m_requiredVersion( 0 )
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 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
212 {
213 if( token == T_LEFT )
214 token = NextTok();
215
216 switch( token )
217 {
218 case T_setup: // Defines default values for graphic items
219 parseSetup( aLayout );
220 break;
221
222 case T_line:
224 parseGraphic( item );
225 aLayout->Append( item );
226 break;
227
228 case T_rect:
230 parseGraphic( item );
231 aLayout->Append( item );
232 break;
233
234 case T_polygon:
235 item = new DS_DATA_ITEM_POLYGONS();
237 aLayout->Append( item );
238 break;
239
240 case T_bitmap:
241 item = new DS_DATA_ITEM_BITMAP( NULL );
243 aLayout->Append( item );
244 break;
245
246 case T_tbtext:
247 NeedSYMBOLorNUMBER();
248 item = new DS_DATA_ITEM_TEXT( convertLegacyVariableRefs( FromUTF8() ) );
249 parseText( (DS_DATA_ITEM_TEXT*) item );
250 aLayout->Append( item );
251 break;
252
253 default:
254 Unexpected( CurText() );
255 break;
256 }
257 }
258}
259
261{
262 // The older files had no versioning and their first token after the initial left parenthesis
263 // was a `page_layout` or `drawing_sheet` token. The newer files have versions and have a
264 // `kicad_wks` token instead.
265
266 if( aHeaderType == T_kicad_wks || aHeaderType == T_drawing_sheet )
267 {
268 NeedLEFT();
269
270 T tok = NextTok();
271
272 if( tok == T_version )
273 {
275
277 throw FUTURE_FORMAT_ERROR( FromUTF8() );
278
279 NeedRIGHT();
280 }
281 else
282 {
283 Expecting( T_version );
284 }
285
286 // Ignore generator info.
287 NeedLEFT();
288 NeedSYMBOL();
289 NeedSYMBOL();
290 NeedRIGHT();
291 }
292 else
293 {
294 // We assign version 0 to files that were created before there was any versioning of
295 // worksheets. The below line is not strictly necessary, as `m_requiredVersion` is already
296 // initialized to 0 in the constructor.
298 }
299}
300
302{
303 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
304 {
305 switch( token )
306 {
307 case T_LEFT:
308 break;
309
310 case T_linewidth:
311 aLayout->m_DefaultLineWidth = parseDouble();
312 NeedRIGHT();
313 break;
314
315 case T_textsize:
316 aLayout->m_DefaultTextSize.x = parseDouble();
317 aLayout->m_DefaultTextSize.y = parseDouble();
318 NeedRIGHT();
319 break;
320
321 case T_textlinewidth:
323 NeedRIGHT();
324 break;
325
326 case T_left_margin:
327 aLayout->SetLeftMargin( parseDouble() );
328 NeedRIGHT();
329 break;
330
331 case T_right_margin:
332 aLayout->SetRightMargin( parseDouble() );
333 NeedRIGHT();
334 break;
335
336 case T_top_margin:
337 aLayout->SetTopMargin( parseDouble() );
338 NeedRIGHT();
339 break;
340
341 case T_bottom_margin:
342 aLayout->SetBottomMargin( parseDouble() );
343 NeedRIGHT();
344 break;
345
346 default:
347 Unexpected( CurText() );
348 break;
349 }
350 }
351
352 // The file is well-formed. If it has no further items, then that's the way the
353 // user wants it.
354 aLayout->AllowVoidList( true );
355}
356
357
359{
360 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
361 {
362 if( token == T_LEFT )
363 token = NextTok();
364
365 switch( token )
366 {
367 case T_comment:
368 NeedSYMBOLorNUMBER();
369 aItem->m_Info = FromUTF8();
370 NeedRIGHT();
371 break;
372
373 case T_pos:
374 parseCoordinate( aItem->m_Pos );
375 break;
376
377 case T_name:
378 NeedSYMBOLorNUMBER();
379 aItem->m_Name = FromUTF8();
380 NeedRIGHT();
381 break;
382
383 case T_option:
384 readOption( aItem );
385 break;
386
387 case T_pts:
388 parsePolyOutline( aItem );
389 aItem->CloseContour();
390 break;
391
392 case T_rotate:
394 NeedRIGHT();
395 break;
396
397 case T_repeat:
398 aItem->m_RepeatCount = parseInt( -1, 100 );
399 NeedRIGHT();
400 break;
401
402 case T_incrx:
404 NeedRIGHT();
405 break;
406
407 case T_incry:
409 NeedRIGHT();
410 break;
411
412 case T_linewidth:
413 aItem->m_LineWidth = parseDouble();
414 NeedRIGHT();
415 break;
416
417 default:
418 Unexpected( CurText() );
419 break;
420 }
421 }
422
423 aItem->SetBoundingBox();
424}
425
427{
428 VECTOR2D corner;
429
430 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
431 {
432 if( token == T_LEFT )
433 token = NextTok();
434
435 switch( token )
436 {
437 case T_xy:
438 corner.x = parseDouble();
439 corner.y = parseDouble();
440 aItem->AppendCorner( corner );
441 NeedRIGHT();
442 break;
443
444 default:
445 Unexpected( CurText() );
446 break;
447 }
448 }
449}
450
451
453{
455 aItem->m_ImageBitmap = image;
456
457 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
458 {
459 if( token == T_LEFT )
460 token = NextTok();
461
462 switch( token )
463 {
464 case T_name:
465 NeedSYMBOLorNUMBER();
466 aItem->m_Name = FromUTF8();
467 NeedRIGHT();
468 break;
469
470 case T_pos:
471 parseCoordinate( aItem->m_Pos );
472 break;
473
474 case T_repeat:
475 aItem->m_RepeatCount = parseInt( -1, 100 );
476 NeedRIGHT();
477 break;
478
479 case T_incrx:
481 NeedRIGHT();
482 break;
483
484 case T_incry:
486 NeedRIGHT();
487 break;
488
489 case T_linewidth:
490 aItem->m_LineWidth = parseDouble();
491 NeedRIGHT();
492 break;
493
494 case T_scale:
496 NeedRIGHT();
497 break;
498
499 case T_comment:
500 NeedSYMBOLorNUMBER();
501 aItem->m_Info = FromUTF8();
502 NeedRIGHT();
503 break;
504
505 case T_pngdata:
506 readPngdata( aItem );
507 break;
508
509 case T_option:
510 readOption( aItem );
511 break;
512
513 default:
514 Unexpected( CurText() );
515 break;
516 }
517 }
518}
519
521{
522 std::string tmp;
523
524 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
525 {
526 if( token == T_LEFT )
527 token = NextTok();
528
529 switch( token )
530 {
531 case T_data:
532 NeedSYMBOLorNUMBER();
533 tmp += CurStr();
534 tmp += "\n";
535 NeedRIGHT();
536 break;
537
538 default:
539 Unexpected( CurText() );
540 break;
541 }
542 }
543
544 tmp += "EndData";
545
546 wxString msg;
547 STRING_LINE_READER str_reader( tmp, wxT("Png kicad_wks data") );
548
549 if( ! aItem->m_ImageBitmap->LoadData( str_reader, msg ) )
550 wxLogMessage(msg);
551}
552
553
555{
556 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
557 {
558 switch( token )
559 {
560 case T_page1only: aItem->SetPage1Option( FIRST_PAGE_ONLY ); break;
561 case T_notonpage1: aItem->SetPage1Option( SUBSEQUENT_PAGES ); break;
562 default: Unexpected( CurText() ); break;
563 }
564 }
565}
566
567
569{
570 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
571 {
572 if( token == T_LEFT )
573 token = NextTok();
574 else
575 {
576 // If another token than T_LEFT is read here, this is an error
577 // however, due to a old bug in kicad, the token T_end can be found
578 // without T_LEFT in a very few .wks files (perhaps only one in a demo).
579 // So this ugly hack disables the error detection.
580 if( token != T_end )
581 Unexpected( CurText() );
582 }
583
584 switch( token )
585 {
586 case T_comment:
587 NeedSYMBOLorNUMBER();
588 aItem->m_Info = FromUTF8();
589 NeedRIGHT();
590 break;
591
592 case T_option:
593 readOption( aItem );
594 break;
595
596 case T_name:
597 NeedSYMBOLorNUMBER();
598 aItem->m_Name = FromUTF8();
599 NeedRIGHT();
600 break;
601
602 case T_start:
603 parseCoordinate( aItem->m_Pos );
604 break;
605
606 case T_end:
607 parseCoordinate( aItem->m_End );
608 break;
609
610 case T_repeat:
611 aItem->m_RepeatCount = parseInt( -1, 100 );
612 NeedRIGHT();
613 break;
614
615 case T_incrx:
617 NeedRIGHT();
618 break;
619
620 case T_incry:
622 NeedRIGHT();
623 break;
624
625 case T_linewidth:
626 aItem->m_LineWidth = parseDouble();
627 NeedRIGHT();
628 break;
629
630 default:
631 Unexpected( CurText() );
632 break;
633 }
634 }
635}
636
637
639{
640 if( m_requiredVersion < 20210606 )
642
643 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
644 {
645 if( token == T_LEFT )
646 token = NextTok();
647
648 switch( token )
649 {
650 case T_comment:
651 NeedSYMBOLorNUMBER();
652 aItem->m_Info = FromUTF8();
653 NeedRIGHT();
654 break;
655
656 case T_option:
657 readOption( aItem );
658 break;
659
660 case T_name:
661 NeedSYMBOLorNUMBER();
662 aItem->m_Name = FromUTF8();
663 NeedRIGHT();
664 break;
665
666 case T_pos:
667 parseCoordinate( aItem->m_Pos );
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_incrlabel:
686 aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
687 NeedRIGHT();
688 break;
689
690 case T_maxlen:
692 NeedRIGHT();
693 break;
694
695 case T_maxheight:
697 NeedRIGHT();
698 break;
699
700 case T_font:
701 {
702 wxString faceName;
703
704 aItem->m_TextColor = COLOR4D::UNSPECIFIED;
705
706 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
707 {
708 switch( token )
709 {
710 case T_LEFT:
711 break;
712
713 case T_face:
714 NeedSYMBOL();
715 faceName = FromUTF8();
716 NeedRIGHT();
717 break;
718
719 case T_bold:
720 aItem->m_Bold = true;
721 break;
722
723 case T_italic:
724 aItem->m_Italic = true;
725 break;
726
727 case T_size:
728 aItem->m_TextSize.x = parseDouble();
729 aItem->m_TextSize.y = parseDouble();
730 NeedRIGHT();
731 break;
732
733 case T_color:
734 aItem->m_TextColor.r = parseInt( 0, 255 ) / 255.0;
735 aItem->m_TextColor.g = parseInt( 0, 255 ) / 255.0;
736 aItem->m_TextColor.b = parseInt( 0, 255 ) / 255.0;
737 aItem->m_TextColor.a = Clamp( parseDouble(), 0.0, 1.0 );
738 NeedRIGHT();
739 break;
740
741 case T_linewidth:
742 aItem->m_LineWidth = parseDouble();
743 NeedRIGHT();
744 break;
745
746 default:
747 Unexpected( CurText() );
748 break;
749 }
750 }
751
752 if( !faceName.IsEmpty() )
753 aItem->m_Font = KIFONT::FONT::GetFont( faceName, aItem->m_Bold, aItem->m_Italic );
754
755 break;
756 }
757
758 case T_justify:
759 for( token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
760 {
761 switch( token )
762 {
763 case T_center:
766 break;
767
768 case T_left:
770 break;
771
772 case T_right:
774 break;
775
776 case T_top:
778 break;
779
780 case T_bottom:
782 break;
783
784 default:
785 Unexpected( CurText() );
786 break;
787 }
788 }
789 break;
790
791 case T_rotate:
792 aItem->m_Orient = parseDouble();
793 NeedRIGHT();
794 break;
795
796 default:
797 Unexpected( CurText() );
798 break;
799 }
800 }
801}
802
803// parse an expression like " 25 1 ltcorner)"
805{
806 aCoord.m_Pos.x = parseDouble();
807 aCoord.m_Pos.y = parseDouble();
808
809 for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )
810 {
811 switch( token )
812 {
813 case T_ltcorner: aCoord.m_Anchor = LT_CORNER; break;
814 case T_lbcorner: aCoord.m_Anchor = LB_CORNER; break;
815 case T_rbcorner: aCoord.m_Anchor = RB_CORNER; break;
816 case T_rtcorner: aCoord.m_Anchor = RT_CORNER; break;
817 default: Unexpected( CurText() ); break;
818 }
819 }
820}
821
823{
824 T token = NextTok();
825
826 if( token != T_NUMBER )
827 Expecting( T_NUMBER );
828
829 return atoi( CurText() );
830}
831
832int DRAWING_SHEET_PARSER::parseInt( int aMin, int aMax )
833{
834 int val = parseInt();
835
836 if( val < aMin )
837 val = aMin;
838 else if( val > aMax )
839 val = aMax;
840
841 return val;
842}
843
844
846{
847 T token = NextTok();
848
849 if( token != T_NUMBER )
850 Expecting( T_NUMBER );
851
852
853 return DSNLEXER::parseDouble();
854}
855
856// defaultDrawingSheet is the default drawing sheet using the S expr.
857extern const char defaultDrawingSheet[];
858
860{
861 SetPageLayout( defaultDrawingSheet, false, wxT( "default page" ) );
862}
863
864// Returns defaultDrawingSheet as a string;
866{
867 return wxString( defaultDrawingSheet );
868}
869
870// emptyDrawingSheet is a "empty" drawing sheet using the S expr.
871// there is a 0 length line to fool something somewhere.
872extern const char emptyDrawingSheet[];
873
875{
876 SetPageLayout( emptyDrawingSheet, false, wxT( "empty page" ) );
877}
878
879
881{
882 return wxString( emptyDrawingSheet );
883}
884
885
886void DS_DATA_MODEL::SetPageLayout( const char* aPageLayout, bool Append, const wxString& aSource )
887{
888 if( ! Append )
889 ClearList();
890
891 DRAWING_SHEET_PARSER parser( aPageLayout, wxT( "Sexpr_string" ) );
892
893 try
894 {
895 parser.Parse( this );
896 }
897 catch( const IO_ERROR& ioe )
898 {
899 wxLogMessage( ioe.What() );
900 }
901 catch( const std::bad_alloc& )
902 {
903 wxLogMessage( "Memory exhaustion reading drawing sheet" );
904 }
905}
906
907
908bool DS_DATA_MODEL::LoadDrawingSheet( const wxString& aFullFileName, bool Append )
909{
910 wxString fullFileName = aFullFileName;
911
912 if( !Append )
913 {
914 if( fullFileName.IsEmpty() )
915 wxGetEnv( wxT( "KICAD_WKSFILE" ), &fullFileName );
916
917 if( fullFileName.IsEmpty() )
918 {
920 return true; // we assume its fine / default init
921 }
922
923 if( !wxFileExists( fullFileName ) )
924 {
925 wxLogMessage( _( "Drawing sheet '%s' not found." ), fullFileName );
927 return false;
928 }
929 }
930
931 wxFFile wksFile( fullFileName, "rb" );
932
933 if( ! wksFile.IsOpened() )
934 {
935 wxLogMessage( _( "Drawing sheet '%s' could not be opened." ), fullFileName );
936
937 if( !Append )
939
940 return false;
941 }
942
943 size_t filelen = wksFile.Length();
944 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(filelen+10);
945
946 if( wksFile.Read( buffer.get(), filelen ) != filelen )
947 {
948 wxLogMessage( _( "Drawing sheet '%s' was not fully read." ), fullFileName.GetData() );
949 return false;
950 }
951 else
952 {
953 buffer[filelen]=0;
954
955 if( ! Append )
956 ClearList();
957
958 DRAWING_SHEET_PARSER parser( buffer.get(), fullFileName );
959
960 try
961 {
962 parser.Parse( this );
963 }
964 catch( const IO_ERROR& ioe )
965 {
966 wxLogMessage( ioe.What() );
967 return false;
968 }
969 catch( const std::bad_alloc& )
970 {
971 wxLogMessage( "Memory exhaustion reading drawing sheet" );
972 return false;
973 }
974 }
975
976 return true;
977}
This class handle bitmap images in KiCad.
Definition: bitmap_base.h:51
bool LoadData(LINE_READER &aLine, wxString &aErrorMsg)
Load an image data saved by SaveData.
void SetScale(double aScale)
Definition: bitmap_base.h:79
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:825
BITMAP_BASE * m_ImageBitmap
Definition: ds_data_item.h:370
void SetBoundingBox()
Calculate the bounding box of the set polygons.
void CloseContour()
Close the current contour, by storing the index of the last corner of the current polygon in m_polyIn...
Definition: ds_data_item.h:238
void AppendCorner(const VECTOR2D &aCorner)
Add a corner in corner list.
Definition: ds_data_item.h:229
KIFONT::FONT * m_Font
Definition: ds_data_item.h:342
GR_TEXT_H_ALIGN_T m_Hjustify
Definition: ds_data_item.h:338
KIGFX::COLOR4D m_TextColor
Definition: ds_data_item.h:344
VECTOR2D m_BoundingBoxSize
Definition: ds_data_item.h:345
GR_TEXT_V_ALIGN_T m_Vjustify
Definition: ds_data_item.h:339
Drawing sheet structure type definitions.
Definition: ds_data_item.h:96
void SetPage1Option(PAGE_OPTION aChoice)
Definition: ds_data_item.h:134
wxString m_Name
Definition: ds_data_item.h:198
VECTOR2D m_IncrementVector
Definition: ds_data_item.h:204
POINT_COORD m_Pos
Definition: ds_data_item.h:200
wxString m_Info
Definition: ds_data_item.h:199
double m_LineWidth
Definition: ds_data_item.h:202
POINT_COORD m_End
Definition: ds_data_item.h:201
int m_IncrementLabel
Definition: ds_data_item.h:205
Handle the graphic items list to draw/plot the frame and title block.
Definition: ds_data_model.h:39
void SetBottomMargin(double aMargin)
Definition: ds_data_model.h:73
VECTOR2D m_DefaultTextSize
void SetRightMargin(double aMargin)
Definition: ds_data_model.h:67
double m_DefaultLineWidth
static wxString DefaultLayout()
Return a string containing the empty layout shape.
static wxString EmptyLayout()
Return a string containing the empty layout shape.
void SetLeftMargin(double aMargin)
Definition: ds_data_model.h:64
double m_DefaultTextThickness
void Append(DS_DATA_ITEM *aItem)
void AllowVoidList(bool Allow)
In KiCad applications, a drawing sheet is needed So if the list is empty, a default drawing sheet is ...
Definition: ds_data_model.h:83
void ClearList()
Erase the list of items.
void SetTopMargin(double aMargin)
Definition: ds_data_model.h:70
void SetFileFormatVersionAtLoad(int aVersion)
Definition: ds_data_model.h:61
void SetPageLayout(const char *aPageLayout, bool aAppend=false, const wxString &aSource=wxT("Sexpr_string"))
Populate the list from a S expr description stored in a string.
bool LoadDrawingSheet(const wxString &aFullFileName=wxEmptyString, bool Append=false)
Populates the list with a custom layout or the default layout if no custom layout is available.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:65
double r
Red component.
Definition: color4d.h:384
double g
Green component.
Definition: color4d.h:385
double a
Alpha component.
Definition: color4d.h:387
double b
Blue component.
Definition: color4d.h:386
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:241
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
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:175
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
constexpr T Clamp(const T &lower, const T &value, const T &upper)
Limit value within the range lower <= value <= upper.
Definition: util.h:64