diff --git a/bitmaps_png/cpp_26/erc_green.cpp b/bitmaps_png/cpp_26/erc_green.cpp index 5ca5060616..afeccd3f8d 100644 --- a/bitmaps_png/cpp_26/erc_green.cpp +++ b/bitmaps_png/cpp_26/erc_green.cpp @@ -1,28 +1,41 @@ - -/* Do not modify this file, it was automatically generated by the - * PNG2cpp CMake script, using a *.png file as input. - */ - -#include "bitmaps.h" - -static const char png[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c, - 0xce, 0x00, 0x00, 0x00, 0xb1, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0xf8, 0xff, 0xff, 0x3f, - 0x03, 0x3d, 0x30, 0x82, 0xd1, 0xc0, 0xc0, 0x24, 0x50, 0x20, 0x20, 0x40, 0x4d, 0xcc, 0x90, 0xc6, - 0xc0, 0x8a, 0x61, 0x91, 0x50, 0x01, 0xd7, 0x6e, 0xa1, 0x7c, 0xce, 0x2f, 0x42, 0x05, 0x9c, 0x9f, - 0xa8, 0x86, 0x73, 0x38, 0x9f, 0x30, 0x84, 0x32, 0xb0, 0xc1, 0x2d, 0x12, 0x49, 0x62, 0xe0, 0x15, - 0xcc, 0xe1, 0xfc, 0xa1, 0x74, 0x56, 0xe8, 0xbf, 0xd2, 0x39, 0xea, 0x61, 0x91, 0x3a, 0xee, 0x77, - 0x82, 0x99, 0x1c, 0xb6, 0x70, 0x8b, 0x40, 0xde, 0x14, 0xca, 0xe3, 0xfc, 0x46, 0x4d, 0x4b, 0x40, - 0x58, 0xb4, 0x99, 0xe7, 0x9d, 0x40, 0x06, 0x87, 0xc3, 0xa8, 0x45, 0xa3, 0x16, 0x8d, 0x5a, 0x34, - 0x6a, 0xd1, 0xa8, 0x45, 0xa3, 0x16, 0x8d, 0x4c, 0x8b, 0x04, 0xd3, 0x04, 0xf9, 0x69, 0x62, 0x51, - 0x13, 0xd0, 0xa2, 0x4c, 0x0e, 0x7b, 0xb8, 0x45, 0x40, 0xc0, 0x08, 0xb4, 0xe8, 0xbe, 0x58, 0x3b, - 0xcf, 0x27, 0xb1, 0x2e, 0x9e, 0x0f, 0xd4, 0xc2, 0x42, 0xb9, 0x5c, 0x1f, 0x79, 0xb3, 0x79, 0x85, - 0x51, 0x5b, 0x41, 0x59, 0x9c, 0xb2, 0x02, 0x99, 0x5c, 0x01, 0xd4, 0xc4, 0x82, 0x99, 0xdc, 0x7a, - 0x18, 0xcd, 0x2d, 0x5a, 0x63, 0x00, 0xe2, 0xb1, 0x17, 0xfe, 0x13, 0xe0, 0x61, 0xbb, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, -}; - -const BITMAP_OPAQUE erc_green_xpm[1] = {{ png, sizeof( png ), "erc_green_xpm" }}; - -//EOF + +/* Do not modify this file, it was automatically generated by the + * PNG2cpp CMake script, using a *.png file as input. + */ + +#include "bitmaps.h" + +static const char png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c, + 0xce, 0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x07, 0xb2, 0x66, 0x2f, 0x00, 0x00, 0x01, 0x64, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, + 0xd5, 0x96, 0xb1, 0x4e, 0x02, 0x41, 0x10, 0x86, 0xbf, 0xb9, 0xbb, 0xa5, 0x38, 0xa3, 0x31, 0x21, + 0xda, 0x28, 0x34, 0x1a, 0xe9, 0xa4, 0x35, 0x3c, 0x03, 0xa1, 0xb1, 0xb2, 0xb0, 0xf7, 0x21, 0xe4, + 0x11, 0x78, 0x05, 0x0b, 0x5e, 0x81, 0xc6, 0xc6, 0x52, 0x63, 0x30, 0x34, 0x24, 0x58, 0x99, 0xa0, + 0x84, 0x82, 0xc4, 0x12, 0x84, 0x53, 0xb8, 0x1d, 0x0b, 0x90, 0x28, 0x9c, 0xd1, 0x18, 0xee, 0x12, + 0xff, 0x6e, 0x27, 0x9b, 0xf9, 0xb2, 0xff, 0xec, 0xce, 0x8e, 0x00, 0x04, 0x41, 0x50, 0x02, 0xca, + 0x02, 0x79, 0x44, 0x0c, 0x9f, 0x24, 0x00, 0x22, 0x7c, 0x89, 0x2d, 0xac, 0xbf, 0x51, 0x08, 0xb4, + 0x80, 0x8a, 0x31, 0xa6, 0x2a, 0xa3, 0xd1, 0xa8, 0x08, 0xd4, 0x54, 0x2d, 0xfd, 0xd7, 0xc1, 0xd2, + 0xee, 0x48, 0xd0, 0x2f, 0xe1, 0x7e, 0xca, 0xc7, 0xb8, 0x06, 0xe0, 0x4c, 0x86, 0xc3, 0xe1, 0x35, + 0x50, 0x38, 0xb9, 0x38, 0xa6, 0xf1, 0x54, 0xc7, 0x71, 0x1c, 0x56, 0xa5, 0x75, 0x6f, 0x83, 0xfa, + 0x79, 0x93, 0x94, 0x97, 0xea, 0x7a, 0x6a, 0xed, 0xe1, 0xcb, 0xdb, 0x0b, 0xb7, 0x0f, 0x37, 0xac, + 0x9d, 0xba, 0x20, 0xe1, 0xca, 0x40, 0xc1, 0x65, 0x40, 0xe3, 0xf1, 0x8e, 0xa3, 0xbd, 0xc2, 0xae, + 0xa3, 0xaa, 0x66, 0x62, 0x43, 0x5c, 0xd7, 0x99, 0x79, 0xb2, 0x3a, 0x89, 0x11, 0x42, 0x1b, 0xa2, + 0xaa, 0x38, 0xaa, 0x8a, 0xaa, 0x12, 0x97, 0x3e, 0xf2, 0x4f, 0x41, 0xd6, 0x26, 0x04, 0x4a, 0xea, + 0x44, 0xc4, 0x06, 0x9a, 0xe6, 0x8e, 0xff, 0x44, 0x1a, 0x65, 0x9d, 0xc6, 0x68, 0x9d, 0xb5, 0x09, + 0xd4, 0x68, 0x06, 0x8b, 0x1d, 0x34, 0xaf, 0x11, 0x89, 0xbe, 0xa3, 0x44, 0x40, 0xd6, 0xc6, 0x06, + 0xd2, 0xa5, 0x1a, 0x41, 0xac, 0x35, 0x22, 0xf9, 0xce, 0x90, 0x64, 0xaf, 0xd3, 0xff, 0x7e, 0xeb, + 0x48, 0x14, 0x34, 0x6b, 0x41, 0xe3, 0x18, 0x7d, 0x9b, 0xdb, 0xe7, 0xa9, 0x6a, 0xd3, 0x37, 0x7e, + 0x21, 0xed, 0xa7, 0x19, 0x5c, 0xf5, 0x71, 0x3c, 0x89, 0x9a, 0x83, 0xfe, 0xa4, 0xf1, 0xf3, 0x84, + 0xfd, 0xad, 0x03, 0x54, 0xb5, 0x2b, 0x9d, 0x76, 0xbb, 0x08, 0xd4, 0x7a, 0xfd, 0x1e, 0xf7, 0xbd, + 0x56, 0xc4, 0xc7, 0x2f, 0x11, 0xa8, 0x08, 0xb8, 0x2c, 0x44, 0x45, 0xc8, 0x6c, 0x66, 0xc8, 0x6d, + 0xe7, 0xa6, 0xe3, 0x16, 0x40, 0xa7, 0xdd, 0x2e, 0x01, 0x65, 0x20, 0x0f, 0x98, 0x9f, 0xa7, 0x8e, + 0x08, 0xf8, 0x62, 0x4c, 0x24, 0x04, 0x5a, 0x02, 0x95, 0x9d, 0x6c, 0xb6, 0xfa, 0x0e, 0x74, 0x04, + 0x22, 0x77, 0x71, 0x16, 0xc1, 0x16, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, + 0x60, 0x82, +}; + +const BITMAP_OPAQUE erc_green_xpm[1] = {{ png, sizeof( png ), "erc_green_xpm" }}; + +//EOF diff --git a/bitmaps_png/cpp_26/ercwarn.cpp b/bitmaps_png/cpp_26/ercwarn.cpp index a092b11fda..84013eccff 100644 --- a/bitmaps_png/cpp_26/ercwarn.cpp +++ b/bitmaps_png/cpp_26/ercwarn.cpp @@ -8,71 +8,65 @@ static const char png[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c, - 0xce, 0x00, 0x00, 0x03, 0xf2, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xbd, 0x56, 0xeb, 0x4f, 0x93, - 0x57, 0x18, 0xaf, 0x7f, 0x80, 0x0a, 0xda, 0xa8, 0x40, 0x91, 0x62, 0x54, 0xdc, 0x12, 0xd4, 0x38, - 0x4d, 0x50, 0xa4, 0xe5, 0xba, 0x98, 0x4d, 0x2e, 0x4b, 0x43, 0xcc, 0x3e, 0x4d, 0x31, 0x99, 0x90, - 0x19, 0x83, 0xa2, 0x14, 0x50, 0xb4, 0x08, 0x61, 0x4c, 0xcd, 0x0c, 0x24, 0x73, 0x06, 0xf0, 0x92, - 0x10, 0xc2, 0x30, 0x5e, 0x12, 0xf5, 0xcb, 0x64, 0x36, 0x81, 0x44, 0x64, 0x64, 0xb1, 0x26, 0x8c, - 0xd4, 0x88, 0x06, 0xa7, 0x76, 0xf1, 0xce, 0x45, 0x90, 0x02, 0x7d, 0xcf, 0xcf, 0xe7, 0x3c, 0x7d, - 0xdb, 0xb4, 0xb4, 0x20, 0x1f, 0x8a, 0x6f, 0xf2, 0xe4, 0x3d, 0xef, 0x39, 0xcf, 0x79, 0x7e, 0xcf, - 0xf9, 0x3d, 0x97, 0xf3, 0x6a, 0x00, 0x68, 0x3e, 0x87, 0x78, 0x07, 0x66, 0x73, 0xec, 0xba, 0xd2, - 0xd2, 0xe8, 0x9c, 0xd0, 0x8a, 0xce, 0xe8, 0x07, 0x74, 0xf8, 0xb0, 0x2e, 0xaa, 0xbc, 0x3c, 0x66, - 0xe4, 0xe2, 0xc5, 0x35, 0xc3, 0xa1, 0x94, 0xca, 0x4a, 0xfd, 0x48, 0x49, 0xc9, 0xf2, 0x74, 0x2f, - 0x90, 0xd9, 0x1c, 0x9d, 0x7d, 0xfe, 0x7c, 0xdc, 0x80, 0xa2, 0x24, 0x23, 0x94, 0x62, 0xb5, 0xae, - 0x07, 0x01, 0x1d, 0xf3, 0x02, 0xc9, 0x63, 0x5e, 0xb8, 0xf0, 0xc5, 0x5c, 0x01, 0x59, 0x02, 0x80, - 0x84, 0xf8, 0x03, 0x42, 0x74, 0x93, 0x52, 0x21, 0x26, 0x27, 0x8d, 0x70, 0xb9, 0xa6, 0x6e, 0x36, - 0xf1, 0xba, 0x5b, 0xe7, 0x14, 0xeb, 0x04, 0x02, 0xa4, 0xd0, 0xfa, 0x1d, 0x92, 0xbf, 0xd1, 0xde, - 0x9e, 0x08, 0xb3, 0x39, 0x28, 0x50, 0x33, 0xe4, 0xf3, 0xe1, 0x43, 0x0b, 0xee, 0xdd, 0xdb, 0x88, - 0x27, 0x4f, 0x36, 0xfb, 0x81, 0x09, 0x71, 0x02, 0x9e, 0x67, 0x74, 0xd4, 0xce, 0x3a, 0xc3, 0xc3, - 0x49, 0x53, 0x80, 0x76, 0xf3, 0xfa, 0xc4, 0x44, 0x3f, 0x1a, 0x1a, 0xe2, 0xb0, 0x77, 0x6f, 0x54, - 0xb5, 0x46, 0xa3, 0x99, 0x37, 0x05, 0x68, 0xbf, 0x6a, 0xe4, 0x5f, 0xa4, 0xa4, 0x84, 0xa3, 0xb0, - 0x50, 0x87, 0xb1, 0x31, 0x83, 0x0f, 0x50, 0x3b, 0xad, 0x0a, 0x0c, 0x0d, 0x3d, 0xa4, 0xb1, 0x40, - 0x56, 0xd6, 0x2a, 0xdc, 0xbc, 0x19, 0x4f, 0x46, 0x8d, 0x3e, 0x3a, 0x75, 0x6c, 0xe3, 0xd6, 0xad, - 0x7a, 0x6c, 0xd8, 0x30, 0x1f, 0x3b, 0x77, 0x2e, 0xfb, 0x35, 0x00, 0x48, 0x51, 0x32, 0xe8, 0xd3, - 0x49, 0xe2, 0x42, 0x76, 0x76, 0x14, 0x32, 0x32, 0x16, 0xe1, 0xfd, 0x7b, 0x8f, 0xc7, 0x69, 0x34, - 0x3f, 0x42, 0x86, 0x1e, 0x91, 0x91, 0x93, 0x6c, 0xac, 0xa2, 0xe2, 0x47, 0x1c, 0x3d, 0xaa, 0x87, - 0xd3, 0xe9, 0x0b, 0xd4, 0xc1, 0x6b, 0x87, 0x0e, 0x99, 0x90, 0x96, 0x16, 0x8e, 0x03, 0x07, 0x74, - 0x95, 0x41, 0x93, 0x41, 0xf2, 0x2f, 0x9f, 0xfa, 0xfa, 0x1d, 0xd8, 0xba, 0x75, 0x21, 0xee, 0xdf, - 0xdf, 0xa4, 0xc6, 0x62, 0x1f, 0xcf, 0x8f, 0x8f, 0xb7, 0xd2, 0x49, 0xd3, 0x79, 0xdc, 0xd9, 0x79, - 0x15, 0x99, 0x99, 0x5a, 0x1f, 0x67, 0x52, 0x68, 0x76, 0x80, 0xde, 0xe3, 0x48, 0x4f, 0x5f, 0x8a, - 0x82, 0x82, 0x28, 0x14, 0x15, 0x45, 0x1f, 0x9f, 0x06, 0xe8, 0x77, 0x36, 0xd2, 0xd3, 0x53, 0x87, - 0xa4, 0xa4, 0x85, 0x68, 0x6e, 0xfe, 0x92, 0xa9, 0xf1, 0xc4, 0xef, 0xc1, 0x83, 0x9f, 0x90, 0x9c, - 0xbc, 0x88, 0x4e, 0xf1, 0x8e, 0x68, 0x1d, 0xe0, 0xb1, 0xcd, 0xb6, 0x51, 0x75, 0xe6, 0x07, 0xd6, - 0x79, 0xfa, 0xf4, 0x0e, 0xef, 0xad, 0xad, 0x5d, 0x85, 0xe2, 0xe2, 0xe5, 0x15, 0xd3, 0xa4, 0xf7, - 0x6e, 0x35, 0x4e, 0x5d, 0xac, 0x5c, 0x5a, 0x1a, 0xc3, 0x71, 0x02, 0xfa, 0x98, 0xd6, 0xb3, 0x67, - 0xe3, 0x61, 0x30, 0x84, 0x51, 0x9c, 0xfe, 0x64, 0xbd, 0x3d, 0x7b, 0xd2, 0xd0, 0xd8, 0x18, 0x47, - 0x27, 0x95, 0xce, 0x9c, 0xe6, 0xb9, 0x4b, 0x97, 0x8e, 0x23, 0x35, 0x35, 0x1c, 0xd7, 0xaf, 0xc7, - 0x07, 0x4f, 0x6f, 0xdf, 0xe3, 0x0b, 0x31, 0x8a, 0xdc, 0xdc, 0x65, 0x14, 0x2b, 0x2d, 0x65, 0xe1, - 0x77, 0x6c, 0xc0, 0xe5, 0xea, 0x42, 0x5e, 0x5e, 0x04, 0xcd, 0x2f, 0x21, 0xc3, 0xd5, 0x3c, 0xd7, - 0xd4, 0x54, 0x83, 0xfc, 0xfc, 0x48, 0x76, 0x46, 0x08, 0x2b, 0xcf, 0xe5, 0xe5, 0x6d, 0x91, 0xd9, - 0x46, 0xb1, 0x5c, 0x37, 0x13, 0x90, 0xa4, 0xef, 0x2f, 0xde, 0xd0, 0xd0, 0xf0, 0x2d, 0x7b, 0xff, - 0xf2, 0x65, 0x15, 0x7f, 0x0f, 0x0e, 0x9e, 0x86, 0xd1, 0x18, 0x86, 0x9a, 0x9a, 0x15, 0x04, 0xe4, - 0x06, 0xef, 0xef, 0xff, 0x87, 0xe8, 0x0b, 0xc3, 0x8b, 0x17, 0x89, 0xf4, 0xf5, 0x86, 0xe6, 0x5f, - 0x31, 0x13, 0xd4, 0x82, 0xd0, 0xd6, 0xf6, 0x49, 0xa0, 0x5f, 0xd8, 0x48, 0x6f, 0xef, 0xcf, 0xbc, - 0xc9, 0xe1, 0x70, 0xd3, 0x64, 0xb5, 0x6e, 0xe7, 0xef, 0xdb, 0xb7, 0xd7, 0x73, 0x4c, 0x64, 0x06, - 0x2a, 0xca, 0x24, 0x65, 0x67, 0x04, 0xee, 0xde, 0xcd, 0x62, 0x1d, 0xbb, 0xfd, 0x0a, 0x3b, 0xd7, - 0xd3, 0xb3, 0x89, 0xf5, 0x66, 0x04, 0x52, 0x94, 0x5c, 0xb5, 0x70, 0xdb, 0xa8, 0x9e, 0x16, 0x13, - 0x2d, 0x43, 0x34, 0xf7, 0x3f, 0xa7, 0xb2, 0x4c, 0xd9, 0xd7, 0xaf, 0x13, 0x55, 0x87, 0x5a, 0x58, - 0xef, 0xe0, 0x41, 0x13, 0x19, 0x2d, 0xe3, 0x71, 0x63, 0x63, 0x01, 0x72, 0x72, 0xb4, 0x14, 0x63, - 0xc3, 0xf4, 0x2d, 0xc8, 0xb7, 0xc2, 0x81, 0xff, 0xc8, 0x90, 0x03, 0x16, 0xcb, 0xd7, 0x6c, 0xc0, - 0xe9, 0xbc, 0x46, 0x05, 0xaa, 0x65, 0xee, 0x3d, 0x45, 0xec, 0x29, 0xf0, 0xcb, 0x97, 0x4f, 0x52, - 0xaa, 0xb7, 0xd2, 0x48, 0x81, 0xc9, 0xb4, 0x92, 0xea, 0x2b, 0x96, 0x6b, 0x6b, 0x56, 0x40, 0x42, - 0x5c, 0x61, 0x23, 0xdd, 0xdd, 0xbf, 0xa9, 0x34, 0x16, 0x32, 0x25, 0x92, 0x7b, 0x99, 0x61, 0x6e, - 0x3d, 0x59, 0x4f, 0x63, 0xe8, 0xeb, 0x6b, 0xc3, 0xf3, 0xe7, 0x8f, 0xa8, 0x1d, 0xf5, 0xb2, 0x8e, - 0xec, 0x16, 0x92, 0xda, 0x59, 0x02, 0x95, 0xa9, 0x3d, 0x6b, 0x80, 0x36, 0x4d, 0x50, 0x73, 0x8c, - 0xe3, 0xf8, 0x48, 0xee, 0x7d, 0x9b, 0xa9, 0x10, 0x9d, 0xa4, 0x33, 0xa8, 0xb6, 0x9d, 0x3a, 0x4e, - 0x16, 0x87, 0x63, 0x0b, 0xf7, 0xc8, 0x59, 0x01, 0x29, 0xca, 0x37, 0xdc, 0x8a, 0xe4, 0x63, 0xb3, - 0x75, 0x20, 0x21, 0x61, 0x01, 0xa7, 0xba, 0xe4, 0xde, 0xdf, 0xa1, 0x5a, 0x6f, 0xa3, 0xcd, 0xcf, - 0xdf, 0x86, 0x5d, 0xbb, 0x22, 0x28, 0xb6, 0x86, 0x99, 0xaf, 0x89, 0xa9, 0x2d, 0x5f, 0x88, 0x1b, - 0xf4, 0xb6, 0x51, 0x77, 0xd8, 0xcf, 0x94, 0x54, 0x55, 0xc5, 0xfa, 0xf5, 0x35, 0xb7, 0x7c, 0xcf, - 0x3a, 0x76, 0x7b, 0x07, 0x25, 0x8e, 0x16, 0x67, 0xce, 0xac, 0xf6, 0x52, 0x3b, 0x6b, 0x20, 0x29, - 0x92, 0x82, 0xc7, 0x8f, 0x13, 0xd0, 0xd5, 0xf5, 0x15, 0x9e, 0x3d, 0xdb, 0x1c, 0xe4, 0x8e, 0xf2, - 0xd7, 0x91, 0xf5, 0xe4, 0xd1, 0x09, 0x00, 0x92, 0x57, 0xf9, 0xb9, 0x73, 0xd3, 0x5f, 0xe5, 0x72, - 0x63, 0xf0, 0x8b, 0x70, 0x66, 0x1d, 0xaa, 0x23, 0xe1, 0x77, 0x95, 0x17, 0x15, 0x45, 0x6a, 0xcb, - 0xcb, 0xf5, 0x43, 0x74, 0xec, 0xb7, 0xa1, 0x14, 0x8b, 0x25, 0x66, 0xa4, 0xb8, 0x58, 0x9f, 0xe0, - 0xf7, 0xbb, 0x75, 0xe4, 0x48, 0x4c, 0x6c, 0x49, 0x89, 0x3e, 0x39, 0x94, 0x52, 0x56, 0xa6, 0x5b, - 0x1b, 0xf0, 0x5f, 0x37, 0xd7, 0xf2, 0x11, 0x7a, 0x44, 0x55, 0x8d, 0x15, 0xe4, 0xa5, 0xf6, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, + 0xce, 0x00, 0x00, 0x03, 0x8b, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xc5, 0x56, 0x5b, 0x4b, 0x54, + 0x51, 0x14, 0xf6, 0x2f, 0x94, 0x52, 0x56, 0x8e, 0xa3, 0x20, 0x5e, 0xa2, 0xcc, 0x0a, 0x2b, 0x21, + 0x6b, 0x28, 0xb5, 0x54, 0xb0, 0x42, 0xc4, 0x27, 0x89, 0x8c, 0x54, 0x90, 0x4a, 0x9d, 0xb1, 0xf1, + 0x92, 0xa4, 0x29, 0x68, 0x92, 0xd4, 0x43, 0x5a, 0x69, 0xea, 0xa0, 0xa8, 0x0f, 0x29, 0x3e, 0x28, + 0x4a, 0xde, 0x22, 0x15, 0xd4, 0xbc, 0xa6, 0x28, 0x46, 0x48, 0x85, 0x05, 0x81, 0xa9, 0x8c, 0x33, + 0x79, 0x39, 0x7b, 0x9c, 0xaf, 0x75, 0xb6, 0xe3, 0x61, 0x46, 0x9d, 0x52, 0x18, 0xeb, 0xc0, 0xe2, + 0x9c, 0xd9, 0xfb, 0xdb, 0xfb, 0x5b, 0xeb, 0x5b, 0x6b, 0xaf, 0x3d, 0x76, 0x00, 0xec, 0xfe, 0x85, + 0x49, 0x1f, 0x6a, 0xb5, 0xeb, 0xb1, 0xd4, 0x54, 0xd9, 0x55, 0xdb, 0x9a, 0xd3, 0x79, 0x0b, 0xa2, + 0xf4, 0x74, 0xa7, 0x43, 0x19, 0x19, 0x72, 0xbd, 0x46, 0xe3, 0xb9, 0x60, 0x4b, 0xcb, 0xce, 0x76, + 0xd1, 0xa7, 0xa4, 0x38, 0x07, 0x48, 0x44, 0x6a, 0xb5, 0xec, 0x4a, 0x59, 0x99, 0xc7, 0xfc, 0xea, + 0xaa, 0x02, 0xb6, 0xb4, 0x8e, 0x0e, 0x1f, 0x10, 0xd1, 0x03, 0x89, 0x48, 0x0c, 0xb3, 0xbc, 0xdc, + 0x6b, 0xb7, 0x88, 0x32, 0xff, 0x2f, 0x91, 0xd1, 0x58, 0x4a, 0xa0, 0xf7, 0x58, 0x5e, 0xbe, 0x05, + 0xc6, 0xce, 0x6f, 0x5a, 0x6c, 0x34, 0x16, 0xf3, 0x79, 0x83, 0xe1, 0x0d, 0x96, 0x96, 0xce, 0x6d, + 0x41, 0x10, 0x42, 0x98, 0x3e, 0x5a, 0xdb, 0x80, 0x96, 0x96, 0x63, 0xd6, 0x89, 0x18, 0x2b, 0x84, + 0xf8, 0x68, 0x34, 0x39, 0xe8, 0xed, 0x3d, 0x49, 0xbf, 0x37, 0x12, 0xcd, 0x60, 0xfd, 0x49, 0x4a, + 0xf2, 0xc5, 0xe2, 0xa2, 0x25, 0x99, 0xc1, 0xa0, 0xe6, 0x73, 0xcd, 0xcd, 0x15, 0x88, 0x8c, 0xdc, + 0x07, 0xa5, 0x52, 0x96, 0x6d, 0x85, 0xe8, 0x06, 0x07, 0xf6, 0xf4, 0xb4, 0xa0, 0xa4, 0xc4, 0x03, + 0x2b, 0x2b, 0xe6, 0x51, 0x45, 0xf3, 0xb9, 0x91, 0x91, 0x6e, 0xfe, 0x7e, 0xfc, 0x38, 0x09, 0x1f, + 0x3f, 0x9e, 0xa6, 0xcd, 0xcd, 0x9d, 0xa9, 0xe2, 0x73, 0xf7, 0xef, 0x5f, 0x47, 0x72, 0xb2, 0x0c, + 0x2a, 0x95, 0xec, 0xa1, 0x15, 0x22, 0xd1, 0x66, 0xa1, 0xd7, 0x6b, 0x91, 0x90, 0xe0, 0x4c, 0xf2, + 0x98, 0x13, 0x3d, 0xe7, 0x9b, 0xc4, 0xc7, 0x87, 0xd0, 0xe6, 0x0c, 0x5d, 0x5d, 0x4d, 0xa8, 0xae, + 0x3e, 0x0c, 0x41, 0x30, 0xc7, 0x8c, 0x93, 0x19, 0x10, 0x1c, 0x2c, 0xe7, 0x8e, 0xaa, 0xd5, 0xce, + 0x59, 0x56, 0x8b, 0x81, 0xb1, 0x16, 0xbe, 0x61, 0x5c, 0x9c, 0x3f, 0x74, 0x3a, 0x73, 0x69, 0x06, + 0xf1, 0xeb, 0xd7, 0x2c, 0x14, 0x8a, 0x3d, 0xf4, 0x1e, 0x24, 0xd9, 0xf4, 0xe4, 0xb1, 0xab, 0x99, + 0x33, 0x97, 0x69, 0x95, 0x01, 0x93, 0x93, 0xfd, 0x08, 0x0d, 0xb5, 0x47, 0x53, 0x93, 0xf7, 0x9f, + 0xab, 0x8e, 0xb1, 0x5c, 0x4e, 0x54, 0x50, 0xa0, 0xc4, 0xd8, 0x98, 0xaf, 0x29, 0x4f, 0xe2, 0x26, + 0x02, 0x45, 0x51, 0x8b, 0xe8, 0xe8, 0x03, 0xb4, 0xf9, 0x4b, 0x8e, 0x49, 0x4e, 0x0e, 0xc3, 0xfc, + 0xfc, 0x59, 0x13, 0x91, 0x8a, 0x8f, 0x95, 0x95, 0xe5, 0x22, 0x3d, 0x5d, 0xfe, 0xe7, 0x62, 0x58, + 0x23, 0x0a, 0xe7, 0x0b, 0x5a, 0x5b, 0x5f, 0xa3, 0xa6, 0x66, 0x5d, 0x9a, 0x34, 0x3e, 0x96, 0x93, + 0x13, 0x83, 0xc2, 0x42, 0x77, 0x22, 0xba, 0xc9, 0x7f, 0x57, 0x55, 0x3d, 0x25, 0xf2, 0xe3, 0xa6, + 0x0a, 0xad, 0x30, 0x29, 0x11, 0x84, 0xfa, 0xfa, 0x23, 0x68, 0x6b, 0xfb, 0x0b, 0x91, 0x98, 0x5c, + 0x41, 0xf8, 0x8c, 0x1f, 0x3f, 0xa6, 0x29, 0xa9, 0x72, 0x93, 0x34, 0xf5, 0x04, 0x35, 0x22, 0x2c, + 0xcc, 0x0d, 0x7d, 0x7d, 0x27, 0x69, 0x5e, 0x74, 0x68, 0x0e, 0x9f, 0x3e, 0x8d, 0xe1, 0xc9, 0x13, + 0x37, 0x3a, 0x0e, 0x22, 0xe6, 0x03, 0x61, 0xb5, 0x24, 0xad, 0x3d, 0xbe, 0x7e, 0xf5, 0x43, 0x7b, + 0xfb, 0x36, 0x0e, 0x2c, 0x63, 0x75, 0xdc, 0xbb, 0x98, 0x18, 0x1f, 0xca, 0xc7, 0x39, 0x2a, 0xeb, + 0xef, 0x98, 0x9e, 0x1e, 0x45, 0x48, 0x88, 0x3d, 0x16, 0x16, 0xfc, 0x4d, 0x98, 0x37, 0x34, 0xbe, + 0x8a, 0xd8, 0x58, 0x77, 0xca, 0x57, 0x00, 0x97, 0xb6, 0xa7, 0xa7, 0x01, 0x51, 0x51, 0xfb, 0x79, + 0xd9, 0x6f, 0xab, 0x33, 0x08, 0x42, 0x2a, 0x27, 0xca, 0xca, 0xba, 0x89, 0x6f, 0xdf, 0x22, 0xf8, + 0x77, 0x75, 0x75, 0x81, 0xb8, 0x50, 0x4a, 0xbe, 0x20, 0xe4, 0xf0, 0x71, 0x95, 0x2a, 0x1c, 0x73, + 0x73, 0xf1, 0xfc, 0x3b, 0x3f, 0xff, 0xae, 0x14, 0xe1, 0xb6, 0x88, 0x18, 0x0b, 0x26, 0x6f, 0x0d, + 0xa8, 0xad, 0x7d, 0x81, 0xd1, 0xd1, 0x6c, 0x53, 0x59, 0x5f, 0x42, 0x5d, 0xdd, 0x11, 0xa9, 0x9c, + 0x19, 0xbb, 0xca, 0xe5, 0xd4, 0x68, 0x1e, 0x61, 0x6a, 0xea, 0x19, 0xc7, 0x44, 0x44, 0x1c, 0x45, + 0x67, 0xe7, 0x5a, 0xce, 0xb6, 0xdd, 0xeb, 0x04, 0x61, 0x14, 0x13, 0x13, 0xfd, 0x64, 0x8d, 0xe4, + 0xe1, 0x02, 0x2e, 0x5c, 0x70, 0xc0, 0x97, 0x2f, 0x7e, 0xd2, 0x01, 0x5d, 0xcb, 0xe5, 0x24, 0x06, + 0x06, 0xde, 0xd2, 0xf8, 0x3b, 0xfc, 0xfc, 0x39, 0x85, 0xa0, 0xa0, 0xbd, 0x14, 0xdd, 0xd9, 0x9d, + 0x35, 0x55, 0xc6, 0xca, 0xc9, 0x56, 0xa0, 0xd5, 0xce, 0xa0, 0xbf, 0xbf, 0x91, 0xb4, 0x77, 0xdc, + 0xd4, 0x72, 0x18, 0xab, 0x24, 0x29, 0x75, 0x94, 0x47, 0x2d, 0xb5, 0x9d, 0x62, 0x24, 0x26, 0x3a, + 0x49, 0xd2, 0xee, 0x20, 0xa2, 0x78, 0xa9, 0xaf, 0xe5, 0xe5, 0xdd, 0xe6, 0xda, 0x5b, 0xb6, 0x24, + 0x11, 0x73, 0x47, 0xc2, 0x28, 0x95, 0x11, 0xa8, 0xac, 0xf4, 0x92, 0xa4, 0xdd, 0x41, 0x44, 0x17, + 0x29, 0x9a, 0x5e, 0x0c, 0x0f, 0x77, 0xe3, 0xda, 0x35, 0x4f, 0x74, 0x77, 0x9f, 0xd8, 0xd4, 0xd1, + 0x19, 0x0b, 0x20, 0x4c, 0x1f, 0x86, 0x86, 0x3a, 0x11, 0x18, 0xe8, 0x88, 0xf1, 0xf1, 0x53, 0x52, + 0x23, 0xde, 0xd1, 0x7d, 0x24, 0x96, 0xf6, 0xab, 0x57, 0x9e, 0xdc, 0x74, 0x3a, 0xff, 0x2d, 0xef, + 0x1d, 0xbd, 0x7e, 0x0d, 0xa3, 0xd1, 0x78, 0x99, 0xce, 0x93, 0x15, 0x22, 0xf1, 0x2a, 0x2f, 0x2d, + 0xb5, 0x7e, 0x95, 0x8b, 0x72, 0x6d, 0x94, 0x6c, 0x2b, 0x8c, 0x65, 0x73, 0x55, 0x88, 0x07, 0xd6, + 0x68, 0x71, 0x95, 0x2b, 0x95, 0x07, 0x1d, 0x32, 0x32, 0x5c, 0xb4, 0x45, 0x45, 0xee, 0xb3, 0xb6, + 0xb4, 0xcc, 0x4c, 0xb9, 0xfe, 0xde, 0x3d, 0x97, 0x33, 0x16, 0x7f, 0xb7, 0xa8, 0xd5, 0xb8, 0xa6, + 0xa4, 0xb8, 0x28, 0x6c, 0x69, 0x69, 0x69, 0x4e, 0xde, 0x9b, 0xfe, 0xd7, 0xed, 0xb6, 0xfd, 0x06, + 0xf5, 0x7b, 0x75, 0x19, 0x48, 0x1d, 0x69, 0x95, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, + 0xae, 0x42, 0x60, 0x82, }; const BITMAP_OPAQUE ercwarn_xpm[1] = {{ png, sizeof( png ), "ercwarn_xpm" }}; diff --git a/bitmaps_png/cpp_48/icon_pcbcalculator.cpp b/bitmaps_png/cpp_48/icon_pcbcalculator.cpp index 2ce8440eb1..cc86e376c0 100644 --- a/bitmaps_png/cpp_48/icon_pcbcalculator.cpp +++ b/bitmaps_png/cpp_48/icon_pcbcalculator.cpp @@ -8,189 +8,188 @@ static const char png[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x00, 0x57, 0x02, 0xf9, - 0x87, 0x00, 0x00, 0x0b, 0x49, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xd5, 0x9a, 0x7f, 0x6c, 0x5b, - 0xd7, 0x75, 0xc7, 0x3f, 0xf7, 0x3e, 0x52, 0xfc, 0x21, 0x8a, 0xa2, 0x18, 0x8a, 0x22, 0x25, 0xea, - 0xb7, 0x25, 0x19, 0x96, 0x15, 0xa9, 0x49, 0x6c, 0x2f, 0xce, 0x8f, 0xc2, 0xc5, 0xb2, 0x16, 0x2b, - 0xe6, 0xa1, 0x6d, 0xe0, 0xae, 0x41, 0xdb, 0x24, 0x6d, 0x91, 0xfe, 0x1a, 0x86, 0x0e, 0xe8, 0x32, - 0xac, 0xeb, 0xb2, 0x75, 0x5b, 0xd0, 0xac, 0xdb, 0x82, 0xfe, 0xd5, 0xa4, 0x68, 0x80, 0x64, 0x6b, - 0xd3, 0x04, 0xeb, 0x32, 0x18, 0x29, 0x50, 0x14, 0x45, 0x7f, 0x7a, 0x88, 0xdb, 0x3a, 0xb0, 0xdd, - 0x2a, 0xaa, 0x65, 0xcb, 0x92, 0x23, 0x5b, 0xb6, 0x65, 0xd9, 0xa2, 0x48, 0x51, 0xa2, 0x28, 0xf2, - 0xbd, 0x77, 0xef, 0xfe, 0xe0, 0x0f, 0x8b, 0x14, 0x49, 0xc9, 0xb1, 0x3d, 0xa0, 0x17, 0x78, 0x7a, - 0x57, 0xef, 0x91, 0xe7, 0xde, 0x73, 0xce, 0xf7, 0x7c, 0xcf, 0xb9, 0xf7, 0x52, 0x68, 0xad, 0xf9, - 0x7d, 0x6e, 0x8e, 0xdb, 0x21, 0x54, 0x08, 0x21, 0x01, 0x03, 0x10, 0xb7, 0x41, 0xbc, 0xad, 0xb5, - 0xb6, 0x6f, 0x9b, 0x02, 0x42, 0x88, 0x86, 0x23, 0x47, 0x8e, 0x7c, 0xba, 0xab, 0xb3, 0xe3, 0xf3, - 0x86, 0xe1, 0xf0, 0xde, 0x52, 0xe1, 0x4a, 0xe9, 0x64, 0x6a, 0xe5, 0xc8, 0xc1, 0x83, 0x07, 0xff, - 0xf2, 0xf5, 0xd7, 0x5f, 0x5f, 0xbc, 0x2d, 0x0a, 0xdc, 0x7b, 0xef, 0xbd, 0x7d, 0x03, 0xfd, 0x3d, - 0xff, 0x06, 0xba, 0xe1, 0x96, 0xdb, 0xde, 0x90, 0xb4, 0x85, 0x83, 0x1f, 0x7d, 0xfc, 0xd1, 0x8f, - 0x5f, 0x13, 0x42, 0xfc, 0x95, 0xd6, 0xda, 0x76, 0xdc, 0x62, 0xeb, 0x3b, 0xfe, 0xfd, 0x5f, 0xff, - 0xe5, 0x03, 0x5a, 0xeb, 0x06, 0xad, 0x15, 0x99, 0xb5, 0x34, 0xa9, 0x95, 0x6b, 0x68, 0xad, 0x6e, - 0x5a, 0xb6, 0xab, 0xa1, 0x89, 0x96, 0x60, 0x2b, 0x4a, 0x29, 0x9a, 0x9a, 0x7c, 0x7f, 0x00, 0xf8, - 0x80, 0xe5, 0x6a, 0x0a, 0x88, 0xe7, 0x9f, 0x7f, 0xfe, 0xc3, 0x2e, 0x97, 0x6b, 0xaf, 0x94, 0x52, - 0x48, 0x29, 0x91, 0x52, 0x16, 0x3c, 0xa8, 0x50, 0x4a, 0xa1, 0xb5, 0xc6, 0xb2, 0xac, 0x4d, 0xfd, - 0x67, 0x9e, 0x79, 0xc6, 0x30, 0x6d, 0x7b, 0x9f, 0x56, 0x36, 0x5a, 0x6b, 0xb2, 0xd9, 0x34, 0x67, - 0xde, 0xfe, 0x31, 0x0e, 0xe7, 0xcd, 0xdb, 0xa9, 0x23, 0x7c, 0x37, 0x4d, 0x4d, 0xcd, 0x18, 0x86, - 0x03, 0x33, 0x97, 0x73, 0x00, 0xae, 0xaa, 0x10, 0x7a, 0xee, 0xb9, 0xe7, 0x3e, 0xd2, 0xdf, 0xdf, - 0xff, 0xc2, 0xd8, 0xd8, 0x98, 0x47, 0x08, 0x51, 0xb4, 0x6c, 0xe9, 0xfd, 0x46, 0xd6, 0x2a, 0xf6, - 0x8b, 0xf7, 0x6c, 0x36, 0xcb, 0x6f, 0x4e, 0x9e, 0x28, 0x29, 0x26, 0x1d, 0x92, 0xe6, 0x16, 0x3f, - 0x2e, 0xb7, 0xeb, 0x86, 0x26, 0x3b, 0x7f, 0x39, 0xce, 0x5b, 0xe3, 0xe7, 0x88, 0x46, 0x83, 0x8c, - 0x8c, 0xf6, 0x03, 0x20, 0xa5, 0x2e, 0x19, 0xd1, 0x56, 0xa5, 0x18, 0x46, 0x6e, 0x82, 0x99, 0x61, - 0xec, 0x19, 0x1a, 0x1a, 0xf2, 0xb8, 0xdd, 0x6e, 0x6c, 0xdb, 0xc6, 0xb6, 0x6d, 0x2c, 0xcb, 0xca, - 0x87, 0xbf, 0x6d, 0x97, 0x79, 0xa1, 0x24, 0xa4, 0xe0, 0xa5, 0xbc, 0xa7, 0x44, 0xe9, 0x33, 0x0e, - 0xc3, 0x01, 0x42, 0xde, 0xb0, 0xb5, 0xcf, 0xcd, 0x5c, 0xe6, 0xfe, 0x07, 0x46, 0x58, 0xb8, 0x92, - 0x40, 0xa9, 0xfc, 0x38, 0xd2, 0x30, 0xd0, 0x05, 0xd9, 0x96, 0xad, 0x28, 0x32, 0x5c, 0x55, 0xdf, - 0x6a, 0xad, 0x31, 0x4d, 0x93, 0x4c, 0x26, 0x83, 0x10, 0x02, 0xdb, 0xb6, 0xf1, 0x7a, 0xbd, 0xe4, - 0x72, 0xb9, 0x32, 0x6f, 0x54, 0xf6, 0xb3, 0xd9, 0x2c, 0xa6, 0x95, 0x43, 0xeb, 0x82, 0x07, 0x0c, - 0x89, 0xe0, 0xc6, 0xf3, 0x8c, 0xaf, 0xc9, 0x8b, 0x34, 0x24, 0xcd, 0x81, 0x46, 0x8a, 0x43, 0x14, - 0x65, 0x29, 0xad, 0x50, 0xb6, 0x25, 0x6a, 0x2a, 0xa0, 0xb5, 0xa6, 0x12, 0x3a, 0xb5, 0xee, 0xd5, - 0xfa, 0x45, 0x2f, 0x15, 0x21, 0x54, 0x8c, 0x9f, 0x1b, 0x0a, 0x58, 0x97, 0x93, 0x5f, 0xff, 0xf2, - 0x14, 0x52, 0x4a, 0xe2, 0x8b, 0x29, 0x5c, 0x6e, 0x27, 0xc1, 0x46, 0x81, 0xd6, 0x85, 0x38, 0xb4, - 0x55, 0xfd, 0x44, 0x76, 0x33, 0x4a, 0x50, 0x18, 0x44, 0x6b, 0x8d, 0x21, 0x0a, 0x2e, 0x2f, 0x40, - 0x70, 0xbb, 0x6d, 0xc7, 0x40, 0x3b, 0x1d, 0x1d, 0x77, 0xe0, 0x72, 0x37, 0x20, 0x44, 0x41, 0xbe, - 0x14, 0x68, 0xad, 0x37, 0xc5, 0x80, 0x63, 0x73, 0xae, 0x50, 0x9b, 0x26, 0xb6, 0x5d, 0x25, 0x44, - 0x61, 0xc2, 0xba, 0xa0, 0x80, 0x43, 0x36, 0xd2, 0xd7, 0x75, 0x3f, 0x4a, 0x5b, 0x37, 0xcd, 0x42, - 0x4d, 0x9e, 0x88, 0xce, 0xac, 0x66, 0x85, 0xd6, 0x0a, 0xa5, 0x6c, 0xb1, 0x2d, 0x05, 0xb6, 0x82, - 0x4b, 0xb5, 0x67, 0x45, 0x2b, 0x69, 0xad, 0x59, 0x5d, 0x59, 0x01, 0x3c, 0xb7, 0xa4, 0x9e, 0x58, - 0xcd, 0xa5, 0x4b, 0x62, 0x54, 0xbd, 0x20, 0xae, 0xf4, 0xc0, 0xc6, 0x6b, 0x2b, 0x08, 0x69, 0xad, - 0xf3, 0xcc, 0xa5, 0x14, 0x68, 0xcd, 0x7f, 0xff, 0xcf, 0x61, 0xc6, 0xdf, 0xfa, 0x1d, 0x81, 0x40, - 0x80, 0xe5, 0x64, 0x92, 0xbf, 0x7f, 0xea, 0x4b, 0x9c, 0x9f, 0x3d, 0xcf, 0x37, 0xbe, 0xf9, 0x02, - 0xd1, 0x68, 0x3b, 0xf3, 0xf3, 0x97, 0xf9, 0xd4, 0x27, 0x1e, 0x65, 0x70, 0x60, 0x07, 0xff, 0xf4, - 0xf4, 0xd7, 0x70, 0xb9, 0xdd, 0x24, 0x12, 0x4b, 0x8c, 0x8d, 0x8e, 0xf0, 0x67, 0x87, 0x1e, 0xe6, - 0xc8, 0x77, 0x5e, 0x26, 0x3d, 0x3b, 0x8b, 0x56, 0x0a, 0xd5, 0xd0, 0xc0, 0xfb, 0xff, 0xfa, 0xc9, - 0x7c, 0x9c, 0xe5, 0x21, 0x24, 0xaa, 0xd2, 0x68, 0xd1, 0x7a, 0xf5, 0xac, 0xbd, 0xf1, 0x5e, 0xd9, - 0xd7, 0x5a, 0x17, 0x58, 0x48, 0x31, 0x79, 0xfa, 0x0c, 0x4b, 0x89, 0x24, 0x2d, 0xc1, 0x3b, 0x58, - 0x5c, 0x4a, 0x90, 0xcb, 0x66, 0x99, 0x3c, 0x73, 0x86, 0xb5, 0xcc, 0x3a, 0x7f, 0x72, 0xf0, 0x20, - 0x6b, 0x99, 0x75, 0x4e, 0x4d, 0x9e, 0xc6, 0x34, 0x73, 0x5c, 0xbd, 0x76, 0x8d, 0x68, 0x7b, 0x3b, - 0x3b, 0x06, 0x06, 0x99, 0x3c, 0x3d, 0x85, 0xd6, 0x8a, 0xa5, 0xdf, 0x8e, 0x33, 0xb6, 0x6b, 0x37, - 0xf7, 0xdc, 0x75, 0x37, 0x8d, 0x97, 0xe7, 0x31, 0xcd, 0x3c, 0xc3, 0xd9, 0x96, 0x5d, 0x9f, 0x85, - 0x2a, 0x3d, 0x50, 0x4f, 0x89, 0xe9, 0xe9, 0x69, 0x5a, 0x5b, 0x5b, 0x09, 0x04, 0x02, 0xd7, 0x59, - 0xc8, 0x56, 0x80, 0x26, 0xd2, 0xd6, 0xc6, 0x5a, 0x66, 0x9d, 0xb9, 0xb9, 0x0b, 0x34, 0xfb, 0xfd, - 0x08, 0x01, 0x6d, 0xe1, 0x30, 0x3e, 0x5f, 0x23, 0x3f, 0xfd, 0xe9, 0x4f, 0xf0, 0xf9, 0x1a, 0x89, - 0xb4, 0xb5, 0x01, 0x10, 0x08, 0x34, 0x13, 0x8f, 0x2f, 0x12, 0x8f, 0xc7, 0x69, 0x8f, 0x44, 0x50, - 0x4a, 0xe1, 0x8e, 0x46, 0x38, 0x3f, 0xf9, 0x3b, 0xb4, 0xd2, 0x58, 0xcd, 0xfe, 0xaa, 0x89, 0xec, - 0x96, 0x04, 0x71, 0x25, 0xcc, 0x74, 0x61, 0x80, 0xc7, 0x3e, 0xf6, 0x91, 0x12, 0x03, 0x09, 0x21, - 0x31, 0xa4, 0x64, 0x74, 0x64, 0x98, 0x5d, 0x3b, 0x07, 0x4b, 0x63, 0x38, 0x9d, 0x4e, 0x00, 0xfe, - 0xee, 0x6f, 0xbe, 0x58, 0x1a, 0xdb, 0x30, 0x0c, 0xb4, 0x52, 0xbc, 0xe7, 0xf3, 0x9f, 0xc5, 0xb6, - 0xed, 0xeb, 0xc9, 0x52, 0x88, 0x3c, 0x9c, 0xf2, 0x79, 0xa0, 0xb6, 0x02, 0x95, 0x5e, 0xa8, 0x75, - 0x4f, 0x24, 0x12, 0x24, 0x93, 0x49, 0x72, 0xb9, 0x1c, 0x3e, 0x9f, 0xaf, 0xe0, 0x41, 0x55, 0x9a, - 0xc8, 0xcb, 0xaf, 0x7c, 0x8f, 0xe3, 0x27, 0x7f, 0x43, 0x24, 0x12, 0x21, 0x91, 0x48, 0xf0, 0xf4, - 0x57, 0xbe, 0xcc, 0xd9, 0xe9, 0x19, 0xbe, 0xf9, 0xc2, 0x7f, 0xb0, 0x7b, 0x64, 0x37, 0x13, 0x6f, - 0x4d, 0xf0, 0xf8, 0xc7, 0x1f, 0x61, 0x78, 0xd7, 0x4e, 0x9e, 0xfa, 0xc7, 0xaf, 0xd2, 0xd4, 0xd4, - 0xc4, 0xea, 0xea, 0x2a, 0xfd, 0x7d, 0x3d, 0x3c, 0xf6, 0xb1, 0x47, 0x38, 0xfc, 0xda, 0x6b, 0xcc, - 0x9d, 0x9f, 0xcd, 0xe7, 0x06, 0xb7, 0x87, 0x4f, 0x7d, 0xe6, 0x33, 0x48, 0x29, 0x8b, 0x4a, 0xd5, - 0x8e, 0x81, 0xed, 0xe4, 0x04, 0x21, 0x04, 0xc9, 0x64, 0x92, 0x68, 0x34, 0x0a, 0xc0, 0xda, 0xda, - 0x5a, 0x89, 0x46, 0x8b, 0xd7, 0xdc, 0xc5, 0x4b, 0x74, 0xf7, 0xf4, 0xf2, 0xc0, 0x83, 0xef, 0x26, - 0x9b, 0x33, 0xc9, 0xe5, 0x72, 0xbc, 0x3d, 0x7b, 0x01, 0x84, 0xe0, 0x9e, 0x7b, 0xf6, 0x80, 0x10, - 0xbc, 0x3d, 0x7b, 0x1e, 0xd3, 0x34, 0x59, 0xcb, 0xac, 0xb3, 0x7b, 0xe4, 0x4e, 0xa2, 0xed, 0x1d, - 0x5c, 0xbc, 0x34, 0x8f, 0x52, 0x8a, 0x95, 0xe5, 0x24, 0x7d, 0x5d, 0x9d, 0x8c, 0xec, 0xda, 0x85, - 0xd7, 0x69, 0x60, 0x9a, 0x66, 0x1e, 0x42, 0xf6, 0x75, 0x1a, 0xdd, 0xa4, 0x80, 0x6d, 0xdb, 0x25, - 0x0f, 0x4c, 0x4c, 0x4c, 0x30, 0x39, 0x39, 0x49, 0x32, 0x99, 0xac, 0x1a, 0xb8, 0x00, 0x5e, 0xaf, - 0x17, 0xa7, 0xd3, 0x59, 0x7a, 0xa6, 0xec, 0x42, 0x1e, 0x50, 0x8a, 0xee, 0xce, 0x18, 0x89, 0xa5, - 0x38, 0x47, 0x7e, 0xf1, 0x73, 0x82, 0xc1, 0x00, 0x52, 0x08, 0x3a, 0x63, 0xed, 0xf8, 0x9b, 0x7c, - 0xfc, 0xe2, 0xe7, 0x3f, 0xc3, 0xdf, 0xe4, 0xa3, 0xab, 0xb3, 0x03, 0x21, 0x04, 0xa1, 0x3b, 0x82, - 0x9c, 0x39, 0x3d, 0x49, 0x62, 0x29, 0x4e, 0x77, 0x67, 0x0c, 0xad, 0x14, 0xa1, 0xd6, 0x30, 0x6b, - 0x99, 0x0c, 0xd7, 0xae, 0x5d, 0xc5, 0xe5, 0xf5, 0xe6, 0x49, 0x42, 0x29, 0x94, 0xb5, 0x8d, 0x3c, - 0x20, 0x84, 0x20, 0x12, 0x89, 0x30, 0x33, 0x33, 0xc3, 0xd0, 0xd0, 0xd0, 0xb6, 0x82, 0x3a, 0x4f, - 0x71, 0x0a, 0x55, 0xa8, 0xff, 0x1f, 0xfe, 0xd0, 0xc1, 0x4d, 0x70, 0x1c, 0x1c, 0xe8, 0xe7, 0x4b, - 0x4f, 0x7e, 0x61, 0x13, 0x44, 0xbf, 0xf8, 0x85, 0xcf, 0x95, 0x3d, 0x53, 0x5a, 0xf1, 0x87, 0xef, - 0x7b, 0x6f, 0xc5, 0xf7, 0xc9, 0xd7, 0x42, 0x5a, 0xe9, 0x6d, 0xe5, 0x81, 0x70, 0x38, 0x4c, 0x38, - 0x1c, 0xae, 0x99, 0xdc, 0xaa, 0xe5, 0x84, 0x22, 0x7c, 0x00, 0x5e, 0xfc, 0xcf, 0xef, 0x72, 0x6e, - 0x76, 0x0e, 0xbf, 0xdf, 0x4f, 0x7c, 0xf1, 0x1a, 0x4f, 0x7f, 0xe5, 0x6f, 0x39, 0x75, 0x7a, 0x8a, - 0x97, 0xbe, 0xfd, 0x0a, 0x77, 0xdd, 0x75, 0x37, 0x27, 0x4e, 0x1c, 0xe7, 0x91, 0x0f, 0x7f, 0x88, - 0x77, 0x8d, 0x8e, 0xf0, 0xe5, 0x7f, 0xf8, 0x2a, 0x91, 0x68, 0x94, 0x54, 0x2a, 0x45, 0x38, 0xd4, - 0xc2, 0x13, 0x9f, 0x7c, 0x94, 0xd7, 0xfe, 0xeb, 0x7b, 0xc4, 0x17, 0xae, 0xd0, 0xe8, 0xf3, 0xb1, - 0x9e, 0xcd, 0xf2, 0xf8, 0x13, 0x4f, 0x14, 0x63, 0x40, 0x6c, 0x3b, 0x0f, 0x54, 0xe3, 0xfa, 0x4d, - 0xf5, 0x4f, 0x99, 0x32, 0x94, 0x20, 0x94, 0x48, 0x2c, 0x63, 0x18, 0x06, 0x23, 0x23, 0x23, 0x48, - 0xc3, 0x81, 0x65, 0x9a, 0x2c, 0x5c, 0x59, 0xc0, 0xe5, 0x72, 0x33, 0x38, 0x38, 0x88, 0xcb, 0xe5, - 0x66, 0x61, 0x61, 0x01, 0xcb, 0x34, 0x41, 0x08, 0x82, 0xc1, 0x20, 0x7d, 0x7d, 0x7d, 0x24, 0x97, - 0x53, 0x68, 0xa5, 0xb0, 0xcd, 0x1c, 0x83, 0x03, 0x3b, 0x78, 0xe0, 0xc1, 0x77, 0x13, 0xf0, 0x79, - 0xb1, 0x4c, 0x33, 0x0f, 0x21, 0xa5, 0x6a, 0xc7, 0x40, 0x3e, 0x11, 0xe9, 0x9a, 0xc9, 0xac, 0xb2, - 0xbf, 0xbe, 0xbe, 0x5e, 0x56, 0xac, 0xe5, 0xab, 0xd1, 0xfc, 0x35, 0xb0, 0xa3, 0x97, 0x66, 0xbf, - 0x8f, 0x99, 0xe9, 0x29, 0xda, 0xc2, 0x21, 0x84, 0x10, 0xf4, 0xf6, 0x76, 0x12, 0x0c, 0x34, 0x73, - 0xf2, 0xe4, 0x71, 0x82, 0x81, 0x66, 0xfa, 0x7b, 0xbb, 0x11, 0x02, 0xa2, 0x91, 0x30, 0x4b, 0xf1, - 0x6b, 0xcc, 0x5f, 0xbe, 0xc8, 0x40, 0x7f, 0x2f, 0x4a, 0xd9, 0x84, 0x23, 0x11, 0x92, 0xa9, 0x14, - 0x27, 0x8e, 0xbf, 0x49, 0x83, 0xd7, 0x97, 0x87, 0x90, 0xb2, 0xd1, 0x4a, 0xd7, 0x4e, 0x64, 0x95, - 0x95, 0x63, 0x3d, 0x25, 0x5a, 0x5a, 0x5a, 0x38, 0x7b, 0xf6, 0x2c, 0x1e, 0x8f, 0x07, 0xaf, 0xd7, - 0x5b, 0xe2, 0xec, 0x22, 0x84, 0xde, 0xf7, 0xd0, 0x81, 0x4d, 0x18, 0xee, 0x8a, 0xc5, 0xf8, 0x8b, - 0xcf, 0x7d, 0x72, 0x93, 0xcc, 0x4f, 0x7f, 0xe2, 0xa3, 0xe5, 0x31, 0xa0, 0x14, 0xf7, 0x3d, 0x70, - 0x3f, 0x95, 0xfb, 0x56, 0x79, 0x84, 0x28, 0xb6, 0x15, 0xc4, 0x5b, 0x29, 0x11, 0x0a, 0x85, 0x58, - 0x5c, 0x5c, 0x24, 0x12, 0x89, 0xe0, 0x72, 0xb9, 0xf2, 0x54, 0x4a, 0x1e, 0x42, 0x00, 0xdf, 0x7a, - 0xf1, 0x65, 0x16, 0x13, 0x49, 0xc2, 0xe1, 0x30, 0xd3, 0x67, 0xa7, 0xf9, 0xe7, 0xa7, 0x9e, 0xe4, - 0xec, 0xd4, 0x59, 0x8e, 0x1d, 0x7d, 0xa3, 0x24, 0xe3, 0x5d, 0x7b, 0xf6, 0xb1, 0x6b, 0x78, 0x17, - 0x2f, 0xbf, 0xf4, 0x12, 0x3b, 0x06, 0x87, 0x58, 0xb8, 0x32, 0x8f, 0x16, 0x92, 0x0f, 0x3e, 0xfc, - 0x41, 0x2e, 0xfc, 0xe0, 0xeb, 0x0c, 0xb8, 0x96, 0x70, 0x78, 0xfc, 0x5c, 0xb9, 0x72, 0x05, 0xef, - 0x9f, 0x7e, 0x0d, 0xc3, 0x90, 0x68, 0xad, 0x65, 0xdd, 0x20, 0x2e, 0x6a, 0x5d, 0x4f, 0x89, 0x12, - 0x6d, 0x2a, 0xc5, 0xc2, 0xc2, 0x02, 0xe9, 0x74, 0x9a, 0x6c, 0x36, 0xcb, 0x72, 0x2a, 0x55, 0x62, - 0xa1, 0x4c, 0x36, 0x4b, 0x5f, 0x5f, 0x3f, 0xa1, 0x50, 0x88, 0x8b, 0x17, 0x2f, 0x61, 0x5a, 0x26, - 0xab, 0xe9, 0x55, 0xda, 0x42, 0x41, 0x9a, 0x5b, 0x82, 0x2c, 0x27, 0x96, 0x48, 0xa7, 0x57, 0xb1, - 0x6c, 0x8b, 0x50, 0x4b, 0x33, 0x03, 0x83, 0x83, 0x0c, 0x0e, 0x0d, 0xf1, 0xc6, 0xff, 0x1e, 0x41, - 0x69, 0x85, 0x1b, 0x93, 0x60, 0xf0, 0x0e, 0x0c, 0x6f, 0x00, 0x3b, 0x9d, 0x60, 0xd9, 0xb6, 0x10, - 0xd2, 0x81, 0xd2, 0xaa, 0x36, 0x8d, 0x56, 0xba, 0xac, 0xd6, 0xc4, 0x6b, 0x15, 0x75, 0xc5, 0x3c, - 0xa2, 0xb5, 0x66, 0xf7, 0xae, 0x21, 0xce, 0x4c, 0xcd, 0xb0, 0xb4, 0x78, 0x95, 0xce, 0x8e, 0x08, - 0x52, 0x4a, 0x3a, 0x3a, 0x63, 0x5c, 0x9d, 0x9f, 0x67, 0x69, 0x39, 0x05, 0xd2, 0x41, 0xac, 0x2b, - 0x86, 0x94, 0x02, 0xc3, 0xdb, 0xc8, 0x9b, 0xc7, 0x7e, 0x05, 0x40, 0x34, 0xd6, 0x81, 0x52, 0x8a, - 0x54, 0x68, 0x8c, 0xa3, 0x0b, 0x33, 0x40, 0x86, 0x9c, 0x63, 0x27, 0x7d, 0xb2, 0xb0, 0x40, 0x32, - 0x6d, 0xb5, 0xa5, 0x07, 0xaa, 0x95, 0x13, 0xd5, 0xfe, 0x37, 0x0c, 0x83, 0xb6, 0xb6, 0x36, 0x82, - 0xc1, 0x20, 0xb6, 0x6d, 0xd3, 0xd9, 0xd5, 0x43, 0x3a, 0x9d, 0xc1, 0xeb, 0x71, 0xf3, 0xe0, 0xfe, - 0xbd, 0x3c, 0xb8, 0x7f, 0x2f, 0x08, 0x51, 0x5a, 0x13, 0x84, 0x43, 0xad, 0xbc, 0xf7, 0xfd, 0x7f, - 0x0c, 0x15, 0xfb, 0x8e, 0x0f, 0xfd, 0xd1, 0x43, 0xc5, 0x05, 0x5d, 0xe9, 0x4f, 0xef, 0xdd, 0x07, - 0x80, 0x03, 0xe8, 0xeb, 0x0f, 0x91, 0x42, 0xf2, 0xe6, 0xf1, 0x13, 0x13, 0xc0, 0x72, 0xdd, 0x20, - 0x16, 0x42, 0xb0, 0xba, 0xba, 0xca, 0xec, 0xec, 0x2c, 0xc3, 0xc3, 0xc3, 0x08, 0x21, 0xc8, 0xe5, - 0x72, 0x00, 0xb8, 0xdd, 0x6e, 0x84, 0x10, 0x58, 0x96, 0x45, 0x2e, 0x97, 0xc3, 0xe1, 0xc8, 0x8b, - 0x71, 0x38, 0x1c, 0x8c, 0x8c, 0x8c, 0xf0, 0xea, 0xab, 0xaf, 0xd0, 0x1a, 0xf4, 0xe3, 0x71, 0x7b, - 0x90, 0x86, 0xc4, 0x90, 0x06, 0x86, 0x61, 0x20, 0x0d, 0x03, 0x43, 0x4a, 0xa4, 0x61, 0x20, 0xa5, - 0xcc, 0x3f, 0x93, 0xb2, 0x20, 0xab, 0xc8, 0x5e, 0x0a, 0x65, 0xdb, 0x24, 0x12, 0x09, 0xcb, 0x90, - 0xf2, 0xaa, 0xad, 0x6c, 0x6d, 0x59, 0x36, 0xca, 0xb6, 0xb4, 0x69, 0x99, 0xea, 0x8d, 0x5f, 0x1e, - 0x9b, 0xfa, 0xe1, 0x8f, 0x7e, 0xf2, 0x0a, 0x90, 0xaa, 0x09, 0xa1, 0xa2, 0xf5, 0x4f, 0x9f, 0x3e, - 0x4d, 0x4b, 0x4b, 0x0b, 0x8b, 0x8b, 0x8b, 0xc4, 0x62, 0x31, 0xe2, 0xf1, 0x38, 0x96, 0x65, 0xd1, - 0xdd, 0xdd, 0xcd, 0xfc, 0xfc, 0x3c, 0x73, 0x73, 0x73, 0xb4, 0xb5, 0xb5, 0xe1, 0xf7, 0xfb, 0x4b, - 0x30, 0xea, 0xee, 0xee, 0xe6, 0xb1, 0xc7, 0x1e, 0xe7, 0xdc, 0xb9, 0x73, 0x64, 0xb3, 0xd9, 0xda, - 0x6b, 0xe7, 0x8a, 0x31, 0x8d, 0x86, 0xeb, 0x75, 0x97, 0x65, 0x59, 0x7c, 0xeb, 0xc5, 0x6f, 0x5f, - 0x3a, 0x7a, 0xf4, 0xe8, 0x9f, 0x57, 0x02, 0x04, 0xb8, 0x00, 0x5c, 0xd0, 0x3a, 0xbf, 0x4e, 0xad, - 0x9b, 0x89, 0xf7, 0xec, 0xd9, 0xc3, 0xec, 0xec, 0x2c, 0xa1, 0x50, 0xa8, 0x8c, 0xf7, 0x4f, 0x9e, - 0x3c, 0x89, 0xc7, 0xe3, 0x61, 0x74, 0x74, 0x14, 0x8f, 0xc7, 0x53, 0xb1, 0xa3, 0xe0, 0xa2, 0xab, - 0xab, 0x8b, 0x58, 0x2c, 0x56, 0x77, 0xf9, 0x59, 0x6b, 0x73, 0x0c, 0xc0, 0x34, 0x4d, 0x0e, 0x1f, - 0x3e, 0xbc, 0x72, 0xf4, 0xe8, 0xd1, 0x1f, 0xd6, 0xd8, 0x9d, 0xd6, 0x35, 0x83, 0xd8, 0xb2, 0xac, - 0x32, 0x61, 0xbd, 0xbd, 0xbd, 0x25, 0xa5, 0x94, 0x52, 0xc4, 0xe3, 0x71, 0x86, 0x87, 0x87, 0x4b, - 0x0b, 0x98, 0x5a, 0x31, 0x62, 0x18, 0x46, 0xcd, 0xcc, 0xbd, 0x71, 0x09, 0x5a, 0xe9, 0xf9, 0xe2, - 0xaa, 0x4e, 0x4a, 0xa9, 0x8b, 0x56, 0xbe, 0xa1, 0xf3, 0x81, 0xca, 0x20, 0x2e, 0x96, 0xb0, 0xc5, - 0x41, 0x63, 0xb1, 0x58, 0xd9, 0xe4, 0xb7, 0x13, 0xe8, 0x5b, 0x95, 0x1f, 0xd5, 0x68, 0xfb, 0x1d, - 0x1f, 0x70, 0x54, 0xd2, 0xe8, 0xcc, 0xcc, 0x0c, 0xeb, 0xeb, 0xeb, 0x18, 0x86, 0x81, 0xc3, 0xe1, - 0xc0, 0xef, 0xf7, 0x6f, 0x6b, 0xd2, 0xdb, 0x55, 0x62, 0x63, 0xc9, 0xf2, 0x4e, 0x4e, 0x8b, 0xb6, - 0xcc, 0xc4, 0x3b, 0x77, 0xee, 0xcc, 0xaf, 0x4f, 0xdd, 0x6e, 0x2e, 0x5c, 0xb8, 0xb0, 0xe5, 0x26, - 0xd5, 0x8d, 0x28, 0xb1, 0x11, 0x32, 0x5b, 0x05, 0xfa, 0x0d, 0x43, 0xa8, 0xfa, 0x01, 0x89, 0x62, - 0x76, 0x76, 0x16, 0xa7, 0xd3, 0x49, 0x20, 0x10, 0xc0, 0xe7, 0xf3, 0xd5, 0x1c, 0x70, 0x69, 0x69, - 0x89, 0xe9, 0xe9, 0xe9, 0xb2, 0xf7, 0x3d, 0x3d, 0x3d, 0xb4, 0xb7, 0xb7, 0xb3, 0xb2, 0xb2, 0xc2, - 0xc4, 0xc4, 0x44, 0x99, 0xd5, 0xdb, 0xdb, 0xdb, 0xe9, 0xec, 0xec, 0xbc, 0x79, 0x0f, 0x14, 0x0b, - 0xb2, 0x6a, 0x4d, 0x4a, 0x49, 0x67, 0x67, 0x27, 0xab, 0xab, 0xab, 0x9c, 0x3a, 0x75, 0x8a, 0x68, - 0x34, 0xca, 0x9d, 0x77, 0xde, 0x59, 0xf5, 0xb3, 0xcd, 0xcd, 0xcd, 0x8c, 0x8e, 0x8e, 0x96, 0x59, - 0xb5, 0xa1, 0x21, 0x7f, 0x68, 0xe3, 0xf3, 0xf9, 0x18, 0x1b, 0x1b, 0x2b, 0x0b, 0x5e, 0xc3, 0x30, - 0x6e, 0xcd, 0x21, 0x5f, 0x3d, 0x0f, 0x14, 0x93, 0x55, 0x47, 0x47, 0x07, 0xa9, 0x54, 0x8a, 0x4b, - 0x97, 0x2e, 0xb1, 0xbe, 0xbe, 0xce, 0xbe, 0x7d, 0xfb, 0xaa, 0x7a, 0x60, 0x72, 0x72, 0xb2, 0x0c, - 0xeb, 0xa1, 0x50, 0x88, 0xd1, 0xd1, 0x51, 0x96, 0x97, 0x97, 0x39, 0x71, 0xe2, 0x44, 0xd9, 0xbb, - 0xae, 0xae, 0x2e, 0x7a, 0x7b, 0x7b, 0x6f, 0x0e, 0x42, 0x42, 0x08, 0xd7, 0xa1, 0x43, 0x87, 0xdc, - 0x95, 0xa5, 0x44, 0xb1, 0x45, 0xa3, 0x51, 0x84, 0x10, 0x48, 0x29, 0xd9, 0xbb, 0x77, 0x2f, 0x00, - 0xe3, 0xe3, 0xe3, 0x24, 0x12, 0x09, 0x82, 0xc1, 0x60, 0x19, 0xae, 0x5b, 0x5b, 0x5b, 0x09, 0x87, - 0xc3, 0x25, 0x0f, 0x58, 0x96, 0xc5, 0xb1, 0x63, 0xc7, 0x4a, 0xde, 0x39, 0x70, 0xe0, 0xc0, 0xa6, - 0xc4, 0xb9, 0xb1, 0xaf, 0x94, 0x72, 0x08, 0x21, 0x1a, 0xb5, 0xd6, 0xe9, 0x7a, 0x0a, 0xc8, 0x8d, - 0xa7, 0x8b, 0x40, 0x53, 0x36, 0x9b, 0x75, 0xd5, 0xdb, 0xb1, 0xae, 0xb4, 0x50, 0x43, 0x43, 0x43, - 0xd5, 0x64, 0x54, 0x8b, 0xe7, 0x2b, 0xaf, 0x5a, 0xec, 0x57, 0x28, 0x99, 0x9b, 0x85, 0x10, 0xbe, - 0xed, 0x7a, 0xc0, 0x0d, 0x78, 0x2c, 0xcb, 0x72, 0x6e, 0x87, 0xce, 0x4c, 0xd3, 0x64, 0x6a, 0x6a, - 0x8a, 0xe5, 0xe5, 0x65, 0x32, 0x99, 0x0c, 0x2b, 0x2b, 0x2b, 0xf4, 0xf4, 0xf4, 0xd4, 0xa4, 0x47, - 0xa7, 0xd3, 0xc9, 0xfe, 0xfd, 0xfb, 0xeb, 0xd2, 0x66, 0xc5, 0x3b, 0x03, 0xf0, 0x00, 0x39, 0x21, - 0xc4, 0x7a, 0xad, 0xa4, 0xe6, 0xa8, 0xf0, 0x86, 0xb4, 0x6d, 0xdb, 0x36, 0x4d, 0x53, 0xbb, 0x5c, - 0x2e, 0xe1, 0x70, 0x38, 0x4a, 0xab, 0x23, 0xc3, 0x30, 0xca, 0x06, 0x50, 0x4a, 0x95, 0x61, 0xd6, - 0xe9, 0x74, 0x96, 0x76, 0xd9, 0xb6, 0xb3, 0xa2, 0xab, 0xf7, 0xce, 0xb6, 0x6d, 0x84, 0x10, 0x56, - 0x61, 0x4e, 0xa2, 0xda, 0xd2, 0xb7, 0x9a, 0x02, 0x26, 0x60, 0x5e, 0xbe, 0x7c, 0xf9, 0xfb, 0xcf, - 0x3e, 0xfb, 0xec, 0xa1, 0xfb, 0xee, 0xbb, 0xef, 0x1d, 0x65, 0xc6, 0x77, 0x9a, 0x51, 0x37, 0xb6, - 0xf1, 0xf1, 0x71, 0xb1, 0xb0, 0xb0, 0xf0, 0x2a, 0x90, 0x2b, 0xce, 0xab, 0xe6, 0x58, 0x1b, 0xd2, - 0xb8, 0x00, 0x9a, 0x80, 0xa6, 0x68, 0x34, 0x1a, 0x0d, 0x85, 0x42, 0x83, 0x42, 0x08, 0xa7, 0xd6, - 0x5a, 0x14, 0xf0, 0x78, 0xdb, 0x9b, 0x94, 0xd2, 0x12, 0x42, 0xe8, 0x74, 0x3a, 0x3d, 0x37, 0x3d, - 0x3d, 0xfd, 0x36, 0xb0, 0x0a, 0xa4, 0xb4, 0xd6, 0x5b, 0x2b, 0xb0, 0xc1, 0x7a, 0x6e, 0xc0, 0x0b, - 0x34, 0x14, 0x7e, 0xef, 0x60, 0xd4, 0x73, 0xe1, 0x2d, 0x6e, 0x56, 0xa1, 0x64, 0xce, 0x01, 0xeb, - 0xc0, 0x9a, 0xde, 0xe2, 0x94, 0x5c, 0xd4, 0x0a, 0xd8, 0x82, 0x47, 0x8c, 0x02, 0xcc, 0xc4, 0xff, - 0xa3, 0x02, 0xb6, 0xbe, 0x81, 0xa3, 0x7d, 0xf1, 0xfb, 0xfe, 0x73, 0x9b, 0xff, 0x03, 0xce, 0xd3, - 0x2b, 0x55, 0x21, 0x2a, 0xd7, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, - 0x60, 0x82, + 0x87, 0x00, 0x00, 0x0b, 0x40, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xd5, 0x9a, 0x7d, 0x6c, 0x5b, + 0xd7, 0x79, 0xc6, 0x7f, 0xe7, 0x5c, 0x52, 0xa4, 0x68, 0x52, 0xa2, 0x68, 0x8a, 0x22, 0x25, 0x51, + 0x9f, 0x96, 0x64, 0x58, 0x96, 0xa5, 0x26, 0xb1, 0x3a, 0x77, 0x4e, 0x0a, 0x17, 0x4d, 0x5b, 0xac, + 0x98, 0x87, 0xb5, 0x81, 0xbb, 0x06, 0x6d, 0x93, 0xb4, 0x45, 0xda, 0xb5, 0xd8, 0xd0, 0x01, 0x5d, + 0x86, 0x75, 0x5d, 0xb6, 0x6e, 0x0b, 0x8a, 0x74, 0x5b, 0xb0, 0xbf, 0x96, 0x14, 0x4d, 0xd1, 0xf4, + 0x23, 0x4b, 0xb0, 0x2e, 0x83, 0x91, 0x01, 0x43, 0x31, 0xac, 0x5f, 0x2e, 0xdc, 0x6e, 0x31, 0x6c, + 0x35, 0x8e, 0x6a, 0x59, 0xb6, 0x98, 0xc8, 0x96, 0x23, 0x59, 0x91, 0x48, 0x51, 0xd4, 0x07, 0x3f, + 0xee, 0xbd, 0xe7, 0xec, 0x0f, 0x7e, 0x84, 0xa2, 0x44, 0x8a, 0xaa, 0xed, 0x01, 0xbd, 0x80, 0x74, + 0x2f, 0x2f, 0xc9, 0xf7, 0x9c, 0xe7, 0xbc, 0xcf, 0xf3, 0x3e, 0xe7, 0x9c, 0x4b, 0xa1, 0xb5, 0xe6, + 0x37, 0xf9, 0x70, 0xdc, 0x89, 0xa0, 0x42, 0x08, 0x09, 0x18, 0x80, 0xb8, 0x03, 0xe1, 0x6d, 0xad, + 0xb5, 0x7d, 0xc7, 0x00, 0x08, 0x21, 0x1a, 0xce, 0x9c, 0x39, 0xf3, 0x99, 0xae, 0x68, 0xc7, 0xe7, + 0x0d, 0xc3, 0xe1, 0xb9, 0xad, 0xc1, 0x95, 0xd2, 0xc9, 0xd4, 0xda, 0x99, 0x93, 0x27, 0x4f, 0xfe, + 0xc9, 0xcb, 0x2f, 0xbf, 0xbc, 0x7c, 0x47, 0x00, 0x1c, 0x3b, 0x76, 0xac, 0x6f, 0xa0, 0xbf, 0xe7, + 0x1f, 0x40, 0x37, 0xdc, 0xf6, 0xb1, 0x37, 0x24, 0x6d, 0xa1, 0xc0, 0xc7, 0x1e, 0x79, 0xe8, 0x13, + 0x4b, 0x42, 0x88, 0x3f, 0xd5, 0x5a, 0xdb, 0x8e, 0xdb, 0x3c, 0xfa, 0x8e, 0x7f, 0xfc, 0xfb, 0x27, + 0x7f, 0x5f, 0x6b, 0xdd, 0xa0, 0xb5, 0x22, 0xbd, 0xb9, 0x41, 0x6a, 0x6d, 0x09, 0xad, 0xd5, 0x2d, + 0xc7, 0x76, 0x35, 0xf8, 0x68, 0x09, 0xb4, 0xa2, 0x94, 0xc2, 0xe7, 0xf3, 0xfe, 0x16, 0xe0, 0x05, + 0x56, 0x77, 0x02, 0x20, 0x9e, 0x79, 0xe6, 0x99, 0x8f, 0xb8, 0x5c, 0xae, 0x71, 0x29, 0xa5, 0x90, + 0x52, 0x22, 0xa5, 0x2c, 0x64, 0x50, 0xa1, 0x94, 0x42, 0x6b, 0x8d, 0x65, 0x59, 0xdb, 0xae, 0x9f, + 0x7c, 0xf2, 0x49, 0x23, 0x67, 0xa9, 0x77, 0x6a, 0x65, 0xa3, 0xb5, 0x26, 0x9b, 0xdd, 0x60, 0xfa, + 0x8d, 0xff, 0xc6, 0xe1, 0xbc, 0xf5, 0x71, 0xea, 0x08, 0xdd, 0x8d, 0xcf, 0xd7, 0x8c, 0x61, 0x38, + 0x30, 0x73, 0x39, 0x07, 0xe0, 0xda, 0x91, 0x42, 0x4f, 0x3f, 0xfd, 0xf4, 0x47, 0xfb, 0xfb, 0xfb, + 0x9f, 0x1d, 0x1b, 0x1b, 0x6b, 0x14, 0x42, 0x14, 0x47, 0xb6, 0xf4, 0x7e, 0x79, 0xd5, 0x2a, 0x5e, + 0x17, 0xcf, 0xb9, 0x5c, 0x8e, 0x5f, 0x4e, 0x5c, 0x28, 0x01, 0x93, 0x0e, 0x49, 0x73, 0x4b, 0x13, + 0x2e, 0xb7, 0x6b, 0x4f, 0x9d, 0x5d, 0x98, 0x8f, 0xf3, 0xda, 0xc5, 0xd7, 0x89, 0x44, 0x02, 0x8c, + 0x8c, 0xf6, 0x03, 0x20, 0xa5, 0x2e, 0x0d, 0xa2, 0xad, 0x4a, 0x1a, 0x46, 0x6e, 0xa3, 0x99, 0x61, + 0x1c, 0x1d, 0x1a, 0x1a, 0x6a, 0x74, 0xbb, 0xdd, 0xd8, 0xb6, 0x8d, 0x6d, 0xdb, 0x58, 0x96, 0x95, + 0x97, 0xbf, 0x6d, 0x6f, 0xc9, 0x42, 0x29, 0x48, 0x21, 0x4b, 0x52, 0x4a, 0x74, 0x59, 0xa6, 0x1c, + 0x86, 0x03, 0x84, 0xdc, 0xf3, 0x68, 0xbf, 0x1e, 0x9b, 0xe7, 0xf8, 0xbd, 0x23, 0x2c, 0xde, 0x5c, + 0x41, 0xa9, 0x7c, 0x3b, 0xd2, 0x30, 0xd0, 0x08, 0x94, 0x52, 0x58, 0xb6, 0xa2, 0x58, 0xe1, 0x76, + 0xcc, 0xad, 0xd6, 0x1a, 0xd3, 0x34, 0x49, 0xa7, 0xd3, 0x08, 0x21, 0xb0, 0x6d, 0x1b, 0x8f, 0xc7, + 0x43, 0x2e, 0x97, 0xdb, 0x92, 0x8d, 0xca, 0xeb, 0x6c, 0x36, 0x8b, 0x99, 0xcb, 0xa1, 0x75, 0x21, + 0x03, 0x86, 0x44, 0xb0, 0x77, 0x9f, 0xf1, 0xfa, 0x3c, 0x48, 0x43, 0xd2, 0xec, 0xdf, 0x47, 0xb1, + 0x89, 0x62, 0x2c, 0xa5, 0x15, 0xca, 0xb6, 0x44, 0x55, 0x00, 0x5a, 0x6b, 0x2a, 0xa9, 0x53, 0xed, + 0xbc, 0xd3, 0xb5, 0xd6, 0x7a, 0x0b, 0x85, 0x8a, 0xfa, 0xd9, 0x93, 0x60, 0x5d, 0x4e, 0xfe, 0xf7, + 0x17, 0x97, 0x90, 0x52, 0x12, 0x5f, 0x4e, 0xe1, 0x72, 0x3b, 0x09, 0xec, 0x13, 0x68, 0x5d, 0xc8, + 0xae, 0xad, 0x6a, 0x1b, 0xd9, 0xad, 0x80, 0x28, 0xa7, 0x98, 0x21, 0x0a, 0x29, 0x2f, 0x50, 0xb0, + 0xde, 0xe3, 0xc0, 0x40, 0x3b, 0x1d, 0x1d, 0xfb, 0x71, 0xb9, 0x1b, 0x10, 0xa2, 0x10, 0x5f, 0xbe, + 0x3d, 0x38, 0xe5, 0x1a, 0x70, 0x6c, 0xf7, 0x0a, 0xb5, 0xad, 0x63, 0xf5, 0x82, 0x10, 0x85, 0x0e, + 0xeb, 0x02, 0x00, 0x87, 0xe1, 0xa5, 0xaf, 0xeb, 0x38, 0x4a, 0x5b, 0xb7, 0x5c, 0x85, 0x7c, 0x8d, + 0x61, 0x9d, 0x5e, 0xcf, 0x0a, 0xad, 0x15, 0x4a, 0xd9, 0xa2, 0x2e, 0x00, 0xbb, 0xd1, 0x65, 0xa7, + 0x7b, 0xb6, 0xb2, 0x4b, 0x19, 0x58, 0x4f, 0xa5, 0x80, 0xc6, 0xdb, 0x32, 0x9f, 0x58, 0xcf, 0x6d, + 0x94, 0xc2, 0xa8, 0x5a, 0x22, 0xae, 0xcc, 0x40, 0xf9, 0x5f, 0x3d, 0x14, 0xd2, 0x4a, 0x63, 0x2b, + 0x05, 0x5a, 0xf3, 0x6f, 0xff, 0x7e, 0x9a, 0x8b, 0xaf, 0xfd, 0x0a, 0xbf, 0xdf, 0xcf, 0x6a, 0x32, + 0xc9, 0x5f, 0x3d, 0xfe, 0x25, 0xae, 0xcd, 0x5e, 0xe3, 0x9f, 0xbf, 0xfe, 0x2c, 0x91, 0x48, 0x3b, + 0x0b, 0x0b, 0xf3, 0x7c, 0xfa, 0x93, 0x0f, 0x31, 0x38, 0x70, 0x80, 0xbf, 0x7d, 0xe2, 0x6b, 0xb8, + 0xdc, 0x6e, 0x56, 0x56, 0x12, 0x8c, 0x8d, 0x8e, 0xf0, 0x07, 0xa7, 0x1e, 0xe0, 0xcc, 0xf7, 0x9e, + 0x67, 0x63, 0x76, 0x16, 0xad, 0x14, 0xaa, 0xa1, 0x81, 0x0f, 0xfe, 0xd9, 0x63, 0xa5, 0x41, 0x2a, + 0x02, 0x90, 0x3b, 0x01, 0x28, 0xd7, 0xc0, 0x6e, 0x14, 0xaa, 0xbc, 0xd6, 0x5a, 0x17, 0xaa, 0x90, + 0x62, 0xea, 0xf2, 0x34, 0x89, 0x95, 0x24, 0x2d, 0x81, 0xfd, 0x2c, 0x27, 0x56, 0xc8, 0x65, 0xb3, + 0x4c, 0x4d, 0x4f, 0xb3, 0x99, 0xce, 0xf0, 0xbb, 0x27, 0x4f, 0xb2, 0x99, 0xce, 0x70, 0x69, 0xea, + 0x32, 0xa6, 0x99, 0xe3, 0xad, 0xa5, 0x25, 0x22, 0xed, 0xed, 0x1c, 0x18, 0x18, 0x64, 0xea, 0xf2, + 0x15, 0xb4, 0x56, 0x24, 0x5e, 0xbd, 0xc8, 0xd8, 0xa1, 0xc3, 0xdc, 0x73, 0xd7, 0xdd, 0xec, 0x9b, + 0x5f, 0xc0, 0x34, 0xf3, 0x15, 0xce, 0xb6, 0xec, 0xda, 0x55, 0xa8, 0x32, 0x03, 0xb5, 0x40, 0xcc, + 0xcc, 0xcc, 0xd0, 0xda, 0xda, 0x8a, 0xdf, 0xef, 0x2f, 0x69, 0x20, 0x9f, 0x62, 0x4d, 0xb8, 0xad, + 0x8d, 0xcd, 0x74, 0x86, 0xb9, 0xb9, 0xeb, 0x34, 0x37, 0x35, 0x21, 0x04, 0xb4, 0x85, 0x42, 0x78, + 0xbd, 0xfb, 0xf8, 0xd1, 0x8f, 0x7e, 0x88, 0xd7, 0xbb, 0x8f, 0x70, 0x5b, 0x1b, 0x00, 0x7e, 0x7f, + 0x33, 0xf1, 0xf8, 0x32, 0xf1, 0x78, 0x9c, 0xf6, 0x70, 0x18, 0xa5, 0x14, 0xee, 0x48, 0x98, 0x6b, + 0x53, 0xbf, 0x42, 0x2b, 0x8d, 0xd5, 0xdc, 0xb4, 0xa3, 0x91, 0xdd, 0x16, 0x11, 0x97, 0x03, 0xd5, + 0x5a, 0xa3, 0x0b, 0x0d, 0x3c, 0xfc, 0xf1, 0x8f, 0x96, 0x2a, 0x90, 0x10, 0x12, 0x43, 0x4a, 0x46, + 0x47, 0x86, 0x39, 0x74, 0x70, 0xb0, 0xd4, 0x86, 0xd3, 0xe9, 0x04, 0xe0, 0x2f, 0xff, 0xfc, 0x8b, + 0xa5, 0xb6, 0x0d, 0xc3, 0x40, 0x2b, 0xc5, 0x7b, 0x3e, 0xff, 0x87, 0xd8, 0xb6, 0xfd, 0xb6, 0x59, + 0x0a, 0x91, 0xa7, 0x53, 0xde, 0x07, 0xaa, 0x03, 0xa8, 0xcc, 0x42, 0xb5, 0x73, 0x22, 0x91, 0x20, + 0x99, 0x4c, 0x92, 0xcd, 0x66, 0xf1, 0x7a, 0xbd, 0x79, 0xb7, 0x2e, 0x88, 0x18, 0xe0, 0xf9, 0x17, + 0xbe, 0xcf, 0xf9, 0x89, 0x5f, 0x12, 0x0e, 0x87, 0x59, 0x59, 0x59, 0xe1, 0x89, 0xaf, 0x7c, 0x99, + 0xab, 0x33, 0x31, 0xbe, 0xfe, 0xec, 0xb7, 0x39, 0x3c, 0x72, 0x98, 0xc9, 0xd7, 0x26, 0x79, 0xe4, + 0x13, 0x0f, 0x32, 0x7c, 0xe8, 0x20, 0x8f, 0xff, 0xcd, 0x57, 0xf1, 0xf9, 0x7c, 0xac, 0xaf, 0xaf, + 0xd3, 0xdf, 0xd7, 0xc3, 0xc3, 0x1f, 0x7f, 0x90, 0xd3, 0x2f, 0xbd, 0xc4, 0xdc, 0xb5, 0xd9, 0xbc, + 0x37, 0xb8, 0x1b, 0xf9, 0xf4, 0x67, 0x3f, 0x8b, 0x94, 0xb2, 0x08, 0xaa, 0xba, 0x06, 0xea, 0xf1, + 0x04, 0x21, 0x04, 0xab, 0xab, 0xab, 0x44, 0x22, 0x11, 0xa4, 0x94, 0x6c, 0x6e, 0x6e, 0xe6, 0x29, + 0x64, 0xab, 0x92, 0x17, 0xcc, 0xdd, 0x78, 0x93, 0xee, 0x9e, 0x5e, 0xee, 0xbd, 0xef, 0xdd, 0x64, + 0x73, 0x26, 0xb9, 0x5c, 0x8e, 0x37, 0x66, 0xaf, 0x83, 0x10, 0xdc, 0x73, 0xcf, 0x51, 0x10, 0x82, + 0x37, 0x66, 0xaf, 0x61, 0x9a, 0x26, 0x9b, 0xe9, 0x0c, 0x87, 0x47, 0x8e, 0x10, 0x69, 0xef, 0xe0, + 0xc6, 0x9b, 0x0b, 0x28, 0xa5, 0x58, 0x5b, 0x4d, 0xd2, 0xd7, 0x15, 0x65, 0xe4, 0xd0, 0x21, 0x3c, + 0x4e, 0x03, 0xd3, 0x34, 0xf3, 0x14, 0xb2, 0xdf, 0x2e, 0xa3, 0xdb, 0x00, 0xd8, 0xb6, 0x5d, 0xca, + 0xc0, 0xe4, 0xe4, 0x24, 0x53, 0x53, 0x53, 0x24, 0x93, 0xc9, 0xaa, 0xc2, 0xf5, 0x78, 0x3c, 0x38, + 0x9d, 0xce, 0xad, 0x02, 0x2e, 0x78, 0x41, 0x77, 0xb4, 0x93, 0x95, 0x44, 0x9c, 0x33, 0x3f, 0xfd, + 0x09, 0x81, 0x80, 0x1f, 0x29, 0x04, 0xd1, 0xce, 0x76, 0x9a, 0x7c, 0x5e, 0x7e, 0xfa, 0x93, 0x1f, + 0xd3, 0xe4, 0xf3, 0xd2, 0x15, 0xed, 0x40, 0x08, 0x41, 0x70, 0x7f, 0x80, 0xe9, 0xcb, 0x53, 0xac, + 0x24, 0xe2, 0x74, 0x47, 0x3b, 0xd1, 0x4a, 0x11, 0x6c, 0x0d, 0xb1, 0x99, 0x4e, 0xb3, 0xb4, 0xf4, + 0x16, 0x2e, 0x8f, 0x27, 0xdf, 0x86, 0x52, 0x28, 0xab, 0x0e, 0x1f, 0x10, 0x42, 0x10, 0x0e, 0x87, + 0x89, 0xc5, 0x62, 0x0c, 0x0d, 0x0d, 0x55, 0x15, 0xf5, 0x36, 0xc1, 0x6b, 0x50, 0x85, 0xf9, 0xff, + 0x03, 0x1f, 0x3e, 0xb9, 0x8d, 0x8e, 0x83, 0x03, 0xfd, 0x7c, 0xe9, 0xb1, 0x2f, 0x6c, 0xa3, 0xe8, + 0x17, 0xbf, 0xf0, 0xb9, 0x2d, 0xf7, 0x94, 0x56, 0xbc, 0xf7, 0x03, 0xef, 0xaf, 0xf8, 0x7e, 0x3e, + 0xb6, 0xd2, 0x4a, 0xd7, 0xe5, 0x03, 0xa1, 0x50, 0x88, 0x50, 0x28, 0x54, 0xd3, 0xdc, 0x2a, 0xef, + 0xdb, 0x05, 0xfa, 0x00, 0x7c, 0xeb, 0x3b, 0xff, 0xc2, 0xeb, 0xb3, 0x73, 0x34, 0x35, 0x35, 0x11, + 0x5f, 0x5e, 0xe2, 0x89, 0xaf, 0xfc, 0x05, 0x97, 0x2e, 0x5f, 0xe1, 0xb9, 0xef, 0xbe, 0xc0, 0x5d, + 0x77, 0xdd, 0xcd, 0x85, 0x0b, 0xe7, 0x79, 0xf0, 0x23, 0x1f, 0xe6, 0x1d, 0xa3, 0x23, 0x7c, 0xf9, + 0xaf, 0xbf, 0x4a, 0x38, 0x12, 0x21, 0x95, 0x4a, 0x11, 0x0a, 0xb6, 0xf0, 0xe8, 0xa7, 0x1e, 0xe2, + 0xa5, 0x7f, 0xfd, 0x3e, 0xf1, 0xc5, 0x9b, 0xec, 0xf3, 0x7a, 0xc9, 0x64, 0xb3, 0x3c, 0xf2, 0xe8, + 0xa3, 0x45, 0x0d, 0x88, 0xba, 0x7d, 0x60, 0xa7, 0x5a, 0x5f, 0x4b, 0xdc, 0xe5, 0x14, 0x5a, 0x59, + 0x59, 0xc5, 0x30, 0x0c, 0x46, 0x46, 0x46, 0x90, 0x86, 0x03, 0xcb, 0x34, 0x59, 0xbc, 0xb9, 0x88, + 0xcb, 0xe5, 0x66, 0x70, 0x70, 0x10, 0x97, 0xcb, 0xcd, 0xe2, 0xe2, 0x22, 0x96, 0x69, 0x82, 0x10, + 0x04, 0x02, 0x01, 0xfa, 0xfa, 0xfa, 0x48, 0xae, 0xa6, 0xd0, 0x4a, 0x61, 0x9b, 0x39, 0x06, 0x07, + 0x0e, 0x70, 0xef, 0x7d, 0xef, 0xc6, 0xef, 0xf5, 0x60, 0x99, 0x66, 0x9e, 0x42, 0x4a, 0x55, 0xd7, + 0x40, 0x9e, 0xc7, 0xba, 0xaa, 0x99, 0x55, 0x76, 0x3a, 0x93, 0xc9, 0x94, 0x95, 0xca, 0x82, 0x0f, + 0x28, 0x1b, 0xa5, 0x6c, 0x06, 0x0e, 0xf4, 0xd2, 0xdc, 0xe4, 0x25, 0x36, 0x73, 0x85, 0xb6, 0x50, + 0x10, 0x21, 0x04, 0xbd, 0xbd, 0x51, 0x02, 0xfe, 0x66, 0x26, 0x26, 0xce, 0x13, 0xf0, 0x37, 0xd3, + 0xdf, 0xdb, 0x8d, 0x10, 0x10, 0x09, 0x87, 0x48, 0xc4, 0x97, 0x58, 0x98, 0xbf, 0xc1, 0x40, 0x7f, + 0x2f, 0x4a, 0xd9, 0x84, 0xc2, 0x61, 0x92, 0xa9, 0x14, 0x17, 0xce, 0x9f, 0xa3, 0xc1, 0xe3, 0xcd, + 0x53, 0x48, 0xd9, 0x68, 0xa5, 0xab, 0x1b, 0x59, 0xe5, 0xcc, 0xb1, 0x16, 0x88, 0x96, 0x96, 0x16, + 0xa6, 0xa7, 0xa7, 0xf1, 0x78, 0x3c, 0x78, 0x3c, 0x1e, 0x94, 0x52, 0x48, 0x29, 0x4b, 0x14, 0xfa, + 0xc0, 0xfd, 0x27, 0xb6, 0x71, 0xb8, 0xab, 0xb3, 0x93, 0x3f, 0xfe, 0xdc, 0xa7, 0xb6, 0xc5, 0xfc, + 0xcc, 0x27, 0x3f, 0xb6, 0x55, 0x03, 0x4a, 0xf1, 0xdb, 0xf7, 0x1e, 0xa7, 0x72, 0xdf, 0x2a, 0xcf, + 0x10, 0x45, 0x5d, 0x22, 0xde, 0x0d, 0xc4, 0xfe, 0xfd, 0xfb, 0x09, 0x04, 0x02, 0x84, 0xc3, 0x61, + 0x5c, 0x2e, 0x17, 0x9b, 0x9b, 0x9b, 0x28, 0x3b, 0x4f, 0x1f, 0x80, 0x6f, 0x7c, 0xeb, 0x79, 0x96, + 0x57, 0x92, 0x84, 0x42, 0x21, 0x66, 0xae, 0xce, 0xf0, 0x77, 0x8f, 0x3f, 0xc6, 0xd5, 0x2b, 0x57, + 0x79, 0xe5, 0xe7, 0x67, 0x4b, 0x31, 0xde, 0x71, 0xf4, 0x9d, 0x1c, 0x1a, 0x3e, 0xc4, 0xf3, 0xcf, + 0x3d, 0xc7, 0x81, 0xc1, 0x21, 0x16, 0x6f, 0x2e, 0xa0, 0x85, 0xe4, 0x43, 0x0f, 0x7c, 0x88, 0xeb, + 0xff, 0xf9, 0x4f, 0x0c, 0xb8, 0x12, 0x38, 0x1a, 0x9b, 0xb8, 0x79, 0xf3, 0x26, 0x9e, 0xdf, 0xfb, + 0x1a, 0x86, 0x21, 0xd1, 0x5a, 0xcb, 0x9a, 0x22, 0x2e, 0xa2, 0xae, 0x05, 0xa2, 0xdc, 0x79, 0x17, + 0x17, 0x17, 0xd9, 0xd8, 0xd8, 0x20, 0x93, 0xc9, 0x90, 0x5a, 0x4b, 0x95, 0xaa, 0x50, 0x3a, 0x9b, + 0xa5, 0xaf, 0xaf, 0x9f, 0x60, 0x30, 0xc8, 0x8d, 0x1b, 0x6f, 0x62, 0x5a, 0x26, 0xeb, 0x1b, 0xeb, + 0xb4, 0x05, 0x03, 0x34, 0xb7, 0x04, 0x58, 0x5d, 0x49, 0xb0, 0xb1, 0xb1, 0x8e, 0x65, 0x5b, 0x04, + 0x5b, 0x9a, 0x19, 0x18, 0x1c, 0x64, 0x70, 0x68, 0x88, 0xb3, 0x3f, 0x3b, 0x83, 0xd2, 0x0a, 0x37, + 0x26, 0x81, 0xc0, 0x7e, 0x0c, 0x8f, 0x1f, 0x7b, 0x63, 0x85, 0x55, 0xdb, 0x42, 0x48, 0x07, 0x4a, + 0xab, 0xea, 0x65, 0xb4, 0x32, 0x65, 0xd5, 0x3a, 0x5e, 0x6d, 0x2a, 0x51, 0xf4, 0x11, 0xad, 0x35, + 0x87, 0x0f, 0x0d, 0x31, 0x7d, 0x25, 0x46, 0x62, 0xf9, 0x2d, 0xa2, 0x1d, 0x61, 0xa4, 0x94, 0x74, + 0x44, 0x3b, 0x79, 0x6b, 0x61, 0x81, 0xc4, 0x6a, 0x0a, 0xa4, 0x83, 0xce, 0xae, 0x4e, 0xa4, 0x14, + 0x18, 0x9e, 0x7d, 0x9c, 0x7b, 0xe5, 0x7f, 0x00, 0x88, 0x74, 0x76, 0xa0, 0x94, 0x22, 0x15, 0x1c, + 0xe3, 0xe7, 0x8b, 0x31, 0x20, 0x4d, 0xce, 0x71, 0x90, 0x3e, 0x59, 0x58, 0x20, 0x99, 0xb6, 0xda, + 0x35, 0x03, 0x3b, 0x4d, 0x27, 0x76, 0x7a, 0x2d, 0xa5, 0xa4, 0xad, 0xad, 0x8d, 0x40, 0x20, 0x80, + 0x6d, 0xdb, 0x44, 0xbb, 0x7a, 0xd8, 0xd8, 0x4c, 0xe3, 0x71, 0xbb, 0xb9, 0xef, 0x5d, 0xe3, 0xdc, + 0xf7, 0xae, 0x71, 0x10, 0xa2, 0xb4, 0x26, 0x08, 0x05, 0x5b, 0x79, 0xff, 0x07, 0x7f, 0x07, 0x2a, + 0xf6, 0x1d, 0xef, 0x7f, 0xdf, 0xfd, 0xf9, 0x01, 0x2c, 0xfb, 0xd7, 0x7b, 0xf7, 0x09, 0xe0, 0x04, + 0xfa, 0xed, 0x9b, 0x48, 0x21, 0x39, 0x77, 0xfe, 0xc2, 0x24, 0xb0, 0x5a, 0x53, 0xc4, 0x42, 0x08, + 0xd6, 0xd7, 0xd7, 0x99, 0x9d, 0x9d, 0x65, 0x78, 0x78, 0x18, 0x21, 0x44, 0x69, 0x51, 0xef, 0x72, + 0xb9, 0x10, 0x42, 0x60, 0x59, 0x16, 0xb9, 0x5c, 0x0e, 0x87, 0x23, 0x1f, 0xc6, 0xe1, 0x70, 0x30, + 0x32, 0x32, 0xc2, 0x8b, 0x2f, 0xbe, 0x40, 0x28, 0xe0, 0xa7, 0xb1, 0xd1, 0x8d, 0x61, 0x18, 0x88, + 0xc2, 0x8e, 0x85, 0x61, 0x18, 0x5b, 0xce, 0xc5, 0x6b, 0x10, 0x85, 0xca, 0xa5, 0x4a, 0x3b, 0x21, + 0xc9, 0x64, 0xd2, 0x34, 0x84, 0x58, 0xb2, 0x95, 0xad, 0x2d, 0xcb, 0x46, 0xd9, 0x96, 0x36, 0x2d, + 0x53, 0x9d, 0xfd, 0xc5, 0x2b, 0x57, 0x7e, 0xf0, 0x5f, 0x3f, 0x7c, 0x01, 0x48, 0x55, 0xa5, 0x50, + 0x71, 0xf4, 0x2f, 0x5f, 0xbe, 0x4c, 0x4b, 0x4b, 0x0b, 0xcb, 0xcb, 0xcb, 0x74, 0x76, 0x76, 0x92, + 0x48, 0x24, 0x30, 0x4d, 0x93, 0xee, 0xee, 0x6e, 0x16, 0x16, 0x16, 0x98, 0x9b, 0x9b, 0xa3, 0xad, + 0xad, 0x0d, 0x9f, 0xcf, 0x57, 0xa2, 0x51, 0x77, 0x77, 0x37, 0x0f, 0x3f, 0xfc, 0x08, 0xb1, 0x58, + 0x8c, 0x5c, 0x2e, 0x57, 0x97, 0x01, 0x6a, 0xad, 0x31, 0x2a, 0xa6, 0x33, 0xdf, 0x7c, 0xee, 0x7b, + 0x6f, 0x9e, 0x3d, 0x7b, 0xf6, 0x8f, 0x2a, 0x09, 0x02, 0x5c, 0x07, 0xae, 0x6b, 0x9d, 0x5f, 0xa7, + 0xd6, 0x74, 0xe2, 0xa3, 0x47, 0x8f, 0x32, 0x3b, 0x3b, 0x4b, 0x30, 0x18, 0x2c, 0xdd, 0xcb, 0x64, + 0x32, 0x4c, 0x4c, 0x4c, 0xe0, 0x76, 0xbb, 0x19, 0x1d, 0x1d, 0xa5, 0xb1, 0xb1, 0xb1, 0x62, 0x47, + 0xc1, 0x45, 0x57, 0x57, 0x17, 0x1d, 0x1d, 0x1d, 0x35, 0x57, 0x71, 0xd5, 0x36, 0xc7, 0x00, 0x4c, + 0xd3, 0xe4, 0xf4, 0xe9, 0xd3, 0xeb, 0xc0, 0x0f, 0xaa, 0xec, 0x4e, 0xeb, 0xaa, 0x22, 0xb6, 0x2c, + 0x6b, 0x4b, 0xb0, 0xde, 0xde, 0xde, 0x12, 0x28, 0xad, 0x35, 0xf1, 0x78, 0x9c, 0xe1, 0xe1, 0xe1, + 0xd2, 0x02, 0xa6, 0x9a, 0x46, 0x1c, 0x0e, 0x47, 0xd5, 0xb9, 0x53, 0x79, 0x05, 0xab, 0xcc, 0x7c, + 0x71, 0x52, 0x28, 0xa5, 0xd4, 0xc5, 0x51, 0xde, 0xd3, 0xf3, 0x81, 0x4a, 0x11, 0x17, 0xa7, 0xb0, + 0xc5, 0xc0, 0x9d, 0x9d, 0x9d, 0x5b, 0x3a, 0x5f, 0x8f, 0xd0, 0x6b, 0x01, 0x2d, 0x07, 0x52, 0x8d, + 0x62, 0x7b, 0x02, 0x50, 0x59, 0x46, 0x63, 0xb1, 0x18, 0x99, 0x4c, 0x06, 0xc3, 0x30, 0x70, 0x38, + 0x1c, 0x34, 0x35, 0x35, 0xd5, 0xd5, 0xe9, 0x7a, 0x41, 0x94, 0x4f, 0x59, 0x7e, 0x9d, 0xa7, 0x45, + 0xbb, 0x3a, 0xf1, 0xc1, 0x83, 0x07, 0xf3, 0xeb, 0x53, 0xb7, 0x9b, 0xb9, 0xb9, 0x39, 0x4c, 0xd3, + 0xdc, 0x6d, 0x8b, 0xbd, 0x6e, 0x10, 0xe5, 0x94, 0xd9, 0x4d, 0xe8, 0x7b, 0xa6, 0x50, 0xb5, 0x6a, + 0x71, 0xed, 0xda, 0x35, 0x9c, 0x4e, 0x27, 0xcd, 0xcd, 0xcd, 0xa5, 0xea, 0xb3, 0xd3, 0x11, 0x8f, + 0xc7, 0x89, 0xc5, 0x62, 0x5b, 0x3a, 0xd5, 0xd3, 0xd3, 0x43, 0x7b, 0x7b, 0x3b, 0x6b, 0x6b, 0x6b, + 0x4c, 0x4e, 0x4e, 0x6e, 0x19, 0xf5, 0xf6, 0xf6, 0x76, 0xa2, 0xd1, 0xe8, 0xad, 0x67, 0xa0, 0xb8, + 0x88, 0xae, 0x36, 0xba, 0xd1, 0x68, 0x94, 0x8d, 0x8d, 0x0d, 0x2e, 0x5d, 0xba, 0x44, 0x24, 0x12, + 0xe1, 0xc8, 0x91, 0x23, 0x3b, 0x7e, 0xd6, 0xef, 0xf7, 0x73, 0xe4, 0xc8, 0x91, 0x2d, 0x42, 0x6e, + 0x68, 0xc8, 0x3f, 0xb4, 0xf1, 0x7a, 0xbd, 0x8c, 0x8d, 0x8d, 0x6d, 0x11, 0x6f, 0xde, 0x0f, 0xb8, + 0x3d, 0x14, 0xaa, 0xc5, 0x45, 0xc3, 0x30, 0x68, 0x6f, 0x6f, 0x67, 0x75, 0x75, 0x95, 0xf9, 0xf9, + 0x79, 0x32, 0x99, 0x0c, 0xe3, 0xe3, 0xe3, 0xdb, 0x32, 0x91, 0x48, 0x24, 0x98, 0x9a, 0x9a, 0xda, + 0x02, 0x3e, 0x10, 0x08, 0x30, 0x3a, 0x3a, 0x4a, 0x32, 0x99, 0x64, 0x62, 0x62, 0x62, 0xcb, 0xe7, + 0xa3, 0xd1, 0x28, 0xbd, 0xbd, 0xbd, 0xb7, 0x46, 0x21, 0x21, 0x84, 0xeb, 0xd4, 0xa9, 0x53, 0xee, + 0xca, 0xa9, 0x44, 0xf1, 0x08, 0x87, 0xc3, 0x08, 0x21, 0x90, 0x52, 0x32, 0x3e, 0x3e, 0x8e, 0xd6, + 0x9a, 0x8b, 0x17, 0x2f, 0x92, 0x4c, 0x26, 0x09, 0x04, 0x02, 0x5b, 0x78, 0xdd, 0xda, 0xda, 0x4a, + 0x28, 0x14, 0x2a, 0x75, 0xde, 0x34, 0x4d, 0xce, 0x9d, 0x3b, 0x57, 0xca, 0xce, 0x89, 0x13, 0x27, + 0xb6, 0x19, 0x67, 0xf9, 0xb5, 0x52, 0xca, 0x21, 0x84, 0xd8, 0xa7, 0xb5, 0xde, 0xa8, 0x05, 0x40, + 0x96, 0x3f, 0x5d, 0x04, 0x7c, 0xd9, 0x6c, 0xd6, 0x55, 0x6b, 0xc7, 0xba, 0x52, 0x94, 0x2e, 0x97, + 0x6b, 0x47, 0x33, 0xaa, 0x56, 0x55, 0xca, 0x17, 0x4c, 0x3b, 0x3d, 0xed, 0x29, 0x7b, 0x6d, 0x00, + 0xcd, 0x42, 0x08, 0x6f, 0xbd, 0x19, 0x70, 0x03, 0x8d, 0x96, 0x65, 0x39, 0xea, 0x29, 0x67, 0xa6, + 0x69, 0x72, 0xf5, 0xea, 0x55, 0x92, 0xc9, 0x24, 0xe9, 0x74, 0x9a, 0xb5, 0xb5, 0x35, 0x7a, 0x7a, + 0x7a, 0xaa, 0x96, 0x47, 0xa7, 0xd3, 0xc9, 0xb1, 0x63, 0xc7, 0x6a, 0x96, 0xcd, 0x8a, 0xf7, 0x24, + 0xd0, 0x08, 0xe4, 0x84, 0x10, 0x99, 0x6a, 0xa6, 0xe6, 0xa8, 0xc8, 0x86, 0xb4, 0x6d, 0x5b, 0x99, + 0xa6, 0xa9, 0x5d, 0x2e, 0x97, 0x28, 0xba, 0xa9, 0x52, 0x2a, 0xbf, 0x5b, 0x56, 0xd1, 0x78, 0x4f, + 0x4f, 0x4f, 0xe9, 0xb5, 0xd3, 0xe9, 0x2c, 0xed, 0xb2, 0xd5, 0xb3, 0xa2, 0xab, 0xf5, 0x9e, 0x6d, + 0xdb, 0x08, 0x21, 0xac, 0x42, 0x9f, 0xc4, 0x4e, 0x4b, 0xdf, 0x9d, 0x00, 0x98, 0x80, 0x39, 0x3f, + 0x3f, 0xff, 0x1f, 0x4f, 0x3d, 0xf5, 0xd4, 0xa9, 0xe3, 0xc7, 0x8f, 0x6b, 0x51, 0x88, 0xba, 0x57, + 0x83, 0xf9, 0x75, 0x1c, 0xb5, 0xec, 0x7b, 0xfa, 0xd5, 0x57, 0x5f, 0x95, 0x8b, 0x8b, 0x8b, 0x2f, + 0x02, 0xb9, 0x62, 0xbf, 0xaa, 0x7e, 0xa7, 0xcc, 0xc6, 0x05, 0xe0, 0x03, 0x7c, 0x91, 0x48, 0x24, + 0x12, 0x0c, 0x06, 0x07, 0x85, 0x10, 0x4e, 0xad, 0xb5, 0x28, 0xa4, 0xf3, 0x8e, 0x1f, 0x52, 0x4a, + 0x0b, 0xd0, 0x9b, 0x9b, 0x9b, 0x73, 0x33, 0x33, 0x33, 0x6f, 0x00, 0xeb, 0x40, 0x4a, 0x6b, 0xbd, + 0x3b, 0x80, 0xb2, 0x51, 0x70, 0x03, 0x1e, 0xa0, 0xa1, 0xf0, 0x7b, 0x07, 0xa3, 0x56, 0x0a, 0x6f, + 0xf3, 0x61, 0x15, 0xa6, 0xcc, 0x39, 0x20, 0x03, 0x6c, 0xea, 0x5d, 0x9e, 0x92, 0x8b, 0x6a, 0xf4, + 0x28, 0x64, 0xc4, 0x28, 0xd0, 0x4c, 0xfc, 0x3f, 0x02, 0xb0, 0xf5, 0x1e, 0x1e, 0xed, 0x8b, 0xdf, + 0xf4, 0x9f, 0xdb, 0xfc, 0x1f, 0x45, 0xe2, 0x2c, 0x7d, 0x65, 0x42, 0xd5, 0x87, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, }; const BITMAP_OPAQUE icon_pcbcalculator_xpm[1] = {{ png, sizeof( png ), "icon_pcbcalculator_xpm" }}; diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp index 4c53e9151f..a286bdec89 100644 --- a/cvpcb/class_DisplayFootprintsFrame.cpp +++ b/cvpcb/class_DisplayFootprintsFrame.cpp @@ -59,7 +59,7 @@ DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( CVPCB_MAINFRAME* father, icon.CopyFromBitmap( KiBitmap( icon_cvpcb_xpm ) ); SetIcon( icon ); - SetBoard( new BOARD( NULL ) ); + SetBoard( new BOARD( NULL, this ) ); SetScreen( new PCB_SCREEN() ); LoadSettings(); @@ -68,7 +68,6 @@ DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( CVPCB_MAINFRAME* father, if( (m_LastGridSizeId <= 0) || (m_LastGridSizeId > (ID_POPUP_GRID_USER - ID_POPUP_GRID_LEVEL_1000)) ) m_LastGridSizeId = ID_POPUP_GRID_LEVEL_500 - ID_POPUP_GRID_LEVEL_1000; - GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); // Initialize some display options diff --git a/gerbview/class_gerber_draw_item.cpp b/gerbview/class_gerber_draw_item.cpp index 76b759492e..eb2d182aa9 100644 --- a/gerbview/class_gerber_draw_item.cpp +++ b/gerbview/class_gerber_draw_item.cpp @@ -41,11 +41,10 @@ #include "class_GERBER.h" -#define SHOW_BOUNDING_BOX 0 // Set to 1 to draw the bounding box for debugging purposes. - - +/**********************************************************/ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( BOARD_ITEM* aParent, GERBER_IMAGE* aGerberparams ) : BOARD_ITEM( aParent, TYPE_GERBER_DRAW_ITEM ) +/**********************************************************/ { m_imageParams = aGerberparams; m_Layer = 0; @@ -340,8 +339,10 @@ bool GERBER_DRAW_ITEM::HasNegativeItems() } +/*********************************************************************/ void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoint& aOffset ) +/*********************************************************************/ { static D_CODE dummyD_CODE( 0 ); // used when a D_CODE is not found. default D_CODE to draw a flashed item int color, alt_color; @@ -485,14 +486,6 @@ void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, } break; } - -#if SHOW_BOUNDING_BOX - /* Draw the component boundary box */ - { - EDA_RECT boundaryBox = GetBoundingBox(); - GRRect( &aPanel->m_ClipBox, aDC, boundaryBox, 0, BROWN ); - } -#endif } /** diff --git a/gerbview/draw_gerber_screen.cpp b/gerbview/draw_gerber_screen.cpp index 0571d9d4b2..f267bc047e 100644 --- a/gerbview/draw_gerber_screen.cpp +++ b/gerbview/draw_gerber_screen.cpp @@ -139,7 +139,6 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoin // this is due to negative objects (drawn using background color) that create artefacct // on other images when drawn on screen bool useBufferBitmap = false; - if( (aDrawMode == GR_COPY) || ( aDrawMode == GR_OR ) ) useBufferBitmap = true; @@ -174,11 +173,9 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoin bool doBlit = false; // this flag requests an image transfert to actual screen when true. bool end = false; - for( int layer = 0; !end; layer++ ) { - int active_layer = ( (GERBVIEW_FRAME*) aPanel->GetParent() )->getActiveLayer(); - + int active_layer = ( (GERBVIEW_FRAME*) m_PcbFrame )->getActiveLayer(); if( layer == active_layer ) // active layer will be drawn after other layers continue; @@ -208,7 +205,6 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoin layerDC.SetDeviceOrigin(0,0); layerDC.SetLogicalOrigin( 0, 0 ); layerDC.SetUserScale( 1, 1 ); - if( aDrawMode == GR_COPY ) { // Use the layer bitmap itself as a mask when blitting. The bitmap @@ -216,7 +212,8 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoin layerDC.SelectObject( wxNullBitmap ); layerBitmap->SetMask( new wxMask( *layerBitmap, bgColor ) ); layerDC.SelectObject( *layerBitmap ); - screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, &layerDC, 0, 0, wxCOPY, true ); + screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, + &layerDC, 0, 0, wxCOPY, true ); } else if( aDrawMode == GR_OR ) { @@ -227,9 +224,9 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoin // the cpu cycles needed to create the monochromatic bitmap above, and // the extra time needed to do bit indexing into the monochromatic bitmap // on the blit above. - screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, &layerDC, 0, 0, wxOR ); + screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, + &layerDC, 0, 0, wxOR ); } - // Restore actual values and clear bitmpap for next drawing layerDC.SetDeviceOrigin( dev_org.x, dev_org.y ); layerDC.SetLogicalOrigin( logical_org.x, logical_org.y ); @@ -259,7 +256,7 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoin int dcode_highlight = 0; - if( layer == ( (GERBVIEW_FRAME*) aPanel->GetParent() )->getActiveLayer() ) + if( layer == ( (GERBVIEW_FRAME*) m_PcbFrame )->getActiveLayer() ) dcode_highlight = gerber->m_Selected_Tool; int layerdrawMode = GR_COPY; @@ -280,7 +277,6 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoin if( dcode_highlight && dcode_highlight == gerb_item->m_DCode ) drawMode |= GR_SURBRILL; - gerb_item->Draw( aPanel, plotDC, drawMode ); doBlit = true; } @@ -301,12 +297,14 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoin layerDC.SelectObject( wxNullBitmap ); layerBitmap->SetMask( new wxMask( *layerBitmap, bgColor ) ); layerDC.SelectObject( *layerBitmap ); - screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, &layerDC, 0, 0, wxCOPY, true ); + screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, + &layerDC, 0, 0, wxCOPY, true ); } else if( aDrawMode == GR_OR ) { - screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, &layerDC, 0, 0, wxOR ); + screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, + &layerDC, 0, 0, wxOR ); } } diff --git a/gerbview/export_to_pcbnew.cpp b/gerbview/export_to_pcbnew.cpp index 03c9b674aa..9f215f017f 100644 --- a/gerbview/export_to_pcbnew.cpp +++ b/gerbview/export_to_pcbnew.cpp @@ -47,7 +47,7 @@ GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME * aFrame, FILE * aFile { m_gerbview_frame = aFrame; m_file = aFile; - m_pcb = new BOARD( NULL ); + m_pcb = new BOARD( NULL, m_gerbview_frame ); } GBR_TO_PCB_EXPORTER::~GBR_TO_PCB_EXPORTER() diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp index e4c3655c79..b6fb086b37 100644 --- a/gerbview/gerbview_frame.cpp +++ b/gerbview/gerbview_frame.cpp @@ -44,7 +44,7 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( wxWindow* father, m_SelLayerBox = NULL; m_DCodeSelector = NULL; m_displayMode = 0; - m_drillFileHistory.SetBaseId( ID_GERBVIEW_DRILL_FILE1 ); + m_drillFileHistory.SetBaseId(ID_GERBVIEW_DRILL_FILE1); if( DrawPanel ) DrawPanel->m_Block_Enable = true; @@ -56,7 +56,7 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( wxWindow* father, SetScreen( ScreenPcb ); - SetBoard( new BOARD( NULL ) ); + SetBoard( new BOARD( NULL, this ) ); GetBoard()->SetEnabledLayers( FULL_LAYERS ); // All 32 layers enabled at first. GetBoard()->SetVisibleLayers( FULL_LAYERS ); // All 32 layers visible. @@ -74,7 +74,7 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( wxWindow* father, // initialize parameters in m_LayersManager LoadSettings(); SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); - GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); + GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); ReCreateMenuBar(); ReCreateHToolbar(); @@ -144,6 +144,34 @@ void GERBVIEW_FRAME::OnCloseWindow( wxCloseEvent& Event ) } +double GERBVIEW_FRAME::BestZoom() +{ + // gives a minimal value to zoom, if no item in list + if( GetBoard()->m_Drawings == NULL ) + return 160.0; + + EDA_RECT bbox; + BOARD_ITEM* item = GetBoard()->m_Drawings; + + bbox = ( (GERBER_DRAW_ITEM*) item )->GetBoundingBox(); + + for( ; item; item = item->Next() ) + { + GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item; + bbox.Merge( gerb_item->GetBoundingBox() ); + } + + wxSize size = DrawPanel->GetClientSize(); + + double x = (double) bbox.GetWidth() / (double) size.x; + double y = (double) bbox.GetHeight() / (double) size.y; + GetScreen()->SetScrollCenterPosition( bbox.Centre() ); + + double best_zoom = MAX( x, y ); + return best_zoom; +} + + void GERBVIEW_FRAME::LoadSettings() { wxConfig* config = wxGetApp().m_EDA_Config; diff --git a/gerbview/gerbview_frame.h b/gerbview/gerbview_frame.h index 0461de7026..704202b0cf 100644 --- a/gerbview/gerbview_frame.h +++ b/gerbview/gerbview_frame.h @@ -52,8 +52,8 @@ private: // a gerber file public: GERBVIEW_FRAME( wxWindow* father, const wxString& title, - const wxPoint& pos, const wxSize& size, - long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); + const wxPoint& pos, const wxSize& size, + long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); ~GERBVIEW_FRAME(); @@ -68,6 +68,7 @@ public: GERBVIEW_FRAME( wxWindow* father, const wxString& title, void OnLeftClick( wxDC* DC, const wxPoint& MousePos ); void OnLeftDClick( wxDC* DC, const wxPoint& MousePos ); bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ); + double BestZoom(); /** * Function ReportMessage diff --git a/include/base_struct.h b/include/base_struct.h index 8f5924a8e0..2766636d49 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -357,7 +357,8 @@ public: int m_Flags; // flags for editing and other uses. unsigned long m_TimeStamp; // Time stamp used for logical links - int m_Selected; /* Used by block commands, and selective editing */ + int m_Selected; /* Used by block commands, and selective + * editing */ // member used in undo/redo function EDA_ITEM* m_Image; // Link to an image copy to save a copy of diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 4df661e2c9..b591dd67e8 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -182,6 +182,7 @@ set(PCBNEW_SRCS tool_pcb.cpp toolbars_update_user_interface.cpp tracepcb.cpp + track.cpp tr_modif.cpp trpiste.cpp work.cpp diff --git a/pcbnew/attribut.cpp b/pcbnew/attribut.cpp index 6da53e3c87..309d092a6e 100644 --- a/pcbnew/attribut.cpp +++ b/pcbnew/attribut.cpp @@ -39,7 +39,7 @@ void PCB_EDIT_FRAME::Attribut_Track( TRACK* track, wxDC* DC, bool Flag_On ) return; DrawPanel->CrossHairOff( DC ); // Erase cursor shape - Track = GetBoard()->MarkTrace( track, &nb_segm, NULL, NULL, true ); + Track = MarkTrace( GetBoard(), track, &nb_segm, NULL, NULL, true ); DrawTraces( DrawPanel, DC, Track, nb_segm, GR_OR | GR_SURBRILL ); for( ; (Track != NULL) && (nb_segm > 0); nb_segm-- ) diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 576eba9881..f3f62d184d 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -105,48 +105,32 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard ) double PCB_BASE_FRAME::BestZoom( void ) { int dx, dy; - double zx, zy; + double ii, jj; wxSize size; - wxPoint center; - if( m_Pcb != NULL && m_Pcb->ComputeBoundingBox() ) - { - dx = m_Pcb->m_BoundaryBox.GetWidth(); - dy = m_Pcb->m_BoundaryBox.GetHeight(); - center = m_Pcb->m_BoundaryBox.Centre(); - } - else - { - if( m_Draw_Sheet_Ref ) - { - dx = GetScreen()->ReturnPageSize().x; - dy = GetScreen()->ReturnPageSize().y; - } - else - { - dx = GetScreen()->ReturnPageSize().x; - dy = GetScreen()->ReturnPageSize().y; - } + if( m_Pcb == NULL ) + return 32.0; - center = wxPoint( dx / 2, dy / 2 ); - } + m_Pcb->ComputeBoundingBox(); + dx = m_Pcb->m_BoundaryBox.GetWidth(); + dy = m_Pcb->m_BoundaryBox.GetHeight(); size = DrawPanel->GetClientSize(); if( size.x ) - zx = (double) dx / (double) size.x; + ii = (double)(dx + ( size.x / 2) ) / (double) size.x; else - zx = 32.0; + ii = 32.0; if ( size.y ) - zy = (double) dy / (double) size.y; + jj = (double)( dy + (size.y / 2) ) / (double) size.y; else - zy = 32.0; + jj = 32.0; - double bestzoom = MAX( zx, zy ); - GetScreen()->SetScrollCenterPosition( center ); + double bestzoom = MAX( ii, jj ); + GetScreen()->SetScrollCenterPosition( m_Pcb->m_BoundaryBox.Centre() ); - return bestzoom; + return bestzoom ; } diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 386ef7e10c..efe493b69b 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -19,67 +19,26 @@ wxPoint BOARD_ITEM::ZeroOffset( 0, 0 ); BOARD_DESIGN_SETTINGS boardDesignSettings; -/** - * Function SortPadsByXCoord - * is used to sort a pad list by x coordinate value. - */ -static int SortPadsByXCoord( const void* aRef, const void* aComp ) -{ - D_PAD* ref = *(LISTE_PAD*) aRef; - D_PAD* comp = *(LISTE_PAD*) aComp; - - return ref->m_Pos.x - comp->m_Pos.x; -} - - -TRACK* GetTraceByEndPoint( TRACK* aStartTrace, TRACK* aEndTrace, - const wxPoint& aPosition, int aLayerMask ) -{ - if( aStartTrace == NULL ) - return NULL; - - for( TRACK* trace = aStartTrace; trace != NULL; trace = trace->Next() ) - { - if( trace->GetState( IS_DELETED | BUSY ) == 0 ) - { - if( aPosition == trace->m_Start ) - { - if( aLayerMask & trace->ReturnMaskLayer() ) - return trace; - } - - if( aPosition == trace->m_End ) - { - if( aLayerMask & trace->ReturnMaskLayer() ) - return trace; - } - } - - if( trace == aEndTrace ) - break; - } - - return NULL; -} - - /*****************/ /* Class BOARD: */ /*****************/ -BOARD::BOARD( EDA_ITEM* aParent ) : - BOARD_ITEM( (BOARD_ITEM*) aParent, TYPE_PCB ), +BOARD::BOARD( EDA_ITEM* parent, PCB_BASE_FRAME* frame ) : + BOARD_ITEM( (BOARD_ITEM*)parent, TYPE_PCB ), m_NetClasses( this ) { + m_PcbFrame = frame; m_Status_Pcb = 0; // Status word: bit 1 = calculate. - SetBoardDesignSettings( &boardDesignSettings ); - SetColorsSettings( &g_ColorsSettings ); + SetBoardDesignSettings(&boardDesignSettings); + SetColorsSettings(&g_ColorsSettings); m_NbNodes = 0; // Number of connected pads. m_NbNoconnect = 0; // Number of unconnected nets. m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the - // zone contour currently in progress - m_NetInfo = new NETINFO_LIST( this ); // handle nets info list (name, design constraints .. + // zone contour currently in + // progress + m_NetInfo = new NETINFO_LIST( this ); // handle nets info list (name, + // design constraints .. m_NetInfo->BuildListOfNets(); // prepare pads and nets lists containers. for( int layer = 0; layer < NB_COPPER_LAYERS; ++layer ) @@ -88,10 +47,12 @@ BOARD::BOARD( EDA_ITEM* aParent ) : m_Layer[layer].m_Type = LT_SIGNAL; } - // Initial parameters for the default NETCLASS come from the global preferences - // within g_DesignSettings via the NETCLASS() constructor. Should the user - // eventually load a board from a disk file, then these defaults will get - // overwritten during load. + // Initial parameters for the default NETCLASS come from the global + // preferences + // within g_DesignSettings via the NETCLASS() constructor. + // Should user eventually load a board from a disk file, then these + // defaults + // will get overwritten during load. m_NetClasses.GetDefault()->SetDescription( _( "This is the default net class." ) ); m_ViaSizeSelector = 0; m_TrackWidthSelector = 0; @@ -103,6 +64,9 @@ BOARD::BOARD( EDA_ITEM* aParent ) : BOARD::~BOARD() { + if( m_PcbFrame->GetScreen() ) + m_PcbFrame->GetScreen()->ClearUndoRedoList(); + while( m_ZoneDescriptorList.size() ) { ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0]; @@ -123,124 +87,20 @@ BOARD::~BOARD() } -void BOARD::chainMarkedSegments( wxPoint& aPosition, int aLayerMask, TRACK_PTRS* aList ) -{ - TRACK* pt_segm; // The current segment being analyzed. - TRACK* pt_via; // The via identified, eventually destroy - TRACK* SegmentCandidate; // The end segment to destroy (or NULL = pt_segm - int NbSegm; - - if( m_Track == NULL ) - return; - - /* Set the BUSY flag of all connected segments, first search starting at - * aPosition - * Search ends when: - * - a pad is found (end of a track) - * - a segment end has more than one other segment end connected - * - and obviously when no connected item found - * Vias are a special case, because we must see others segment connected - * on others layers and they change the layer mask. They can be a track - * end or not - * They will be analyzer later, and vias on terminal points of the track - * will be considered as part of this track if they do not connect segments - * of an other track together and will be considered as part of an other - * track if when removing the via, the segments of that other track are - * disconnected - */ - for( ; ; ) - { - if( GetPadFast( aPosition, aLayerMask ) != NULL ) - return; - - /* Test for a via: a via changes the layer mask and can connect a lot - * of segments at location aPosition. When found, the via is just - * pushed in list. Vias will be examined later, when all connected - * segment are found and push in list. This is because when a via - * is found we do not know at this time the number of connected items - * and we do not know if this via is on the track or finish the track - */ - pt_via = m_Track->GetVia( NULL, aPosition, aLayerMask ); - - if( pt_via ) - { - aLayerMask = pt_via->ReturnMaskLayer(); - aList->push_back( pt_via ); - } - - /* Now we search all segments connected to point aPosition - * if only 1 segment: this segment is candidate - * if > 1 segment: - * end of track (more than 2 segment connected at this location) - */ - pt_segm = m_Track; - SegmentCandidate = NULL; - NbSegm = 0; - - while( ( pt_segm = GetTraceByEndPoint( pt_segm, NULL, aPosition, aLayerMask ) ) != NULL ) - { - if( pt_segm->GetState( BUSY ) ) // already found and selected: skip it - { - pt_segm = pt_segm->Next(); - continue; - } - - if( pt_segm == pt_via ) // just previously found: skip it - { - pt_segm = pt_segm->Next(); - continue; - } - - NbSegm++; - - if( NbSegm == 1 ) /* First time we found a connected item: pt_segm is candidate */ - { - SegmentCandidate = pt_segm; - pt_segm = pt_segm->Next(); - } - else /* More than 1 segment connected -> this location is an end of the track */ - { - return; - } - } - - if( SegmentCandidate ) // A candidate is found: flag it an push it in list - { - /* Initialize parameters to search items connected to this - * candidate: - * we must analyze connections to its other end - */ - aLayerMask = SegmentCandidate->ReturnMaskLayer(); - - if( aPosition == SegmentCandidate->m_Start ) - { - aPosition = SegmentCandidate->m_End; - } - else - { - aPosition = SegmentCandidate->m_Start; - } - - pt_segm = m_Track; /* restart list of tracks to analyze */ - - /* flag this item an push it in list of selected items */ - aList->push_back( SegmentCandidate ); - SegmentCandidate->SetState( BUSY, ON ); - } - else - { - return; - } - } -} - - +/* + * Function PushHightLight + * save current hight light info for later use + */ void BOARD::PushHightLight() { m_hightLightPrevious = m_hightLight; } +/* + * Function PopHightLight + * retrieve a previously saved hight light info + */ void BOARD::PopHightLight() { m_hightLight = m_hightLightPrevious; @@ -248,6 +108,15 @@ void BOARD::PopHightLight() } +/** + * Function SetCurrentNetClass + * Must be called after a netclass selection (or after a netclass parameter + * change + * Initialize vias and tracks values displayed in combo boxes of the auxiliary + * toolbar and some other parameters (netclass name ....) + * @param aNetClassName = the new netclass name + * @return true if lists of tracks and vias sizes are modified + */ bool BOARD::SetCurrentNetClass( const wxString& aNetClassName ) { NETCLASS* netClass = m_NetClasses.Find( aNetClassName ); @@ -296,6 +165,10 @@ bool BOARD::SetCurrentNetClass( const wxString& aNetClassName ) } +/** + * Function GetBiggestClearanceValue + * @return the biggest clearance value found in NetClasses list + */ int BOARD::GetBiggestClearanceValue() { int clearance = m_NetClasses.GetDefault()->GetClearance(); @@ -311,6 +184,11 @@ int BOARD::GetBiggestClearanceValue() } +/** + * Function GetCurrentMicroViaSize + * @return the current micro via size, + * that is the current netclass value + */ int BOARD::GetCurrentMicroViaSize() { NETCLASS* netclass = m_NetClasses.Find( m_CurrentNetClassName ); @@ -319,6 +197,11 @@ int BOARD::GetCurrentMicroViaSize() } +/** + * Function GetCurrentMicroViaDrill + * @return the current micro via drill, + * that is the current netclass value + */ int BOARD::GetCurrentMicroViaDrill() { NETCLASS* netclass = m_NetClasses.Find( m_CurrentNetClassName ); @@ -497,13 +380,11 @@ LAYER_T LAYER::ParseType( const char* aType ) return LAYER_T( -1 ); } - int BOARD::GetCopperLayerCount() const { return GetBoardDesignSettings()->GetCopperLayerCount(); } - void BOARD::SetCopperLayerCount( int aCount ) { GetBoardDesignSettings()->SetCopperLayerCount( aCount ); @@ -667,6 +548,13 @@ int BOARD::GetLayerColor( int aLayer ) } +/** + * Function IsModuleLayerVisible + * expects either of the two layers on which a module can reside, and returns + * whether that layer is visible. + * @param layer One of the two allowed layers for modules: LAYER_N_FRONT or LAYER_N_BACK + * @return bool - true if the layer is visible, else false. + */ bool BOARD::IsModuleLayerVisible( int layer ) { if( layer==LAYER_N_FRONT ) @@ -946,6 +834,23 @@ bool BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) } } + if( !hasItems && m_PcbFrame ) + { + if( m_PcbFrame->m_Draw_Sheet_Ref ) + { + area.SetOrigin( 0, 0 ); + area.SetEnd( m_PcbFrame->GetScreen()->ReturnPageSize().x, + m_PcbFrame->GetScreen()->ReturnPageSize().y ); + } + else + { + area.SetOrigin( -m_PcbFrame->GetScreen()->ReturnPageSize().x / 2, + -m_PcbFrame->GetScreen()->ReturnPageSize().y / 2 ); + area.SetEnd( m_PcbFrame->GetScreen()->ReturnPageSize().x / 2, + m_PcbFrame->GetScreen()->ReturnPageSize().y / 2 ); + } + } + m_BoundaryBox = area; return hasItems; @@ -953,6 +858,9 @@ bool BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) // virtual, see pcbstruct.h + +/* Display board statistics: pads, nets, connections.. count + */ void BOARD::DisplayInfo( EDA_DRAW_FRAME* frame ) { wxString txt; @@ -1266,6 +1174,12 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData, */ +/** + * Function FindNet + * searches for a net with the given netcode. + * @param aNetcode The netcode to search for. + * @return NETINFO_ITEM* - the net or NULL if not found. + */ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const { // the first valid netcode is 1 and the last is m_NetInfo->GetCount()-1. @@ -1288,6 +1202,12 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const } +/** + * Function FindNet overlaid + * searches for a net with the given name. + * @param aNetname A Netname to search for. + * @return NETINFO_ITEM* - the net or NULL if not found. + */ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const { // the first valid netcode is 1. @@ -1366,125 +1286,6 @@ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const } -TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, - PICKED_ITEMS_LIST* aItemsListPicker ) -{ - if( aSegment->m_Start == aPosition || aSegment->m_End == aPosition ) - return NULL; - - /* A via is a good lock point */ - if( aSegment->Type() == TYPE_VIA ) - { - aPosition = aSegment->m_Start; - return aSegment; - } - - /* Calculation coordinate of intermediate point relative to - * the start point of aSegment - */ - wxPoint delta = aSegment->m_End - aSegment->m_Start; - - // Not yet in use: -#if 0 - int ox, oy, fx, fy; - - if( aRefSegm ) - { - ox = aRefSegm->m_Start.x - aSegment->m_Start.x; - oy = aRefSegm->m_Start.y - aSegment->m_Start.y; - fx = aRefSegm->m_End.x - aSegment->m_Start.x; - fy = aRefSegm->m_End.y - aSegment->m_Start.y; - } -#endif - - // calculate coordinates of aPosition relative to aSegment->m_Start - wxPoint newPoint = aPosition - aSegment->m_Start; - - // newPoint must be on aSegment: - // Ensure newPoint.y/newPoint.y = delta.y/delta.x - if( delta.x == 0 ) - newPoint.x = 0; /* horizontal segment*/ - else - newPoint.y = wxRound(( (double)newPoint.x * delta.y ) / delta.x); - - /* Create the intermediate point (that is to say creation of a new - * segment, beginning at the intermediate point. - */ - newPoint.x += aSegment->m_Start.x; - newPoint.y += aSegment->m_Start.y; - - TRACK* newTrack = aSegment->Copy(); - - if( aItemsListPicker ) - { - ITEM_PICKER picker( newTrack, UR_NEW ); - aItemsListPicker->PushItem( picker ); - } - - - DLIST* list = (DLIST*)aSegment->GetList(); - wxASSERT( list ); - list->Insert( newTrack, aSegment->Next() ); - - if( aItemsListPicker ) - { - ITEM_PICKER picker( aSegment, UR_CHANGED ); - picker.m_Link = aSegment->Copy(); - aItemsListPicker->PushItem( picker ); - } - - /* Correct pointer at the end of the new segment. */ - newTrack->end = aSegment->end; - newTrack->SetState( END_ONPAD, aSegment->GetState( END_ONPAD ) ); - - /* Set connections info relative to the new point - */ - - /* Old segment now ends at new point. */ - aSegment->m_End = newPoint; - aSegment->end = newTrack; - aSegment->SetState( END_ONPAD, OFF ); - - /* The new segment begins at the new point. */ - newTrack->m_Start = newPoint; - newTrack->start = aSegment; - newTrack->SetState( BEGIN_ONPAD, OFF ); - - D_PAD * pad = GetPad( newTrack, START ); - - if ( pad ) - { - newTrack->start = pad; - newTrack->SetState( BEGIN_ONPAD, ON ); - aSegment->end = pad; - aSegment->SetState( END_ONPAD, ON ); - } - - aPosition = newPoint; - return newTrack; -} - - -BOARD_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, int aLayerMask ) -{ - for( MODULE* module = m_Modules; module; module = module->Next() ) - { - D_PAD* pad = module->GetPad( aPosition, aLayerMask ); - - if( pad ) - return pad; - } - - /* No pad has been located so check for a segment of the trace. */ - TRACK* trace = GetTraceByEndPoint( m_Track, NULL, aPosition, aLayerMask ); - - if( trace == NULL ) - trace = GetTrace( aPosition, aLayerMask ); - - return trace; -} - - MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const { struct FindModule : public INSPECTOR @@ -1519,185 +1320,20 @@ MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const } -MODULE* BOARD::GetModule( const wxPoint& aPosition, int aActiveLayer, - bool aVisibleOnly, bool aIgnoreLocked ) -{ - MODULE* pt_module; - MODULE* module = NULL; - MODULE* Altmodule = NULL; - int min_dim = 0x7FFFFFFF; - int alt_min_dim = 0x7FFFFFFF; - int layer; - - pt_module = m_Modules; - - for( ; pt_module; pt_module = (MODULE*) pt_module->Next() ) - { - // is the ref point within the module's bounds? - if( !pt_module->HitTest( aPosition ) ) - continue; - - // if caller wants to ignore locked modules, and this one is locked, skip it. - if( aIgnoreLocked && pt_module->IsLocked() ) - continue; - - /* Calculate priority: the priority is given to the layer of the - * module and the copper layer if the module layer is indelible, - * adhesive copper, a layer if cmp module layer is indelible, - * adhesive component. - */ - layer = pt_module->GetLayer(); - - if( layer==ADHESIVE_N_BACK || layer==SILKSCREEN_N_BACK ) - layer = LAYER_N_BACK; - else if( layer==ADHESIVE_N_FRONT || layer==SILKSCREEN_N_FRONT ) - layer = LAYER_N_FRONT; - - /* Test of minimum size to choosing the best candidate. */ - - EDA_RECT bb = pt_module->GetFootPrintRect(); - int offx = bb.GetX() + bb.GetWidth() / 2; - int offy = bb.GetY() + bb.GetHeight() / 2; - - //off x & offy point to the middle of the box. - int dist = abs( aPosition.x - offx ) + abs( aPosition.y - offy ); - - //int dist = MIN(lx, ly); // to pick the smallest module (kinda - // screwy with same-sized modules -- this is bad!) - - if( aActiveLayer == layer ) - { - if( dist <= min_dim ) - { - /* better footprint shown on the active layer */ - module = pt_module; - min_dim = dist; - } - } - else if( aVisibleOnly && IsModuleLayerVisible( layer ) ) - { - if( dist <= alt_min_dim ) - { - /* better footprint shown on other layers */ - Altmodule = pt_module; - alt_min_dim = dist; - } - } - } - - if( module ) - { - return module; - } - - if( Altmodule ) - { - return Altmodule; - } - - return NULL; -} - - -TRACK* BOARD::GetTrace( const wxPoint& aPosition, int aLayer ) -{ - return m_Track->GetTrace( aPosition, aLayer ); -} - - -TRACK* BOARD::GetVia( const wxPoint& aPosition, int aLayer ) -{ - TRACK* track; - - for( track = m_Track; track; track = track->Next() ) - { - if( track->Type() != TYPE_VIA - || track->m_Start != aPosition - || track->GetState( BUSY | IS_DELETED ) ) - continue; - - if( aLayer < 0 || track->IsOnLayer( aLayer ) ) - break; - } - - return track; -} - - -D_PAD* BOARD::GetPad( TRACK* aTrace, int aEnd ) -{ - D_PAD* pad = NULL; - wxPoint pos; - - int aLayerMask = g_TabOneLayerMask[ aTrace->GetLayer() ]; - - if( aEnd == START ) - { - pos = aTrace->m_Start; - } - else - { - pos = aTrace->m_End; - } - - for( MODULE* module = m_Modules; module; module = module->Next() ) - { - pad = module->GetPad( pos, aLayerMask ); - - if( pad != NULL ) - break; - } - - return pad; -} - - -D_PAD* BOARD::GetPad( const wxPoint& aPosition, int aLayerMask ) -{ - D_PAD* pad = NULL; - - for( MODULE* module = m_Modules; module && ( pad == NULL ); module = module->Next() ) - { - pad = module->GetPad( aPosition, aLayerMask ); - } - - return pad; -} - - -D_PAD* BOARD::GetPadFast( const wxPoint& aPosition, int aLayerMask ) -{ - for( unsigned i=0; iGetPad(i); - - if( pad->m_Pos != aPosition ) - continue; - - /* Pad found, it must be on the correct layer */ - if( pad->m_layerMask & aLayerMask ) - return pad; - } - - return NULL; -} - - -void BOARD::CreateSortedPadListByXCoord( std::vector* aVector ) -{ - aVector->insert( aVector->end(), m_NetInfo->m_PadsFullList.begin(), - m_NetInfo->m_PadsFullList.end() ); - - qsort( &(*aVector)[0], GetPadsCount(), sizeof( D_PAD*), SortPadsByXCoord ); -} - - +// Sort nets by decreasing pad count static bool s_SortByNodes( const NETINFO_ITEM* a, const NETINFO_ITEM* b ) { return b->GetNodesCount() < a->GetNodesCount(); } +/** + * Function ReturnSortedNetnamesList + * @param aNames An array string to fill with net names. + * @param aSortbyPadsCount : true = sort by active pads count, false = no sort + * (i.e. leave the sort by net names) + * @return int - net names count. + */ int BOARD::ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount ) { if( m_NetInfo->GetCount() == 0 ) @@ -1803,6 +1439,10 @@ out: } +/* + * Function RedrawAreasOutlines + * Redraw all areas outlines on layer aLayer ( redraw all if aLayer < 0 ) + */ void BOARD::RedrawAreasOutlines( EDA_DRAW_PANEL* panel, wxDC* aDC, int aDrawMode, int aLayer ) { if( !aDC ) @@ -1818,6 +1458,10 @@ void BOARD::RedrawAreasOutlines( EDA_DRAW_PANEL* panel, wxDC* aDC, int aDrawMode } +/** + * Function RedrawFilledAreas + * Redraw all areas outlines on layer aLayer ( redraw all if aLayer < 0 ) + */ void BOARD::RedrawFilledAreas( EDA_DRAW_PANEL* panel, wxDC* aDC, int aDrawMode, int aLayer ) { if( !aDC ) @@ -1833,6 +1477,18 @@ void BOARD::RedrawFilledAreas( EDA_DRAW_PANEL* panel, wxDC* aDC, int aDrawMode, } +/** + * Function HitTestForAnyFilledArea + * tests if the given wxPoint is within the bounds of a filled area of this + * zone. + * the test is made on zones on layer from aStartLayer to aEndLayer + * Note: if a zone has its flag BUSY (in .m_State) is set, it is ignored. + * @param aRefPos A wxPoint to test + * @param aStartLayer the first layer to test + * @param aEndLayer the last layer (-1 to ignore it) to test + * @return ZONE_CONTAINER* return a pointer to the ZONE_CONTAINER found, else + * NULL + */ ZONE_CONTAINER* BOARD::HitTestForAnyFilledArea( const wxPoint& aRefPos, int aStartLayer, int aEndLayer ) @@ -1863,6 +1519,19 @@ ZONE_CONTAINER* BOARD::HitTestForAnyFilledArea( const wxPoint& aRefPos, } +/** + * Function SetAreasNetCodesFromNetNames + * Set the .m_NetCode member of all copper areas, according to the area Net + * Name + * The SetNetCodesFromNetNames is an equivalent to net name, for fast + * comparisons. + * However the Netcode is an arbitrary equivalence, it must be set after each + * netlist read + * or net change + * Must be called after pad netcodes are calculated + * @return : error count + * For non copper areas, netcode is set to 0 + */ int BOARD::SetAreasNetCodesFromNetNames( void ) { int error_count = 0; @@ -1896,248 +1565,15 @@ int BOARD::SetAreasNetCodesFromNetNames( void ) } -TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount, int* aLength, int* aLengthDie, bool aReorder ) -{ - wxCHECK( aTrace != NULL, NULL ); - - int NbSegmBusy; - - TRACK_PTRS trackList; - - if( aCount ) - *aCount = 0; - - if( aLength ) - *aLength = 0; - - // Ensure the flag BUSY of all tracks of the board is cleared - // because we use it to mark segments of the track - for( TRACK* track = m_Track; track; track = track->Next() ) - track->SetState( BUSY, OFF ); - - /* Set flags of the initial track segment */ - aTrace->SetState( BUSY, ON ); - int layerMask = aTrace->ReturnMaskLayer(); - - trackList.push_back( aTrace ); - - /* Examine the initial track segment : if it is really a segment, this is - * easy. - * If it is a via, one must search for connected segments. - * If <=2, this via connect 2 segments (or is connected to only one - * segment) and this via and these 2 segments are a part of a track. - * If > 2 only this via is flagged (the track has only this via) - */ - if( aTrace->Type() == TYPE_VIA ) - { - TRACK* Segm1, * Segm2 = NULL, * Segm3 = NULL; - Segm1 = GetTraceByEndPoint( m_Track, NULL, aTrace->m_Start, layerMask ); - - if( Segm1 ) - { - Segm2 = GetTraceByEndPoint( Segm1->Next(), NULL, aTrace->m_Start, layerMask ); - } - - if( Segm2 ) - { - Segm3 = GetTraceByEndPoint( Segm2->Next(), NULL, aTrace->m_Start, layerMask ); - } - - if( Segm3 ) // More than 2 segments are connected to this via. the track" is only this via - { - if( aCount ) - *aCount = 1; - - return aTrace; - } - - if( Segm1 ) // search for others segments connected to the initial segment start point - { - layerMask = Segm1->ReturnMaskLayer(); - chainMarkedSegments( aTrace->m_Start, layerMask, &trackList ); - } - - if( Segm2 ) // search for others segments connected to the initial segment end point - { - layerMask = Segm2->ReturnMaskLayer(); - chainMarkedSegments( aTrace->m_Start, layerMask, &trackList ); - } - } - else // mark the chain using both ends of the initial segment - { - chainMarkedSegments( aTrace->m_Start, layerMask, &trackList ); - chainMarkedSegments( aTrace->m_End, layerMask, &trackList ); - } - - // Now examine selected vias and flag them if they are on the track - // If a via is connected to only one or 2 segments, it is flagged (is on - // the track) - // If a via is connected to more than 2 segments, it is a track end, and it - // is removed from the list - // go through the list backwards. - for( int i = trackList.size() - 1; i>=0; --i ) - { - TRACK* via = trackList[i]; - - if( via->Type() != TYPE_VIA ) - continue; - - if( via == aTrace ) - continue; - - via->SetState( BUSY, ON ); // Try to flag it. the flag will be cleared later if needed - - layerMask = via->ReturnMaskLayer(); - - TRACK* track = GetTraceByEndPoint( m_Track, NULL, via->m_Start, layerMask ); - - // GetTrace does not consider tracks flagged BUSY. - // So if no connected track found, this via is on the current track - // only: keep it - if( track == NULL ) - continue; - - /* If a track is found, this via connects also others segments of an - * other track. This case happens when the vias ends the selected - * track but must we consider this via is on the selected track, or - * on an other track. - * (this is important when selecting a track for deletion: must this - * via be deleted or not?) - * We consider here this via on the track if others segment connected - * to this via remain connected when removing this via. - * We search for all others segment connected together: - * if there are on the same layer, the via is on the selected track - * if there are on different layers, the via is on an other track - */ - int layer = track->GetLayer(); - - while( ( track = GetTraceByEndPoint( track->Next(), NULL, - via->m_Start, layerMask ) ) != NULL ) - { - if( layer != track->GetLayer() ) - { - // The via connects segments of an other track: it is removed - // from list because it is member of an other track - via->SetState( BUSY, OFF ); - break; - } - } - } - - /* Rearrange the track list in order to have flagged segments linked - * from firstTrack so the NbSegmBusy segments are consecutive segments - * in list, the first item in the full track list is firstTrack, and - * the NbSegmBusy-1 next items (NbSegmBusy when including firstTrack) - * are the flagged segments - */ - NbSegmBusy = 0; - TRACK* firstTrack; - - for( firstTrack = m_Track; firstTrack; firstTrack = firstTrack->Next() ) - { - // Search for the first flagged BUSY segments - if( firstTrack->GetState( BUSY ) ) - { - NbSegmBusy = 1; - break; - } - } - - if( firstTrack == NULL ) - return NULL; - - double full_len = 0; - double lenDie = 0; - - if( aReorder ) - { - DLIST* list = (DLIST*)firstTrack->GetList(); - wxASSERT( list ); - - /* Rearrange the chain starting at firstTrack - * All others flagged items are moved from their position to the end - * of the flagged list - */ - TRACK* next; - - for( TRACK* track = firstTrack->Next(); track; track = next ) - { - next = track->Next(); - - if( track->GetState( BUSY ) ) // move it! - { - NbSegmBusy++; - track->UnLink(); - list->Insert( track, firstTrack->Next() ); - - if( aLength ) - full_len += track->GetLength(); - - if( aLengthDie ) // Add now length die. - { - // In fact only 2 pads (maximum) will be taken in account: - // that are on each end of the track, if any - if( track->GetState( BEGIN_ONPAD ) ) - { - D_PAD * pad = (D_PAD *) track->start; - lenDie += (double) pad->m_LengthDie; - } - - if( track->GetState( END_ONPAD ) ) - { - D_PAD * pad = (D_PAD *) track->end; - lenDie += (double) pad->m_LengthDie; - } - } - } - } - } - else if( aLength ) - { - NbSegmBusy = 0; - - for( TRACK* track = firstTrack; track; track = track->Next() ) - { - if( track->GetState( BUSY ) ) - { - NbSegmBusy++; - track->SetState( BUSY, OFF ); - full_len += track->GetLength(); - - // Add now length die. - // In fact only 2 pads (maximum) will be taken in account: - // that are on each end of the track, if any - if( track->GetState( BEGIN_ONPAD ) ) - { - D_PAD * pad = (D_PAD *) track->start; - lenDie += (double) pad->m_LengthDie; - } - - if( track->GetState( END_ONPAD ) ) - { - D_PAD * pad = (D_PAD *) track->end; - lenDie += (double) pad->m_LengthDie; - } - } - } - } - - if( aLength ) - *aLength = wxRound( full_len ); - - if( aLengthDie ) - *aLengthDie = wxRound( lenDie ); - - if( aCount ) - *aCount = NbSegmBusy; - - return firstTrack; -} - - #if defined(DEBUG) - +/** + * Function Show + * is used to output the object tree, currently for debugging only. + * @param nestLevel An aid to prettier tree indenting, and is the level + * of nesting of this object within the overall tree. + * @param os The ostream& to output to. + */ void BOARD::Show( int nestLevel, std::ostream& os ) { BOARD_ITEM* p; diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index e4f0ed9dfe..6bcbf40485 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -1,7 +1,6 @@ -/** - * @file class_board.h - * @brief Class BOARD to handle a board - */ +/*************************************************/ +/* class_board.h - Class BOARD to handle a board */ +/*************************************************/ #ifndef CLASS_BOARD_H #define CLASS_BOARD_H @@ -13,29 +12,8 @@ class ZONE_CONTAINER; -class TRACK; -#define HISTORY_MAX_COUNT 8 - -// Used to buffer item candidates when search for items on the same track -typedef std::vector TRACK_PTRS; - - -/** - * Function GetTraceByEndPoint - * returns a trace starting at \a aStartTrace and ending at \a aEndTrace that has an - * end point at \a aPosition on \a aLayerMask. - * - * @param aStartTrace Pointer to the TRACK object to begin the search. - * @param aEndTrace Pointer to the TRACK object to end then search. - * @param aPosition The wxPoint to check the trace end points against. - * @param aLayerMask The layer or layers to search. - * @return A pointer to the TRACK or SEGVIA object if found, else NULL. - */ -TRACK* GetTraceByEndPoint( TRACK* aStartTrace, TRACK* aEndTrace, - const wxPoint& aPosition, int aLayerMask ); - /** * Enum LAYER_T * gives the allowed types of layers, same as Specctra DSN spec. @@ -63,6 +41,7 @@ struct LAYER // int m_Color; // bool m_Visible; // ? use flags in m_Color instead ? + /** * Function ShowType * converts a LAYER_T enum to a const char* @@ -99,7 +78,8 @@ public: bool operator ==( const VIA_DIMENSION& other ) const { - return (m_Diameter == other.m_Diameter) && (m_Drill == other.m_Drill); + return (m_Diameter == other.m_Diameter) + && (m_Drill == other.m_Drill); } @@ -107,17 +87,14 @@ public: { if( m_Diameter != other.m_Diameter ) return m_Diameter < other.m_Diameter; - return m_Drill < other.m_Drill; } }; - // Helper class to handle hight light nets class HIGHT_LIGHT_INFO { friend class BOARD; - protected: int m_netCode; // net selected for hightlight (-1 when no net selected ) bool m_hightLightOn; // hightlight active @@ -135,52 +112,51 @@ protected: } }; - /** * Class BOARD * holds information pertinent to a PCBNEW printed circuit board. */ +#define HISTORY_MAX_COUNT 8 class BOARD : public BOARD_ITEM { friend class PCB_EDIT_FRAME; private: - typedef std::vector MARKERS; // @todo: switch to boost:ptr_vector, and change ~BOARD() - - MARKERS m_markers; ///< MARKER_PCBs for clearance problems, owned by pointer + typedef std::vector MARKERS; // @todo: switch to boost:ptr_vector, and change ~BOARD() + MARKERS m_markers; ///< MARKER_PCBs for clearance problems, owned by pointer typedef std::vector ZONE_CONTAINERS; // @todo: switch to boost::ptr_vector, and change ~BOARD() + ZONE_CONTAINERS m_ZoneDescriptorList; ///< edge zone descriptors, owned by pointer - ZONE_CONTAINERS m_ZoneDescriptorList; ///< edge zone descriptors, owned by pointer - - LAYER m_Layer[NB_COPPER_LAYERS]; - // if true m_hightLight_NetCode is used - HIGHT_LIGHT_INFO m_hightLight; // current hight light data - HIGHT_LIGHT_INFO m_hightLightPrevious; // a previously stored hight light data + LAYER m_Layer[NB_COPPER_LAYERS]; + // if true m_hightLight_NetCode is used + HIGHT_LIGHT_INFO m_hightLight; // current hight light data + HIGHT_LIGHT_INFO m_hightLightPrevious; // a previously stored hight light data public: - EDA_RECT m_BoundaryBox; // Board size and position - int m_Status_Pcb; // Flags used in ratsnet calculation and update - int m_NbNodes; // Active pads (pads attached to a net ) count - int m_NbNoconnect; // Active ratsnet count (rastnests not already connected by tracks) + PCB_BASE_FRAME* m_PcbFrame; // Window of visualization + EDA_RECT m_BoundaryBox; // Board size and position + int m_Status_Pcb; // Flags used in ratsnet calculation and update + int m_NbNodes; // Active pads (pads attached to a net ) count + int m_NbNoconnect; // Active ratsnet count (rastnests not already connected by tracks) - DLIST m_Drawings; // linked list of lines & texts - DLIST m_Modules; // linked list of MODULEs - DLIST m_Track; // linked list of TRACKs and SEGVIAs - DLIST m_Zone; // linked list of SEGZONEs + DLIST m_Drawings; // linked list of lines & texts + DLIST m_Modules; // linked list of MODULEs + DLIST m_Track; // linked list of TRACKs and SEGVIAs + DLIST m_Zone; // linked list of SEGZONEs - NETINFO_LIST* m_NetInfo; // nets info list (name, design constraints .. + NETINFO_LIST* m_NetInfo; // nets info list (name, design constraints .. - std::vector m_FullRatsnest; // Ratsnest list for the BOARD - std::vector m_LocalRatsnest; /* Ratsnest list relative to a given footprint - * (used while moving a footprint) */ + std::vector m_FullRatsnest; // Rastnest list for the BOARD + std::vector m_LocalRatsnest; /* Rastnest list relative to a given footprint + * (used while moving a footprint) */ - ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress + ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress - NETCLASSES m_NetClasses; ///< List of current netclasses. There is always the default netclass - wxString m_CurrentNetClassName; /* Current net class name used to display netclass info. - * this is also the last used netclass after starting a track - */ + NETCLASSES m_NetClasses; ///< List of current netclasses. There is always the default netclass + wxString m_CurrentNetClassName; /* Current net class name used to display netclass info. + * this is also the last used netclass after starting a track + */ // handling of vias and tracks size: @@ -191,7 +167,6 @@ public: std::vector m_TrackWidthList; // tracks widths (max count = HISTORY_MAX_COUNT) // The first value is the current netclass track width unsigned m_ViaSizeSelector; // index for m_ViaSizeList to select the value - // 0 is the index selection of the default value Netclass unsigned m_TrackWidthSelector; // index for m_TrackWidthList to select the value @@ -199,25 +174,9 @@ private: BOARD_DESIGN_SETTINGS* m_boardDesignSettings; // Link to current design settings COLORS_DESIGN_SETTINGS* m_colorsSettings; // Link to current colors settings - /** - * Function chainMarkedSegments - * add all trace segments to \a aList attached to a trace found at \a aPosition on - * \a aLayerMask. - *

