Eeschema, Pin helpers: fix wrong label orientation if the symbol is rotated

From Master branch

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18012
This commit is contained in:
jean-pierre charras 2024-05-16 19:53:23 +02:00
parent 76f38600af
commit e66d25b6e8
5 changed files with 166 additions and 52 deletions

View File

@ -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

View File

@ -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() )
{

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 ) );
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 );

View File

@ -64,6 +64,7 @@
#include <view/view_controls.h>
#include <wx/log.h>
#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<SCH_PIN*>( aItem );
if( pin )
return pin->GetOrientation();
{
const SCH_SYMBOL* parent = dynamic_cast<const SCH_SYMBOL*>( 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<SCH_SHEET_PIN*>( aItem );