diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 734fb5fc29..4d9dd7d45b 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -397,6 +397,7 @@ set( EESCHEMA_SRCS symbol_tree_model_adapter.cpp symbol_tree_synchronizing_adapter.cpp symbol_viewer_frame.cpp + symb_transforms_utils.cpp toolbars_sch_editor.cpp toolbars_symbol_viewer.cpp diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index ff8a90520a..22cdb00489 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -68,6 +68,8 @@ #include "sch_shape.h" #include "common.h" +#include "symb_transforms_utils.h" + namespace KIGFX { @@ -2429,56 +2431,6 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer ) } -static void orientSymbol( LIB_SYMBOL* symbol, int orientation ) -{ - struct ORIENT - { - int flag; - int n_rots; - int mirror_x; - int mirror_y; - } - orientations[] = - { - { SYM_ORIENT_0, 0, 0, 0 }, - { SYM_ORIENT_90, 1, 0, 0 }, - { SYM_ORIENT_180, 2, 0, 0 }, - { SYM_ORIENT_270, 3, 0, 0 }, - { SYM_MIRROR_X + SYM_ORIENT_0, 0, 1, 0 }, - { SYM_MIRROR_X + SYM_ORIENT_90, 1, 1, 0 }, - { SYM_MIRROR_Y, 0, 0, 1 }, - { SYM_MIRROR_X + SYM_ORIENT_270, 3, 1, 0 }, - { SYM_MIRROR_Y + SYM_ORIENT_0, 0, 0, 1 }, - { SYM_MIRROR_Y + SYM_ORIENT_90, 1, 0, 1 }, - { SYM_MIRROR_Y + SYM_ORIENT_180, 2, 0, 1 }, - { SYM_MIRROR_Y + SYM_ORIENT_270, 3, 0, 1 } - }; - - ORIENT o = orientations[ 0 ]; - - for( ORIENT& i : orientations ) - { - if( i.flag == orientation ) - { - o = i; - break; - } - } - - for( LIB_ITEM& item : symbol->GetDrawItems() ) - { - for( int i = 0; i < o.n_rots; i++ ) - item.Rotate( VECTOR2I(0, 0 ), true ); - - if( o.mirror_x ) - item.MirrorVertical( VECTOR2I( 0, 0 ) ); - - if( o.mirror_y ) - item.MirrorHorizontal( VECTOR2I( 0, 0 ) ); - } -} - - wxString SCH_PAINTER::expandLibItemTextVars( const wxString& aSourceText, const SCH_SYMBOL* aSymbolContext ) { @@ -2530,7 +2482,7 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer ) tempSymbol.SetFlags( aSymbol->GetFlags() ); - orientSymbol( &tempSymbol, aSymbol->GetOrientation() ); + OrientAndMirrorSymbolItems( &tempSymbol, aSymbol->GetOrientation() ); for( LIB_ITEM& tempItem : tempSymbol.GetDrawItems() ) { diff --git a/eeschema/symb_transforms_utils.cpp b/eeschema/symb_transforms_utils.cpp new file mode 100644 index 0000000000..b15e287cde --- /dev/null +++ b/eeschema/symb_transforms_utils.cpp @@ -0,0 +1,107 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Author Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +#include "lib_symbol.h" +#include "sch_symbol.h" +#include "sch_pin.h" + +struct ORIENT_MIRROR +{ + int flag; + int n_rots; + int mirror_x; + int mirror_y; +}; + + +// symbols_orientations_list is the list of possible orientation+mirror values +// like returned by SCH_SYMBOL::GetOrientation() +// Some transforms are equivalent, like rotation 180 + mirror X = mirror Y + +static ORIENT_MIRROR symbols_orientations_list[] = +{ + { SYM_ORIENT_0, 0, 0, 0 }, + { SYM_ORIENT_90, 1, 0, 0 }, + { SYM_ORIENT_180, 2, 0, 0 }, + { SYM_ORIENT_270, 3, 0, 0 }, + { SYM_MIRROR_X + SYM_ORIENT_0, 0, 1, 0 }, + { SYM_MIRROR_X + SYM_ORIENT_90, 1, 1, 0 }, + { SYM_MIRROR_Y, 0, 0, 1 }, + { SYM_MIRROR_X + SYM_ORIENT_270, 3, 1, 0 }, + { SYM_MIRROR_Y + SYM_ORIENT_0, 0, 0, 1 }, + { SYM_MIRROR_Y + SYM_ORIENT_90, 1, 0, 1 }, + { SYM_MIRROR_Y + SYM_ORIENT_180, 2, 0, 1 }, + { SYM_MIRROR_Y + SYM_ORIENT_270, 3, 0, 1 } +}; + + +void OrientAndMirrorSymbolItems( LIB_SYMBOL* aSymbol, int aOrientation ) +{ + ORIENT_MIRROR o = symbols_orientations_list[ 0 ]; + + for( ORIENT_MIRROR& i : symbols_orientations_list ) + { + if( i.flag == aOrientation ) + { + o = i; + break; + } + } + + for( LIB_ITEM& item : aSymbol->GetDrawItems() ) + { + for( int i = 0; i < o.n_rots; i++ ) + item.Rotate( VECTOR2I( 0, 0 ), true ); + + if( o.mirror_x ) + item.MirrorVertical( VECTOR2I( 0, 0 ) ); + + if( o.mirror_y ) + item.MirrorHorizontal( VECTOR2I( 0, 0 ) ); + } +} + + + +// Rotate and/or mirror a SCH_PIN according to aOrientMirror. +// aOrientMirror is the orientation/mirror of the parent symbol. +// The modified pin orientation is the actual pin orientation/mirror +// when the parent symbol is drawn. +void RotateAndMirrorPin( LIB_PIN& aPin, int aOrientMirror ) +{ + ORIENT_MIRROR o = symbols_orientations_list[ 0 ]; + + for( ORIENT_MIRROR& i : symbols_orientations_list ) + { + if( i.flag == aOrientMirror ) + { + o = i; + break; + } + } + + for( int i = 0; i < o.n_rots; i++ ) + aPin.Rotate( VECTOR2I( 0, 0 ), true ); + + if( o.mirror_x ) + aPin.MirrorVertical( VECTOR2I( 0, 0 ) ); + + if( o.mirror_y ) + aPin.MirrorHorizontal( VECTOR2I( 0, 0 ) ); +} diff --git a/eeschema/symb_transforms_utils.h b/eeschema/symb_transforms_utils.h new file mode 100644 index 0000000000..f26f93503c --- /dev/null +++ b/eeschema/symb_transforms_utils.h @@ -0,0 +1,42 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Author Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#pragma once + +class LIB_SYMBOL; +class LIB_PIN; + +/** + * Rotate and/or mirror graphic objects of LIB_SYMBOL aSymbol according to aOrientMirror. + * @param aLibSymbol is the LIB_SYMBOL to modify + * @param aOrientation is the orientation+mirror value like returned by SCH_SYMBOL::GetOrientation() + */ +void OrientAndMirrorSymbolItems( LIB_SYMBOL* aLibSymbol, int aOrientation ); + + +/** + * Rotate and/or mirror a SCH_PIN according to aOrientMirror. + * aOrientMirror is usually the orientation/mirror of the parent symbol. + * The modified pin orientation is the actual pin orientation/mirror + * when the parent symbol is drawn. + * @param aPin is the SCH_PIN to modify + * @param aOrientation is the orientation+mirror value like returned by SCH_SYMBOL::GetOrientation() + */ +void RotateAndMirrorPin( LIB_PIN& aPin, int aOrientMirror ); diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 5fb8cce7e2..735b231440 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -64,6 +64,7 @@ #include #include +#include "symb_transforms_utils.h" SELECTION_CONDITION EE_CONDITIONS::SingleSymbol = []( const SELECTION& aSel ) { @@ -376,7 +377,18 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) SCH_PIN* pin = dynamic_cast( aItem ); if( pin ) - return pin->GetOrientation(); + { + const SCH_SYMBOL* parent = dynamic_cast( pin->GetParentSymbol() ); + + if( !parent ) + return pin->GetOrientation(); + else + { + LIB_PIN dummy( *pin->GetLibPin() ); + RotateAndMirrorPin( dummy, parent->GetOrientation() ); + return dummy.GetOrientation(); + } + } SCH_SHEET_PIN* sheetPin = dynamic_cast( aItem );