- * The BUSY flag of all connected segments is set. Vias are also put in list but - * their flags BUSY is not set. - *

- * @param aPosition A wxPoint object contatining thhe reference coordinate of the - * to search. - * @param aLayerMask The allowed layers for segments to search (1 layer when starting - * point is on a segment, but more than one when starting point is - * on a via) - * @param aList The track list to fill with flagged segments. - */ - void chainMarkedSegments( wxPoint& aPosition, int aLayerMask, TRACK_PTRS* aList ); - + /**********************************/ public: - BOARD( EDA_ITEM* aParent ); + BOARD( EDA_ITEM* aParent, PCB_BASE_FRAME* frame ); ~BOARD(); /** @@ -248,7 +207,7 @@ public: * @param aBoardItem The item to add to this board. * @param aControl An int which can vary how the item is added. */ - void Add( BOARD_ITEM* aBoardItem, int aControl = 0 ); + void Add( BOARD_ITEM* aBoardItem, int aControl = 0 ); #define ADD_APPEND 1 ///< aControl flag for Add( aControl ), appends not inserts @@ -258,10 +217,9 @@ public: * removes the given single item from this BOARD and deletes its memory. * @param aBoardItem The item to remove from this board and delete */ - void Delete( BOARD_ITEM* aBoardItem ) + void Delete( BOARD_ITEM* aBoardItem ) { - wxASSERT( aBoardItem ); // developers should run DEBUG versions and fix calls with NULL - + wxASSERT( aBoardItem ); // developers should run DEBUG versions and fix such calls with NULL if( aBoardItem ) delete Remove( aBoardItem ); } @@ -269,7 +227,8 @@ public: /** * Function Remove - * removes \a aBoardItem from this BOARD and returns it to caller without deleting it. + * removes \a aBoardItem from this BOARD and returns it to caller without + * deleting it. * @param aBoardItem The item to remove from this board. * @return BOARD_ITEM* \a aBoardItem which was passed in. */ @@ -280,13 +239,14 @@ public: * Function DeleteMARKERs * deletes ALL MARKERS from the board. */ - void DeleteMARKERs(); + void DeleteMARKERs(); /** * Function DeleteZONEOutlines * deletes ALL zone outlines from the board. */ - void DeleteZONEOutlines(); + void DeleteZONEOutlines(); + /** * Function GetMARKER @@ -298,7 +258,6 @@ public: { if( (unsigned) index < m_markers.size() ) return m_markers[index]; - return NULL; } @@ -374,7 +333,7 @@ public: * Function GetCopperLayerCount * @return int - The number of copper layers in the BOARD. */ - int GetCopperLayerCount() const; + int GetCopperLayerCount() const; void SetCopperLayerCount( int aCount ); @@ -385,7 +344,7 @@ public: * Returns a bit-mask of all the layers that are enabled * @return int - the enabled layers in bit-mapped form. */ - int GetEnabledLayers() const; + int GetEnabledLayers() const; /** * Function SetEnabledLayers @@ -425,7 +384,7 @@ public: * Returns a bit-mask of all the layers that are visible * @return int - the visible layers in bit-mapped form. */ - int GetVisibleLayers() const; + int GetVisibleLayers() const; /** * Function SetVisibleLayers @@ -445,7 +404,7 @@ public: * @return int - the visible element bitmap or-ed from enum PCB_VISIBLE * @see enum PCB_VISIBLE */ - int GetVisibleElements() const; + int GetVisibleElements() const; /** * Function SetVisibleElements @@ -496,10 +455,10 @@ public: * returns the color of a pcb visible element. * @see enum PCB_VISIBLE */ - int GetVisibleElementColor( int aPCB_VISIBLE ); - + int GetVisibleElementColor( int aPCB_VISIBLE ); void SetVisibleElementColor( int aPCB_VISIBLE, int aColor ); + /** * Function GetBoardDesignSettings * @return the current BOARD_DESIGN_SETTINGS in use @@ -556,7 +515,7 @@ public: * @return bool - true if aLayerName was legal and unique amoung other * layer names at other layer indices and aLayerIndex was within range, else false. */ - bool SetLayerName( int aLayerIndex, const wxString& aLayerName ); + bool SetLayerName( int aLayerIndex, const wxString& aLayerName ); /** * Function GetLayerType @@ -566,7 +525,7 @@ public: * @return LAYER_T - the layer type, or LAYER_T(-1) if the * index was out of range. */ - LAYER_T GetLayerType( int aLayerIndex ) const; + LAYER_T GetLayerType( int aLayerIndex ) const; /** * Function SetLayerType @@ -576,32 +535,30 @@ public: * @param aLayerType The new layer type. * @return bool - true if aLayerType was legal and aLayerIndex was within range, else false. */ - bool SetLayerType( int aLayerIndex, LAYER_T aLayerType ); + bool SetLayerType( int aLayerIndex, LAYER_T aLayerType ); /** * Function SetLayerColor * changes a layer color for any valid layer, including non-copper ones. */ - void SetLayerColor( int aLayer, int aColor ); + void SetLayerColor( int aLayer, int aColor ); /** * Function GetLayerColor * gets a layer color for any valid layer, including non-copper ones. */ - int GetLayerColor( int aLayer ); + int GetLayerColor( int aLayer ); /* Functions to get some items count */ - int GetNumSegmTrack(); - - int GetNumSegmZone(); - + int GetNumSegmTrack(); + int GetNumSegmZone(); unsigned GetNoconnectCount(); // Return the number of missing links. /** * Function GetNumRatsnests * @return int - The number of rats */ - unsigned GetRatsnestsCount() + unsigned GetRatsnestsCount() { return m_FullRatsnest.size(); } @@ -617,7 +574,7 @@ public: * Function GetPadsCount * @return the number of pads in board */ - unsigned GetPadsCount() + unsigned GetPadsCount() { return m_NetInfo->GetPadsCount(); } @@ -628,7 +585,7 @@ public: * @param aBoardEdgesOnly is true if we are interested in board edge segments only. * @return bool - True if items (or board edge segments) were found. */ - bool ComputeBoundingBox( bool aBoardEdgesOnly = false ); + bool ComputeBoundingBox( bool aBoardEdgesOnly = false ); /** * Function DisplayInfo @@ -637,7 +594,7 @@ public: * Is virtual from EDA_ITEM. * @param frame A EDA_DRAW_FRAME in which to print status information. */ - void DisplayInfo( EDA_DRAW_FRAME* frame ); + void DisplayInfo( EDA_DRAW_FRAME* frame ); /** * Function Draw. @@ -647,8 +604,8 @@ public: * @param aDrawMode = GR_COPY, GR_OR ... (not always used) * @param aOffset = an draw offset value (default = 0,0) */ - void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, - int aDrawMode, const wxPoint& aOffset = ZeroOffset ); + void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, + int aDrawMode, const wxPoint& aOffset = ZeroOffset ); /** * Function DrawHighLight @@ -659,7 +616,7 @@ public: * @param aDC = the curent device context * @param aNetCode is the net number to highlight or to dim. */ - void DrawHighLight( EDA_DRAW_PANEL* aDrawPanel, wxDC* aDC, int aNetCode ); + void DrawHighLight( EDA_DRAW_PANEL* aDrawPanel, wxDC* aDC, int aNetCode ); /** * Function Visit @@ -694,36 +651,6 @@ public: */ NETINFO_ITEM* FindNet( const wxString& aNetname ) const; - /** - * Function CreateLockPoint - * creates an intermediate point on \a aSegment - * aSegm segment is broken into 2 segments connecting point pX, pY - * After insertion: - * The new segment starts from to new point, and ends to initial aSegm ending point - * the old segment aSegm ends to new point - * Returns: - * NULL if no new point (ie if aRefPoint already corresponded at one end of aSegm - * or - * Pointer to the segment created - * Returns the exact value of aRefPoint - * If aSegm points to a via: - * Returns the exact value of aRefPoint and a pointer to the via, - * But does not create extra point - */ - TRACK* CreateLockPoint( wxPoint& aRefPoint, TRACK* aSegment, - PICKED_ITEMS_LIST* aItemsListPicker ); - - - /** - * Function GetLockPoint - * returns the object at the end of a trace locacted at \a aPosition on \a aLayer. - * - * @param aPosition A wxPoint object containing the position to hit test. - * @param aLayerMask A layer or layers to mask the hit test. - * @return A pointer to the board item if found or NULL if not found. - */ - BOARD_ITEM* GetLockPoint( const wxPoint& aPosition, int aLayerMask ); - /** * Function FindModuleByReference * searches for a MODULE within this board with the given @@ -733,95 +660,15 @@ public: * @return MODULE* - If found, the MODULE having the given reference * designator, else NULL. */ - MODULE* FindModuleByReference( const wxString& aReference ) const; - - /** - * Function Locate_Prefered_Module - * locates a footprint at \a aPosition on \a aActiveLayer. - *

