From efc93aa52b2475013975e53535b2997f1ee7c6ac Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Tue, 13 Sep 2011 09:29:43 -0400 Subject: [PATCH] PCBNew locate code refactoring. * Move various locate functions into the appropriate board item object. * Unified best zoom for all frames derived from PCB_BASE_FRAME. * Remove track.cpp as it is no longer needed. * Dead code removal. * Remove scary frame window pointer member from board item objects. * Add draw bounding box to gerber draw item for debugging purposes. --- bitmaps_png/cpp_26/erc_green.cpp | 69 +- bitmaps_png/cpp_26/ercwarn.cpp | 118 +-- bitmaps_png/cpp_48/icon_pcbcalculator.cpp | 365 +++++----- cvpcb/class_DisplayFootprintsFrame.cpp | 3 +- gerbview/class_gerber_draw_item.cpp | 15 +- gerbview/draw_gerber_screen.cpp | 22 +- gerbview/export_to_pcbnew.cpp | 2 +- gerbview/gerbview_frame.cpp | 34 +- gerbview/gerbview_frame.h | 5 +- include/base_struct.h | 3 +- pcbnew/CMakeLists.txt | 1 - pcbnew/attribut.cpp | 2 +- pcbnew/basepcbframe.cpp | 42 +- pcbnew/class_board.cpp | 836 ++++++++++++++++++---- pcbnew/class_board.h | 367 +++++++--- pcbnew/class_module.cpp | 16 + pcbnew/class_module.h | 10 + pcbnew/class_track.cpp | 371 ++++++---- pcbnew/class_track.h | 124 +++- pcbnew/class_zone.cpp | 67 +- pcbnew/class_zone.h | 16 +- pcbnew/clean.cpp | 20 +- pcbnew/connect.cpp | 24 +- pcbnew/deltrack.cpp | 4 +- pcbnew/drc.cpp | 5 +- pcbnew/edit.cpp | 2 +- pcbnew/edit_track_width.cpp | 2 +- pcbnew/editrack-part2.cpp | 10 +- pcbnew/editrack.cpp | 17 +- pcbnew/hotkeys_board_editor.cpp | 11 +- pcbnew/initpcb.cpp | 2 +- pcbnew/locate.cpp | 409 +---------- pcbnew/magnetic_tracks_functions.cpp | 6 +- pcbnew/moduleframe.cpp | 3 +- pcbnew/move_or_drag_track.cpp | 149 +--- pcbnew/onrightclick.cpp | 57 +- pcbnew/pcbframe.cpp | 4 +- pcbnew/protos.h | 209 +----- pcbnew/solve.cpp | 6 +- pcbnew/tr_modif.cpp | 16 +- pcbnew/track.cpp | 541 -------------- 41 files changed, 1802 insertions(+), 2183 deletions(-) delete mode 100644 pcbnew/track.cpp diff --git a/bitmaps_png/cpp_26/erc_green.cpp b/bitmaps_png/cpp_26/erc_green.cpp index afeccd3f8d..5ca5060616 100644 --- a/bitmaps_png/cpp_26/erc_green.cpp +++ b/bitmaps_png/cpp_26/erc_green.cpp @@ -1,41 +1,28 @@ - -/* 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 + +/* 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 diff --git a/bitmaps_png/cpp_26/ercwarn.cpp b/bitmaps_png/cpp_26/ercwarn.cpp index 84013eccff..619cca4479 100644 --- a/bitmaps_png/cpp_26/ercwarn.cpp +++ b/bitmaps_png/cpp_26/ercwarn.cpp @@ -8,65 +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, 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, + 0xce, 0x00, 0x00, 0x03, 0x97, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xbd, 0x56, 0xeb, 0x4b, 0x93, + 0x51, 0x18, 0xef, 0x4f, 0x28, 0x4c, 0x0a, 0xf3, 0x32, 0xa3, 0xb4, 0xa2, 0xb2, 0x30, 0x4b, 0x13, + 0xdd, 0x94, 0xbc, 0x40, 0x45, 0x51, 0x54, 0x52, 0x99, 0x7d, 0x08, 0x44, 0x52, 0x33, 0x34, 0x37, + 0x2f, 0xb3, 0x85, 0x74, 0xb1, 0xd0, 0x08, 0x4c, 0x83, 0xb4, 0x24, 0x29, 0x28, 0xc3, 0x02, 0x5b, + 0xe8, 0xbc, 0x10, 0xd8, 0x07, 0x9b, 0xe4, 0x07, 0x35, 0x35, 0x0b, 0x2f, 0x28, 0x26, 0xa2, 0x78, + 0x9b, 0xd3, 0xbd, 0xef, 0xb6, 0x5f, 0xcf, 0x7b, 0xa6, 0xaf, 0x9b, 0x6e, 0xba, 0x0f, 0xab, 0xc1, + 0xb3, 0xf3, 0x9e, 0x73, 0x7e, 0xe7, 0xf9, 0x9d, 0xf3, 0x3c, 0xbf, 0xf7, 0x39, 0xef, 0x06, 0x00, + 0x1b, 0xfe, 0x87, 0x89, 0x0f, 0x72, 0xb9, 0x6f, 0x40, 0x56, 0x96, 0xd7, 0x69, 0xd7, 0x9a, 0xa7, + 0xd4, 0x86, 0x28, 0x27, 0xc7, 0x73, 0x9b, 0x52, 0xe9, 0xa3, 0xab, 0xa8, 0xd8, 0x35, 0xe3, 0x4a, + 0xcb, 0xcf, 0x97, 0xe8, 0x14, 0x0a, 0xef, 0x63, 0x22, 0x91, 0x5c, 0xee, 0x75, 0xea, 0xc5, 0x0b, + 0xff, 0x49, 0x93, 0x49, 0x06, 0x57, 0x5a, 0x53, 0xd3, 0x01, 0x10, 0xd1, 0x6d, 0x91, 0x48, 0x38, + 0xe6, 0xcb, 0x97, 0xbb, 0xff, 0x15, 0x91, 0xca, 0x2e, 0x91, 0xd1, 0x28, 0x03, 0xcf, 0x5b, 0x5a, + 0x47, 0x0e, 0x84, 0x79, 0xc1, 0x1c, 0xcd, 0x2f, 0xf9, 0x68, 0x6c, 0x74, 0x48, 0x74, 0x0d, 0x66, + 0x33, 0x87, 0x99, 0x19, 0x2d, 0xfa, 0xfa, 0x82, 0xed, 0x90, 0x25, 0x13, 0x9c, 0x23, 0x8c, 0x01, + 0x03, 0x03, 0x79, 0x98, 0x9e, 0x0e, 0x5b, 0x45, 0x62, 0x36, 0x6b, 0x98, 0x8f, 0xde, 0xde, 0x44, + 0xd4, 0xd4, 0xec, 0xb3, 0x4f, 0xc4, 0xf3, 0x11, 0xe4, 0x7c, 0x0a, 0x0b, 0x0b, 0xf3, 0x48, 0x4d, + 0x95, 0x60, 0x7e, 0x3e, 0x7c, 0x85, 0xa3, 0x57, 0x10, 0x7e, 0x26, 0x93, 0x09, 0xf5, 0xf5, 0x55, + 0xa8, 0xae, 0xde, 0x0b, 0x8e, 0x93, 0xae, 0x20, 0x1a, 0x87, 0xc1, 0xa0, 0x47, 0x4c, 0xcc, 0x56, + 0xbc, 0x79, 0xb3, 0xc7, 0x71, 0xe8, 0x78, 0xbe, 0x89, 0x39, 0x4b, 0x4e, 0x8e, 0xc2, 0xd4, 0x54, + 0xd8, 0x0a, 0x27, 0x3f, 0x31, 0x36, 0xf6, 0x0b, 0x5d, 0x5d, 0xad, 0x34, 0x37, 0x81, 0xac, 0x2c, + 0x61, 0x33, 0xd6, 0x44, 0x97, 0xd9, 0xda, 0x6f, 0xdf, 0xea, 0x71, 0xee, 0x9c, 0x3b, 0x6a, 0x6b, + 0xf7, 0x3b, 0x26, 0xe2, 0xb8, 0x87, 0x0c, 0x5c, 0x5c, 0x9c, 0x8b, 0xd6, 0xd6, 0x40, 0xab, 0x5c, + 0x9c, 0xa6, 0x51, 0x33, 0x3e, 0x7d, 0x2a, 0x83, 0x5a, 0xfd, 0x98, 0x61, 0xd2, 0xd2, 0xa2, 0x28, + 0xcc, 0xd6, 0x9b, 0xb1, 0xac, 0x7d, 0xf2, 0x44, 0x8e, 0x07, 0x0f, 0xb6, 0x43, 0xa3, 0x09, 0x58, + 0xeb, 0x44, 0x17, 0x18, 0xb8, 0xb9, 0x59, 0x8d, 0x8a, 0x8a, 0xdd, 0x14, 0x06, 0xe9, 0x62, 0x82, + 0xef, 0xb2, 0x71, 0x85, 0x22, 0x8e, 0x62, 0x7f, 0x91, 0x3d, 0x97, 0x97, 0xdf, 0x83, 0x56, 0x6b, + 0xbd, 0x19, 0x0d, 0x1b, 0xbf, 0x74, 0x29, 0x88, 0x42, 0x1b, 0x80, 0x86, 0x86, 0x75, 0x54, 0xc7, + 0x71, 0x43, 0x14, 0x9a, 0x71, 0x64, 0x64, 0x78, 0x59, 0x85, 0x46, 0x43, 0xc6, 0x21, 0x3a, 0xda, + 0x03, 0x1d, 0x1d, 0x82, 0x50, 0x66, 0xd1, 0xd9, 0xa9, 0x45, 0x69, 0xa9, 0x9f, 0xb8, 0x19, 0xb3, + 0x79, 0x14, 0x13, 0x13, 0xc3, 0x88, 0x8c, 0xdc, 0x44, 0x21, 0x0e, 0x5d, 0x4b, 0x75, 0x4b, 0xf2, + 0xfd, 0xc8, 0x76, 0x96, 0x98, 0x78, 0x04, 0x73, 0x73, 0x82, 0x20, 0x22, 0xc8, 0xc9, 0x24, 0x7a, + 0x7a, 0xbe, 0xe2, 0xcc, 0x19, 0x77, 0xe8, 0x74, 0xe1, 0x84, 0xf9, 0x42, 0xe3, 0x46, 0xa4, 0xa4, + 0xec, 0x82, 0x5e, 0x2f, 0x60, 0xe2, 0xd8, 0x1a, 0xb5, 0xfa, 0x15, 0x92, 0x92, 0x3c, 0x98, 0x90, + 0xd6, 0x7c, 0x8f, 0x2c, 0x79, 0x52, 0xb2, 0x45, 0x05, 0x05, 0x29, 0xe8, 0xee, 0x3e, 0x4c, 0xbb, + 0x4f, 0x64, 0xfd, 0x67, 0xcf, 0xf2, 0x90, 0x9f, 0xef, 0x4b, 0xaa, 0x94, 0x12, 0xe6, 0x11, 0x1b, + 0x53, 0x2a, 0xaf, 0x60, 0x64, 0xe4, 0x28, 0x61, 0xee, 0x8b, 0xfd, 0xe7, 0xcf, 0xfd, 0xd9, 0x29, + 0xd7, 0x25, 0xe2, 0xf9, 0x13, 0x74, 0x02, 0x13, 0x3e, 0x7f, 0x7e, 0x8d, 0xf7, 0xef, 0xf7, 0x52, + 0xbf, 0x8c, 0x39, 0x49, 0x48, 0x08, 0x21, 0x25, 0x05, 0x50, 0x5f, 0x4a, 0x76, 0x9e, 0x8d, 0xbd, + 0x7d, 0xfb, 0x94, 0x8d, 0x19, 0x8d, 0x6a, 0x5a, 0x63, 0xc4, 0xf1, 0xe3, 0x12, 0xb4, 0xb5, 0x1d, + 0x62, 0x79, 0x5b, 0x97, 0xc8, 0x92, 0xa7, 0x1f, 0x18, 0x1a, 0xfa, 0x8d, 0x3b, 0x77, 0x7c, 0xa9, + 0xdf, 0x4e, 0xea, 0xfa, 0x83, 0x88, 0x88, 0x8d, 0x18, 0x1d, 0x0d, 0x65, 0xf3, 0x16, 0xcc, 0x00, + 0x93, 0x7a, 0x61, 0xe1, 0x0e, 0x5a, 0x37, 0x8c, 0xfe, 0xfe, 0xef, 0x38, 0x79, 0xd2, 0x0d, 0xb3, + 0xb3, 0x61, 0xeb, 0x97, 0xa0, 0xe5, 0x53, 0x55, 0x2e, 0xbe, 0x4f, 0x07, 0xe9, 0x9f, 0xa7, 0xc4, + 0xbe, 0xa6, 0x9c, 0x79, 0x2c, 0xe6, 0x63, 0x09, 0xf3, 0x8e, 0x08, 0x39, 0xc8, 0xe5, 0x41, 0x0c, + 0x5b, 0x59, 0x59, 0x80, 0xdc, 0x5c, 0x1f, 0x51, 0x40, 0x4e, 0x12, 0xdd, 0x58, 0x0c, 0x4d, 0x31, + 0x6b, 0xf3, 0xf2, 0xae, 0x8a, 0xb1, 0x5f, 0xce, 0xe5, 0x2d, 0x36, 0x57, 0x55, 0xf5, 0x94, 0xb5, + 0x49, 0x49, 0x51, 0xf8, 0xf0, 0x61, 0xb9, 0x5a, 0x38, 0x49, 0x74, 0x8c, 0xda, 0x79, 0x3a, 0x81, + 0x8e, 0xa9, 0x2b, 0x36, 0xd6, 0x5b, 0x8c, 0xfd, 0x32, 0x26, 0x9a, 0x5a, 0x03, 0xc3, 0xe8, 0xf5, + 0xd3, 0x90, 0xc9, 0xdc, 0x30, 0x38, 0x18, 0x22, 0xd6, 0x48, 0xa7, 0x88, 0x2c, 0x8e, 0x5a, 0xd8, + 0x4e, 0xdb, 0xdb, 0x5b, 0x28, 0xc9, 0x42, 0xec, 0xc3, 0xed, 0x54, 0x72, 0x2d, 0xc3, 0x34, 0x36, + 0x7e, 0x44, 0x7c, 0xfc, 0x16, 0x9b, 0xd0, 0x3a, 0x4d, 0x64, 0x30, 0xa4, 0x51, 0x19, 0x29, 0xa2, + 0x17, 0xf7, 0x2c, 0x54, 0x2a, 0x09, 0x93, 0xf5, 0x6a, 0xcc, 0x4d, 0xd4, 0xd5, 0x15, 0xe1, 0xfa, + 0xf5, 0x18, 0x2a, 0x3d, 0x3b, 0x6d, 0x42, 0xeb, 0x34, 0x91, 0x10, 0x82, 0xfe, 0xfe, 0x60, 0x2a, + 0x92, 0x81, 0xa4, 0xc0, 0x10, 0xbb, 0x77, 0x94, 0x35, 0x66, 0x49, 0x91, 0x0e, 0x89, 0x84, 0xab, + 0xbc, 0xbc, 0xdc, 0xfe, 0x55, 0xee, 0xcc, 0x45, 0xe8, 0x08, 0x43, 0x25, 0xc8, 0x6c, 0x73, 0x95, + 0xa7, 0xa7, 0x7b, 0x6c, 0x56, 0x2a, 0x25, 0xd3, 0x25, 0x25, 0x7e, 0x13, 0xae, 0x34, 0x95, 0xca, + 0x47, 0x97, 0x99, 0x29, 0x09, 0xb6, 0xf9, 0xdc, 0x22, 0xfd, 0xfb, 0x2a, 0x14, 0x12, 0x99, 0x2b, + 0x2d, 0x3b, 0xdb, 0x73, 0xff, 0xaa, 0xef, 0xba, 0x7f, 0x6d, 0x7f, 0x01, 0x03, 0xc2, 0x73, 0xc0, + 0xbc, 0xef, 0xab, 0xb5, 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 cc86e376c0..2ce8440eb1 100644 --- a/bitmaps_png/cpp_48/icon_pcbcalculator.cpp +++ b/bitmaps_png/cpp_48/icon_pcbcalculator.cpp @@ -8,188 +8,189 @@ 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, 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, + 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, }; 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 a286bdec89..4c53e9151f 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, this ) ); + SetBoard( new BOARD( NULL ) ); SetScreen( new PCB_SCREEN() ); LoadSettings(); @@ -68,6 +68,7 @@ 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 eb2d182aa9..76b759492e 100644 --- a/gerbview/class_gerber_draw_item.cpp +++ b/gerbview/class_gerber_draw_item.cpp @@ -41,10 +41,11 @@ #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; @@ -339,10 +340,8 @@ 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; @@ -486,6 +485,14 @@ 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 f267bc047e..0571d9d4b2 100644 --- a/gerbview/draw_gerber_screen.cpp +++ b/gerbview/draw_gerber_screen.cpp @@ -139,6 +139,7 @@ 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; @@ -173,9 +174,11 @@ 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*) m_PcbFrame )->getActiveLayer(); + int active_layer = ( (GERBVIEW_FRAME*) aPanel->GetParent() )->getActiveLayer(); + if( layer == active_layer ) // active layer will be drawn after other layers continue; @@ -205,6 +208,7 @@ 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 @@ -212,8 +216,7 @@ 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 ) { @@ -224,9 +227,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 ); @@ -256,7 +259,7 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDrawMode, const wxPoin int dcode_highlight = 0; - if( layer == ( (GERBVIEW_FRAME*) m_PcbFrame )->getActiveLayer() ) + if( layer == ( (GERBVIEW_FRAME*) aPanel->GetParent() )->getActiveLayer() ) dcode_highlight = gerber->m_Selected_Tool; int layerdrawMode = GR_COPY; @@ -277,6 +280,7 @@ 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; } @@ -297,14 +301,12 @@ 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 9f215f017f..03c9b674aa 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_gerbview_frame ); + m_pcb = new BOARD( NULL ); } GBR_TO_PCB_EXPORTER::~GBR_TO_PCB_EXPORTER() diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp index b6fb086b37..e4c3655c79 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, this ) ); + SetBoard( new BOARD( NULL ) ); 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,34 +144,6 @@ 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 704202b0cf..0461de7026 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,7 +68,6 @@ 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 2766636d49..8f5924a8e0 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -357,8 +357,7 @@ 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 b591dd67e8..4df661e2c9 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -182,7 +182,6 @@ 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 309d092a6e..6da53e3c87 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 = MarkTrace( GetBoard(), track, &nb_segm, NULL, NULL, true ); + Track = GetBoard()->MarkTrace( 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 f3f62d184d..576eba9881 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -105,32 +105,48 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard ) double PCB_BASE_FRAME::BestZoom( void ) { int dx, dy; - double ii, jj; + double zx, zy; wxSize size; + wxPoint center; - if( m_Pcb == NULL ) - return 32.0; + 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; + } - m_Pcb->ComputeBoundingBox(); + center = wxPoint( dx / 2, dy / 2 ); + } - dx = m_Pcb->m_BoundaryBox.GetWidth(); - dy = m_Pcb->m_BoundaryBox.GetHeight(); size = DrawPanel->GetClientSize(); if( size.x ) - ii = (double)(dx + ( size.x / 2) ) / (double) size.x; + zx = (double) dx / (double) size.x; else - ii = 32.0; + zx = 32.0; if ( size.y ) - jj = (double)( dy + (size.y / 2) ) / (double) size.y; + zy = (double) dy / (double) size.y; else - jj = 32.0; + zy = 32.0; - double bestzoom = MAX( ii, jj ); - GetScreen()->SetScrollCenterPosition( m_Pcb->m_BoundaryBox.Centre() ); + double bestzoom = MAX( zx, zy ); + GetScreen()->SetScrollCenterPosition( center ); - return bestzoom ; + return bestzoom; } diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index efe493b69b..386ef7e10c 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -19,26 +19,67 @@ 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* parent, PCB_BASE_FRAME* frame ) : - BOARD_ITEM( (BOARD_ITEM*)parent, TYPE_PCB ), +BOARD::BOARD( EDA_ITEM* aParent ) : + BOARD_ITEM( (BOARD_ITEM*) aParent, 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 ) @@ -47,12 +88,10 @@ BOARD::BOARD( EDA_ITEM* parent, PCB_BASE_FRAME* frame ) : 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 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 the 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; @@ -64,9 +103,6 @@ BOARD::BOARD( EDA_ITEM* parent, PCB_BASE_FRAME* frame ) : BOARD::~BOARD() { - if( m_PcbFrame->GetScreen() ) - m_PcbFrame->GetScreen()->ClearUndoRedoList(); - while( m_ZoneDescriptorList.size() ) { ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0]; @@ -87,20 +123,124 @@ BOARD::~BOARD() } -/* - * Function PushHightLight - * save current hight light info for later use - */ +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; + } + } +} + + void BOARD::PushHightLight() { m_hightLightPrevious = m_hightLight; } -/* - * Function PopHightLight - * retrieve a previously saved hight light info - */ void BOARD::PopHightLight() { m_hightLight = m_hightLightPrevious; @@ -108,15 +248,6 @@ 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 ); @@ -165,10 +296,6 @@ 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(); @@ -184,11 +311,6 @@ 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 ); @@ -197,11 +319,6 @@ 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 ); @@ -380,11 +497,13 @@ 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 ); @@ -548,13 +667,6 @@ 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 ) @@ -834,23 +946,6 @@ 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; @@ -858,9 +953,6 @@ 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; @@ -1174,12 +1266,6 @@ 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. @@ -1202,12 +1288,6 @@ 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. @@ -1286,6 +1366,125 @@ 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 @@ -1320,20 +1519,185 @@ MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const } -// Sort nets by decreasing pad count +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 ); +} + + 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 ) @@ -1439,10 +1803,6 @@ 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 ) @@ -1458,10 +1818,6 @@ 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 ) @@ -1477,18 +1833,6 @@ 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 ) @@ -1519,19 +1863,6 @@ 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; @@ -1565,15 +1896,248 @@ 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 6bcbf40485..e4f0ed9dfe 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -1,6 +1,7 @@ -/*************************************************/ -/* class_board.h - Class BOARD to handle a board */ -/*************************************************/ +/** + * @file class_board.h + * @brief Class BOARD to handle a board + */ #ifndef CLASS_BOARD_H #define CLASS_BOARD_H @@ -12,8 +13,29 @@ 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. @@ -41,7 +63,6 @@ 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* @@ -78,8 +99,7 @@ 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); } @@ -87,14 +107,17 @@ 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 @@ -112,51 +135,52 @@ 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 - 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 + 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 public: - 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) + 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; // Rastnest list for the BOARD - std::vector m_LocalRatsnest; /* Rastnest list relative to a given footprint - * (used while moving a footprint) */ + 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) */ - 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: @@ -167,6 +191,7 @@ 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 @@ -174,9 +199,25 @@ 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, PCB_BASE_FRAME* frame ); + BOARD( EDA_ITEM* aParent ); ~BOARD(); /** @@ -207,7 +248,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 @@ -217,9 +258,10 @@ 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 such calls with NULL + wxASSERT( aBoardItem ); // developers should run DEBUG versions and fix calls with NULL + if( aBoardItem ) delete Remove( aBoardItem ); } @@ -227,8 +269,7 @@ 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. */ @@ -239,14 +280,13 @@ 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 @@ -258,6 +298,7 @@ public: { if( (unsigned) index < m_markers.size() ) return m_markers[index]; + return NULL; } @@ -333,7 +374,7 @@ public: * Function GetCopperLayerCount * @return int - The number of copper layers in the BOARD. */ - int GetCopperLayerCount() const; + int GetCopperLayerCount() const; void SetCopperLayerCount( int aCount ); @@ -344,7 +385,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 @@ -384,7 +425,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 @@ -404,7 +445,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 @@ -455,9 +496,9 @@ public: * returns the color of a pcb visible element. * @see enum PCB_VISIBLE */ - int GetVisibleElementColor( int aPCB_VISIBLE ); - void SetVisibleElementColor( int aPCB_VISIBLE, int aColor ); + int GetVisibleElementColor( int aPCB_VISIBLE ); + void SetVisibleElementColor( int aPCB_VISIBLE, int aColor ); /** * Function GetBoardDesignSettings @@ -515,7 +556,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 @@ -525,7 +566,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 @@ -535,30 +576,32 @@ 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(); } @@ -574,7 +617,7 @@ public: * Function GetPadsCount * @return the number of pads in board */ - unsigned GetPadsCount() + unsigned GetPadsCount() { return m_NetInfo->GetPadsCount(); } @@ -585,7 +628,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 @@ -594,7 +637,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. @@ -604,8 +647,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 @@ -616,7 +659,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 @@ -651,6 +694,36 @@ 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 @@ -660,15 +733,95 @@ public: * @return MODULE* - If found, the MODULE having the given reference * designator, else NULL. */ - MODULE* FindModuleByReference( const wxString& aReference ) const; + 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 ); /** * 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 ); + 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 ); /**************************************/ /** @@ -678,9 +831,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(); @@ -706,7 +859,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]; } @@ -718,7 +871,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; } @@ -742,14 +895,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(); /***************************************************************************/ @@ -761,7 +914,6 @@ public: */ bool Save( FILE* aFile ) const; - /** * Function GetClass * returns the class name. @@ -809,10 +961,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 @@ -906,7 +1058,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 @@ -919,7 +1071,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 @@ -937,11 +1089,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 @@ -965,8 +1117,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 @@ -981,8 +1133,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 ); @@ -1004,13 +1156,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 @@ -1019,9 +1171,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 @@ -1034,8 +1186,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: */ @@ -1045,6 +1197,29 @@ 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 0aecfdf49c..1f081fab43 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -819,6 +819,22 @@ 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 cb36aa9d8a..38f14f8135 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -298,6 +298,16 @@ 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 95410d1dae..7caa4c8033 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -152,14 +152,15 @@ 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 ); @@ -173,30 +174,14 @@ 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 ) @@ -215,7 +200,6 @@ int TRACK::GetDrillValue() const } -// return true if segment length = 0 bool TRACK::IsNull() { if( ( Type() != TYPE_VIA ) && ( m_Start == m_End ) ) @@ -225,24 +209,17 @@ bool TRACK::IsNull() } -/* 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 TRACK::IsPointOnEnds( const wxPoint& aPosition, int aDistance ) { int result = 0; - if( min_dist < 0 ) - min_dist = m_Width / 2; + if( aDistance < 0 ) + aDistance = m_Width / 2; - int dx = m_Start.x - point.x; - int dy = m_Start.y - point.y; + int dx = m_Start.x - aPosition.x; + int dy = m_Start.y - aPosition.y; - if( min_dist == 0 ) + if( aDistance == 0 ) { if( (dx == 0) && (dy == 0 ) ) result |= STARTPOINT; @@ -251,14 +228,14 @@ int TRACK::IsPointOnEnds( const wxPoint& point, int min_dist ) { double dist = hypot( (double)dx, (double) dy ); - if( min_dist >= (int) dist ) + if( aDistance >= (int) dist ) result |= STARTPOINT; } - dx = m_End.x - point.x; - dy = m_End.y - point.y; + dx = m_End.x - aPosition.x; + dy = m_End.y - aPosition.y; - if( min_dist == 0 ) + if( aDistance == 0 ) { if( (dx == 0) && (dy == 0 ) ) result |= ENDPOINT; @@ -267,7 +244,7 @@ int TRACK::IsPointOnEnds( const wxPoint& point, int min_dist ) { double dist = hypot( (double) dx, (double) dy ); - if( min_dist >= (int) dist ) + if( aDistance >= (int) dist ) result |= ENDPOINT; } @@ -331,12 +308,6 @@ 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 ); @@ -344,29 +315,18 @@ 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 ) - { - // Huh? Wouldn't it be better to us Type() != VIA and get rid of these brackets? - } - else + if( Type() != TYPE_VIA ) { 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[] ) { @@ -400,9 +360,6 @@ 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 ) @@ -435,14 +392,6 @@ 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 ) @@ -458,13 +407,6 @@ 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; @@ -506,9 +448,6 @@ 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; @@ -538,9 +477,6 @@ 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; @@ -760,6 +696,226 @@ 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; @@ -830,17 +986,19 @@ 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; @@ -977,7 +1135,6 @@ 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; @@ -991,7 +1148,7 @@ void TRACK::DisplayInfo( EDA_DRAW_FRAME* frame ) { int trackLen = 0; int lenDie = 0; - MarkTrace( board, this, NULL, &trackLen, &lenDie, false ); + board->MarkTrace( this, NULL, &trackLen, &lenDie, false ); msg = frame->CoordinateToString( trackLen ); frame->AppendMsgPanel( _( "Track Len" ), msg, DARKCYAN ); @@ -1026,13 +1183,6 @@ 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; @@ -1148,12 +1298,6 @@ 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; @@ -1180,13 +1324,6 @@ 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 ) ) @@ -1231,13 +1368,6 @@ 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() << @@ -1258,13 +1388,6 @@ 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 45dce8fa37..06e86afb9d 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -1,6 +1,7 @@ -/*******************************************************************/ -/* class_track.h: definitions relatives to tracks, vias and zones */ -/*******************************************************************/ +/** + * @file class_track.h + * @brief Class definitions for tracks, vias, and zones. + */ #ifndef CLASS_TRACK_H #define CLASS_TRACK_H @@ -16,6 +17,9 @@ * to the near neighbor internal layer */ #define VIA_NOT_DEFINED 0 /* not yet used */ +#define IGNORE_LAYERS -1 + + /***/ class TRACK : public BOARD_CONNECTED_ITEM @@ -105,7 +109,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 @@ -115,24 +119,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; @@ -141,9 +145,53 @@ 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; } @@ -196,15 +244,20 @@ public: * TRACK segment or SEGVIA physically resides. * @return int - a layer mask, see pcbstruct.h's LAYER_BACK, etc. */ - int ReturnMaskLayer(); + int ReturnMaskLayer(); - int IsPointOnEnds( const wxPoint& point, int min_dist = 0 ); + /** + * 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 ); /** * Function IsNull * returns true if segment length is zero. */ - bool IsNull(); + bool IsNull(); /** * Function DisplayInfo @@ -214,7 +267,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 @@ -223,13 +276,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 @@ -244,8 +297,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[] ); /** @@ -254,7 +307,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) @@ -263,7 +316,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 @@ -348,9 +401,8 @@ 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 @@ -359,10 +411,28 @@ 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; - void SetLayerPair( int top_layer, int bottom_layer ); - void ReturnLayerPair( int* top_layer, int* bottom_layer ) 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; /** * Function GetPosition @@ -375,7 +445,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 f58dd38b7b..84074a1563 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -857,43 +857,26 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos ) } -/** - * 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 ) +bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& aPosition, int aMinDistance ) { m_CornerSelection = -1; // Set to not found - #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; + int x, y; + int closestDistance = aMinDistance; unsigned lim = m_Poly->corner.size(); for( unsigned item_pos = 0; item_pos < lim; item_pos++ ) { - 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( delta.x ), abs( delta.y ) ); + x = aPosition.x - m_Poly->corner[item_pos].x; + y = aPosition.y - m_Poly->corner[item_pos].y; - if( dist < min_dist ) // this corner is a candidate: + // Calculate a distance: + int dist = MAX( abs( x ), abs( y ) ); + + if( dist < closestDistance ) // this corner is a candidate: { m_CornerSelection = item_pos; - min_dist = dist; + closestDistance = dist; } } @@ -901,31 +884,13 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) } -/** - * 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 ) +bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& aPosition, int aMinDistance ) { unsigned lim = m_Poly->corner.size(); m_CornerSelection = -1; // Set to not found - #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 ) ); - } + int closestDistance = aMinDistance; unsigned first_corner_pos = 0; @@ -945,17 +910,17 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) } /* test the dist between segment and ref point */ - int dist = (int) GetPointToLineSegmentDistance( refPos.x, - refPos.y, + int dist = (int) GetPointToLineSegmentDistance( aPosition.x, + aPosition.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 < min_dist ) + if( dist < closestDistance ) { m_CornerSelection = item_pos; - min_dist = dist; + closestDistance = dist; } } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index ed8d296bfd..4bdd9240c1 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -12,6 +12,10 @@ #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 { @@ -246,21 +250,23 @@ public: /** * Function HitTestForCorner - * tests if the given wxPoint near a corner + * tests if \a aPosition is with \a aDistance a zone corner. * Set m_CornerSelection to -1 if nothing found, or index of corner * @return true if found - * @param refPos : A wxPoint to test + * @param aPosition A wxPoint to test + * @param aMinDistance The minimum distance with \a aPosition that will still yield a hit. */ - bool HitTestForCorner( const wxPoint& refPos ); + bool HitTestForCorner( const wxPoint& aPosition, int aMinDistance = CORNER_MIN_DIST ); /** * 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 refPos : A wxPoint to test + * @param aPosition A wxPoint to test + * @param aMinDistance The minimum distance with \a aPosition that will still yield a hit. */ - bool HitTestForEdge( const wxPoint& refPos ); + bool HitTestForEdge( const wxPoint& aPosition, int aMinDistance = EDGE_MIN_DIST ); /** * Function HitTest (overlayed) diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 0c8ae7fcde..b63913695b 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 = Fast_Locate_Pad_Connecte( aPcb, track->m_Start, ALL_CU_LAYERS ); + D_PAD* pad = aPcb->GetPadFast( 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 = Fast_Locate_Pad_Connecte( frame->GetBoard(), segment->m_Start, masklayer ); + pad = frame->GetBoard()->GetPadFast( 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 = Fast_Locate_Pad_Connecte( frame->GetBoard(), segment->m_End, masklayer ); + pad = frame->GetBoard()->GetPadFast( segment->m_End, masklayer ); if( pad != NULL ) { @@ -601,8 +601,7 @@ static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extre if( extremite == START ) { /* We do not have a pad */ - if( Fast_Locate_Pad_Connecte( Pcb, pt_ref->m_Start, - g_TabOneLayerMask[pt_ref->GetLayer()] ) ) + if( Pcb->GetPadFast( pt_ref->m_Start, g_TabOneLayerMask[pt_ref->GetLayer()] ) ) return NULL; /* change the common point coordinate of pt_segm tu use the other point @@ -621,8 +620,7 @@ static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extre else /* extremite == END */ { /* We do not have a pad */ - if( Fast_Locate_Pad_Connecte( Pcb, pt_ref->m_End, - g_TabOneLayerMask[pt_ref->GetLayer()] ) ) + if( Pcb->GetPadFast( pt_ref->m_End, g_TabOneLayerMask[pt_ref->GetLayer()] ) ) return NULL; /* change the common point coordinate of pt_segm tu use the other point @@ -782,7 +780,7 @@ static void Gen_Raccord_Track( PCB_EDIT_FRAME* frame, wxDC* DC ) { TRACK* newTrack; - other = GetTrace( other, segment->m_Start, layerMask ); + other = frame->GetBoard()->GetTrace( other, segment->m_Start, layerMask ); if( other == NULL ) break; @@ -831,7 +829,7 @@ static void Gen_Raccord_Track( PCB_EDIT_FRAME* frame, wxDC* DC ) { TRACK* newTrack; - other = GetTrace( other, segment->m_End, layerMask ); + other = frame->GetBoard()->GetTrace( other, segment->m_End, layerMask ); if( other == NULL ) break; @@ -980,7 +978,7 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* frame, wxDC* DC ) if( frame->DrawPanel->m_AbortRequest ) return; - pad = Locate_Pad_Connecte( frame->GetBoard(), segment, START ); + pad = frame->GetBoard()->GetPad( segment, START ); if( pad ) { @@ -1004,7 +1002,7 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* frame, wxDC* DC ) } } - pad = Locate_Pad_Connecte( frame->GetBoard(), segment, END ); + pad = frame->GetBoard()->GetPad( segment, END ); if( pad ) { diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp index fe261aaed3..2761e95580 100644 --- a/pcbnew/connect.cpp +++ b/pcbnew/connect.cpp @@ -562,28 +562,6 @@ 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: @@ -622,7 +600,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() /**************************************************************/ /* Pass 1: search the connections between track ends and pads */ /**************************************************************/ - CreateSortedPadListByXCoord( m_Pcb, &sortedPads ); + m_Pcb->CreateSortedPadListByXCoord( &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 344db56e5b..4329fb66d6 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 = MarkTrace( GetBoard(), pt_segm, &segments_to_delete_count, - NULL, NULL, true ); + TRACK* trackList = GetBoard()->MarkTrace( 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 4923c48668..f0838d8372 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -411,7 +411,7 @@ void DRC::testPad2Pad() { std::vector sortedPads; - CreateSortedPadListByXCoord( m_pcb, &sortedPads ); + m_pcb->CreateSortedPadListByXCoord( &sortedPads ); // find the max size of the pads (used to stop the test) int max_size = 0; @@ -420,7 +420,8 @@ void DRC::testPad2Pad() { D_PAD* pad = sortedPads[i]; - if( pad->m_ShapeMaxRadius > max_size ) // m_ShapeMaxRadius is the radius value of the circle containing the pad + // m_ShapeMaxRadius is the radius value of the circle containing the pad. + if( pad->m_ShapeMaxRadius > max_size ) max_size = pad->m_ShapeMaxRadius; } diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index d4080c55e8..40bab98dc2 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 = CreateLockPoint( GetBoard(), pos, track, &itemsListPicker ); + TRACK* newtrack = GetBoard()->CreateLockPoint( 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 225bf4ba15..1004b8b2bb 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 = MarkTrace( GetBoard(), aTrackSegment, &nb_segm, NULL, NULL, true ); + pt_track = GetBoard()->MarkTrace( 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 77cf7eb03d..6a5c9050fe 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 = MarkTrace( GetBoard(), pt_segm, &nb_segm, NULL, NULL, true ); + pt_track = GetBoard()->MarkTrace( 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 = Locate_Pad_Connecte( GetBoard(), pt_segm, START ); - pt_segm->end = Locate_Pad_Connecte( GetBoard(), pt_segm, END ); + pt_segm->start = GetBoard()->GetPad( pt_segm, START ); + pt_segm->end = GetBoard()->GetPad( 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( Locate_Via( GetBoard(), g_CurrentTrackSegment->m_End, g_CurrentTrackSegment->GetLayer() ) ) + if( GetBoard()->GetVia( 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 = GetTrace( GetBoard(), GetBoard()->m_Track, pos, layerMask ); + pt_segm = GetBoard()->GetTrace( pos, layerMask ); if( pt_segm == NULL ) GetBoard()->DisplayInfo( this ); diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index fbcf43afea..3a430d6102 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 = LocateLockPoint( GetBoard(), pos, layerMask ); + LockPoint = GetBoard()->GetLockPoint( 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() ); - CreateLockPoint( GetBoard(), pos, TrackOnStartPoint, &s_ItemsListPicker ); + GetBoard()->CreateLockPoint( 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 = Locate_Pad_Connecte( GetBoard(), oneBeforeLatest, END ); + oneBeforeLatest->end = GetBoard()->GetPad( 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 = LocateLockPoint( GetBoard(), pos, layerMask ); + BOARD_ITEM* LockPoint = GetBoard()->GetLockPoint( pos, layerMask ); if( LockPoint ) /* End of trace is on a pad. */ { @@ -466,10 +466,9 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* DC ) GetBoard()->SetHightLightNet( adr_buf->GetNet() ); /* Possible establishment of a hanging point. */ - LockPoint = CreateLockPoint( GetBoard(), - g_CurrentTrackSegment->m_End, - adr_buf, - &s_ItemsListPicker ); + LockPoint = GetBoard()->CreateLockPoint( g_CurrentTrackSegment->m_End, + adr_buf, + &s_ItemsListPicker ); } } @@ -1050,7 +1049,7 @@ void DeleteNullTrackSegments( BOARD* pcb, DLIST& aTrackList ) while( track != NULL ) { TRACK* next_track = track->Next(); - LockPoint = Locate_Pad_Connecte( pcb, track, END ); + LockPoint = pcb->GetPad( track, END ); if( LockPoint ) { diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp index 6086ae8c71..c4070556a2 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 = Locate_Prefered_Module( GetBoard(), pos, screen->m_Active_Layer, true ); + module = GetBoard()->GetModule( 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 = Locate_Prefered_Module( GetBoard(), pos, ALL_LAYERS, false ); + MODULE* module = GetBoard()->GetModule( pos, ALL_LAYERS, false ); if( module == NULL ) return false; @@ -659,14 +659,19 @@ 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 bd8a724920..2a8003abe5 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, this ) ); + SetBoard( new BOARD( NULL ) ); SetCurItem( NULL ); /* clear filename, to avoid overwriting an old file */ diff --git a/pcbnew/locate.cpp b/pcbnew/locate.cpp index a7cb4bb2c5..2016ce796c 100644 --- a/pcbnew/locate.cpp +++ b/pcbnew/locate.cpp @@ -13,246 +13,6 @@ -/* 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) @@ -265,7 +25,9 @@ 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; @@ -419,168 +181,3 @@ 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 dcbe7cf126..f4b42cc061 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 = Locate_Any_Pad( m_Pcb, pos, layer_mask ); + D_PAD* pad = m_Pcb->GetPad( 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 = Locate_Via_Area( via, *curpos, layer )) != NULL; + via && (via = via->GetVia( *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 = GetTrace( m_Pcb, m_Pcb->m_Track, pos, layer_mask ); + TRACK* track = m_Pcb->m_Track->GetTrace( pos, layer_mask ); if( !track || track->Type() != TYPE_TRACK ) { diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 511e2023b9..0f7615757e 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -127,10 +127,9 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( wxWindow* father, UpdateTitle(); if( g_ModuleEditor_Pcb == NULL ) - g_ModuleEditor_Pcb = new BOARD( NULL, this ); + g_ModuleEditor_Pcb = new BOARD( NULL ); 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 2a0d077869..47850ee3b7 100644 --- a/pcbnew/move_or_drag_track.cpp +++ b/pcbnew/move_or_drag_track.cpp @@ -1019,14 +1019,15 @@ 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 = Fast_Locate_Pad_Connecte( GetBoard(), Track->m_Start, layerMask ); + Track->start = GetBoard()->GetPadFast( Track->m_Start, layerMask ); if( Track->start ) Track->SetState( BEGIN_ONPAD, ON ); else Track->SetState( BEGIN_ONPAD, OFF ); - Track->end = Fast_Locate_Pad_Connecte( GetBoard(), Track->m_End, layerMask ); + Track->end = GetBoard()->GetPadFast( Track->m_End, layerMask ); + if( Track->end ) Track->SetState( END_ONPAD, ON ); else @@ -1054,147 +1055,3 @@ 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 6e30a51fa1..26ae935332 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -48,7 +48,8 @@ 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 { @@ -166,7 +167,8 @@ 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 ) ); @@ -293,7 +295,8 @@ 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 ) ); @@ -375,7 +378,8 @@ 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 ) ); @@ -404,7 +408,8 @@ 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 { @@ -485,10 +490,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 ) ); @@ -497,7 +502,8 @@ 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 @@ -511,7 +517,8 @@ 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 ); @@ -557,14 +564,19 @@ void PCB_EDIT_FRAME::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* AddMenuItem( aPopMenu, zones_menu, -1, _( "Zones" ), KiBitmap( add_zone_xpm ) ); - if( edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) ) + // Use grid size because it is known + wxRealPoint grid = DrawPanel->GetGrid(); + + if( edge_zone->HitTestForCorner( GetScreen()->RefPos( true ), + wxRound( MIN( grid.x, grid.y ) ) ) ) { 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 ) ) ) + else if( edge_zone->HitTestForEdge( GetScreen()->RefPos( true ), + wxRound( MIN( grid.x, grid.y ) ) ) ) { AddMenuItem( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER, _( "Create Corner" ), KiBitmap( add_corner_xpm ) ); @@ -582,7 +594,8 @@ 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 ) { @@ -645,7 +658,8 @@ 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 ) ); @@ -725,8 +739,10 @@ 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(); @@ -790,14 +806,17 @@ 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 f407f820b6..2a2b3aceeb 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -277,10 +277,11 @@ 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, this ) ); + SetBoard( new BOARD( NULL ) ); // Create the PCB_LAYER_WIDGET *after* SetBoard(): @@ -417,6 +418,7 @@ 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 6e50cefda1..f7e060db30 100644 --- a/pcbnew/protos.h +++ b/pcbnew/protos.h @@ -1,16 +1,11 @@ -/***********/ -/* protos.h */ -/***********/ +/** + * @file pcbnew/protos.h + */ #ifndef PROTO_H #define PROTO_H -#include - - -class COMMAND; - /** * Function SwapData * Used in undo / redo command: @@ -22,24 +17,6 @@ class COMMAND; 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 */ /***************/ @@ -66,31 +43,6 @@ 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 @@ -100,86 +52,6 @@ TRACK* GetTrace( TRACK* start_adr, TRACK* end_adr, const wxPoint& ref_pos, int m */ 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 */ @@ -204,84 +76,9 @@ 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 86a20a2eec..7d8dc68eee 100644 --- a/pcbnew/solve.cpp +++ b/pcbnew/solve.cpp @@ -1268,14 +1268,12 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) g_CurrentTrackList.PushBack( newTrack ); } - g_FirstTrackSegment->start = Locate_Pad_Connecte( pcbframe->GetBoard(), - g_FirstTrackSegment, START ); + g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment, START ); if( g_FirstTrackSegment->start ) g_FirstTrackSegment->SetState( BEGIN_ONPAD, ON ); - g_CurrentTrackSegment->end = Locate_Pad_Connecte( pcbframe->GetBoard(), - g_CurrentTrackSegment, END ); + g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( 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 a2e06772b8..24876b2fc8 100644 --- a/pcbnew/tr_modif.cpp +++ b/pcbnew/tr_modif.cpp @@ -10,8 +10,6 @@ #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 ); /** @@ -54,7 +52,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, if( aNewTrack->Type() == TYPE_VIA && ( aNewTrackSegmentsCount > 1 ) ) aNewTrack = aNewTrack->Next(); - aNewTrack = MarkTrace( GetBoard(), aNewTrack, &aNewTrackSegmentsCount, NULL, NULL, true ); + aNewTrack = GetBoard()->MarkTrace( aNewTrack, &aNewTrackSegmentsCount, NULL, NULL, true ); wxASSERT( aNewTrack ); #if 0 && defined(DEBUG) @@ -92,7 +90,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, break; } - if( ReturnEndsTrack( aNewTrack, aNewTrackSegmentsCount, &StartTrack, &EndTrack ) == 0 ) + if( aNewTrack->GetEndSegments( aNewTrackSegmentsCount, &StartTrack, &EndTrack ) == 0 ) return 0; if( ( StartTrack == NULL ) || ( EndTrack == NULL ) ) @@ -110,7 +108,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 = Fast_Locate_Via( m_Pcb->m_Track, NULL, start, startmasklayer ); + pt_segm = m_Pcb->m_Track->GetVia( NULL, start, startmasklayer ); if( pt_segm ) startmasklayer |= pt_segm->ReturnMaskLayer(); @@ -122,7 +120,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, startmasklayer |= pt_pad->m_layerMask; } - pt_segm = Fast_Locate_Via( m_Pcb->m_Track, NULL, end, endmasklayer ); + pt_segm = m_Pcb->m_Track->GetVia( NULL, end, endmasklayer ); if( pt_segm ) endmasklayer |= pt_segm->ReturnMaskLayer(); @@ -141,7 +139,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 = GetTrace( bufStart, bufEnd, start, startmasklayer ); + pt_segm = GetTraceByEndPoint( bufStart, bufEnd, start, startmasklayer ); if( pt_segm == NULL ) /* Not connected to the track starting point. */ { @@ -156,7 +154,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, */ for( pt_del = bufStart, nbconnect = 0; ; ) { - pt_segm = GetTrace( pt_del, bufEnd, end, endmasklayer ); + pt_segm = GetTraceByEndPoint( pt_del, bufEnd, end, endmasklayer ); if( pt_segm == NULL ) break; @@ -211,7 +209,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, nbconnect--; pt_del->SetState( IS_LINKED, OFF ); - pt_del = MarkTrace( GetBoard(), pt_del, &nb_segm, NULL, NULL, true ); + pt_del = GetBoard()->MarkTrace( 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 deleted file mode 100644 index b6e3f51d95..0000000000 --- a/pcbnew/track.cpp +++ /dev/null @@ -1,541 +0,0 @@ -/***************** -* 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; -}