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 );