- * If several footprints are are at \a aPosition, then the priority is the closest on the - * active layer, then closest to \a aPosition. The distance is calculatedvia manhattan - * distance from the center of the bounding rectangle to \a aposition. - *

- * @param aPosition A wxPoint object containing the position to hit test. - * @param aActiveLayer The layer to test. - * @param aVisibleOnly Search only the visible layers if true. - * @param aIgnoreLocked Ignore locked modules when true. - * @return MODULE* The best module or NULL if none. - */ - MODULE* GetModule( const wxPoint& aPosition, int aActiveLayer, - bool aVisibleOnly, bool aIgnoreLocked = false ); - - /** - * Function GetTrace - * returns a trace segment or via at \a aPosition on \a aLayer. - * - * @param aPosition The wxPoint to HitTest() against. - * @param aLayer The layer to search. Use -1 for a don't care. - * @return A pointer to the TRACK or SEGVIA object if found, else NULL. - */ - TRACK* GetTrace( const wxPoint& aPosition, int aLayer ); - - /** - * Function GetVia - * finds the first via at \a aPosition on \a aLayer. - * @param aPosition The wxPoint to HitTest() against. - * @param aLayer The layer to search. Use -1 for a don't care. - * @return TRACK* A point a to the SEGVIA object if found, else NULL. - */ - TRACK* GetVia( const wxPoint& aPosition, int aLayer = -1 ); - - /** - * Function GetPad - * returns the pad connected to the beginning or end of \a aTrace at \a aEnd - * - * @param aTrace A pointer to the trace to test for a pad connection. - * @param aEnd The end point of \a aTrace to test for a pad connection. - * @return A pointer to a D_PAD object if connection found or NULL if not found. - */ - D_PAD* GetPad( TRACK* aTrace, int aEnd ); - - /** - * Function GetPad - * finds a pad \a aPosition on \a aLayer. - * - * @param aPosition A wxPoint object containing the position to hit test. - * @param aLayerMask A layer or layers to mask the hit test. - * @return A pointer to a D_PAD object if found or NULL if not found. - */ - D_PAD* GetPad( const wxPoint& aPosition, int aLayerMask = ALL_LAYERS ); - - /** - * Function GetPadFast - * return pad found at \a aPosition on \a aLayer uning the fast search method. - *

- * The fast search method only works if the pad list has already exists. - *

- * @param aPosition A wxPoint object containing the position to hit test. - * @param aLayer A layer or layers to mask the hit test. - * @return A pointer to a D_PAD object if found or NULL if not found. - */ - D_PAD* GetPadFast( const wxPoint& aPosition, int aLayer ); + MODULE* FindModuleByReference( const wxString& aReference ) const; /** * Function ReturnSortedNetnamesList * @param aNames An array string to fill with net names. - * @param aSortbyPadsCount : true = sort by active pads count, false = no sort (i.e. - * leave the sort by net names) + * @param aSortbyPadsCount : true = sort by active pads count, false = no sort (i.e. leave the sort by net names) * @return int - net names count. */ - int ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount ); - - /** - * Function CreateSortedPadListByXCoord - * clears then fills \a aVector with all pads on the board and sorts them by - * increasing x coordinate. - * - * @note Do not delete any pointers in \a aVector. The pointers are only references to - * pads which are owned by the BOARD. - * @param aVector Where to put the pad pointers. - */ - void CreateSortedPadListByXCoord( std::vector* aVector ); + int ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount ); /**************************************/ /** @@ -831,9 +678,9 @@ public: /** * Function SynchronizeNetsAndNetClasses * copies NETCLASS info to each NET, based on NET membership in a NETCLASS. - * Must be called after a Design Rules edition, or after reading a netlist (or editing - * the list of nets). Also this function removes the non existing nets in netclasses - * and add net nets in default netclass (this happens after reading a netlist) + * Must be called after a Design Rules edition, or after reading a netlist (or editing the list of nets) + * Also this function removes the non existing nets in netclasses and add net nets in default netclass + * (this happens after reading a netlist) */ void SynchronizeNetsAndNetClasses(); @@ -859,7 +706,7 @@ public: * ( using the default netclass value or a preset value ) * the default netclass is always in m_TrackWidthList[0] */ - int GetCurrentTrackWidth() + int GetCurrentTrackWidth() { return m_TrackWidthList[m_TrackWidthSelector]; } @@ -871,7 +718,7 @@ public: * ( using the default netclass value or a preset value ) * the default netclass is always in m_TrackWidthList[0] */ - int GetCurrentViaSize() + int GetCurrentViaSize() { return m_ViasDimensionsList[m_ViaSizeSelector].m_Diameter; } @@ -895,14 +742,14 @@ public: * @return the current micro via size, * that is the current netclass value */ - int GetCurrentMicroViaSize(); + int GetCurrentMicroViaSize(); /** * Function GetCurrentMicroViaDrill * @return the current micro via drill, * that is the current netclass value */ - int GetCurrentMicroViaDrill(); + int GetCurrentMicroViaDrill(); /***************************************************************************/ @@ -914,6 +761,7 @@ public: */ bool Save( FILE* aFile ) const; + /** * Function GetClass * returns the class name. @@ -961,10 +809,10 @@ public: * Function RedrawAreasOutlines * Redraw all areas outlines on layer aLayer ( redraw all if aLayer < 0 ) */ - void RedrawAreasOutlines( EDA_DRAW_PANEL* aPanel, - wxDC* aDC, - int aDrawMode, - int aLayer ); + void RedrawAreasOutlines( EDA_DRAW_PANEL* aPanel, + wxDC* aDC, + int aDrawMode, + int aLayer ); /** * Function RedrawFilledAreas @@ -1058,7 +906,7 @@ public: * @param style = style of last corner * @return 1 if Ok, 0 if area removed */ - int CompleteArea( ZONE_CONTAINER* area_to_complete, int style ); + int CompleteArea( ZONE_CONTAINER* area_to_complete, int style ); /** * Function TestAreaPolygon @@ -1071,7 +919,7 @@ public: * 1 if intersecting sides, but no intersecting arcs * Also sets utility2 flag of area with return value */ - int TestAreaPolygon( ZONE_CONTAINER* CurrArea ); + int TestAreaPolygon( ZONE_CONTAINER* CurrArea ); /** * Function ClipAreaPolygon @@ -1089,11 +937,11 @@ public: * 1 if intersecting sides * Also sets areas->utility1 flags if areas are modified */ - int ClipAreaPolygon( PICKED_ITEMS_LIST* aNewZonesList, - ZONE_CONTAINER* aCurrArea, - bool bMessageBoxArc, - bool bMessageBoxInt, - bool bRetainArcs = true ); + int ClipAreaPolygon( PICKED_ITEMS_LIST* aNewZonesList, + ZONE_CONTAINER* aCurrArea, + bool bMessageBoxArc, + bool bMessageBoxInt, + bool bRetainArcs = true ); /** * Process an area that has been modified, by clipping its polygon against @@ -1117,8 +965,8 @@ public: /** * Function CombineAllAreasInNet * Checks all copper areas in net for intersections, combining them if found - * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in - * undo commands can be NULL + * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands + * can be NULL * @param aNetCode = net to consider * @param bMessageBox : if true display warning message box * @param bUseUtility : if true, don't check areas if both utility flags are 0 @@ -1133,8 +981,8 @@ public: /** * Function RemoveArea * remove copper area from net, and put it in a deleted list (if exists) - * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in - * undo commands can be NULL + * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands + * can be NULL * @param area_to_remove = area to delete or put in deleted list */ void RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove ); @@ -1156,13 +1004,13 @@ public: * 1 if intersection * 2 if arcs intersect */ - int TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test ); + int TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test ); /** * Function CombineAreas * If possible, combine 2 copper areas - * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in - * undo commands can be NULL + * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands + * can be NULL * @param area_ref = the main area (zone) * @param area_to_combine = the zone that can be merged with area_ref * area_ref must be BEFORE area_to_combine @@ -1171,9 +1019,9 @@ public: * 1 if intersection * 2 if arcs intersect */ - int CombineAreas( PICKED_ITEMS_LIST* aDeletedList, - ZONE_CONTAINER* area_ref, - ZONE_CONTAINER* area_to_combine ); + int CombineAreas( PICKED_ITEMS_LIST* aDeletedList, + ZONE_CONTAINER* area_ref, + ZONE_CONTAINER* area_to_combine ); /** * Function Test_Drc_Areas_Outlines_To_Areas_Outlines @@ -1186,8 +1034,8 @@ public: * @param aCreate_Markers: if true create DRC markers. False: do not creates anything * @return errors count */ - int Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine, - bool aCreate_Markers ); + int Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine, + bool aCreate_Markers ); /****** function relative to ratsnest calculations: */ @@ -1197,29 +1045,6 @@ public: * @param aNetcode = netcode to analyze. if -1, analyze all nets */ void Test_Connections_To_Copper_Areas( int aNetcode = -1 ); - - /** - * Function MarkTrace - * marks a chain of track segments connected to aTrace. - * Each segment is marked by setting the BUSY bit into m_Flags. Electrical - * continuity is detected by walking each segment, and finally the segments - * are rearranged into a contiguous chain within the given list. - * - * @param aTrace The trace segment to test for connections. - * @param aCount A pointer to an integer where to return the number of interesting - * segments. - * @param aLength A pointer to an integer where to return the length of the track - * @param aLengthDie A pointer to an integer where to return the extra lengths - * inside integrated circuits from the pads connected to this - * track to the die (if any) - * @param aReorder True to reorder the interesting segments (useful for track - * edition or deletion) in this case the flag BUSY is set (the - * user is responsible for flag clearing). False for no reorder: - * useful when we want just calculate the track length in this - * case, flags are reset - * @return A point to a TRACK object that is the first in the chain of interesting segments. - */ - TRACK* MarkTrace( TRACK* aTrace, int* aCount, int* aLength, int* aLengthDie, bool aReorder ); }; #endif // #ifndef CLASS_BOARD_H diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 1f081fab43..0aecfdf49c 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -819,22 +819,6 @@ D_PAD* MODULE::FindPadByName( const wxString& aPadName ) const } -D_PAD* MODULE::GetPad( const wxPoint& aPosition, int aLayerMask ) -{ - for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) - { - /* ... and on the correct layer. */ - if( ( pad->m_layerMask & aLayerMask ) == 0 ) - continue; - - if( pad->HitTest( aPosition ) ) - return pad; - } - - return NULL; -} - - // see class_module.h SEARCH_RESULT MODULE::Visit( INSPECTOR* inspector, const void* testData, const KICAD_T scanTypes[] ) diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 38f14f8135..cb36aa9d8a 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -298,16 +298,6 @@ public: D_PAD* FindPadByName( const wxString& aPadName ) const; - /** - * Function GetPad - * return a pad at \a aPosition on \a aLayerMask - * - * @param aPosition A wxPoint object containing the position to hit test. - * @param aLayerMask A layer or layers to mask the hit test. - * @return A pointer to a D_PAD object if found or NULL if not found. - */ - D_PAD* GetPad( const wxPoint& aPosition, int aLayerMask = ALL_LAYERS ); - /** * Function Visit * should be re-implemented for each derived class in order to handle diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 7caa4c8033..95410d1dae 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -152,15 +152,14 @@ TRACK::TRACK( const TRACK& Source ) : } +/* Because of the way SEGVIA and SEGZONE are derived from TRACK and because there are + * virtual functions being used, we can no longer simply copy a TRACK and + * expect it to be a via or zone. We must construct a true SEGVIA or SEGZONE so its constructor + * can initialize the virtual function table properly. This factory type of + * function called Copy() can duplicate either a TRACK, SEGVIA, or SEGZONE. + */ TRACK* TRACK::Copy() const { - /* Because of the way SEGVIA and SEGZONE are derived from TRACK and because - * there are virtual functions being used, we can no longer simply copy a - * TRACK and expect it to be a via or zone. We must construct a true SEGVIA - * or SEGZONE so its constructor can initialize the virtual function table - * properly. This factory type of function called Copy() can duplicate either - * a TRACK, SEGVIA, or SEGZONE. - */ if( Type() == TYPE_TRACK ) return new TRACK( *this ); @@ -174,14 +173,30 @@ TRACK* TRACK::Copy() const } +/** + * Function GetClearance (virtual) + * returns the clearance in internal units. If \a aItem is not NULL then the + * returned clearance is the greater of this object's clearance and + * aItem's clearance. If \a aItem is NULL, then this objects + * clearance + * is returned. + * @param aItem is another BOARD_CONNECTED_ITEM or NULL + * @return int - the clearance in internal units. + */ int TRACK::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const { - // Currently tracks have no specific clearance parameter on a per track or per - // segment basis. The NETCLASS clearance is used + // Currently tracks have no specific clearance parameter + // on a per track or per segment basis. + // the NETCLASS clearance is used return BOARD_CONNECTED_ITEM::GetClearance( aItem ); } +/** + * Function GetDrillValue + * calculate the drill value for vias (m_Drill if > 0, or default drill value for the Netclass + * @return real drill_value + */ int TRACK::GetDrillValue() const { if( Type() != TYPE_VIA ) @@ -200,6 +215,7 @@ int TRACK::GetDrillValue() const } +// return true if segment length = 0 bool TRACK::IsNull() { if( ( Type() != TYPE_VIA ) && ( m_Start == m_End ) ) @@ -209,17 +225,24 @@ bool TRACK::IsNull() } -int TRACK::IsPointOnEnds( const wxPoint& aPosition, int aDistance ) +/* Return: + * STARTPOINT if point if near (dist = min_dist) star point + * ENDPOINT if point if near (dist = min_dist) end point + * STARTPOINT|ENDPOINT if point if near (dist = min_dist) both ends + * 0 if no + * if min_dist < 0: min_dist = track_width/2 + */ +int TRACK::IsPointOnEnds( const wxPoint& point, int min_dist ) { int result = 0; - if( aDistance < 0 ) - aDistance = m_Width / 2; + if( min_dist < 0 ) + min_dist = m_Width / 2; - int dx = m_Start.x - aPosition.x; - int dy = m_Start.y - aPosition.y; + int dx = m_Start.x - point.x; + int dy = m_Start.y - point.y; - if( aDistance == 0 ) + if( min_dist == 0 ) { if( (dx == 0) && (dy == 0 ) ) result |= STARTPOINT; @@ -228,14 +251,14 @@ int TRACK::IsPointOnEnds( const wxPoint& aPosition, int aDistance ) { double dist = hypot( (double)dx, (double) dy ); - if( aDistance >= (int) dist ) + if( min_dist >= (int) dist ) result |= STARTPOINT; } - dx = m_End.x - aPosition.x; - dy = m_End.y - aPosition.y; + dx = m_End.x - point.x; + dy = m_End.y - point.y; - if( aDistance == 0 ) + if( min_dist == 0 ) { if( (dx == 0) && (dy == 0 ) ) result |= ENDPOINT; @@ -244,7 +267,7 @@ int TRACK::IsPointOnEnds( const wxPoint& aPosition, int aDistance ) { double dist = hypot( (double) dx, (double) dy ); - if( aDistance >= (int) dist ) + if( min_dist >= (int) dist ) result |= ENDPOINT; } @@ -308,6 +331,12 @@ EDA_RECT TRACK::GetBoundingBox() const } +/** + * Function Rotate + * Rotate this object. + * @param aRotCentre - the rotation point. + * @param aAngle - the rotation angle in 0.1 degree. + */ void TRACK::Rotate( const wxPoint& aRotCentre, int aAngle ) { RotatePoint( &m_Start, aRotCentre, aAngle ); @@ -315,18 +344,29 @@ void TRACK::Rotate( const wxPoint& aRotCentre, int aAngle ) } +/** + * Function Flip + * Flip this object, i.e. change the board side for this object + * @param aCentre - the rotation point. + */ void TRACK::Flip( const wxPoint& aCentre ) { m_Start.y = aCentre.y - (m_Start.y - aCentre.y); m_End.y = aCentre.y - (m_End.y - aCentre.y); - if( Type() != TYPE_VIA ) + if( Type() == TYPE_VIA ) + { + // Huh? Wouldn't it be better to us Type() != VIA and get rid of these brackets? + } + else { SetLayer( ChangeSideNumLayer( GetLayer() ) ); } } +// see class_track.h +// SEGVIA and SEGZONE inherit this version SEARCH_RESULT TRACK::Visit( INSPECTOR* inspector, const void* testData, const KICAD_T scanTypes[] ) { @@ -360,6 +400,9 @@ bool SEGVIA::IsOnLayer( int layer_number ) const } +/* Return the mask layer for this. + * for a via, there is more than one layer used + */ int TRACK::ReturnMaskLayer() { if( Type() == TYPE_VIA ) @@ -392,6 +435,14 @@ int TRACK::ReturnMaskLayer() } +/** Set the .m_Layer member param: + * For a via m_Layer contains the 2 layers : + * top layer and bottom layer used by the via. + * The via connect all layers from top layer to bottom layer + * 4 bits for the first layer and 4 next bits for the secaon layer + * @param top_layer = first layer connected by the via + * @param bottom_layer = last layer connected by the via + */ void SEGVIA::SetLayerPair( int top_layer, int bottom_layer ) { if( Shape() == VIA_THROUGH ) @@ -407,6 +458,13 @@ void SEGVIA::SetLayerPair( int top_layer, int bottom_layer ) } +/** + * Function ReturnLayerPair + * Return the 2 layers used by the via (the via actually uses + * all layers between these 2 layers) + * @param top_layer = pointer to the first layer (can be null) + * @param bottom_layer = pointer to the last layer (can be null) + */ void SEGVIA::ReturnLayerPair( int* top_layer, int* bottom_layer ) const { int b_layer = LAYER_N_BACK; @@ -448,6 +506,9 @@ TRACK* TRACK::GetBestInsertPoint( BOARD* aPcb ) } +/* Search (within the track linked list) the first segment matching the netcode + * ( the linked list is always sorted by net codes ) + */ TRACK* TRACK::GetStartNetCode( int NetCode ) { TRACK* Track = this; @@ -477,6 +538,9 @@ TRACK* TRACK::GetStartNetCode( int NetCode ) } +/* Search (within the track linked list) the last segment matching the netcode + * ( the linked list is always sorted by net codes ) + */ TRACK* TRACK::GetEndNetCode( int NetCode ) { TRACK* NextS, * Track = this; @@ -696,226 +760,6 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wxPoint& } -int TRACK::GetEndSegments( int aCount, TRACK** aStartTrack, TRACK** aEndTrack ) -{ - TRACK* Track, * via, * segm, * TrackListEnd; - int NbEnds, layerMask, ii, ok = 0; - - if( aCount <= 1 ) - { - *aStartTrack = *aEndTrack = this; - return 1; - } - - /* Calculation of the limit analysis. */ - *aStartTrack = *aEndTrack = NULL; - TrackListEnd = Track = this; - ii = 0; - - for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() ) - { - TrackListEnd = Track; - Track->m_Param = 0; - } - - /* Calculate the extremes. */ - NbEnds = 0; - Track = this; - ii = 0; - - for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() ) - { - if( Track->Type() == TYPE_VIA ) - continue; - - layerMask = Track->ReturnMaskLayer(); - via = GetVia( TrackListEnd, Track->m_Start, layerMask ); - - if( via ) - { - layerMask |= via->ReturnMaskLayer(); - via->SetState( BUSY, ON ); - } - - Track->SetState( BUSY, ON ); - segm = GetTraceByEndPoint( this, TrackListEnd, Track->m_Start, layerMask ); - Track->SetState( BUSY, OFF ); - - if( via ) - via->SetState( BUSY, OFF ); - - if( segm == NULL ) - { - switch( NbEnds ) - { - case 0: - *aStartTrack = Track; NbEnds++; - break; - - case 1: - int BeginPad, EndPad; - *aEndTrack = Track; - - /* Swap ox, oy with fx, fy */ - BeginPad = Track->GetState( BEGIN_ONPAD ); - EndPad = Track->GetState( END_ONPAD ); - - Track->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); - - if( BeginPad ) - Track->SetState( END_ONPAD, ON ); - - if( EndPad ) - Track->SetState( BEGIN_ONPAD, ON ); - - EXCHG( Track->m_Start, Track->m_End ); - EXCHG( Track->start, Track->end ); - ok = 1; - return ok; - } - } - - layerMask = Track->ReturnMaskLayer(); - via = GetVia( TrackListEnd, Track->m_End, layerMask ); - - if( via ) - { - layerMask |= via->ReturnMaskLayer(); - via->SetState( BUSY, ON ); - } - - Track->SetState( BUSY, ON ); - segm = GetTraceByEndPoint( this, TrackListEnd, Track->m_End, layerMask ); - Track->SetState( BUSY, OFF ); - - if( via ) - via->SetState( BUSY, OFF ); - - if( segm == NULL ) - { - switch( NbEnds ) - { - case 0: - int BeginPad, EndPad; - *aStartTrack = Track; - NbEnds++; - - /* Swap ox, oy with fx, fy */ - BeginPad = Track->GetState( BEGIN_ONPAD ); - EndPad = Track->GetState( END_ONPAD ); - - Track->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); - - if( BeginPad ) - Track->SetState( END_ONPAD, ON ); - - if( EndPad ) - Track->SetState( BEGIN_ONPAD, ON ); - - EXCHG( Track->m_Start, Track->m_End ); - EXCHG( Track->start, Track->end ); - break; - - case 1: - *aEndTrack = Track; - ok = 1; - return ok; - } - } - } - - return ok; -} - - -TRACK* TRACK::GetTrace( const wxPoint& aPosition, int aLayer ) -{ - for( TRACK* track = this; track; track = track->Next() ) - { - int layer = track->GetLayer(); - - if( track->GetState( BUSY | IS_DELETED ) ) - { - // D( printf( "track %p is BUSY | IS_DELETED. BUSY=%d IS_DELETED=%d\n", - // track, track->GetState( BUSY ), - // track->GetState( IS_DELETED ) );) - continue; - } - - if( GetBoard()->GetBoardDesignSettings()->IsLayerVisible( layer ) == false ) - continue; - - if( track->Type() == TYPE_VIA ) /* VIA encountered. */ - { - if( track->HitTest( aPosition ) ) - return track; - } - else - { - if( (g_TabOneLayerMask[layer] & aLayer) == 0 ) - continue; /* Segments on different layers. */ - - if( track->HitTest( aPosition ) ) - return track; - } - } - - return NULL; -} - - -TRACK* TRACK::GetVia( const wxPoint& aPosition, int aLayer ) -{ - TRACK* track; - - for( track = this; track; track = track->Next() ) - { - if( track->Type() != TYPE_VIA ) - continue; - - if( !track->HitTest( aPosition ) ) - continue; - - if( track->GetState( BUSY | IS_DELETED ) ) - continue; - - if( aLayer < 0 ) - break; - - if( track->IsOnLayer( aLayer ) ) - break; - } - - return track; -} - - -TRACK* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, int aLayer ) -{ - TRACK* trace; - - for( trace = this; trace != NULL; trace = trace->Next() ) - { - if( trace->Type() == TYPE_VIA ) - { - if( aPosition == trace->m_Start ) - { - if( trace->GetState( BUSY | IS_DELETED ) == 0 ) - { - if( aLayer & trace->ReturnMaskLayer() ) - return trace; - } - } - } - - if( trace == aEndTrace ) - break; - } - - return NULL; -} - - void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wxPoint& aOffset ) { int color; @@ -986,19 +830,17 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wxPoint else { GRCircle( &panel->m_ClipBox, DC, m_Start + aOffset,radius, 0, color ); - if ( fast_draw ) return; - GRCircle( &panel->m_ClipBox, DC, m_Start + aOffset, inner_radius, 0, color ); } // Draw the via hole if the display option allows it if( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW ) { - if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) // Display all drill holes requested - || ( (drill_radius > 0 ) && !IsDrillDefault() ) ) // Or Display non default holes - { // requested. + if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) // Display all drill holes requested + || ( (drill_radius > 0 ) && !IsDrillDefault() ) ) // Or Display non default holes requested + { if( fillvia ) { bool blackpenstate = false; @@ -1135,6 +977,7 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wxPoint } +// see class_track.h void TRACK::DisplayInfo( EDA_DRAW_FRAME* frame ) { wxString msg; @@ -1148,7 +991,7 @@ void TRACK::DisplayInfo( EDA_DRAW_FRAME* frame ) { int trackLen = 0; int lenDie = 0; - board->MarkTrace( this, NULL, &trackLen, &lenDie, false ); + MarkTrace( board, this, NULL, &trackLen, &lenDie, false ); msg = frame->CoordinateToString( trackLen ); frame->AppendMsgPanel( _( "Track Len" ), msg, DARKCYAN ); @@ -1183,6 +1026,13 @@ void TRACK::DisplayInfo( EDA_DRAW_FRAME* frame ) } +/* + * Function DisplayInfoBase + * has knowledge about the frame and how and where to put status information + * about this object into the frame's message panel. + * Display info about the track segment only, and does not calculate the full track length + * @param frame A EDA_DRAW_FRAME in which to print status information. + */ void TRACK::DisplayInfoBase( EDA_DRAW_FRAME* frame ) { wxString msg; @@ -1298,6 +1148,12 @@ void TRACK::DisplayInfoBase( EDA_DRAW_FRAME* frame ) } +/** + * Function HitTest + * tests if the given wxPoint is within the bounds of this object. + * @param refPos A wxPoint to test + * @return bool - true if a hit, else false + */ bool TRACK::HitTest( const wxPoint& refPos ) { int radius = m_Width >> 1; @@ -1324,6 +1180,13 @@ bool TRACK::HitTest( const wxPoint& refPos ) } +/** + * Function HitTest (overlaid) + * tests if the given EDA_RECT intersect this object. + * For now, an ending point must be inside this rect. + * @param refArea an EDA_RECT to test + * @return bool - true if a hit, else false + */ bool TRACK::HitTest( EDA_RECT& refArea ) { if( refArea.Contains( m_Start ) ) @@ -1368,6 +1231,13 @@ wxString TRACK::GetSelectMenuText() const #if defined(DEBUG) +/** + * Function Show + * is used to output the object tree, currently for debugging only. + * @param nestLevel An aid to prettier tree indenting, and is the level + * of nesting of this object within the overall tree. + * @param os The ostream& to output to. + */ void TRACK::Show( int nestLevel, std::ostream& os ) { NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << @@ -1388,6 +1258,13 @@ void TRACK::Show( int nestLevel, std::ostream& os ) } +/** + * Function Show + * is used to output the object tree, currently for debugging only. + * @param nestLevel An aid to prettier tree indenting, and is the level + * of nesting of this object within the overall tree. + * @param os The ostream& to output to. + */ void SEGVIA::Show( int nestLevel, std::ostream& os ) { const char* cp; diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 06e86afb9d..45dce8fa37 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -1,7 +1,6 @@ -/** - * @file class_track.h - * @brief Class definitions for tracks, vias, and zones. - */ +/*******************************************************************/ +/* class_track.h: definitions relatives to tracks, vias and zones */ +/*******************************************************************/ #ifndef CLASS_TRACK_H #define CLASS_TRACK_H @@ -17,9 +16,6 @@ * to the near neighbor internal layer */ #define VIA_NOT_DEFINED 0 /* not yet used */ -#define IGNORE_LAYERS -1 - - /***/ class TRACK : public BOARD_CONNECTED_ITEM @@ -109,7 +105,7 @@ public: * @param aFile The FILE to write to. * @return bool - true if success writing else false. */ - bool Save( FILE* aFile ) const; + bool Save( FILE* aFile ) const; /** * Function GetBestInsertPoint @@ -119,24 +115,24 @@ public: * @param aPcb The BOARD to search for the insertion point. * @return TRACK* - the item found in the linked list (or NULL if no track) */ - TRACK* GetBestInsertPoint( BOARD* aPcb ); + TRACK* GetBestInsertPoint( BOARD* aPcb ); /* Search (within the track linked list) the first segment matching the netcode * ( the linked list is always sorted by net codes ) */ - TRACK* GetStartNetCode( int NetCode ); + TRACK* GetStartNetCode( int NetCode ); /* Search (within the track linked list) the last segment matching the netcode * ( the linked list is always sorted by net codes ) */ - TRACK* GetEndNetCode( int NetCode ); + TRACK* GetEndNetCode( int NetCode ); /** * Function GetLength * returns the length of the track using the hypotenuse calculation. * @return double - the length of the track */ - double GetLength() const + double GetLength() const { int dx = m_Start.x - m_End.x; int dy = m_Start.y - m_End.y; @@ -145,53 +141,9 @@ public: } - /** - * Function GetEndSegments - * get the end points connected to the track. - * - * @param aCount The maximum number of connected segments to test. - * @param aStartTrack The beginning segment connected to the trace. - * @param aEndTrack The end segment connected to the trace. - * @return A 1 if the end points are valid or a 0 when a trace is a closed loop. - */ - int GetEndSegments( int aCount, TRACK** aStartTrack, TRACK** aEndTrack ); - - /** - * Function GetTrace - * returns a trace segment or via at \a aPosition on \a aLayer starting from this - * trace. - * - * @param aPosition The wxPoint to HitTest() against. - * @param aLayer The layer to search. Use -1 for a don't care. - * @return A pointer to the TRACK or SEGVIA object if found, else NULL. - */ - TRACK* GetTrace( const wxPoint& aPosition, int aLayer ); - - /** - * Function GetVia - * finds the first SEGVIA object at \a aPosition on \a aLayer starting at the trace. - * - * @param aPosition The wxPoint to HitTest() against. - * @param aLayer The layer to match, pass -1 for a don't care. - * @return A pointer to a TRACK object ( actually a SEGVIA ) if found, else NULL. - */ - TRACK* GetVia( const wxPoint& aPosition, int aLayer = IGNORE_LAYERS ); - - /** - * Function GetVia - * finds the first SEGVIA object at \a aPosition on \a aLayer starting at the trace - * and ending at \a aEndTrace. - * - * @param aEndTrace Pointer to the last TRACK object to end search. - * @param aPosition The wxPoint to HitTest() against. - * @param aLayer The layer to match, pass -1 for a don't care. - * @return A pointer to a TRACK object ( actually a SEGVIA ) if found, else NULL. - */ - TRACK* GetVia( TRACK* aEndTrace, const wxPoint& aPosition, int aLayer ); - /* Display on screen: */ - void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, - const wxPoint& aOffset = ZeroOffset ); + void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, + const wxPoint& aOffset = ZeroOffset ); /* divers */ int Shape() const { return m_Shape & 0xFF; } @@ -244,20 +196,15 @@ public: * TRACK segment or SEGVIA physically resides. * @return int - a layer mask, see pcbstruct.h's LAYER_BACK, etc. */ - int ReturnMaskLayer(); + int ReturnMaskLayer(); - /** - * Function IsPointOnEnds - * returns #STARTPOINT or #ENDPOINT if the start or end point is within \a aDistance - * of \a aPosition otherwise 0 is returned. - */ - int IsPointOnEnds( const wxPoint& aPosition, int aDistance = 0 ); + int IsPointOnEnds( const wxPoint& point, int min_dist = 0 ); /** * Function IsNull * returns true if segment length is zero. */ - bool IsNull(); + bool IsNull(); /** * Function DisplayInfo @@ -267,7 +214,7 @@ public: * Display info about the track segment and the full track length * @param frame A EDA_DRAW_FRAME in which to print status information. */ - void DisplayInfo( EDA_DRAW_FRAME* frame ); + void DisplayInfo( EDA_DRAW_FRAME* frame ); /** * Function DisplayInfoBase @@ -276,13 +223,13 @@ public: * Display info about the track segment only, and does not calculate the full track length * @param frame A EDA_DRAW_FRAME in which to print status information. */ - void DisplayInfoBase( EDA_DRAW_FRAME* frame ); + void DisplayInfoBase( EDA_DRAW_FRAME* frame ); /** * Function ShowWidth * returns the width of the track in displayable user units. */ - wxString ShowWidth() const; + wxString ShowWidth() const; /** * Function Visit @@ -297,8 +244,8 @@ public: * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan, * else SCAN_CONTINUE, and determined by the inspector. */ - SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData, - const KICAD_T scanTypes[] ); + SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData, + const KICAD_T scanTypes[] ); /** @@ -307,7 +254,7 @@ public: * @param refPos A wxPoint to test * @return bool - true if a hit, else false */ - bool HitTest( const wxPoint& refPos ); + bool HitTest( const wxPoint& refPos ); /** * Function HitTest (overlaid) @@ -316,7 +263,7 @@ public: * @param refArea an EDA_RECT to test * @return bool - true if a hit, else false */ - bool HitTest( EDA_RECT& refArea ); + bool HitTest( EDA_RECT& refArea ); /** * Function GetClass @@ -401,8 +348,9 @@ public: } - void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, - const wxPoint& aOffset = ZeroOffset ); + void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, + const wxPoint& aOffset = ZeroOffset ); + /** * Function IsOnLayer @@ -411,28 +359,10 @@ public: * @param aLayer the layer to test for. * @return bool - true if on given layer, else false. */ - bool IsOnLayer( int aLayer ) const; + bool IsOnLayer( int aLayer ) const; - /** - * Function SetLayerPair - * set the .m_Layer member for a via m_Layer contains the 2 layers : - * top layer and bottom layer used by the via. - * The via connect all layers from top layer to bottom layer - * 4 bits for the first layer and 4 next bits for the second layer - * @param top_layer = first layer connected by the via - * @param bottom_layer = last layer connected by the via - */ - void SetLayerPair( int top_layer, int bottom_layer ); - - /** - * Function ReturnLayerPair - * return the 2 layers used by the via (the via actually uses all layers between - * these 2 layers) - * - * @param top_layer = pointer to the first layer (can be null) - * @param bottom_layer = pointer to the last layer (can be null) - */ - void ReturnLayerPair( int* top_layer, int* bottom_layer ) const; + void SetLayerPair( int top_layer, int bottom_layer ); + void ReturnLayerPair( int* top_layer, int* bottom_layer ) const; /** * Function GetPosition @@ -445,7 +375,7 @@ public: } - void SetPosition( const wxPoint& aPoint ) { m_Start = aPoint; m_End = aPoint; } + void SetPosition( const wxPoint& aPoint ) { m_Start = aPoint; m_End = aPoint; } /** * Function GetClass diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 84074a1563..f58dd38b7b 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -857,26 +857,43 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos ) } -bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& aPosition, int aMinDistance ) +/** + * Function HitTestForCorner + * tests if the given wxPoint near a corner, or near the segment define by 2 corners. + * Choose the nearest corner + * "near" means grid size (or CORNER_MIN_DIST if grid is not known) + * Set m_CornerSelection to corner index in .m_Poly->corner or -1 if no corner found + * @return true if a corner found + * @param refPos : A wxPoint to test + */ +bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) { m_CornerSelection = -1; // Set to not found - int x, y; - int closestDistance = aMinDistance; + #define CORNER_MIN_DIST 100 // distance (in internal units) to detect a corner in a zone outline + int min_dist = CORNER_MIN_DIST + 1; + + if( GetBoard() && GetBoard()->m_PcbFrame ) + { + // Use grid size because it is known + wxRealPoint grid = GetBoard()->m_PcbFrame->DrawPanel->GetGrid(); + min_dist = wxRound( MIN( grid.x, grid.y ) ); + } + + wxPoint delta; unsigned lim = m_Poly->corner.size(); for( unsigned item_pos = 0; item_pos < lim; item_pos++ ) { - x = aPosition.x - m_Poly->corner[item_pos].x; - y = aPosition.y - m_Poly->corner[item_pos].y; - + delta.x = refPos.x - m_Poly->corner[item_pos].x; + delta.y = refPos.y - m_Poly->corner[item_pos].y; // Calculate a distance: - int dist = MAX( abs( x ), abs( y ) ); + int dist = MAX( abs( delta.x ), abs( delta.y ) ); - if( dist < closestDistance ) // this corner is a candidate: + if( dist < min_dist ) // this corner is a candidate: { m_CornerSelection = item_pos; - closestDistance = dist; + min_dist = dist; } } @@ -884,13 +901,31 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& aPosition, int aMinDistanc } -bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& aPosition, int aMinDistance ) +/** + * Function HitTestForEdge + * tests if the given wxPoint near a corner, or near the segment define by 2 corners. + * choose the nearest segment + * "near" means grid size (or EDGE_MIN_DIST if grid is not known) + * Set m_CornerSelection to -1 if nothing found, or index of the starting corner of edge + * in .m_Poly->corner + * @return true if found + * @param refPos : A wxPoint to test + */ +bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) { unsigned lim = m_Poly->corner.size(); m_CornerSelection = -1; // Set to not found - int closestDistance = aMinDistance; + #define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline + int min_dist = EDGE_MIN_DIST+1; + + if( GetBoard() && GetBoard()->m_PcbFrame ) + { + // Use grid size because it is known + wxRealPoint grid = GetBoard()->m_PcbFrame->DrawPanel->GetGrid(); + min_dist = wxRound( MIN( grid.x, grid.y ) ); + } unsigned first_corner_pos = 0; @@ -910,17 +945,17 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& aPosition, int aMinDistance } /* test the dist between segment and ref point */ - int dist = (int) GetPointToLineSegmentDistance( aPosition.x, - aPosition.y, + int dist = (int) GetPointToLineSegmentDistance( refPos.x, + refPos.y, m_Poly->corner[item_pos].x, m_Poly->corner[item_pos].y, m_Poly->corner[end_segm].x, m_Poly->corner[end_segm].y ); - if( dist < closestDistance ) + if( dist < min_dist ) { m_CornerSelection = item_pos; - closestDistance = dist; + min_dist = dist; } } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 4bdd9240c1..ed8d296bfd 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -12,10 +12,6 @@ #include "class_zone_setting.h" -#define CORNER_MIN_DIST 100 // distance (in internal units) to detect a corner in a zone outline -#define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline - - /* a small class used when filling areas with segments */ class SEGMENT { @@ -250,23 +246,21 @@ public: /** * Function HitTestForCorner - * tests if \a aPosition is with \a aDistance a zone corner. + * tests if the given wxPoint near a corner * Set m_CornerSelection to -1 if nothing found, or index of corner * @return true if found - * @param aPosition A wxPoint to test - * @param aMinDistance The minimum distance with \a aPosition that will still yield a hit. + * @param refPos : A wxPoint to test */ - bool HitTestForCorner( const wxPoint& aPosition, int aMinDistance = CORNER_MIN_DIST ); + bool HitTestForCorner( const wxPoint& refPos ); /** * Function HitTestForEdge * tests if the given wxPoint is near a segment defined by 2 corners. * Set m_CornerSelection to -1 if nothing found, or index of the starting corner of vertice * @return true if found - * @param aPosition A wxPoint to test - * @param aMinDistance The minimum distance with \a aPosition that will still yield a hit. + * @param refPos : A wxPoint to test */ - bool HitTestForEdge( const wxPoint& aPosition, int aMinDistance = EDGE_MIN_DIST ); + bool HitTestForEdge( const wxPoint& refPos ); /** * Function HitTest (overlayed) diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index b63913695b..0c8ae7fcde 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -153,7 +153,7 @@ void clean_vias( BOARD * aPcb ) if( track->m_Shape != VIA_THROUGH ) continue; - D_PAD* pad = aPcb->GetPadFast( track->m_Start, ALL_CU_LAYERS ); + D_PAD* pad = Fast_Locate_Pad_Connecte( aPcb, track->m_Start, ALL_CU_LAYERS ); if( pad && (pad->m_layerMask & EXTERNAL_LAYERS) == EXTERNAL_LAYERS ) // redundant Via { @@ -225,7 +225,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* frame, wxDC* DC ) D_PAD* pad; - pad = frame->GetBoard()->GetPadFast( segment->m_Start, masklayer ); + pad = Fast_Locate_Pad_Connecte( frame->GetBoard(), segment->m_Start, masklayer ); if( pad != NULL ) { @@ -233,7 +233,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* frame, wxDC* DC ) type_end |= START_ON_PAD; } - pad = frame->GetBoard()->GetPadFast( segment->m_End, masklayer ); + pad = Fast_Locate_Pad_Connecte( frame->GetBoard(), segment->m_End, masklayer ); if( pad != NULL ) { @@ -601,7 +601,8 @@ static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extre if( extremite == START ) { /* We do not have a pad */ - if( Pcb->GetPadFast( pt_ref->m_Start, g_TabOneLayerMask[pt_ref->GetLayer()] ) ) + if( Fast_Locate_Pad_Connecte( Pcb, pt_ref->m_Start, + g_TabOneLayerMask[pt_ref->GetLayer()] ) ) return NULL; /* change the common point coordinate of pt_segm tu use the other point @@ -620,7 +621,8 @@ static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extre else /* extremite == END */ { /* We do not have a pad */ - if( Pcb->GetPadFast( pt_ref->m_End, g_TabOneLayerMask[pt_ref->GetLayer()] ) ) + if( Fast_Locate_Pad_Connecte( Pcb, pt_ref->m_End, + g_TabOneLayerMask[pt_ref->GetLayer()] ) ) return NULL; /* change the common point coordinate of pt_segm tu use the other point @@ -780,7 +782,7 @@ static void Gen_Raccord_Track( PCB_EDIT_FRAME* frame, wxDC* DC ) { TRACK* newTrack; - other = frame->GetBoard()->GetTrace( other, segment->m_Start, layerMask ); + other = GetTrace( other, segment->m_Start, layerMask ); if( other == NULL ) break; @@ -829,7 +831,7 @@ static void Gen_Raccord_Track( PCB_EDIT_FRAME* frame, wxDC* DC ) { TRACK* newTrack; - other = frame->GetBoard()->GetTrace( other, segment->m_End, layerMask ); + other = GetTrace( other, segment->m_End, layerMask ); if( other == NULL ) break; @@ -978,7 +980,7 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* frame, wxDC* DC ) if( frame->DrawPanel->m_AbortRequest ) return; - pad = frame->GetBoard()->GetPad( segment, START ); + pad = Locate_Pad_Connecte( frame->GetBoard(), segment, START ); if( pad ) { @@ -1002,7 +1004,7 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* frame, wxDC* DC ) } } - pad = frame->GetBoard()->GetPad( segment, END ); + pad = Locate_Pad_Connecte( frame->GetBoard(), segment, END ); if( pad ) { diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp index 2761e95580..fe261aaed3 100644 --- a/pcbnew/connect.cpp +++ b/pcbnew/connect.cpp @@ -562,6 +562,28 @@ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* aPcb, LISTE_PAD* pt_liste, } +/** + * Function SortPadsByXCoord + * is used to Sort a pad list by x coordinate value. + */ +static int SortPadsByXCoord( const void* pt_ref, const void* pt_comp ) +{ + D_PAD* ref = *(LISTE_PAD*) pt_ref; + D_PAD* comp = *(LISTE_PAD*) pt_comp; + + return ref->m_Pos.x - comp->m_Pos.x; +} + + +void CreateSortedPadListByXCoord( BOARD* aBoard, std::vector* aVector ) +{ + aVector->insert( aVector->end(), aBoard->m_NetInfo->m_PadsFullList.begin(), + aBoard->m_NetInfo->m_PadsFullList.end() ); + + qsort( &(*aVector)[0], aBoard->GetPadsCount(), sizeof( D_PAD*), SortPadsByXCoord ); +} + + /* search connections between tracks and pads, and propagate pad net codes to the track segments * This is a 2 pass computation. * First: @@ -600,7 +622,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() /**************************************************************/ /* Pass 1: search the connections between track ends and pads */ /**************************************************************/ - m_Pcb->CreateSortedPadListByXCoord( &sortedPads ); + CreateSortedPadListByXCoord( m_Pcb, &sortedPads ); /* Reset variables and flags used in computation */ pt_trace = m_Pcb->m_Track; diff --git a/pcbnew/deltrack.cpp b/pcbnew/deltrack.cpp index 4329fb66d6..344db56e5b 100644 --- a/pcbnew/deltrack.cpp +++ b/pcbnew/deltrack.cpp @@ -176,8 +176,8 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm ) if( pt_segm == NULL ) return; - TRACK* trackList = GetBoard()->MarkTrace( pt_segm, &segments_to_delete_count, - NULL, NULL, true ); + TRACK* trackList = MarkTrace( GetBoard(), pt_segm, &segments_to_delete_count, + NULL, NULL, true ); if( segments_to_delete_count == 0 ) return; diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index f0838d8372..4923c48668 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -411,7 +411,7 @@ void DRC::testPad2Pad() { std::vector sortedPads; - m_pcb->CreateSortedPadListByXCoord( &sortedPads ); + CreateSortedPadListByXCoord( m_pcb, &sortedPads ); // find the max size of the pads (used to stop the test) int max_size = 0; @@ -420,8 +420,7 @@ void DRC::testPad2Pad() { D_PAD* pad = sortedPads[i]; - // m_ShapeMaxRadius is the radius value of the circle containing the pad. - if( pad->m_ShapeMaxRadius > max_size ) + if( pad->m_ShapeMaxRadius > max_size ) // m_ShapeMaxRadius is the radius value of the circle containing the pad max_size = pad->m_ShapeMaxRadius; } diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 40bab98dc2..d4080c55e8 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1002,7 +1002,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) wxPoint pos = GetScreen()->GetCrossHairPosition(); track->Draw( DrawPanel, &dc, GR_XOR ); PICKED_ITEMS_LIST itemsListPicker; - TRACK* newtrack = GetBoard()->CreateLockPoint( pos, track, &itemsListPicker ); + TRACK* newtrack = CreateLockPoint( GetBoard(), pos, track, &itemsListPicker ); SaveCopyInUndoList( itemsListPicker, UR_UNSPECIFIED ); track->Draw( DrawPanel, &dc, GR_XOR ); newtrack->Draw( DrawPanel, &dc, GR_XOR ); diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp index 1004b8b2bb..225bf4ba15 100644 --- a/pcbnew/edit_track_width.cpp +++ b/pcbnew/edit_track_width.cpp @@ -166,7 +166,7 @@ void PCB_EDIT_FRAME::Edit_Track_Width( wxDC* aDC, TRACK* aTrackSegment ) if( aTrackSegment == NULL ) return; - pt_track = GetBoard()->MarkTrace( aTrackSegment, &nb_segm, NULL, NULL, true ); + pt_track = MarkTrace( GetBoard(), aTrackSegment, &nb_segm, NULL, NULL, true ); PICKED_ITEMS_LIST itemsListPicker; bool change = false; diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp index 6a5c9050fe..77cf7eb03d 100644 --- a/pcbnew/editrack-part2.cpp +++ b/pcbnew/editrack-part2.cpp @@ -33,7 +33,7 @@ void PCB_EDIT_FRAME::ExChange_Track_Layer( TRACK* pt_segm, wxDC* DC ) l1 = Route_Layer_TOP; l2 = Route_Layer_BOTTOM; - pt_track = GetBoard()->MarkTrace( pt_segm, &nb_segm, NULL, NULL, true ); + pt_track = MarkTrace( GetBoard(), pt_segm, &nb_segm, NULL, NULL, true ); if ( DC ) DrawTraces( DrawPanel, DC, pt_track, nb_segm, GR_XOR ); @@ -87,8 +87,8 @@ void PCB_EDIT_FRAME::ExChange_Track_Layer( TRACK* pt_segm, wxDC* DC ) for( ; ii < nb_segm; pt_segm = pt_segm->Next(), ii++ ) { - pt_segm->start = GetBoard()->GetPad( pt_segm, START ); - pt_segm->end = GetBoard()->GetPad( pt_segm, END ); + pt_segm->start = Locate_Pad_Connecte( GetBoard(), pt_segm, START ); + pt_segm->end = Locate_Pad_Connecte( GetBoard(), pt_segm, END ); } test_1_net_connexion( DC, pt_track->GetNet() ); @@ -113,7 +113,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) } /* Avoid more than one via on the current location: */ - if( GetBoard()->GetVia( g_CurrentTrackSegment->m_End, g_CurrentTrackSegment->GetLayer() ) ) + if( Locate_Via( GetBoard(), g_CurrentTrackSegment->m_End, g_CurrentTrackSegment->GetLayer() ) ) return false; for( TRACK* segm = g_FirstTrackSegment; segm; segm = segm->Next() ) @@ -277,7 +277,7 @@ void PCB_EDIT_FRAME::DisplayNetStatus( wxDC* DC ) int layerMask = (1 << getActiveLayer()); wxPoint pos = GetScreen()->RefPos( true ); - pt_segm = GetBoard()->GetTrace( pos, layerMask ); + pt_segm = GetTrace( GetBoard(), GetBoard()->m_Track, pos, layerMask ); if( pt_segm == NULL ) GetBoard()->DisplayInfo( this ); diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index 3a430d6102..fbcf43afea 100644 --- a/pcbnew/editrack.cpp +++ b/pcbnew/editrack.cpp @@ -104,7 +104,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* DC ) GetBoard()->SetHightLightNet(0); // Search for a starting point of the new track, a track or pad - LockPoint = GetBoard()->GetLockPoint( pos, layerMask ); + LockPoint = LocateLockPoint( GetBoard(), pos, layerMask ); if( LockPoint ) // An item (pad or track) is found { @@ -120,7 +120,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* DC ) { TrackOnStartPoint = (TRACK*) LockPoint; GetBoard()->SetHightLightNet( TrackOnStartPoint->GetNet() ); - GetBoard()->CreateLockPoint( pos, TrackOnStartPoint, &s_ItemsListPicker ); + CreateLockPoint( GetBoard(), pos, TrackOnStartPoint, &s_ItemsListPicker ); } } else // no starting point, but a filled zone area can exist. This is @@ -247,7 +247,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* DC ) newTrack->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); - oneBeforeLatest->end = GetBoard()->GetPad( oneBeforeLatest, END ); + oneBeforeLatest->end = Locate_Pad_Connecte( GetBoard(), oneBeforeLatest, END ); if( oneBeforeLatest->end ) { @@ -451,7 +451,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* DC ) * This helps to reduce the computing time */ /* Attaching the end of the track. */ - BOARD_ITEM* LockPoint = GetBoard()->GetLockPoint( pos, layerMask ); + BOARD_ITEM* LockPoint = LocateLockPoint( GetBoard(), pos, layerMask ); if( LockPoint ) /* End of trace is on a pad. */ { @@ -466,9 +466,10 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* DC ) GetBoard()->SetHightLightNet( adr_buf->GetNet() ); /* Possible establishment of a hanging point. */ - LockPoint = GetBoard()->CreateLockPoint( g_CurrentTrackSegment->m_End, - adr_buf, - &s_ItemsListPicker ); + LockPoint = CreateLockPoint( GetBoard(), + g_CurrentTrackSegment->m_End, + adr_buf, + &s_ItemsListPicker ); } } @@ -1049,7 +1050,7 @@ void DeleteNullTrackSegments( BOARD* pcb, DLIST& aTrackList ) while( track != NULL ) { TRACK* next_track = track->Next(); - LockPoint = pcb->GetPad( track, END ); + LockPoint = Locate_Pad_Connecte( pcb, track, END ); if( LockPoint ) { diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp index c4070556a2..6086ae8c71 100644 --- a/pcbnew/hotkeys_board_editor.cpp +++ b/pcbnew/hotkeys_board_editor.cpp @@ -555,7 +555,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit if( !itemCurrentlyEdited ) { pos = screen->RefPos( true ); - module = GetBoard()->GetModule( pos, screen->m_Active_Layer, true ); + module = Locate_Prefered_Module( GetBoard(), pos, screen->m_Active_Layer, true ); } else if( GetCurItem()->Type() == TYPE_MODULE ) { @@ -641,7 +641,7 @@ bool PCB_EDIT_FRAME::OnHotkeyDeleteItem( wxDC* aDC ) if( ItemFree ) { wxPoint pos = GetScreen()->RefPos( false ); - MODULE* module = GetBoard()->GetModule( pos, ALL_LAYERS, false ); + MODULE* module = Locate_Prefered_Module( GetBoard(), pos, ALL_LAYERS, false ); if( module == NULL ) return false; @@ -659,19 +659,14 @@ bool PCB_EDIT_FRAME::OnHotkeyDeleteItem( wxDC* aDC ) if( ItemFree ) { item = PcbGeneralLocateAndDisplay(); - if( item == NULL ) return false; - if( (item->Type() == TYPE_MODULE) && !IsOK( this, _( "Delete module?" ) ) ) return false; - RemoveStruct( item, aDC ); } else - { - return false; - } + return false; } OnModify(); diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index 2a8003abe5..bd8a724920 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -40,7 +40,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery ) // delete the old BOARD and create a new BOARD so that the default // layer names are put into the BOARD. - SetBoard( new BOARD( NULL ) ); + SetBoard( new BOARD( NULL, this ) ); SetCurItem( NULL ); /* clear filename, to avoid overwriting an old file */ diff --git a/pcbnew/locate.cpp b/pcbnew/locate.cpp index 2016ce796c..a7cb4bb2c5 100644 --- a/pcbnew/locate.cpp +++ b/pcbnew/locate.cpp @@ -13,6 +13,246 @@ +/* Locates a via point pX, pY + * If layer < 0 will be located via whatever layer + * If layer = 0 .. 15 Via will be located according to its type: + * - Traverse: all layers + * - = Blind between layers useful + * - Blind idem + * Entry: coord point of reference, layer + * Output: NULL if not via + * (* TRACK) address via + */ +TRACK* Locate_Via( BOARD* Pcb, const wxPoint& pos, int layer ) +{ + TRACK* track; + + for( track = Pcb->m_Track; track; track = track->Next() ) + { + if( track->Type() != TYPE_VIA ) + continue; + + if( track->m_Start != pos ) + continue; + + if( track->GetState( BUSY | IS_DELETED ) ) + continue; + + if( layer < 0 ) + break; + + if( track->IsOnLayer( layer ) ) + break; + } + + return track; +} + + +TRACK* Locate_Via_Area( TRACK* aStart, const wxPoint& pos, int layer ) +{ + TRACK* track; + + for( track = aStart; track; track = track->Next() ) + { + if( track->Type() != TYPE_VIA ) + continue; + + if( !track->HitTest(pos) ) + continue; + + if( track->GetState( BUSY | IS_DELETED ) ) + continue; + + if( layer < 0 ) + break; + + if( track->IsOnLayer( layer ) ) + break; + } + + return track; +} + + +/* Locate the pad CONNECTED to a track + * input: ptr_trace: pointer to the segment of track + * Extr = flag = START -> beginning of the test segment + * END -> end of the segment to be tested + * Returns: + * A pointer to the description of the pad if found. + * NULL pointer if pad NOT FOUND + */ +D_PAD* Locate_Pad_Connecte( BOARD* Pcb, TRACK* ptr_trace, int extr ) +{ + D_PAD* ptr_pad = NULL; + wxPoint ref_pos; + + int aLayerMask = g_TabOneLayerMask[ptr_trace->GetLayer()]; + + if( extr == START ) + { + ref_pos = ptr_trace->m_Start; + } + else + { + ref_pos = ptr_trace->m_End; + } + + for( MODULE* module = Pcb->m_Modules; module; module = module->Next() ) + { + ptr_pad = Locate_Pads( module, ref_pos, aLayerMask ); + + if( ptr_pad != NULL ) + break; + } + + return ptr_pad; +} + + +/* + * Locate a pad pointed to by the coordinates ref_pos.x, ref_pos.y + * aLayerMask is allowed layers ( bitmap mask) + * Returns: + * Pointer to a pad if found or NULL + */ +D_PAD* Locate_Any_Pad( BOARD* Pcb, const wxPoint& ref_pos, int aLayerMask ) +{ + D_PAD* pad = NULL; + + for( MODULE* module=Pcb->m_Modules; module && ( pad == NULL ); module = module->Next() ) + { + if( aLayerMask ) + pad = Locate_Pads( module, ref_pos, aLayerMask ); + else + pad = Locate_Pads( module, ref_pos, ALL_LAYERS ); + } + + return pad; +} + + +/* Locate the pad pointed to by the coordinate ref_pos.x,, ref_pos.y + * Input: + * - the footprint to test + * - masque_layer layer(s) (bit_masque) which must be the pad + * Returns: + * A pointer to the pad if found or NULL + */ +D_PAD* Locate_Pads( MODULE* module, const wxPoint& ref_pos, int aLayerMask ) +{ + for( D_PAD* pt_pad = module->m_Pads; pt_pad; pt_pad = pt_pad->Next() ) + { + /* ... and on the correct layer. */ + if( ( pt_pad->m_layerMask & aLayerMask ) == 0 ) + continue; + + if( pt_pad->HitTest( ref_pos ) ) + return pt_pad; + } + + return NULL; +} + + +/** + * Function Locate_Prefered_Module + * locates a footprint by its bounding rectangle. If several footprints + * are possible, then the priority is: the closest on the active layer, then + * closest. + * The current mouse or cursor coordinates are grabbed from the active window + * to perform hit-testing. + * distance is calculated via manhattan distance from the center of the + * bounding rectangle to the cursor position. + * + * @param aPcb The BOARD to search within. + * @param aPosition Flag bits, tuning the search, see pcbnew.h + * @param aActiveLayer Layer to test. + * @param aVisibleOnly Search only the visible layers if true. + * @param aIgnoreLocked Ignore locked modules when true. + * @return MODULE* The best module or NULL if none. + */ +MODULE* Locate_Prefered_Module( BOARD* aPcb, const wxPoint& aPosition, int aActiveLayer, + bool aVisibleOnly, bool aIgnoreLocked ) +{ + MODULE* pt_module; + MODULE* module = NULL; + MODULE* Altmodule = NULL; + int min_dim = 0x7FFFFFFF; + int alt_min_dim = 0x7FFFFFFF; + int layer; + + pt_module = aPcb->m_Modules; + + for( ; pt_module; pt_module = (MODULE*) pt_module->Next() ) + { + // is the ref point within the module's bounds? + if( !pt_module->HitTest( aPosition ) ) + continue; + + // if caller wants to ignore locked modules, and this one is locked, skip it. + if( aIgnoreLocked && pt_module->IsLocked() ) + continue; + + /* Calculate priority: the priority is given to the layer of the + * module and the copper layer if the module layer is indelible, + * adhesive copper, a layer if cmp module layer is indelible, + * adhesive component. + */ + layer = pt_module->GetLayer(); + + if( layer==ADHESIVE_N_BACK || layer==SILKSCREEN_N_BACK ) + layer = LAYER_N_BACK; + else if( layer==ADHESIVE_N_FRONT || layer==SILKSCREEN_N_FRONT ) + layer = LAYER_N_FRONT; + + /* Test of minimum size to choosing the best candidate. */ + + EDA_RECT bb = pt_module->GetFootPrintRect(); + int offx = bb.GetX() + bb.GetWidth() / 2; + int offy = bb.GetY() + bb.GetHeight() / 2; + + //off x & offy point to the middle of the box. + int dist = abs( aPosition.x - offx ) + abs( aPosition.y - offy ); + + //int dist = MIN(lx, ly); // to pick the smallest module (kinda + // screwy with same-sized modules -- this is bad!) + + if( aActiveLayer == layer ) + { + if( dist <= min_dim ) + { + /* better footprint shown on the active layer */ + module = pt_module; + min_dim = dist; + } + } + else if( aVisibleOnly && aPcb->IsModuleLayerVisible( layer ) ) + { + if( dist <= alt_min_dim ) + { + /* better footprint shown on other layers */ + Altmodule = pt_module; + alt_min_dim = dist; + } + } + } + + if( module ) + { + return module; + } + + if( Altmodule ) + { + return Altmodule; + } + + return NULL; +} + + /* * return true if the dist between p1 and p2 < max_dist * Currently in test (currently rasnest algos work only if p1 == p2) @@ -25,9 +265,7 @@ int dist; dist = abs(p1.x - p2.x) + abs (p1.y - p2.y); dist *= 7; dist /= 10; - - if ( dist < max_dist ) - return true; + if ( dist < max_dist ) return true; } #else if ( p1 == p2 ) return true; @@ -181,3 +419,168 @@ suite1: return NULL; } + + +/* + * 1 - Locate segment of track leading from the mouse. + * 2 - Locate segment of track point by point + * ref_pos.x, ref_pos.y.r + * + * The search begins to address start_adresse + */ +TRACK* GetTrace( BOARD* aPcb, TRACK* start_adresse, const wxPoint& ref_pos, int LayerMask ) +{ + for( TRACK* track = start_adresse; track; track = track->Next() ) + { + int layer = track->GetLayer(); + + if( track->GetState( BUSY | IS_DELETED ) ) + { + // D( printf( "track %p is BUSY | IS_DELETED. BUSY=%d IS_DELETED=%d\n", + // track, track->GetState( BUSY ), + // track->GetState( IS_DELETED ) );) + continue; + } + + if( aPcb->GetBoardDesignSettings()->IsLayerVisible( layer ) == false ) + continue; + + if( track->Type() == TYPE_VIA ) /* VIA encountered. */ + { + if( track->HitTest( ref_pos ) ) + return track; + } + else + { + if( (g_TabOneLayerMask[layer] & LayerMask) == 0 ) + continue; /* Segments on different layers. */ + + if( track->HitTest( ref_pos ) ) + return track; + } + } + + return NULL; +} + + +/* + * 1 - Locate zone area by the mouse. + * 2 - Locate zone area by point + * def_pos.x, ref_pos.y.r + * + * If layer == -1, tst layer is not + * + * The search begins to address start_adresse + */ +TRACK* Locate_Zone( TRACK* start_adresse, const wxPoint& ref_pos, int layer ) +{ + for( TRACK* Zone = start_adresse; Zone; Zone = Zone->Next() ) + { + if( (layer != -1) && (Zone->GetLayer() != layer) ) + continue; + + if( Zone->HitTest( ref_pos ) ) + return Zone; + } + + return NULL; +} + + +/* Find the pad center px, py, + * The layer INDICATED BY aLayerMask (bitwise) + * (Runway end) + * The list of pads must already exist. + * + * Returns: + * NULL if no pad located. + * Pointer to the structure corresponding descr_pad if pad found + * (Good position and good layer). + */ +D_PAD* Fast_Locate_Pad_Connecte( BOARD* Pcb, const wxPoint& ref_pos, int aLayerMask ) +{ + for( unsigned i=0; iGetPadsCount(); ++i ) + { + D_PAD* pad = Pcb->m_NetInfo->GetPad(i); + + if( pad->m_Pos != ref_pos ) + continue; + + /* Pad found, it must be on the correct layer */ + if( pad->m_layerMask & aLayerMask ) + return pad; + } + + return NULL; +} + + +/* Locate segment with one end that coincides with the point x, y + * Data on layers by masklayer + * Research is done to address start_adr has end_adr + * If end_adr = NULL, end search list + * The segments of track marks with the flag are not IS_DELETED or taken + * into account + */ +TRACK* GetTrace( TRACK* start_adr, TRACK* end_adr, const wxPoint& ref_pos, int MaskLayer ) +{ + TRACK* PtSegm; + + if( start_adr == NULL ) + return NULL; + + for( PtSegm = start_adr; PtSegm != NULL; PtSegm = PtSegm->Next() ) + { + if( PtSegm->GetState( IS_DELETED | BUSY ) == 0 ) + { + if( ref_pos == PtSegm->m_Start ) + { + if( MaskLayer & PtSegm->ReturnMaskLayer() ) + return PtSegm; + } + + if( ref_pos == PtSegm->m_End ) + { + if( MaskLayer & PtSegm->ReturnMaskLayer() ) + return PtSegm; + } + } + + if( PtSegm == end_adr ) + break; + } + + return NULL; +} + + +/* Locates via through the point x, y, on layer data by masklayer. + * Search is done to address start_adr has end_adr. + * If end_adr = NULL, end search list + * Vias whose parameter has the State or IS_DELETED bit BUSY = 1 are ignored + */ +TRACK* Fast_Locate_Via( TRACK* start_adr, TRACK* end_adr, const wxPoint& pos, int MaskLayer ) +{ + TRACK* PtSegm; + + for( PtSegm = start_adr; PtSegm != NULL; PtSegm = PtSegm->Next() ) + { + if( PtSegm->Type() == TYPE_VIA ) + { + if( pos == PtSegm->m_Start ) + { + if( PtSegm->GetState( BUSY | IS_DELETED ) == 0 ) + { + if( MaskLayer & PtSegm->ReturnMaskLayer() ) + return PtSegm; + } + } + } + + if( PtSegm == end_adr ) + break; + } + + return NULL; +} diff --git a/pcbnew/magnetic_tracks_functions.cpp b/pcbnew/magnetic_tracks_functions.cpp index f4b42cc061..dcbe7cf126 100644 --- a/pcbnew/magnetic_tracks_functions.cpp +++ b/pcbnew/magnetic_tracks_functions.cpp @@ -153,7 +153,7 @@ bool Magnetize( BOARD* m_Pcb, PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize gr if( doPad ) { int layer_mask = g_TabOneLayerMask[screen->m_Active_Layer]; - D_PAD* pad = m_Pcb->GetPad( pos, layer_mask ); + D_PAD* pad = Locate_Any_Pad( m_Pcb, pos, layer_mask ); if( pad ) { @@ -171,7 +171,7 @@ bool Magnetize( BOARD* m_Pcb, PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize gr int layer = screen->m_Active_Layer; for( TRACK* via = m_Pcb->m_Track; - via && (via = via->GetVia( *curpos, layer )) != NULL; + via && (via = Locate_Via_Area( via, *curpos, layer )) != NULL; via = via->Next() ) { if( via != currTrack ) // a via cannot influence itself @@ -193,7 +193,7 @@ bool Magnetize( BOARD* m_Pcb, PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize gr { int layer_mask = g_TabOneLayerMask[layer]; - TRACK* track = m_Pcb->m_Track->GetTrace( pos, layer_mask ); + TRACK* track = GetTrace( m_Pcb, m_Pcb->m_Track, pos, layer_mask ); if( !track || track->Type() != TYPE_TRACK ) { diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 0f7615757e..511e2023b9 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -127,9 +127,10 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( wxWindow* father, UpdateTitle(); if( g_ModuleEditor_Pcb == NULL ) - g_ModuleEditor_Pcb = new BOARD( NULL ); + g_ModuleEditor_Pcb = new BOARD( NULL, this ); SetBoard( g_ModuleEditor_Pcb ); + GetBoard()->m_PcbFrame = this; if( s_screenModule == NULL ) s_screenModule = new PCB_SCREEN(); diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp index 47850ee3b7..2a0d077869 100644 --- a/pcbnew/move_or_drag_track.cpp +++ b/pcbnew/move_or_drag_track.cpp @@ -1019,15 +1019,14 @@ bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC ) * (only pad connection must be tested, track connection will be * tested by test_1_net_connexion() ) */ int layerMask = g_TabOneLayerMask[Track->GetLayer()]; - Track->start = GetBoard()->GetPadFast( Track->m_Start, layerMask ); + Track->start = Fast_Locate_Pad_Connecte( GetBoard(), Track->m_Start, layerMask ); if( Track->start ) Track->SetState( BEGIN_ONPAD, ON ); else Track->SetState( BEGIN_ONPAD, OFF ); - Track->end = GetBoard()->GetPadFast( Track->m_End, layerMask ); - + Track->end = Fast_Locate_Pad_Connecte( GetBoard(), Track->m_End, layerMask ); if( Track->end ) Track->SetState( END_ONPAD, ON ); else @@ -1055,3 +1054,147 @@ bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC ) return true; } + + +/* Find the point "attachment" of the end of a trace. + * This may be a TBP or another segment of the trace + * Returns: + * - Pointer to the PAD or: + * - Pointer to the segment or: + * - NULL + * Parameters: + * - position to test + * - mask layers to be tested + */ +BOARD_ITEM* LocateLockPoint( BOARD* Pcb, wxPoint pos, int LayerMask ) +{ + for( MODULE* module = Pcb->m_Modules; module; module = module->Next() ) + { + D_PAD* pad = Locate_Pads( module, pos, LayerMask ); + + if( pad ) + return pad; + } + + /* No pad has been located so check for a segment of the trace. */ + TRACK* ptsegm = GetTrace( Pcb->m_Track, NULL, pos, LayerMask ); + + if( ptsegm == NULL ) + ptsegm = GetTrace( Pcb, Pcb->m_Track, pos, LayerMask ); + + return ptsegm; +} + + +/* Create an intermediate point on a segment + * aSegm segment is broken into 2 segments connecting point pX, pY + * After insertion: + * The new segment starts from to new point, and ends to initial aSegm ending point + * the old segment aSegm ends to new point + * Returns: + * NULL if no new point (ie if aRefPoint already corresponded at one end of aSegm + * or + * Pointer to the segment created + * Returns the exact value of aRefPoint + * If aSegm points to a via: + * Returns the exact value of aRefPoint and a pointer to the via, + * But does not create extra point + */ +TRACK* CreateLockPoint( BOARD* aPcb, + wxPoint& aRefPoint, + TRACK* aSegm, + PICKED_ITEMS_LIST* aItemsListPicker ) +{ + if( aSegm->m_Start == aRefPoint || aSegm->m_End == aRefPoint ) + return NULL; + + /* A via is a good lock point */ + if( aSegm->Type() == TYPE_VIA ) + { + aRefPoint = aSegm->m_Start; + return aSegm; + } + + /* Calculation coordinate of intermediate point relative to + * the start point of aSegm + */ + wxPoint delta = aSegm->m_End - aSegm->m_Start; + + // Not yet in use: +#if 0 + int ox, oy, fx, fy; + + if( aRefSegm ) + { + ox = aRefSegm->m_Start.x - aSegm->m_Start.x; + oy = aRefSegm->m_Start.y - aSegm->m_Start.y; + fx = aRefSegm->m_End.x - aSegm->m_Start.x; + fy = aRefSegm->m_End.y - aSegm->m_Start.y; + } +#endif + + // calculate coordinates of aRefPoint relative to aSegm->m_Start + wxPoint newPoint = aRefPoint - aSegm->m_Start; + // newPoint must be on aSegm: + // Ensure newPoint.y/newPoint.y = delta.y/delta.x + if( delta.x == 0 ) + newPoint.x = 0; /* horizontal segment*/ + else + newPoint.y = wxRound(( (double)newPoint.x * delta.y ) / delta.x); + + /* Create the intermediate point (that is to say creation of a new + * segment, beginning at the intermediate point. + */ + newPoint.x += aSegm->m_Start.x; + newPoint.y += aSegm->m_Start.y; + + TRACK* newTrack = aSegm->Copy(); + + if( aItemsListPicker ) + { + ITEM_PICKER picker( newTrack, UR_NEW ); + aItemsListPicker->PushItem( picker ); + } + + + DLIST* list = (DLIST*)aSegm->GetList(); + wxASSERT( list ); + list->Insert( newTrack, aSegm->Next() ); + + if( aItemsListPicker ) + { + ITEM_PICKER picker( aSegm, UR_CHANGED ); + picker.m_Link = aSegm->Copy(); + aItemsListPicker->PushItem( picker ); + } + + /* Correct pointer at the end of the new segment. */ + newTrack->end = aSegm->end; + newTrack->SetState( END_ONPAD, aSegm->GetState( END_ONPAD ) ); + + /* Set connections info relative to the new point + */ + + /* Old segment now ends at new point. */ + aSegm->m_End = newPoint; + aSegm->end = newTrack; + aSegm->SetState( END_ONPAD, OFF ); + + /* The new segment begins at the new point. */ + newTrack->m_Start = newPoint; + newTrack->start = aSegm; + newTrack->SetState( BEGIN_ONPAD, OFF ); + + D_PAD * pad = Locate_Pad_Connecte( aPcb, newTrack, START ); + + if ( pad ) + { + newTrack->start = pad; + newTrack->SetState( BEGIN_ONPAD, ON ); + aSegm->end = pad; + aSegm->SetState( END_ONPAD, ON ); + } + + aRefPoint = newPoint; + return newTrack; +} diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp index 26ae935332..6e30a51fa1 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -48,8 +48,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) { if( item && item->m_Flags ) { - AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), - KiBitmap( cancel_xpm ) ); + AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); } else { @@ -167,8 +166,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) HK_MOVE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_DRAWING_REQUEST, msg, KiBitmap( move_xpm ) ); - AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DRAWING, _( "Edit Drawing" ), - KiBitmap( edit_xpm ) ); + AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DRAWING, _( "Edit Drawing" ), KiBitmap( edit_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING, _( "Delete Drawing" ), KiBitmap( delete_xpm ) ); @@ -295,8 +293,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) case ID_TRACK_BUTT: if ( ! locate_track ) // This menu is already added when a track is located AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ), - ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ), - KiBitmap( width_track_xpm ) ); + ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ), KiBitmap( width_track_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); @@ -378,8 +375,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) */ void PCB_EDIT_FRAME::createPopUpBlockMenu( wxMenu* menu ) { - AddMenuItem( menu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel Block" ), - KiBitmap( cancel_xpm ) ); + AddMenuItem( menu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel Block" ), KiBitmap( cancel_xpm ) ); AddMenuItem( menu, ID_POPUP_ZOOM_BLOCK, _( "Zoom Block" ), KiBitmap( zoom_area_xpm ) ); menu->AppendSeparator(); AddMenuItem( menu, ID_POPUP_PLACE_BLOCK, _( "Place Block" ), KiBitmap( apply_xpm ) ); @@ -408,8 +404,7 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu ) { if( Track->Type() == TYPE_VIA ) { - AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_TRACK_NODE, _( "Drag Via" ), - KiBitmap( move_xpm ) ); + AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_TRACK_NODE, _( "Drag Via" ), KiBitmap( move_xpm ) ); } else { @@ -490,10 +485,10 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu ) // Delete control: PopMenu->AppendSeparator(); wxMenu* track_mnu = new wxMenu; - AddMenuItem( PopMenu, track_mnu, ID_POPUP_PCB_DELETE_TRACK_MNU, _( "Delete" ), - KiBitmap( delete_xpm ) ); + AddMenuItem( PopMenu, track_mnu, ID_POPUP_PCB_DELETE_TRACK_MNU, _( "Delete" ), KiBitmap( delete_xpm ) ); - msg = AddHotkeyName( Track->Type()==TYPE_VIA ? _( "Delete Via" ) : _( "Delete Segment" ), + msg = AddHotkeyName( Track->Type()==TYPE_VIA ? + _( "Delete Via" ) : _( "Delete Segment" ), g_Board_Editor_Hokeys_Descr, HK_BACK_SPACE ); AddMenuItem( track_mnu, ID_POPUP_PCB_DELETE_TRACKSEG, msg, KiBitmap( delete_line_xpm ) ); @@ -502,8 +497,7 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu ) { msg = AddHotkeyName( _( "Delete Track" ), g_Board_Editor_Hokeys_Descr, HK_DELETE ); AddMenuItem( track_mnu, ID_POPUP_PCB_DELETE_TRACK, msg, KiBitmap( delete_track_xpm ) ); - AddMenuItem( track_mnu, ID_POPUP_PCB_DELETE_TRACKNET, _( "Delete Net" ), - KiBitmap( delete_net_xpm ) ); + AddMenuItem( track_mnu, ID_POPUP_PCB_DELETE_TRACKNET, _( "Delete Net" ), KiBitmap( delete_net_xpm ) ); } // Add global edition command @@ -517,8 +511,7 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu ) // Add lock/unlock flags menu: track_mnu = new wxMenu; - AddMenuItem( PopMenu, track_mnu, ID_POPUP_PCB_SETFLAGS_TRACK_MNU, _( "Set Flags" ), - KiBitmap( flag_xpm ) ); + AddMenuItem( PopMenu, track_mnu, ID_POPUP_PCB_SETFLAGS_TRACK_MNU, _( "Set Flags" ), KiBitmap( flag_xpm ) ); track_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACKSEG, _( "Locked: Yes" ), wxEmptyString, true ); track_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, _( "Locked: No" ), wxEmptyString, true ); @@ -564,19 +557,14 @@ void PCB_EDIT_FRAME::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* AddMenuItem( aPopMenu, zones_menu, -1, _( "Zones" ), KiBitmap( add_zone_xpm ) ); - // Use grid size because it is known - wxRealPoint grid = DrawPanel->GetGrid(); - - if( edge_zone->HitTestForCorner( GetScreen()->RefPos( true ), - wxRound( MIN( grid.x, grid.y ) ) ) ) + if( edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) ) { AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER, _( "Move Corner" ), KiBitmap( move_xpm ) ); AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER, _( "Delete Corner" ), KiBitmap( delete_xpm ) ); } - else if( edge_zone->HitTestForEdge( GetScreen()->RefPos( true ), - wxRound( MIN( grid.x, grid.y ) ) ) ) + else if( edge_zone->HitTestForEdge( GetScreen()->RefPos( true ) ) ) { AddMenuItem( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER, _( "Create Corner" ), KiBitmap( add_corner_xpm ) ); @@ -594,8 +582,7 @@ void PCB_EDIT_FRAME::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* _( "Add Cutout Area" ), KiBitmap( add_zone_cutout_xpm ) ); zones_menu->AppendSeparator(); - AddMenuItem( zones_menu, ID_POPUP_PCB_FILL_ZONE, _( "Fill Zone" ), - KiBitmap( fill_zone_xpm ) ); + AddMenuItem( zones_menu, ID_POPUP_PCB_FILL_ZONE, _( "Fill Zone" ), KiBitmap( fill_zone_xpm ) ); if( edge_zone->m_FilledPolysList.size() > 0 ) { @@ -658,8 +645,7 @@ void PCB_EDIT_FRAME::createPopUpMenuForFootprints( MODULE* aModule, wxMenu* menu if( !flags ) { msg = AddHotkeyName( _( "Edit" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM ); - AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE, msg, - KiBitmap( edit_module_xpm ) ); + AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE, msg, KiBitmap( edit_module_xpm ) ); sub_menu_footprint->AppendSeparator(); AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_DELETE_MODULE, _( "Delete Module" ), KiBitmap( delete_module_xpm ) ); @@ -739,10 +725,8 @@ void PCB_EDIT_FRAME::createPopUpMenuForFpPads( D_PAD* Pad, wxMenu* menu ) sub_menu_Pad = new wxMenu; AddMenuItem( menu, sub_menu_Pad, -1, msg, KiBitmap( pad_xpm ) ); - AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_MOVE_PAD_REQUEST, _( "Move" ), - KiBitmap( move_pad_xpm ) ); - AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_DRAG_PAD_REQUEST, _( "Drag" ), - KiBitmap( drag_pad_xpm ) ); + AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_MOVE_PAD_REQUEST, _( "Move" ), KiBitmap( move_pad_xpm ) ); + AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_DRAG_PAD_REQUEST, _( "Drag" ), KiBitmap( drag_pad_xpm ) ); AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_EDIT_PAD, _( "Edit" ), KiBitmap( options_pad_xpm ) ); sub_menu_Pad->AppendSeparator(); @@ -806,17 +790,14 @@ void PCB_EDIT_FRAME::createPopUpMenuForTexts( TEXTE_PCB* Text, wxMenu* menu ) _( "Reset Size" ), KiBitmap( reset_text_xpm ) ); sub_menu_Text->AppendSeparator(); - AddMenuItem( sub_menu_Text, ID_POPUP_PCB_DELETE_TEXTEPCB, _( "Delete" ), - KiBitmap( delete_text_xpm ) ); + AddMenuItem( sub_menu_Text, ID_POPUP_PCB_DELETE_TEXTEPCB, _( "Delete" ), KiBitmap( delete_text_xpm ) ); } void PCB_EDIT_FRAME::createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aPopMenu ) { - AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_MARKER, _( "Delete Marker" ), - KiBitmap( delete_xpm ) ); - AddMenuItem( aPopMenu, ID_POPUP_PCB_GETINFO_MARKER, _( "Marker Error Info" ), - KiBitmap( info_xpm ) ); + AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_MARKER, _( "Delete Marker" ), KiBitmap( delete_xpm ) ); + AddMenuItem( aPopMenu, ID_POPUP_PCB_GETINFO_MARKER, _( "Marker Error Info" ), KiBitmap( info_xpm ) ); } diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 2a2b3aceeb..f407f820b6 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -277,11 +277,10 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title, m_HotkeysZoomAndGridList = g_Board_Editor_Hokeys_Descr; m_RecordingMacros = -1; - for ( int i = 0; i < 10; i++ ) m_Macros[i].m_Record.clear(); - SetBoard( new BOARD( NULL ) ); + SetBoard( new BOARD( NULL, this ) ); // Create the PCB_LAYER_WIDGET *after* SetBoard(): @@ -418,7 +417,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title, PCB_EDIT_FRAME::~PCB_EDIT_FRAME() { m_RecordingMacros = -1; - for( int i = 0; i < 10; i++ ) m_Macros[i].m_Record.clear(); diff --git a/pcbnew/protos.h b/pcbnew/protos.h index f7e060db30..6e50cefda1 100644 --- a/pcbnew/protos.h +++ b/pcbnew/protos.h @@ -1,11 +1,16 @@ -/** - * @file pcbnew/protos.h - */ +/***********/ +/* protos.h */ +/***********/ #ifndef PROTO_H #define PROTO_H +#include + + +class COMMAND; + /** * Function SwapData * Used in undo / redo command: @@ -17,6 +22,24 @@ void SwapData( BOARD_ITEM* aItem, BOARD_ITEM* aImage ); +/*******************/ +/* PAD_CONNECT.CPP */ +/*******************/ + +class D_PAD; + +/** + * Function CreateSortedPadListByXCoord + * first empties then fills the vector with all pads and sorts them by + * increasing x coordinate. The vector only holds pointers to the pads and + * those pointers are only references to pads which are owned by the BOARD + * through other links. + * @param aBoard Which board to gather pads from. + * @param aVector Where to put the pad pointers. + */ +void CreateSortedPadListByXCoord( BOARD* aBoard, std::vector* aVector ); + + /***************/ /* TRPISTE.CPP */ /***************/ @@ -43,6 +66,31 @@ void DrawTraces( EDA_DRAW_PANEL* panel, /* LOCATE.CPP : */ /****************/ +/* Find a pad by it's name om the module. */ +TRACK* Locate_Via( BOARD* Pcb, const wxPoint& pos, int layer = -1 ); + +/** + * Function Locate_Via_Area + * finds the first SEGVIA which covers the given aPos with a matching layer. + * @param aStart The starting TRACK or SEGVIA in the BOARD's list. + * @param aPos The wxPoint to HitTest() against. + * @param aLayer The layer to match, pass -1 for a don't care. + * @return TRACK* - actually a SEGVIA* if found, else NULL. + */ +TRACK* Locate_Via_Area( TRACK* aStart, const wxPoint& aPos, int aLayer = ALL_LAYERS ); + +/* Locates the center through the point x, y, on layer data + * by masquelayer. + * Search is done to address start_adr has end_adr (not included) + */ +TRACK* Fast_Locate_Via( TRACK* start_adr, TRACK* end_adr, const wxPoint& pos, int masquelayer ); + +/* Locates the center through the point x, y, on layer data + * by masquelayer. + * Search is done to address start_adr has end_adr (not included) + */ +TRACK* GetTrace( TRACK* start_adr, TRACK* end_adr, const wxPoint& ref_pos, int masquelayer ); + /* Search for segment connected to the segment edge by * Ptr_piste: * If int = START, the point of beginning of the segment is used @@ -52,6 +100,86 @@ void DrawTraces( EDA_DRAW_PANEL* panel, */ TRACK* GetConnectedTrace( TRACK* aTrace, TRACK* pt_base, TRACK* pt_lim, int extr ); +/* + * 1 - Locate segment of track leading from the mouse. + * 2 - Locate segment of track point by point. + * Ref_pX, ref_pY. + * + * If layer <0 the layer is not tested. + * + * The search begins to address start_adresse + */ +TRACK* GetTrace( BOARD* aPcb, TRACK* start_adresse, const wxPoint& ref_pos, int layer ); + +/* Locate pad connected to the beginning or end of a segment + * Input: pointer to the segment, and flag = START or END + * Returns: + * A pointer to the description of the patch if pad was found. + * NULL pointer if pad was not found. + */ +D_PAD* Locate_Pad_Connecte( BOARD* aPcb, TRACK* ptr_segment, int extr ); + +/* + * Locate pad pointed to by the coordinate ref_pX,, ref_pY or the current + * cursor position, search done on all tracks. + * Entry: + * - Mouse coord (Curseur_X and Curseur_Y) + * Or ref_pX, ref_pY + * Returns: + * Pointer to the pad if found + * NULL pointer if pad not found + */ +D_PAD* Locate_Any_Pad( BOARD* aPcb, const wxPoint& aPosition, int aLayerMask = ALL_LAYERS ); + +/* Locate pad pointed to by the coordinate ref_pX,, ref_pY or the cursor + * position of the current footprint. + * Input: + * - The module to search. + * - Layer to search or -1 to search all layers. + * Returns: + * A pointer to the pad if found otherwise NULL. + */ +D_PAD* Locate_Pads( MODULE* Module, const wxPoint& ref_pos, int layer ); + +/* Locate a footprint by its bounding rectangle. */ +MODULE* Locate_Prefered_Module( BOARD* aPcb, const wxPoint& aPosition, int aActiveLayer, + bool aVisibleOnly, bool aIgnoreLocked = false ); + +/* Locate a pad pointed to by the cursor on the footprint. + * Module. + * Input: + * - Module to search. + * Returns: + * A pointer to the pad if found otherwise NULL. + */ +D_PAD* Locate_Pads( MODULE* Module, int typeloc ); + +/* Locate a trace segment at the current cursor position. + * The search begins to address start_adresse. + */ +TRACK* GetTrace( TRACK* start_adresse, int typeloc ); + +DRAWSEGMENT* Locate_Segment_Pcb( BOARD* Pcb, int LayerSearch, int typeloc ); + +/* Locate pad containing the point px, py, layer on layer. + * + * The list of pads must already exist. + * + * Returns: + * Pointer to the pad if found, otherwise NULL. + */ +D_PAD* Fast_Locate_Pad_Connecte( BOARD* Pcb, const wxPoint& ref_pos, int layer ); + +/* + * 1 - Locate trace segment at the current cursor position. + * 2 - Locate trace segment at the given coordinates ref_pos. + * + * If layer == -1, check all layers. + * + * The search begins to address start_adresse + */ +TRACK* Locate_Zone( TRACK* start_adresse, const wxPoint& ref_pos, int layer ); + /*************/ /* MODULES.C */ @@ -76,9 +204,84 @@ void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPo void CalculateSegmentEndPoint( const wxPoint& aPosition, int ox, int oy, int* fx, int* fy ); +/*****************/ +/* TRACK.CPP : */ +/*****************/ + +/** + * Function MarkTrace + * marks a chain of track segments, connected to aTrackList. + * Each segment is marked by setting the BUSY bit into m_Flags. Electrical + * continuity is detected by walking each segment, and finally the segments + * are rearranged into a contiguous chain within the given list. + * + * @param aPcb = the board to analyze + * @param aStartSegm - The first interesting segment within a list of track + * segment of aPcb + * @param aSegmCount = a pointer to an integer where to return the number of + * interesting segments + * @param aTrackLen = a pointer to an integer where to return the lenght of the + * track + * @param aLengthDie = a pointer to an integer where to return the extra lengths inside + * integrated circuits from the pads connected to this track to the + * die (if any) + * @param aReorder = true for reorder the interesting segments (useful for + * track edition/deletion) in this case the flag BUSY is + * set (the user is responsible of flag clearing). False + * for no reorder : useful when we want just calculate the + * track length in this case, flags are reset + * @return TRACK* the first in the chain of interesting segments. + */ +TRACK* MarkTrace( BOARD* aPcb, + TRACK* aStartSegm, + int* aSegmCount, + int* aTrackLen, + int* aLengthDie, + bool aReorder ); + +/* Calculate end coordinate of a trace. + * Returns 1 if OK, 0 if trace looped back on itself. + * The coord are returned StartTrack-> ox, oy + * And EndTrack-> fx, fy if OK + * The segments are drawn consecutively. + */ +int ReturnEndsTrack( TRACK* RefTrack, int NbSegm, TRACK** StartTrack, TRACK** EndTrack ); + + /***************/ /***************/ +/* Routine to find the point "attachment" at the end of a trace. + * This may be a PAD or another trace segment. + * Returns: + * - Pointer to the PAD or: + * - Pointer to the segment or: + * - NULL + * Parameters: + * - aPos - coordinate point test + * ALayerMask of mask layers to be tested + */ +BOARD_ITEM* LocateLockPoint( BOARD* aPcb, wxPoint aPos, int aLayerMask ); + +/* Create an intermediate point on a segment + * aSegm segment is broken into 2 segments connecting point pX, pY + * After insertion: + * The new segment starts from to new point, and ends to initial aSegm ending point + * the old segment aSegm ends to new point + * Returns: + * NULL if no new point (ie if aRefPoint already corresponded at one end of aSegm + * or + * Pointer to the segment created + * Returns the exact value of aRefPoint + * If aSegm points to a via: + * Returns the exact value of aRefPoint and a pointer to the via, + * But does not create extra point + */ +TRACK* CreateLockPoint( BOARD* aPcb, + wxPoint& aRefPoint, + TRACK* aSegm, + PICKED_ITEMS_LIST* aItemsListPicker ); + /****************/ /* CONTROLE.CPP */ diff --git a/pcbnew/solve.cpp b/pcbnew/solve.cpp index 7d8dc68eee..86a20a2eec 100644 --- a/pcbnew/solve.cpp +++ b/pcbnew/solve.cpp @@ -1268,12 +1268,14 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) g_CurrentTrackList.PushBack( newTrack ); } - g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment, START ); + g_FirstTrackSegment->start = Locate_Pad_Connecte( pcbframe->GetBoard(), + g_FirstTrackSegment, START ); if( g_FirstTrackSegment->start ) g_FirstTrackSegment->SetState( BEGIN_ONPAD, ON ); - g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment, END ); + g_CurrentTrackSegment->end = Locate_Pad_Connecte( pcbframe->GetBoard(), + g_CurrentTrackSegment, END ); if( g_CurrentTrackSegment->end ) g_CurrentTrackSegment->SetState( END_ONPAD, ON ); diff --git a/pcbnew/tr_modif.cpp b/pcbnew/tr_modif.cpp index 24876b2fc8..a2e06772b8 100644 --- a/pcbnew/tr_modif.cpp +++ b/pcbnew/tr_modif.cpp @@ -10,6 +10,8 @@ #include "protos.h" static void ListSetState( EDA_ITEM* Start, int NbItem, int State, int onoff ); +extern int ReturnEndsTrack( TRACK* RefTrack, int NbSegm, + TRACK** StartTrack, TRACK** EndTrack ); /** @@ -52,7 +54,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, if( aNewTrack->Type() == TYPE_VIA && ( aNewTrackSegmentsCount > 1 ) ) aNewTrack = aNewTrack->Next(); - aNewTrack = GetBoard()->MarkTrace( aNewTrack, &aNewTrackSegmentsCount, NULL, NULL, true ); + aNewTrack = MarkTrace( GetBoard(), aNewTrack, &aNewTrackSegmentsCount, NULL, NULL, true ); wxASSERT( aNewTrack ); #if 0 && defined(DEBUG) @@ -90,7 +92,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, break; } - if( aNewTrack->GetEndSegments( aNewTrackSegmentsCount, &StartTrack, &EndTrack ) == 0 ) + if( ReturnEndsTrack( aNewTrack, aNewTrackSegmentsCount, &StartTrack, &EndTrack ) == 0 ) return 0; if( ( StartTrack == NULL ) || ( EndTrack == NULL ) ) @@ -108,7 +110,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, endmasklayer = EndTrack->ReturnMaskLayer(); /* There may be a via or a pad on the end points. */ - pt_segm = m_Pcb->m_Track->GetVia( NULL, start, startmasklayer ); + pt_segm = Fast_Locate_Via( m_Pcb->m_Track, NULL, start, startmasklayer ); if( pt_segm ) startmasklayer |= pt_segm->ReturnMaskLayer(); @@ -120,7 +122,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, startmasklayer |= pt_pad->m_layerMask; } - pt_segm = m_Pcb->m_Track->GetVia( NULL, end, endmasklayer ); + pt_segm = Fast_Locate_Via( m_Pcb->m_Track, NULL, end, endmasklayer ); if( pt_segm ) endmasklayer |= pt_segm->ReturnMaskLayer(); @@ -139,7 +141,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, /* A segment must be connected to the starting point, otherwise * it is unnecessary to analyze the other point */ - pt_segm = GetTraceByEndPoint( bufStart, bufEnd, start, startmasklayer ); + pt_segm = GetTrace( bufStart, bufEnd, start, startmasklayer ); if( pt_segm == NULL ) /* Not connected to the track starting point. */ { @@ -154,7 +156,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, */ for( pt_del = bufStart, nbconnect = 0; ; ) { - pt_segm = GetTraceByEndPoint( pt_del, bufEnd, end, endmasklayer ); + pt_segm = GetTrace( pt_del, bufEnd, end, endmasklayer ); if( pt_segm == NULL ) break; @@ -209,7 +211,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, nbconnect--; pt_del->SetState( IS_LINKED, OFF ); - pt_del = GetBoard()->MarkTrace( pt_del, &nb_segm, NULL, NULL, true ); + pt_del = MarkTrace( GetBoard(), pt_del, &nb_segm, NULL, NULL, true ); /* Test if the marked track is redundant, i.e. if one of marked segments * is connected to the starting point of the new track. diff --git a/pcbnew/track.cpp b/pcbnew/track.cpp new file mode 100644 index 0000000000..b6e3f51d95 --- /dev/null +++ b/pcbnew/track.cpp @@ -0,0 +1,541 @@ +/***************** +* track.cpp +*****************/ + +#include "fctsys.h" + +#include "common.h" +#include "pcbnew.h" + +#include "protos.h" + +/* Functions to recognize a track. + * A track is a list of connected segments (or/and vias) + * from a starting to an ending point + * starting and ending points are a pad or a point with more than 2 segments + *connected + * (and obviously a dangling segment end) + */ + +typedef std::vector TRACK_PTRS; // buffer of item candidates when + // search for items on the same track + + +/* Local functions */ +static void ChainMarkedSegments( BOARD* Pcb, + wxPoint ref_pos, + int masklayer, + TRACK_PTRS* aList ); + + +TRACK* MarkTrace( BOARD* aPcb, + TRACK* aStartSegm, + int* aSegmCount, + int* aTrackLen, + int* aLengthDie, + bool aReorder ) +{ + int NbSegmBusy; + + TRACK_PTRS trackList; + + if( aSegmCount ) + *aSegmCount = 0; + + if( aTrackLen ) + *aTrackLen = 0; + + if( aStartSegm == NULL ) + return NULL; + + // Ensure the flag BUSY of all tracks of the board is cleared + // because we use it to mark segments of the track + for( TRACK* track = aPcb->m_Track; track; track = track->Next() ) + track->SetState( BUSY, OFF ); + + /* Set flags of the initial track segment */ + aStartSegm->SetState( BUSY, ON ); + int layerMask = aStartSegm->ReturnMaskLayer(); + + trackList.push_back( aStartSegm ); + + /* Examine the initial track segment : if it is really a segment, this is + * easy. + * If it is a via, one must search for connected segments. + * If <=2, this via connect 2 segments (or is connected to only one + * segment) and this via and these 2 segments are a part of a track. + * If > 2 only this via is flagged (the track has only this via) + */ + if( aStartSegm->Type() == TYPE_VIA ) + { + TRACK* Segm1, * Segm2 = NULL, * Segm3 = NULL; + Segm1 = GetTrace( aPcb->m_Track, NULL, aStartSegm->m_Start, layerMask ); + + if( Segm1 ) + { + Segm2 = GetTrace( Segm1->Next(), NULL, aStartSegm->m_Start, layerMask ); + } + + if( Segm2 ) + { + Segm3 = GetTrace( Segm2->Next(), NULL, aStartSegm->m_Start, layerMask ); + } + + if( Segm3 ) // More than 2 segments are connected to this via. the track" is only this via + { + if( aSegmCount ) + *aSegmCount = 1; + + return aStartSegm; + } + + if( Segm1 ) // search for others segments connected to the initial segment start point + { + layerMask = Segm1->ReturnMaskLayer(); + ChainMarkedSegments( aPcb, aStartSegm->m_Start, layerMask, &trackList ); + } + + if( Segm2 ) // search for others segments connected to the initial segment end point + { + layerMask = Segm2->ReturnMaskLayer(); + ChainMarkedSegments( aPcb, aStartSegm->m_Start, layerMask, &trackList ); + } + } + else // mark the chain using both ends of the initial segment + { + ChainMarkedSegments( aPcb, aStartSegm->m_Start, layerMask, &trackList ); + ChainMarkedSegments( aPcb, aStartSegm->m_End, layerMask, &trackList ); + } + + // Now examine selected vias and flag them if they are on the track + // If a via is connected to only one or 2 segments, it is flagged (is on + // the track) + // If a via is connected to more than 2 segments, it is a track end, and it + // is removed from the list + // go through the list backwards. + for( int i = trackList.size() - 1; i>=0; --i ) + { + TRACK* via = trackList[i]; + + if( via->Type() != TYPE_VIA ) + continue; + + if( via == aStartSegm ) + continue; + + via->SetState( BUSY, ON ); // Try to flag it. the flag will be cleared later if needed + + layerMask = via->ReturnMaskLayer(); + + TRACK* track = GetTrace( aPcb->m_Track, NULL, via->m_Start, layerMask ); + + // GetTrace does not consider tracks flagged BUSY. + // So if no connected track found, this via is on the current track + // only: keep it + if( track == NULL ) + continue; + + /* If a track is found, this via connects also others segments of an + * other track. This case happens when the vias ends the selected + * track but must we consider this via is on the selected track, or + * on an other track. + * (this is important when selecting a track for deletion: must this + * via be deleted or not?) + * We consider here this via on the track if others segment connected + * to this via remain connected when removing this via. + * We search for all others segment connected together: + * if there are on the same layer, the via is on the selected track + * if there are on different layers, the via is on an other track + */ + int layer = track->GetLayer(); + + while( ( track = GetTrace( track->Next(), NULL, via->m_Start, layerMask ) ) != NULL ) + { + if( layer != track->GetLayer() ) + { + // The via connects segments of an other track: it is removed + // from list because it is member of an other track + via->SetState( BUSY, OFF ); + break; + } + } + } + + /* Rearrange the track list in order to have flagged segments linked + * from firstTrack so the NbSegmBusy segments are consecutive segments + * in list, the first item in the full track list is firstTrack, and + * the NbSegmBusy-1 next items (NbSegmBusy when including firstTrack) + * are the flagged segments + */ + NbSegmBusy = 0; + TRACK* firstTrack; + + for( firstTrack = aPcb->m_Track; firstTrack; firstTrack = firstTrack->Next() ) + { + // Search for the first flagged BUSY segments + if( firstTrack->GetState( BUSY ) ) + { + NbSegmBusy = 1; + break; + } + } + + if( firstTrack == NULL ) + return NULL; + + double full_len = 0; + double lenDie = 0; + + if( aReorder ) + { + DLIST* list = (DLIST*)firstTrack->GetList(); + wxASSERT( list ); + + /* Rearrange the chain starting at firstTrack + * All others flagged items are moved from their position to the end + * of the flagged list + */ + TRACK* next; + + for( TRACK* track = firstTrack->Next(); track; track = next ) + { + next = track->Next(); + + if( track->GetState( BUSY ) ) // move it! + { + NbSegmBusy++; + track->UnLink(); + list->Insert( track, firstTrack->Next() ); + + if( aTrackLen ) + full_len += track->GetLength(); + + if( aLengthDie ) // Add now length die. + { + // In fact only 2 pads (maximum) will be taken in account: + // that are on each end of the track, if any + if( track->GetState( BEGIN_ONPAD ) ) + { + D_PAD * pad = (D_PAD *) track->start; + lenDie += (double) pad->m_LengthDie; + } + + if( track->GetState( END_ONPAD ) ) + { + D_PAD * pad = (D_PAD *) track->end; + lenDie += (double) pad->m_LengthDie; + } + } + } + } + } + else if( aTrackLen ) + { + NbSegmBusy = 0; + + for( TRACK* track = firstTrack; track; track = track->Next() ) + { + if( track->GetState( BUSY ) ) + { + NbSegmBusy++; + track->SetState( BUSY, OFF ); + full_len += track->GetLength(); + + // Add now length die. + // In fact only 2 pads (maximum) will be taken in account: + // that are on each end of the track, if any + if( track->GetState( BEGIN_ONPAD ) ) + { + D_PAD * pad = (D_PAD *) track->start; + lenDie += (double) pad->m_LengthDie; + } + + if( track->GetState( END_ONPAD ) ) + { + D_PAD * pad = (D_PAD *) track->end; + lenDie += (double) pad->m_LengthDie; + } + } + } + } + + if( aTrackLen ) + *aTrackLen = wxRound( full_len ); + + if( aLengthDie ) + *aLengthDie = wxRound( lenDie ); + + if( aSegmCount ) + *aSegmCount = NbSegmBusy; + + return firstTrack; +} + + +/** + * Function used by MarkTrace + * - Set the BUSY flag of connected segments, the first search point is + * ref_pos on layers allowed in masque_layer + * - Put segments fount in aList + * Vias are put in list but their flags BUSY is not set + * @param aPcb = the board + * @param aRef_pos = the reference coordinate of the starting search + * @param aLayerMask = the allowed layers for segments to search + * (1 layer when starting point is on a segment, but more than one when + * starting point is on a via) + * @param aList = the track list to fill with points of segments flagged + */ +static void ChainMarkedSegments( BOARD* aPcb, + wxPoint aRef_pos, + int aLayerMask, + TRACK_PTRS* aList ) +{ + TRACK* pt_segm, // The current segment being analyzed. + * pt_via, // The via identified, eventually destroy + + * SegmentCandidate; // The end segment to destroy (or NULL = + // pt_segm + int NbSegm; + + if( aPcb->m_Track == NULL ) + return; + + /* Set the BUSY flag of all connected segments, first search starting at + * aRef_pos + * Search ends when: + * - a pad is found (end of a track) + * - a segment end has more than one other segment end connected + * - and obviously when no connected item found + * Vias are a special case, because we must see others segment connected + * on others layers and they change the layer mask. They can be a track + * end or not + * They will be analyzer later, and vias on terminal points of the track + * will be considered as part of this track if they do not connect segments + * of an other track together and will be considered as part of an other + * track if when removing the via, the segments of that other track are + * disconnected + */ + for( ; ; ) + { + if( Fast_Locate_Pad_Connecte( aPcb, aRef_pos, aLayerMask ) != NULL ) + return; + + /* Test for a via: a via changes the layer mask and can connect a lot + * of segments at location aRef_pos. When found, the via is just + * pushed in list. Vias will be examined later, when all connected + * segment are found and push in list. This is because when a via + * is found we do not know at this time the number of connected items + * and we do not know if this via is on the track or finish the track + */ + pt_via = Fast_Locate_Via( aPcb->m_Track, NULL, aRef_pos, aLayerMask ); + + if( pt_via ) + { + aLayerMask = pt_via->ReturnMaskLayer(); + + aList->push_back( pt_via ); + } + + /* Now we search all segments connected to point aRef_pos + * if only 1 segment: this segment is candidate + * if > 1 segment: + * end of track (more than 2 segment connected at this location) + */ + pt_segm = aPcb->m_Track; SegmentCandidate = NULL; + NbSegm = 0; + + while( ( pt_segm = GetTrace( pt_segm, NULL, aRef_pos, aLayerMask ) ) != NULL ) + { + if( pt_segm->GetState( BUSY ) ) // already found and selected: skip it + { + pt_segm = pt_segm->Next(); + continue; + } + + if( pt_segm == pt_via ) // just previously found: skip it + { + pt_segm = pt_segm->Next(); + continue; + } + + NbSegm++; + + if( NbSegm == 1 ) /* First time we found a connected item: pt_segm is candidate */ + { + SegmentCandidate = pt_segm; + pt_segm = pt_segm->Next(); + } + else /* More than 1 segment connected -> this location is an end of the track */ + { + return; + } + } + + if( SegmentCandidate ) // A candidate is found: flag it an push it in list + { + /* Initialize parameters to search items connected to this + * candidate: + * we must analyze connections to its other end + */ + aLayerMask = SegmentCandidate->ReturnMaskLayer(); + + if( aRef_pos == SegmentCandidate->m_Start ) + { + aRef_pos = SegmentCandidate->m_End; + } + else + { + aRef_pos = SegmentCandidate->m_Start; + } + + pt_segm = aPcb->m_Track; /* restart list of tracks to analyze */ + + /* flag this item an push it in list of selected items */ + aList->push_back( SegmentCandidate ); + SegmentCandidate->SetState( BUSY, ON ); + } + else + { + return; + } + } +} + + +/* Calculate the end points coordinates of a track (a list of connected + * segments) + * RefTrack is a segment of the track + * return 1 if OK, 0 when a track is a closed loop + * and the beginning and the end of the track in *StartTrack and *EndTrack + * Modify *StartTrack en *EndTrack : + * (*StartTrack)->m_Start coordinate is the beginning of the track + * (*EndTrack)->m_End coordinate is the end of the track + * Segments connected must be consecutive in list + */ +int ReturnEndsTrack( TRACK* RefTrack, int NbSegm, TRACK** StartTrack, TRACK** EndTrack ) +{ + TRACK* Track, * via, * segm, * TrackListEnd; + int NbEnds, layerMask, ii, ok = 0; + + if( NbSegm <= 1 ) + { + *StartTrack = *EndTrack = RefTrack; + return 1; + } + + /* Calculation of the limit analysis. */ + *StartTrack = *EndTrack = NULL; + TrackListEnd = Track = RefTrack; ii = 0; + + for( ; ( Track != NULL ) && ( ii < NbSegm ); ii++, Track = Track->Next() ) + { + TrackListEnd = Track; + Track->m_Param = 0; + } + + /* Calculate the extremes. */ + NbEnds = 0; Track = RefTrack; ii = 0; + + for( ; ( Track != NULL ) && ( ii < NbSegm ); ii++, Track = Track->Next() ) + { + if( Track->Type() == TYPE_VIA ) + continue; + + layerMask = Track->ReturnMaskLayer(); + via = Fast_Locate_Via( RefTrack, TrackListEnd, Track->m_Start, layerMask ); + + if( via ) + { + layerMask |= via->ReturnMaskLayer(); + via->SetState( BUSY, ON ); + } + + Track->SetState( BUSY, ON ); + segm = GetTrace( RefTrack, TrackListEnd, Track->m_Start, layerMask ); + Track->SetState( BUSY, OFF ); + + if( via ) + via->SetState( BUSY, OFF ); + + if( segm == NULL ) + { + switch( NbEnds ) + { + case 0: + *StartTrack = Track; NbEnds++; + break; + + case 1: + int BeginPad, EndPad; + *EndTrack = Track; + + /* Swap ox, oy with fx, fy */ + BeginPad = Track->GetState( BEGIN_ONPAD ); + EndPad = Track->GetState( END_ONPAD ); + + Track->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); + + if( BeginPad ) + Track->SetState( END_ONPAD, ON ); + + if( EndPad ) + Track->SetState( BEGIN_ONPAD, ON ); + + EXCHG( Track->m_Start, Track->m_End ); + EXCHG( Track->start, Track->end ); + ok = 1; + return ok; + } + } + + layerMask = Track->ReturnMaskLayer(); + via = Fast_Locate_Via( RefTrack, TrackListEnd, Track->m_End, layerMask ); + + if( via ) + { + layerMask |= via->ReturnMaskLayer(); + via->SetState( BUSY, ON ); + } + + Track->SetState( BUSY, ON ); + segm = GetTrace( RefTrack, TrackListEnd, Track->m_End, layerMask ); + Track->SetState( BUSY, OFF ); + + if( via ) + via->SetState( BUSY, OFF ); + + if( segm == NULL ) + { + switch( NbEnds ) + { + case 0: + int BeginPad, EndPad; + *StartTrack = Track; + NbEnds++; + + /* Swap ox, oy with fx, fy */ + BeginPad = Track->GetState( BEGIN_ONPAD ); + EndPad = Track->GetState( END_ONPAD ); + + Track->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); + + if( BeginPad ) + Track->SetState( END_ONPAD, ON ); + + if( EndPad ) + Track->SetState( BEGIN_ONPAD, ON ); + + EXCHG( Track->m_Start, Track->m_End ); + EXCHG( Track->start, Track->end ); + break; + + case 1: + *EndTrack = Track; + ok = 1; + return ok; + } + } + } + + return ok; +}