Flip symbol editor's Y axis to match other editors.

This commit is contained in:
Jeff Young 2024-04-27 13:47:56 +01:00
parent 3b3de58e5e
commit c59ed0bbb7
37 changed files with 407 additions and 586 deletions

View File

@ -93,8 +93,7 @@ EDA_TEXT::EDA_TEXT( const EDA_IU_SCALE& aIuScale, const wxString& aText ) :
m_IuScale( aIuScale ), m_IuScale( aIuScale ),
m_render_cache_font( nullptr ), m_render_cache_font( nullptr ),
m_bounding_box_cache_valid( false ), m_bounding_box_cache_valid( false ),
m_bounding_box_cache_line( -1 ), m_bounding_box_cache_line( -1 )
m_bounding_box_cache_inverted( false )
{ {
SetTextSize( VECTOR2I( EDA_UNIT_UTILS::Mils2IU( m_IuScale, DEFAULT_SIZE_TEXT ), SetTextSize( VECTOR2I( EDA_UNIT_UTILS::Mils2IU( m_IuScale, DEFAULT_SIZE_TEXT ),
EDA_UNIT_UTILS::Mils2IU( m_IuScale, DEFAULT_SIZE_TEXT ) ) ); EDA_UNIT_UTILS::Mils2IU( m_IuScale, DEFAULT_SIZE_TEXT ) ) );
@ -140,7 +139,6 @@ EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
m_bounding_box_cache_valid = aText.m_bounding_box_cache_valid; m_bounding_box_cache_valid = aText.m_bounding_box_cache_valid;
m_bounding_box_cache = aText.m_bounding_box_cache; m_bounding_box_cache = aText.m_bounding_box_cache;
m_bounding_box_cache_line = aText.m_bounding_box_cache_line; m_bounding_box_cache_line = aText.m_bounding_box_cache_line;
m_bounding_box_cache_inverted = aText.m_bounding_box_cache_inverted;
} }
@ -564,14 +562,13 @@ int EDA_TEXT::GetInterline() const
} }
BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const BOX2I EDA_TEXT::GetTextBox( int aLine ) const
{ {
VECTOR2I drawPos = GetDrawPos(); VECTOR2I drawPos = GetDrawPos();
if( m_bounding_box_cache_valid if( m_bounding_box_cache_valid
&& m_bounding_box_cache_pos == drawPos && m_bounding_box_cache_pos == drawPos
&& m_bounding_box_cache_line == aLine && m_bounding_box_cache_line == aLine )
&& m_bounding_box_cache_inverted == aInvertY )
{ {
return m_bounding_box_cache; return m_bounding_box_cache;
} }
@ -618,9 +615,6 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
if( text.Contains( wxT( "~{" ) ) ) if( text.Contains( wxT( "~{" ) ) )
overbarOffset = extents.y / 6; overbarOffset = extents.y / 6;
if( aInvertY )
pos.y = -pos.y;
bbox.SetOrigin( pos ); bbox.SetOrigin( pos );
// for multiline texts and aLine < 0, merge all rectangles (aLine == -1 signals all lines) // for multiline texts and aLine < 0, merge all rectangles (aLine == -1 signals all lines)
@ -696,7 +690,6 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
m_bounding_box_cache_valid = true; m_bounding_box_cache_valid = true;
m_bounding_box_cache_pos = drawPos; m_bounding_box_cache_pos = drawPos;
m_bounding_box_cache_line = aLine; m_bounding_box_cache_line = aLine;
m_bounding_box_cache_inverted = aInvertY;
m_bounding_box_cache = bbox; m_bounding_box_cache = bbox;
return bbox; return bbox;

View File

@ -2775,16 +2775,13 @@ wxString CADSTAR_ARCHIVE_PARSER::HandleTextOverbar( wxString aCadstarString )
} }
void CADSTAR_ARCHIVE_PARSER::FixTextPositionNoAlignment( EDA_TEXT* aKiCadTextItem, bool aInvertY ) void CADSTAR_ARCHIVE_PARSER::FixTextPositionNoAlignment( EDA_TEXT* aKiCadTextItem )
{ {
if( !aKiCadTextItem->GetText().IsEmpty() ) if( !aKiCadTextItem->GetText().IsEmpty() )
{ {
VECTOR2I positionOffset( 0, aKiCadTextItem->GetInterline() ); VECTOR2I positionOffset( 0, aKiCadTextItem->GetInterline() );
RotatePoint( positionOffset, aKiCadTextItem->GetTextAngle() ); RotatePoint( positionOffset, aKiCadTextItem->GetTextAngle() );
if( aInvertY )
positionOffset.y = -positionOffset.y;
//Count num of additional lines //Count num of additional lines
wxString text = aKiCadTextItem->GetText(); wxString text = aKiCadTextItem->GetText();
int numExtraLines = text.Replace( "\n", "\n" ); int numExtraLines = text.Replace( "\n", "\n" );

View File

@ -1423,7 +1423,7 @@ public:
* provided text element has been initialised with a position and orientation. * provided text element has been initialised with a position and orientation.
* @param aKiCadTextItem a Kicad item to correct * @param aKiCadTextItem a Kicad item to correct
*/ */
static void FixTextPositionNoAlignment( EDA_TEXT* aKiCadTextItem, bool aInvertY = false ); static void FixTextPositionNoAlignment( EDA_TEXT* aKiCadTextItem );
static wxString generateLibName( const wxString& aRefName, const wxString& aAlternateName ); static wxString generateLibName( const wxString& aRefName, const wxString& aAlternateName );

View File

@ -68,7 +68,7 @@ double EASYEDA_PARSER_BASE::RelPosY( const wxString& aValue )
void EASYEDA_PARSER_BASE::TransformTextToBaseline( EDA_TEXT* textItem, void EASYEDA_PARSER_BASE::TransformTextToBaseline( EDA_TEXT* textItem,
const wxString& baselineAlign, bool invertY ) const wxString& baselineAlign )
{ {
int upOffset = 0; int upOffset = 0;
@ -103,9 +103,6 @@ void EASYEDA_PARSER_BASE::TransformTextToBaseline( EDA_TEXT* textItem,
VECTOR2I offset( 0, -upOffset ); VECTOR2I offset( 0, -upOffset );
RotatePoint( offset, textItem->GetTextAngle() ); RotatePoint( offset, textItem->GetTextAngle() );
if( invertY )
offset.y = -offset.y;
textItem->SetTextPos( textItem->GetTextPos() + offset ); textItem->SetTextPos( textItem->GetTextPos() + offset );
} }

View File

@ -60,7 +60,7 @@ public:
return ScalePos( aVec - m_relOrigin ); return ScalePos( aVec - m_relOrigin );
} }
void TransformTextToBaseline( EDA_TEXT* textItem, const wxString& baselineAlign, bool invertY ); void TransformTextToBaseline( EDA_TEXT* textItem, const wxString& baselineAlign );
std::vector<SHAPE_LINE_CHAIN> ParseLineChains( const wxString& aData, int aArcMinSegLen, std::vector<SHAPE_LINE_CHAIN> ParseLineChains( const wxString& aData, int aArcMinSegLen,
bool aForceClosed ); bool aForceClosed );

View File

@ -528,12 +528,6 @@ void PS_PLOTTER::Circle( const VECTOR2I& pos, int diametre, FILL_T fill, int wid
} }
VECTOR2D mapCoords( const VECTOR2D& aSource )
{
return VECTOR2D( aSource.x, aSource.y );
}
void PS_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle, void PS_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth ) const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
{ {
@ -551,8 +545,8 @@ void PS_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
VECTOR2D start_device = userToDeviceCoordinates( start ); VECTOR2D start_device = userToDeviceCoordinates( start );
VECTOR2D end_device = userToDeviceCoordinates( end ); VECTOR2D end_device = userToDeviceCoordinates( end );
EDA_ANGLE startAngle( mapCoords( start_device - center_device ) ); EDA_ANGLE startAngle( start_device - center_device );
EDA_ANGLE endAngle( mapCoords( end_device - center_device ) ); EDA_ANGLE endAngle( end_device - center_device );
// userToDeviceCoordinates gets our start/ends out of order // userToDeviceCoordinates gets our start/ends out of order
if( !m_plotMirror ^ ( aAngle < ANGLE_0 ) ) if( !m_plotMirror ^ ( aAngle < ANGLE_0 ) )

View File

@ -227,7 +227,7 @@ protected:
*/ */
SIDE getPinSide( SCH_PIN* aPin ) SIDE getPinSide( SCH_PIN* aPin )
{ {
PIN_ORIENTATION pin_orient = aPin->GetLibPin()->PinDrawOrient( m_symbol->GetTransform() ); PIN_ORIENTATION pin_orient = aPin->PinDrawOrient( m_symbol->GetTransform() );
switch( pin_orient ) switch( pin_orient )
{ {

View File

@ -390,6 +390,8 @@ void DIALOG_PIN_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
// Calculate a suitable scale to fit the available draw area // Calculate a suitable scale to fit the available draw area
BOX2I bBox = m_dummyPin->GetBoundingBox( true, true, false ); BOX2I bBox = m_dummyPin->GetBoundingBox( true, true, false );
bBox.Inflate( schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE ) );
double xscale = (double) dc_size.x / bBox.GetWidth(); double xscale = (double) dc_size.x / bBox.GetWidth();
double yscale = (double) dc_size.y / bBox.GetHeight(); double yscale = (double) dc_size.y / bBox.GetHeight();
double scale = std::min( xscale, yscale ); double scale = std::min( xscale, yscale );
@ -404,7 +406,7 @@ void DIALOG_PIN_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
renderSettings.m_ShowPinNames = true; renderSettings.m_ShowPinNames = true;
renderSettings.m_ShowHiddenFields = true; renderSettings.m_ShowHiddenFields = true;
renderSettings.m_ShowConnectionPoints = true; renderSettings.m_ShowConnectionPoints = true;
renderSettings.m_Transform = DefaultTransform; renderSettings.m_Transform = TRANSFORM();
renderSettings.SetPrintDC( &dc ); renderSettings.SetPrintDC( &dc );
m_dummyPin->Print( &renderSettings, 0, 0, -bBox.Centre(), false, false ); m_dummyPin->Print( &renderSettings, 0, 0, -bBox.Centre(), false, false );

View File

@ -585,67 +585,36 @@ EDA_ANGLE SCH_FIELD::GetDrawRotation() const
const BOX2I SCH_FIELD::GetBoundingBox() const const BOX2I SCH_FIELD::GetBoundingBox() const
{ {
BOX2I bbox; BOX2I bbox = GetTextBox();
if( m_parent && m_parent->Type() == LIB_SYMBOL_T ) // Calculate the bounding box position relative to the parent:
VECTOR2I origin = GetParentPosition();
VECTOR2I pos = GetTextPos() - origin;
VECTOR2I begin = bbox.GetOrigin() - origin;
VECTOR2I end = bbox.GetEnd() - origin;
RotatePoint( begin, pos, GetTextAngle() );
RotatePoint( end, pos, GetTextAngle() );
// Now, apply the symbol transform (mirror/rot)
TRANSFORM transform;
if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
{ {
/* SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
* Y coordinates for LIB_ITEMS are bottom to top, so we must invert the Y position
* when calling GetTextBox() that works using top to bottom Y axis orientation.
*/
bbox = GetTextBox( -1, true );
bbox.RevertYAxis();
// We are using now a bottom to top Y axis. // Due to the Y axis direction, we must mirror the bounding box, relative to the
VECTOR2I orig = bbox.GetOrigin(); // text position:
VECTOR2I end = bbox.GetEnd(); MIRROR( begin.y, pos.y );
MIRROR( end.y, pos.y );
RotatePoint( orig, GetTextPos(), -GetTextAngle() ); transform = parentSymbol->GetTransform();
RotatePoint( end, GetTextPos(), -GetTextAngle() );
bbox.SetOrigin( orig );
bbox.SetEnd( end );
// We are using now a top to bottom Y axis:
bbox.RevertYAxis();
} }
else
{
bbox = GetTextBox();
// Calculate the bounding box position relative to the parent: bbox.SetOrigin( transform.TransformCoordinate( begin ) );
VECTOR2I origin = GetParentPosition(); bbox.SetEnd( transform.TransformCoordinate( end ) );
VECTOR2I pos = GetTextPos() - origin;
VECTOR2I begin = bbox.GetOrigin() - origin;
VECTOR2I end = bbox.GetEnd() - origin;
RotatePoint( begin, pos, GetTextAngle() );
RotatePoint( end, pos, GetTextAngle() );
// Now, apply the symbol transform (mirror/rot) bbox.Move( origin );
TRANSFORM transform; bbox.Normalize();
if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
// Due to the Y axis direction, we must mirror the bounding box, relative to the
// text position:
MIRROR( begin.y, pos.y );
MIRROR( end.y, pos.y );
transform = parentSymbol->GetTransform();
}
else
{
transform = TRANSFORM( 1, 0, 0, 1 ); // identity transform
}
bbox.SetOrigin( transform.TransformCoordinate( begin ) );
bbox.SetEnd( transform.TransformCoordinate( end ) );
bbox.Move( origin );
bbox.Normalize();
}
return bbox; return bbox;
} }

View File

@ -1703,7 +1703,7 @@ const LIB_SYMBOL* CADSTAR_SCH_ARCHIVE_LOADER::loadSymdef( const SYMDEF_ID& aSymd
libtext->SetMultilineAllowed( true ); // temporarily so that we calculate bbox correctly libtext->SetMultilineAllowed( true ); // temporarily so that we calculate bbox correctly
applyTextSettings( libtext.get(), csText.TextCodeID, csText.Alignment, csText.Justification, applyTextSettings( libtext.get(), csText.TextCodeID, csText.Alignment, csText.Justification,
csText.OrientAngle, csText.Mirror, true ); csText.OrientAngle, csText.Mirror );
// Split out multi line text items into individual text elements // Split out multi line text items into individual text elements
if( csText.Text.Contains( "\n" ) ) if( csText.Text.Contains( "\n" ) )
@ -1714,7 +1714,7 @@ const LIB_SYMBOL* CADSTAR_SCH_ARCHIVE_LOADER::loadSymdef( const SYMDEF_ID& aSymd
for( size_t ii = 0; ii < strings.size(); ++ii ) for( size_t ii = 0; ii < strings.size(); ++ii )
{ {
BOX2I bbox = libtext->GetTextBox( ii, true ); BOX2I bbox = libtext->GetTextBox( ii );
VECTOR2I linePos = { bbox.GetLeft(), -bbox.GetBottom() }; VECTOR2I linePos = { bbox.GetLeft(), -bbox.GetBottom() };
RotatePoint( linePos, libtext->GetTextPos(), -libtext->GetTextAngle() ); RotatePoint( linePos, libtext->GetTextPos(), -libtext->GetTextAngle() );
@ -2058,7 +2058,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::applyToLibraryFieldAttribute( const ATTRIBUTE_L
applyTextSettings( aKiCadField, aCadstarAttrLoc.TextCodeID, aCadstarAttrLoc.Alignment, applyTextSettings( aKiCadField, aCadstarAttrLoc.TextCodeID, aCadstarAttrLoc.Alignment,
aCadstarAttrLoc.Justification, aCadstarAttrLoc.OrientAngle, aCadstarAttrLoc.Justification, aCadstarAttrLoc.OrientAngle,
aCadstarAttrLoc.Mirror, true ); aCadstarAttrLoc.Mirror );
} }
@ -2985,8 +2985,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::applyTextSettings( EDA_TEXT* aKiCadT
const ALIGNMENT& aCadstarAlignment, const ALIGNMENT& aCadstarAlignment,
const JUSTIFICATION& aCadstarJustification, const JUSTIFICATION& aCadstarJustification,
const long long aCadstarOrientAngle, const long long aCadstarOrientAngle,
bool aMirrored, bool aMirrored )
bool aInvertY )
{ {
applyTextCodeIfExists( aKiCadTextItem, aCadstarTextCodeID ); applyTextCodeIfExists( aKiCadTextItem, aCadstarTextCodeID );
aKiCadTextItem->SetTextAngle( getAngle( aCadstarOrientAngle ) ); aKiCadTextItem->SetTextAngle( getAngle( aCadstarOrientAngle ) );
@ -3009,7 +3008,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::applyTextSettings( EDA_TEXT* aKiCadT
{ {
case ALIGNMENT::NO_ALIGNMENT: // Bottom left of the first line case ALIGNMENT::NO_ALIGNMENT: // Bottom left of the first line
//No exact KiCad equivalent, so lets move the position of the text //No exact KiCad equivalent, so lets move the position of the text
FixTextPositionNoAlignment( aText, aInvertY ); FixTextPositionNoAlignment( aText );
KI_FALLTHROUGH; KI_FALLTHROUGH;
case ALIGNMENT::BOTTOMLEFT: case ALIGNMENT::BOTTOMLEFT:
aText->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM ); aText->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
@ -3062,7 +3061,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::applyTextSettings( EDA_TEXT* aKiCadT
EDA_ITEM* textEdaItem = dynamic_cast<EDA_ITEM*>( aKiCadTextItem ); EDA_ITEM* textEdaItem = dynamic_cast<EDA_ITEM*>( aKiCadTextItem );
wxCHECK( textEdaItem, /* void */ ); // ensure this is a EDA_ITEM wxCHECK( textEdaItem, /* void */ ); // ensure this is a EDA_ITEM
if( textEdaItem->Type() == SCH_FIELD_T || aInvertY ) if( textEdaItem->Type() == SCH_FIELD_T )
{ {
// Spin style not used. All text justifications are permitted. However, only orientations // Spin style not used. All text justifications are permitted. However, only orientations
// of 0 deg or 90 deg are supported // of 0 deg or 90 deg are supported

View File

@ -236,8 +236,7 @@ private:
const ALIGNMENT& aCadstarAlignment, const ALIGNMENT& aCadstarAlignment,
const JUSTIFICATION& aCadstarJustification, const JUSTIFICATION& aCadstarJustification,
const long long aCadstarOrientAngle = 0, const long long aCadstarOrientAngle = 0,
bool aMirrored = false, bool aMirrored = false );
bool aInvertY = false );
SCH_TEXT* getKiCadSchText( const TEXT& aCadstarTextElement ); SCH_TEXT* getKiCadSchText( const TEXT& aCadstarTextElement );

View File

@ -936,7 +936,7 @@ void SCH_EASYEDA_PARSER::ParseSymbolShapes( LIB_SYMBOL* aSymbol
textItem->SetTextSize( VECTOR2I( ktextSize, ktextSize ) ); textItem->SetTextSize( VECTOR2I( ktextSize, ktextSize ) );
TransformTextToBaseline( textItem, baselineAlign, true ); TransformTextToBaseline( textItem, baselineAlign );
if( added ) if( added )
aSymbol->AddDrawItem( dynamic_cast<SCH_ITEM*>( textItem ) ); aSymbol->AddDrawItem( dynamic_cast<SCH_ITEM*>( textItem ) );
@ -1418,7 +1418,7 @@ void SCH_EASYEDA_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aRoot
textItem->SetTextSize( VECTOR2I( ktextSize, ktextSize ) ); textItem->SetTextSize( VECTOR2I( ktextSize, ktextSize ) );
TransformTextToBaseline( textItem.get(), baselineAlign, false ); TransformTextToBaseline( textItem.get(), baselineAlign );
createdItems.push_back( std::move( textItem ) ); createdItems.push_back( std::move( textItem ) );
} }

View File

@ -1214,27 +1214,27 @@ void SCH_IO_KICAD_SEXPR::saveShape( SCH_SHAPE* aShape, int aNestLevel )
{ {
case SHAPE_T::ARC: case SHAPE_T::ARC:
formatArc( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), formatArc( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid ); aShape->GetFillColor(), false, aShape->m_Uuid );
break; break;
case SHAPE_T::CIRCLE: case SHAPE_T::CIRCLE:
formatCircle( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), formatCircle( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid ); aShape->GetFillColor(), false, aShape->m_Uuid );
break; break;
case SHAPE_T::RECTANGLE: case SHAPE_T::RECTANGLE:
formatRect( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), formatRect( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid ); aShape->GetFillColor(), false, aShape->m_Uuid );
break; break;
case SHAPE_T::BEZIER: case SHAPE_T::BEZIER:
formatBezier( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), formatBezier( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid ); aShape->GetFillColor(), false, aShape->m_Uuid );
break; break;
case SHAPE_T::POLY: case SHAPE_T::POLY:
formatPoly( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), formatPoly( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid ); aShape->GetFillColor(), false, aShape->m_Uuid );
break; break;
default: default:

View File

@ -208,15 +208,28 @@ const char* getTextTypeToken( KICAD_T aType )
} }
std::string formatIU( const int& aValue )
{
return EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aValue );
}
std::string formatIU( const VECTOR2I& aPt, bool aInvertY )
{
VECTOR2I pt( aPt.x, aInvertY ? -aPt.y : aPt.y );
return EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt );
}
void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aArc, void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aArc,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid ) const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid )
{ {
aFormatter->Print( aNestLevel, "(arc%s (start %s) (mid %s) (end %s)\n", aFormatter->Print( aNestLevel, "(arc%s (start %s) (mid %s) (end %s)\n",
aIsPrivate ? " private" : "", aIsPrivate ? " private" : "",
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aArc->GetStart() ).c_str(), formatIU( aArc->GetStart(), aInvertY ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aArc->GetArcMid() ).c_str(), formatIU( aArc->GetArcMid(), aInvertY ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aArc->GetEnd() ).c_str() ); formatIU( aArc->GetEnd(), aInvertY ).c_str() );
aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 ); aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 );
aFormatter->Print( 0, "\n" ); aFormatter->Print( 0, "\n" );
@ -232,13 +245,12 @@ void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aArc,
void formatCircle( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aCircle, void formatCircle( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aCircle,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid ) const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid )
{ {
aFormatter->Print( aNestLevel, "(circle%s (center %s %s) (radius %s)\n", aFormatter->Print( aNestLevel, "(circle%s (center %s) (radius %s)\n",
aIsPrivate ? " private" : "", aIsPrivate ? " private" : "",
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aCircle->GetStart().x ).c_str(), formatIU( aCircle->GetStart(), aInvertY ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aCircle->GetStart().y ).c_str(), formatIU( aCircle->GetRadius() ).c_str() );
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aCircle->GetRadius() ).c_str() );
aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 ); aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 );
aFormatter->Print( 0, "\n" ); aFormatter->Print( 0, "\n" );
@ -254,14 +266,12 @@ void formatCircle( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aCirc
void formatRect( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aRect, void formatRect( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aRect,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid ) const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid )
{ {
aFormatter->Print( aNestLevel, "(rectangle%s (start %s %s) (end %s %s)\n", aFormatter->Print( aNestLevel, "(rectangle%s (start %s) (end %s)\n",
aIsPrivate ? " private" : "", aIsPrivate ? " private" : "",
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aRect->GetStart().x ).c_str(), formatIU( aRect->GetStart(), aInvertY ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aRect->GetStart().y ).c_str(), formatIU( aRect->GetEnd(), aInvertY ).c_str() );
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aRect->GetEnd().x ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aRect->GetEnd().y ).c_str() );
aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 ); aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 );
aFormatter->Print( 0, "\n" ); aFormatter->Print( 0, "\n" );
formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor ); formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
@ -276,7 +286,7 @@ void formatRect( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aRect,
void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aBezier, void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aBezier,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid ) const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid )
{ {
aFormatter->Print( aNestLevel, "(bezier%s (pts ", aFormatter->Print( aNestLevel, "(bezier%s (pts ",
aIsPrivate ? " private" : "" ); aIsPrivate ? " private" : "" );
@ -284,9 +294,8 @@ void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aBezi
for( const VECTOR2I& pt : { aBezier->GetStart(), aBezier->GetBezierC1(), for( const VECTOR2I& pt : { aBezier->GetStart(), aBezier->GetBezierC1(),
aBezier->GetBezierC2(), aBezier->GetEnd() } ) aBezier->GetBezierC2(), aBezier->GetEnd() } )
{ {
aFormatter->Print( 0, " (xy %s %s)", aFormatter->Print( 0, " (xy %s)",
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.x ).c_str(), formatIU( pt, aInvertY ).c_str() );
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.y ).c_str() );
} }
aFormatter->Print( 0, ")\n" ); // Closes pts token on same line. aFormatter->Print( 0, ")\n" ); // Closes pts token on same line.
@ -305,12 +314,11 @@ void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aBezi
void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aPolyLine, void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aPolyLine,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid ) const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid )
{ {
int newLine = 0; int newLine = 0;
int lineCount = 1; int lineCount = 1;
aFormatter->Print( aNestLevel, "(polyline%s\n", aFormatter->Print( aNestLevel, "(polyline%s\n", aIsPrivate ? " private" : "" );
aIsPrivate ? " private" : "" );
aFormatter->Print( aNestLevel + 1, "(pts" ); aFormatter->Print( aNestLevel + 1, "(pts" );
for( const VECTOR2I& pt : aPolyLine->GetPolyShape().Outline( 0 ).CPoints() ) for( const VECTOR2I& pt : aPolyLine->GetPolyShape().Outline( 0 ).CPoints() )
@ -318,17 +326,13 @@ void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aPolyLi
if( newLine == 4 || !ADVANCED_CFG::GetCfg().m_CompactSave ) if( newLine == 4 || !ADVANCED_CFG::GetCfg().m_CompactSave )
{ {
aFormatter->Print( 0, "\n" ); aFormatter->Print( 0, "\n" );
aFormatter->Print( aNestLevel + 2, "(xy %s %s)", aFormatter->Print( aNestLevel + 2, "(xy %s)", formatIU( pt, aInvertY ).c_str() );
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.x ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.y ).c_str() );
newLine = 0; newLine = 0;
lineCount += 1; lineCount += 1;
} }
else else
{ {
aFormatter->Print( 0, " (xy %s %s)", aFormatter->Print( 0, " (xy %s)", formatIU( pt, aInvertY ).c_str() );
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.x ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.y ).c_str() );
} }
newLine += 1; newLine += 1;

View File

@ -53,22 +53,22 @@ extern const char* getTextTypeToken( KICAD_T aType );
extern void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aArc, extern void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aArc,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid = niluuid ); const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid );
extern void formatCircle( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aCircle, extern void formatCircle( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aCircle,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid = niluuid ); const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid );
extern void formatRect( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aRect, extern void formatRect( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aRect,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid = niluuid ); const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid );
extern void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aBezier, extern void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aBezier,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid = niluuid ); const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid );
extern void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aPolyLine, extern void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aPolyLine,
bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
const COLOR4D& aFillColor, const KIID& aUuid = niluuid ); const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid );
#endif // SCH_IO_KICAD_SEXPR_COMMON_H_ #endif // SCH_IO_KICAD_SEXPR_COMMON_H_

View File

@ -346,23 +346,23 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFO
switch( shape->GetShape() ) switch( shape->GetShape() )
{ {
case SHAPE_T::ARC: case SHAPE_T::ARC:
formatArc( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor ); formatArc( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true );
break; break;
case SHAPE_T::CIRCLE: case SHAPE_T::CIRCLE:
formatCircle( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor ); formatCircle( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true );
break; break;
case SHAPE_T::RECTANGLE: case SHAPE_T::RECTANGLE:
formatRect( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor ); formatRect( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true );
break; break;
case SHAPE_T::BEZIER: case SHAPE_T::BEZIER:
formatBezier(&aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor ); formatBezier(&aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true );
break; break;
case SHAPE_T::POLY: case SHAPE_T::POLY:
formatPoly( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor ); formatPoly( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true );
break; break;
default: default:
@ -406,7 +406,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveField( SCH_FIELD* aField, OUTPUTFORMATTER
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, EDA_UNIT_UTILS::FormatInternalUnits( schIUScale,
aField->GetPosition().x ).c_str(), aField->GetPosition().x ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, EDA_UNIT_UTILS::FormatInternalUnits( schIUScale,
aField->GetPosition().y ).c_str(), -aField->GetPosition().y ).c_str(),
aField->GetTextAngle().AsDegrees() ); aField->GetTextAngle().AsDegrees() );
if( aField->IsNameShown() ) if( aField->IsNameShown() )
@ -434,7 +434,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::savePin( SCH_PIN* aPin, OUTPUTFORMATTER& aFor
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, EDA_UNIT_UTILS::FormatInternalUnits( schIUScale,
aPin->GetPosition().x ).c_str(), aPin->GetPosition().x ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, EDA_UNIT_UTILS::FormatInternalUnits( schIUScale,
aPin->GetPosition().y ).c_str(), -aPin->GetPosition().y ).c_str(),
EDA_UNIT_UTILS::FormatAngle( getPinAngle( aPin->GetOrientation() ) ).c_str(), EDA_UNIT_UTILS::FormatAngle( getPinAngle( aPin->GetOrientation() ) ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, EDA_UNIT_UTILS::FormatInternalUnits( schIUScale,
aPin->GetLength() ).c_str() ); aPin->GetLength() ).c_str() );
@ -483,7 +483,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveText( SCH_TEXT* aText, OUTPUTFORMATTER& a
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, EDA_UNIT_UTILS::FormatInternalUnits( schIUScale,
aText->GetPosition().x ).c_str(), aText->GetPosition().x ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, EDA_UNIT_UTILS::FormatInternalUnits( schIUScale,
aText->GetPosition().y ).c_str(), -aText->GetPosition().y ).c_str(),
(double) aText->GetTextAngle().AsTenthsOfADegree() ); (double) aText->GetTextAngle().AsTenthsOfADegree() );
aText->EDA_TEXT::Format( &aFormatter, aNestLevel, 0 ); aText->EDA_TEXT::Format( &aFormatter, aNestLevel, 0 );
@ -505,10 +505,10 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveTextBox( SCH_TEXTBOX* aTextBox, OUTPUTFOR
aFormatter.Print( aNestLevel + 1, "(at %s %s %s) (size %s %s) (margins %s %s %s %s)\n", aFormatter.Print( aNestLevel + 1, "(at %s %s %s) (size %s %s) (margins %s %s %s %s)\n",
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pos.x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pos.x ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pos.y ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, -pos.y ).c_str(),
EDA_UNIT_UTILS::FormatAngle( aTextBox->GetTextAngle() ).c_str(), EDA_UNIT_UTILS::FormatAngle( aTextBox->GetTextAngle() ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, size.x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, size.x ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, size.y ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, -size.y ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTextBox->GetMarginLeft() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTextBox->GetMarginLeft() ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTextBox->GetMarginTop() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTextBox->GetMarginTop() ).c_str(),
EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTextBox->GetMarginRight() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTextBox->GetMarginRight() ).c_str(),

View File

@ -956,7 +956,7 @@ SCH_FIELD* SCH_IO_KICAD_SEXPR_PARSER::parseProperty( std::unique_ptr<LIB_SYMBOL>
break; break;
case T_at: case T_at:
field->SetPosition( parseXY() ); field->SetPosition( parseXY( true ) );
field->SetTextAngle( EDA_ANGLE( parseDouble( "text angle" ), DEGREES_T ) ); field->SetTextAngle( EDA_ANGLE( parseDouble( "text angle" ), DEGREES_T ) );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -1124,18 +1124,18 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolArc()
switch( token ) switch( token )
{ {
case T_start: case T_start:
startPoint = parseXY(); startPoint = parseXY( true );
NeedRIGHT(); NeedRIGHT();
break; break;
case T_mid: case T_mid:
midPoint = parseXY(); midPoint = parseXY( true );
NeedRIGHT(); NeedRIGHT();
hasMidPoint = true; hasMidPoint = true;
break; break;
case T_end: case T_end:
endPoint = parseXY(); endPoint = parseXY( true );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -1150,7 +1150,7 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolArc()
switch( token ) switch( token )
{ {
case T_at: case T_at:
center = parseXY(); center = parseXY( true );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -1316,11 +1316,11 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolBezier()
switch( ii ) switch( ii )
{ {
case 0: bezier->SetStart( parseXY() ); break; case 0: bezier->SetStart( parseXY( true ) ); break;
case 1: bezier->SetBezierC1( parseXY() ); break; case 1: bezier->SetBezierC1( parseXY( true ) ); break;
case 2: bezier->SetBezierC2( parseXY() ); break; case 2: bezier->SetBezierC2( parseXY( true ) ); break;
case 3: bezier->SetEnd( parseXY() ); break; case 3: bezier->SetEnd( parseXY( true ) ); break;
default: Unexpected( "control point" ); break; default: Unexpected( "control point" ); break;
} }
NeedRIGHT(); NeedRIGHT();
@ -1384,7 +1384,7 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolCircle()
switch( token ) switch( token )
{ {
case T_center: case T_center:
center = parseXY(); center = parseXY( true );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -1502,7 +1502,7 @@ SCH_PIN* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolPin()
switch( token ) switch( token )
{ {
case T_at: case T_at:
pin->SetPosition( parseXY() ); pin->SetPosition( parseXY( true ) );
switch( parseInt( "pin orientation" ) ) switch( parseInt( "pin orientation" ) )
{ {
@ -1669,7 +1669,7 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolPolyLine()
if( token != T_xy ) if( token != T_xy )
Expecting( "xy" ); Expecting( "xy" );
poly->AddPoint( parseXY() ); poly->AddPoint( parseXY( true ) );
NeedRIGHT(); NeedRIGHT();
} }
@ -1727,12 +1727,12 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolRectangle()
switch( token ) switch( token )
{ {
case T_start: case T_start:
rectangle->SetPosition( parseXY() ); rectangle->SetPosition( parseXY( true ) );
NeedRIGHT(); NeedRIGHT();
break; break;
case T_end: case T_end:
rectangle->SetEnd( parseXY() ); rectangle->SetEnd( parseXY( true ) );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -1793,7 +1793,7 @@ SCH_TEXT* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolText()
switch( token ) switch( token )
{ {
case T_at: case T_at:
text->SetPosition( parseXY() ); text->SetPosition( parseXY( true ) );
// Yes, LIB_TEXT is really decidegrees even though all the others are degrees. :( // Yes, LIB_TEXT is really decidegrees even though all the others are degrees. :(
text->SetTextAngle( EDA_ANGLE( parseDouble( "text angle" ), TENTHS_OF_A_DEGREE_T ) ); text->SetTextAngle( EDA_ANGLE( parseDouble( "text angle" ), TENTHS_OF_A_DEGREE_T ) );
NeedRIGHT(); NeedRIGHT();
@ -1861,24 +1861,24 @@ SCH_TEXTBOX* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolTextBox()
switch( token ) switch( token )
{ {
case T_start: // Legacy token during 6.99 development; fails to handle angle case T_start: // Legacy token during 6.99 development; fails to handle angle
pos = parseXY(); pos = parseXY( true );
NeedRIGHT(); NeedRIGHT();
break; break;
case T_end: // Legacy token during 6.99 development; fails to handle angle case T_end: // Legacy token during 6.99 development; fails to handle angle
end = parseXY(); end = parseXY( true );
foundEnd = true; foundEnd = true;
NeedRIGHT(); NeedRIGHT();
break; break;
case T_at: case T_at:
pos = parseXY(); pos = parseXY( true );
textBox->SetTextAngle( EDA_ANGLE( parseDouble( "textbox angle" ), DEGREES_T ) ); textBox->SetTextAngle( EDA_ANGLE( parseDouble( "textbox angle" ), DEGREES_T ) );
NeedRIGHT(); NeedRIGHT();
break; break;
case T_size: case T_size:
size = parseXY(); size = parseXY( true );
foundSize = true; foundSize = true;
NeedRIGHT(); NeedRIGHT();
break; break;
@ -2902,9 +2902,9 @@ SCH_SYMBOL* SCH_IO_KICAD_SEXPR_PARSER::parseSchematicSymbol()
switch( static_cast<int>( parseDouble( "symbol orientation" ) ) ) switch( static_cast<int>( parseDouble( "symbol orientation" ) ) )
{ {
case 0: transform = TRANSFORM(); break; case 0: transform = TRANSFORM(); break;
case 90: transform = TRANSFORM( 0, -1, -1, 0 ); break; case 90: transform = TRANSFORM( 0, 1, -1, 0 ); break;
case 180: transform = TRANSFORM( -1, 0, 0, 1 ); break; case 180: transform = TRANSFORM( -1, 0, 0, -1 ); break;
case 270: transform = TRANSFORM( 0, 1, 1, 0 ); break; case 270: transform = TRANSFORM( 0, -1, 1, 0 ); break;
default: Expecting( "0, 90, 180, or 270" ); default: Expecting( "0, 90, 180, or 270" );
} }

View File

@ -145,12 +145,13 @@ private:
return parseInternalUnits( GetTokenText( aToken ) ); return parseInternalUnits( GetTokenText( aToken ) );
} }
VECTOR2I parseXY() VECTOR2I parseXY( bool aInvertY = false )
{ {
VECTOR2I xy; VECTOR2I xy;
xy.x = parseInternalUnits( "X coordinate" ); xy.x = parseInternalUnits( "X coordinate" );
xy.y = parseInternalUnits( "Y coordinate" ); xy.y = aInvertY ? -parseInternalUnits( "Y coordinate" )
: parseInternalUnits( "Y coordinate" );
return xy; return xy;
} }

View File

@ -527,12 +527,6 @@ int SCH_PAINTER::getOperatingPointTextSize() const
} }
//
// TODO: nuke symbol editor's upside-down coordinate system
//
#define MAP_COORDS( aCoord ) VECTOR2D( aCoord.x, invertY ? -aCoord.y : aCoord.y )
static bool isFieldsLayer( int aLayer ) static bool isFieldsLayer( int aLayer )
{ {
return aLayer == LAYER_REFERENCEPART return aLayer == LAYER_REFERENCEPART
@ -627,11 +621,8 @@ void SCH_PAINTER::knockoutText( const wxString& aText, const VECTOR2D& aPosition
void SCH_PAINTER::boxText( const wxString& aText, const VECTOR2D& aPosition, void SCH_PAINTER::boxText( const wxString& aText, const VECTOR2D& aPosition,
const TEXT_ATTRIBUTES& aAttrs, const KIFONT::METRICS& aFontMetrics, const TEXT_ATTRIBUTES& aAttrs, const KIFONT::METRICS& aFontMetrics )
bool aInvertY )
{ {
bool invertY = aInvertY;
KIFONT::FONT* font = aAttrs.m_Font; KIFONT::FONT* font = aAttrs.m_Font;
if( !font ) if( !font )
@ -665,11 +656,10 @@ void SCH_PAINTER::boxText( const wxString& aText, const VECTOR2D& aPosition,
box.Normalize(); // Make h and v sizes always >= 0 box.Normalize(); // Make h and v sizes always >= 0
box = box.GetBoundingBoxRotated( aPosition, aAttrs.m_Angle ); box = box.GetBoundingBoxRotated( aPosition, aAttrs.m_Angle );
box.RevertYAxis();
m_gal->SetIsFill( true ); m_gal->SetIsFill( true );
m_gal->SetIsStroke( false ); m_gal->SetIsStroke( false );
m_gal->DrawRectangle( MAP_COORDS( box.GetOrigin() ), MAP_COORDS( box.GetEnd() ) ); m_gal->DrawRectangle( box.GetOrigin(), box.GetEnd() );
} }
@ -872,12 +862,11 @@ void SCH_PAINTER::draw( const SCH_PIN* aPin, int aLayer, bool aDimmed )
bool drawingDangling = aLayer == LAYER_DANGLING; bool drawingDangling = aLayer == LAYER_DANGLING;
bool drawingOP = aLayer == LAYER_OP_CURRENTS; bool drawingOP = aLayer == LAYER_OP_CURRENTS;
bool isDangling = m_schSettings.m_IsSymbolEditor || aPin->HasFlag( IS_DANGLING ); bool isDangling = m_schSettings.m_IsSymbolEditor || aPin->HasFlag( IS_DANGLING );
bool invertY = true;
if( drawingShadows && !( aPin->IsBrightened() || aPin->IsSelected() ) ) if( drawingShadows && !( aPin->IsBrightened() || aPin->IsSelected() ) )
return; return;
VECTOR2I pos = MAP_COORDS( aPin->GetPosition() ); VECTOR2I pos = aPin->GetPosition();
COLOR4D color = getRenderColor( aPin, LAYER_PIN, drawingShadows, aDimmed ); COLOR4D color = getRenderColor( aPin, LAYER_PIN, drawingShadows, aDimmed );
if( !aPin->IsVisible() ) if( !aPin->IsVisible() )
@ -912,34 +901,9 @@ void SCH_PAINTER::draw( const SCH_PIN* aPin, int aLayer, bool aDimmed )
if( m_schSettings.GetDrawBoundingBoxes() ) if( m_schSettings.GetDrawBoundingBoxes() )
drawItemBoundingBox( aPin ); drawItemBoundingBox( aPin );
VECTOR2I p0; VECTOR2I p0 = aPin->GetPinRoot();
VECTOR2I dir; VECTOR2I dir( sign( pos.x - p0.x ), sign( pos.y - p0.y ) );
int len = aPin->GetLength(); int len = aPin->GetLength();
PIN_ORIENTATION orient = aPin->GetOrientation();
switch( orient )
{
case PIN_ORIENTATION::PIN_UP:
p0 = VECTOR2I( pos.x, pos.y - len );
dir = VECTOR2I( 0, 1 );
break;
case PIN_ORIENTATION::PIN_DOWN:
p0 = VECTOR2I( pos.x, pos.y + len );
dir = VECTOR2I( 0, -1 );
break;
case PIN_ORIENTATION::PIN_LEFT:
p0 = VECTOR2I( pos.x - len, pos.y );
dir = VECTOR2I( 1, 0 );
break;
default:
case PIN_ORIENTATION::PIN_RIGHT:
p0 = VECTOR2I( pos.x + len, pos.y );
dir = VECTOR2I( -1, 0 );
break;
}
if( drawingOP && !aPin->GetOperatingPoint().IsEmpty() ) if( drawingOP && !aPin->GetOperatingPoint().IsEmpty() )
{ {
@ -1246,7 +1210,7 @@ void SCH_PAINTER::draw( const SCH_PIN* aPin, int aLayer, bool aDimmed )
} }
else if( drawingShadows ) else if( drawingShadows )
{ {
boxText( text[i], aPos, attrs, aPin->GetFontMetrics(), invertY ); boxText( text[i], aPos, attrs, aPin->GetFontMetrics() );
} }
else if( nonCached( aPin ) && renderTextAsBitmap ) else if( nonCached( aPin ) && renderTextAsBitmap )
{ {
@ -1260,7 +1224,7 @@ void SCH_PAINTER::draw( const SCH_PIN* aPin, int aLayer, bool aDimmed )
} }
}; };
switch( orient ) switch( aPin->GetOrientation() )
{ {
case PIN_ORIENTATION::PIN_LEFT: case PIN_ORIENTATION::PIN_LEFT:
if( size[INSIDE] ) if( size[INSIDE] )
@ -1539,7 +1503,6 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer, bool aDimmed )
LINE_STYLE lineStyle = aShape->GetEffectiveLineStyle(); LINE_STYLE lineStyle = aShape->GetEffectiveLineStyle();
COLOR4D color = getRenderColor( aShape, aLayer, drawingShadows ); COLOR4D color = getRenderColor( aShape, aLayer, drawingShadows );
bool invertY = aShape->GetLayer() == LAYER_DEVICE;
if( drawingShadows && !( aShape->IsBrightened() || aShape->IsSelected() ) ) if( drawingShadows && !( aShape->IsBrightened() || aShape->IsSelected() ) )
return; return;
@ -1551,9 +1514,9 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer, bool aDimmed )
{ {
case SHAPE_T::ARC: case SHAPE_T::ARC:
{ {
VECTOR2D start = MAP_COORDS( shape->GetStart() ); VECTOR2D start = shape->GetStart();
VECTOR2D mid = MAP_COORDS( shape->GetArcMid() ); VECTOR2D mid = shape->GetArcMid();
VECTOR2D end = MAP_COORDS( shape->GetEnd() ); VECTOR2D end = shape->GetEnd();
VECTOR2D center = CalcArcCenter( start, mid, end ); VECTOR2D center = CalcArcCenter( start, mid, end );
EDA_ANGLE startAngle( start - center ); EDA_ANGLE startAngle( start - center );
@ -1570,41 +1533,34 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer, bool aDimmed )
} }
case SHAPE_T::CIRCLE: case SHAPE_T::CIRCLE:
m_gal->DrawCircle( MAP_COORDS( shape->GetPosition() ), shape->GetRadius() ); m_gal->DrawCircle( shape->GetPosition(), shape->GetRadius() );
break; break;
case SHAPE_T::RECTANGLE: case SHAPE_T::RECTANGLE:
m_gal->DrawRectangle( MAP_COORDS( shape->GetPosition() ), m_gal->DrawRectangle( shape->GetPosition(), shape->GetEnd() );
MAP_COORDS( shape->GetEnd() ) );
break; break;
case SHAPE_T::POLY: case SHAPE_T::POLY:
{ {
const std::vector<SHAPE*> polySegments = shape->MakeEffectiveShapes( true ); const std::vector<SHAPE*> polySegments = shape->MakeEffectiveShapes( true );
std::deque<VECTOR2D> mappedPts; std::deque<VECTOR2D> pts;
for( SHAPE* polySegment : polySegments ) for( SHAPE* polySegment : polySegments )
{ pts.push_back( static_cast<SHAPE_SEGMENT*>( polySegment )->GetSeg().A );
mappedPts.push_back( MAP_COORDS(
static_cast<SHAPE_SEGMENT*>( polySegment )->GetSeg().A ) );
}
mappedPts.push_back( MAP_COORDS( pts.push_back( static_cast<SHAPE_SEGMENT*>( polySegments.back() )->GetSeg().B );
static_cast<SHAPE_SEGMENT*>( polySegments.back() )->GetSeg().B ) );
for( SHAPE* polySegment : polySegments ) for( SHAPE* polySegment : polySegments )
delete polySegment; delete polySegment;
m_gal->DrawPolygon( mappedPts ); m_gal->DrawPolygon( pts );
break; break;
} }
case SHAPE_T::BEZIER: case SHAPE_T::BEZIER:
{ {
m_gal->DrawCurve( MAP_COORDS( shape->GetStart() ), m_gal->DrawCurve( shape->GetStart(), shape->GetBezierC1(),
MAP_COORDS( shape->GetBezierC1() ), shape->GetBezierC2(), shape->GetEnd() );
MAP_COORDS( shape->GetBezierC2() ),
MAP_COORDS( shape->GetEnd() ) );
break; break;
} }
@ -1675,13 +1631,13 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer, bool aDimmed )
for( SHAPE* shape : shapes ) for( SHAPE* shape : shapes )
{ {
STROKE_PARAMS::Stroke( shape, lineStyle, KiROUND( lineWidth ), &m_schSettings, STROKE_PARAMS::Stroke( shape, lineStyle, KiROUND( lineWidth ), &m_schSettings,
[this, invertY]( const VECTOR2I& a, const VECTOR2I& b ) [this]( const VECTOR2I& a, const VECTOR2I& b )
{ {
// DrawLine has problem with 0 length lines so enforce minimum // DrawLine has problem with 0 length lines so enforce minimum
if( a == b ) if( a == b )
m_gal->DrawLine( MAP_COORDS( (a+1) ), MAP_COORDS( b ) ); m_gal->DrawLine( a+1, b );
else else
m_gal->DrawLine( MAP_COORDS( a ), MAP_COORDS( b ) ); m_gal->DrawLine( a, b );
} ); } );
} }
@ -1749,7 +1705,6 @@ void SCH_PAINTER::draw( const SCH_TEXT* aText, int aLayer, bool aDimmed )
VECTOR2I text_offset = aText->GetSchematicTextOffset( &m_schSettings ); VECTOR2I text_offset = aText->GetSchematicTextOffset( &m_schSettings );
TEXT_ATTRIBUTES attrs = aText->GetAttributes(); TEXT_ATTRIBUTES attrs = aText->GetAttributes();
KIFONT::FONT* font = getFont( aText ); KIFONT::FONT* font = getFont( aText );
bool invertY = aText->GetLayer() == LAYER_DEVICE;
attrs.m_Angle = aText->GetDrawRotation(); attrs.m_Angle = aText->GetDrawRotation();
attrs.m_StrokeWidth = KiROUND( getTextThickness( aText ) ); attrs.m_StrokeWidth = KiROUND( getTextThickness( aText ) );
@ -1758,11 +1713,10 @@ void SCH_PAINTER::draw( const SCH_TEXT* aText, int aLayer, bool aDimmed )
{ {
BOX2I bBox = aText->GetBoundingBox(); BOX2I bBox = aText->GetBoundingBox();
bBox.Inflate( KiROUND( getTextThickness( aText ) * 2 ) ); bBox.Inflate( KiROUND( getTextThickness( aText ) * 2 ) );
bBox.RevertYAxis();
m_gal->SetIsStroke( false ); m_gal->SetIsStroke( false );
m_gal->SetIsFill( true ); m_gal->SetIsFill( true );
m_gal->DrawRectangle( MAP_COORDS( bBox.GetPosition() ), MAP_COORDS( bBox.GetEnd() ) ); m_gal->DrawRectangle( bBox.GetPosition(), bBox.GetEnd() );
} }
else if( aText->GetLayer() == LAYER_DEVICE ) else if( aText->GetLayer() == LAYER_DEVICE )
{ {
@ -1928,7 +1882,6 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer, bool aDimmed )
COLOR4D bg = m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ); COLOR4D bg = m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND );
float borderWidth = getLineWidth( aTextBox, drawingShadows ); float borderWidth = getLineWidth( aTextBox, drawingShadows );
KIFONT::FONT* font = getFont( aTextBox ); KIFONT::FONT* font = getFont( aTextBox );
bool invertY = aTextBox->GetLayer() == LAYER_DEVICE;
auto drawText = auto drawText =
[&]() [&]()
@ -1974,8 +1927,7 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer, bool aDimmed )
m_gal->SetIsStroke( false ); m_gal->SetIsStroke( false );
m_gal->SetLineWidth( borderWidth ); m_gal->SetLineWidth( borderWidth );
m_gal->DrawRectangle( MAP_COORDS( aTextBox->GetPosition() ), m_gal->DrawRectangle( aTextBox->GetPosition(), aTextBox->GetEnd() );
MAP_COORDS( aTextBox->GetEnd() ) );
} }
else if( aLayer == LAYER_DEVICE_BACKGROUND || aLayer == LAYER_NOTES_BACKGROUND ) else if( aLayer == LAYER_DEVICE_BACKGROUND || aLayer == LAYER_NOTES_BACKGROUND )
{ {
@ -1987,8 +1939,7 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer, bool aDimmed )
m_gal->SetIsStroke( false ); m_gal->SetIsStroke( false );
m_gal->SetLineWidth( borderWidth ); m_gal->SetLineWidth( borderWidth );
m_gal->DrawRectangle( MAP_COORDS( aTextBox->GetPosition() ), m_gal->DrawRectangle( aTextBox->GetPosition(), aTextBox->GetEnd() );
MAP_COORDS( aTextBox->GetEnd() ) );
} }
} }
else if( aLayer == LAYER_DEVICE || aLayer == LAYER_NOTES || aLayer == LAYER_PRIVATE_NOTES ) else if( aLayer == LAYER_DEVICE || aLayer == LAYER_NOTES || aLayer == LAYER_PRIVATE_NOTES )
@ -2023,8 +1974,7 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer, bool aDimmed )
if( borderStyle <= LINE_STYLE::FIRST_TYPE || drawingShadows ) if( borderStyle <= LINE_STYLE::FIRST_TYPE || drawingShadows )
{ {
m_gal->DrawRectangle( MAP_COORDS( aTextBox->GetPosition() ), m_gal->DrawRectangle( aTextBox->GetPosition(), aTextBox->GetEnd() );
MAP_COORDS( aTextBox->GetEnd() ) );
} }
else else
{ {
@ -2034,13 +1984,13 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer, bool aDimmed )
{ {
STROKE_PARAMS::Stroke( shape, borderStyle, KiROUND( borderWidth ), STROKE_PARAMS::Stroke( shape, borderStyle, KiROUND( borderWidth ),
&m_schSettings, &m_schSettings,
[this, invertY]( const VECTOR2I& a, const VECTOR2I& b ) [this]( const VECTOR2I& a, const VECTOR2I& b )
{ {
// DrawLine has problem with 0 length lines so enforce minimum // DrawLine has problem with 0 length lines so enforce minimum
if( a == b ) if( a == b )
m_gal->DrawLine( MAP_COORDS( (a+1) ), MAP_COORDS( b ) ); m_gal->DrawLine( a+1, b );
else else
m_gal->DrawLine( MAP_COORDS( a ), MAP_COORDS( b ) ); m_gal->DrawLine( a, b );
} ); } );
} }
@ -2273,8 +2223,6 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
// Use dummy symbol if the actual couldn't be found (or couldn't be locked). // Use dummy symbol if the actual couldn't be found (or couldn't be locked).
LIB_SYMBOL* originalSymbol = aSymbol->GetLibSymbolRef() ? aSymbol->GetLibSymbolRef().get() LIB_SYMBOL* originalSymbol = aSymbol->GetLibSymbolRef() ? aSymbol->GetLibSymbolRef().get()
: dummy(); : dummy();
bool invertY = true;
std::vector<SCH_PIN*> originalPins = originalSymbol->GetPins( unit, bodyStyle ); std::vector<SCH_PIN*> originalPins = originalSymbol->GetPins( unit, bodyStyle );
// Copy the source so we can re-orient and translate it. // Copy the source so we can re-orient and translate it.
@ -2288,7 +2236,7 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
for( SCH_ITEM& tempItem : tempSymbol.GetDrawItems() ) for( SCH_ITEM& tempItem : tempSymbol.GetDrawItems() )
{ {
tempItem.SetFlags( aSymbol->GetFlags() ); // SELECTED, HIGHLIGHTED, BRIGHTENED, tempItem.SetFlags( aSymbol->GetFlags() ); // SELECTED, HIGHLIGHTED, BRIGHTENED,
tempItem.Move( MAP_COORDS( aSymbol->GetPosition() ) ); tempItem.Move( aSymbol->GetPosition() );
if( tempItem.Type() == SCH_TEXT_T ) if( tempItem.Type() == SCH_TEXT_T )
{ {
@ -2462,14 +2410,11 @@ void SCH_PAINTER::draw( const SCH_FIELD* aField, int aLayer, bool aDimmed )
if( drawingShadows && getFont( aField )->IsOutline() ) if( drawingShadows && getFont( aField )->IsOutline() )
{ {
BOX2I shadow_box = bbox; BOX2I shadow_box = bbox;
bool invertY = true;
shadow_box.Inflate( KiROUND( getTextThickness( aField ) * 2 ) ); shadow_box.Inflate( KiROUND( getTextThickness( aField ) * 2 ) );
shadow_box.RevertYAxis();
m_gal->SetIsStroke( false ); m_gal->SetIsStroke( false );
m_gal->SetIsFill( true ); m_gal->SetIsFill( true );
m_gal->DrawRectangle( MAP_COORDS( shadow_box.GetPosition() ), m_gal->DrawRectangle( shadow_box.GetPosition(), shadow_box.GetEnd() );
MAP_COORDS( shadow_box.GetEnd() ) );
} }
else else
{ {

View File

@ -133,8 +133,7 @@ private:
void knockoutText( const wxString& aText, const VECTOR2D& aPosition, void knockoutText( const wxString& aText, const VECTOR2D& aPosition,
const TEXT_ATTRIBUTES& aAttrs, const KIFONT::METRICS& aFontMetrics ); const TEXT_ATTRIBUTES& aAttrs, const KIFONT::METRICS& aFontMetrics );
void boxText( const wxString& aText, const VECTOR2D& aPosition, void boxText( const wxString& aText, const VECTOR2D& aPosition,
const TEXT_ATTRIBUTES& aAttrs, const KIFONT::METRICS& aFontMetrics, const TEXT_ATTRIBUTES& aAttrs, const KIFONT::METRICS& aFontMetrics );
bool aInvertY );
wxString expandLibItemTextVars( const wxString& aSourceText, const SCH_SYMBOL* aSymbolContext ); wxString expandLibItemTextVars( const wxString& aSourceText, const SCH_SYMBOL* aSymbolContext );

View File

@ -518,15 +518,20 @@ void SCH_PIN::SetNumberTextSize( int aSize )
VECTOR2I SCH_PIN::GetPinRoot() const VECTOR2I SCH_PIN::GetPinRoot() const
{ {
int length = GetLength(); if( const SCH_SYMBOL* symbol = dynamic_cast<const SCH_SYMBOL*>( GetParentSymbol() ) )
{
const TRANSFORM& t = symbol->GetTransform();
wxCHECK( m_libPin, GetPosition() );
return t.TransformCoordinate( m_libPin->GetPinRoot() ) + symbol->GetPosition();
}
switch( GetOrientation() ) switch( GetOrientation() )
{ {
default: default:
case PIN_ORIENTATION::PIN_RIGHT: return VECTOR2I( m_position.x + length, -( m_position.y ) ); case PIN_ORIENTATION::PIN_RIGHT: return m_position + VECTOR2I( GetLength(), 0 );
case PIN_ORIENTATION::PIN_LEFT: return VECTOR2I( m_position.x - length, -( m_position.y ) ); case PIN_ORIENTATION::PIN_LEFT: return m_position + VECTOR2I( -GetLength(), 0 );
case PIN_ORIENTATION::PIN_UP: return VECTOR2I( m_position.x, -( m_position.y + length ) ); case PIN_ORIENTATION::PIN_UP: return m_position + VECTOR2I( 0, -GetLength() );
case PIN_ORIENTATION::PIN_DOWN: return VECTOR2I( m_position.x, -( m_position.y - length ) ); case PIN_ORIENTATION::PIN_DOWN: return m_position + VECTOR2I( 0, GetLength() );
} }
} }
@ -1303,8 +1308,8 @@ PIN_ORIENTATION SCH_PIN::PinDrawOrient( const TRANSFORM& aTransform ) const
{ {
default: default:
case PIN_ORIENTATION::PIN_RIGHT: end.x = 1; break; case PIN_ORIENTATION::PIN_RIGHT: end.x = 1; break;
case PIN_ORIENTATION::PIN_UP: end.y = 1; break; case PIN_ORIENTATION::PIN_UP: end.y = -1; break;
case PIN_ORIENTATION::PIN_DOWN: end.y = -1; break; case PIN_ORIENTATION::PIN_DOWN: end.y = 1; break;
case PIN_ORIENTATION::PIN_LEFT: end.x = -1; break; case PIN_ORIENTATION::PIN_LEFT: end.x = -1; break;
} }
@ -1480,23 +1485,10 @@ void SCH_PIN::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
{ {
if( dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() ) ) if( dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() ) )
{ {
EDA_ANGLE rot_angle = aRotateCCW ? -ANGLE_90 : ANGLE_90;
RotatePoint( m_position, aCenter, rot_angle );
if( aRotateCCW ) if( aRotateCCW )
{ {
switch( GetOrientation() ) RotatePoint( m_position, aCenter, -ANGLE_90 );
{
default:
case PIN_ORIENTATION::PIN_RIGHT: m_orientation = PIN_ORIENTATION::PIN_UP; break;
case PIN_ORIENTATION::PIN_UP: m_orientation = PIN_ORIENTATION::PIN_LEFT; break;
case PIN_ORIENTATION::PIN_LEFT: m_orientation = PIN_ORIENTATION::PIN_DOWN; break;
case PIN_ORIENTATION::PIN_DOWN: m_orientation = PIN_ORIENTATION::PIN_RIGHT; break;
}
}
else
{
switch( GetOrientation() ) switch( GetOrientation() )
{ {
default: default:
@ -1506,6 +1498,19 @@ void SCH_PIN::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
case PIN_ORIENTATION::PIN_DOWN: m_orientation = PIN_ORIENTATION::PIN_LEFT; break; case PIN_ORIENTATION::PIN_DOWN: m_orientation = PIN_ORIENTATION::PIN_LEFT; break;
} }
} }
else
{
RotatePoint( m_position, aCenter, ANGLE_90 );
switch( GetOrientation() )
{
default:
case PIN_ORIENTATION::PIN_RIGHT: m_orientation = PIN_ORIENTATION::PIN_UP; break;
case PIN_ORIENTATION::PIN_UP: m_orientation = PIN_ORIENTATION::PIN_LEFT; break;
case PIN_ORIENTATION::PIN_LEFT: m_orientation = PIN_ORIENTATION::PIN_DOWN; break;
case PIN_ORIENTATION::PIN_DOWN: m_orientation = PIN_ORIENTATION::PIN_RIGHT; break;
}
}
} }
} }
@ -1573,11 +1578,8 @@ void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITE
if( dynamic_cast<LIB_SYMBOL*>( symbol ) ) if( dynamic_cast<LIB_SYMBOL*>( symbol ) )
{ {
VECTOR2I pinpos = GetPosition(); aList.emplace_back( _( "Pos X" ), aFrame->MessageTextFromValue( GetPosition().x, true ) );
pinpos.y = -pinpos.y; // Display coords are top to bottom; lib item coords are bottom to top aList.emplace_back( _( "Pos Y" ), aFrame->MessageTextFromValue( GetPosition().y, true ) );
aList.emplace_back( _( "Pos X" ), aFrame->MessageTextFromValue( pinpos.x, true ) );
aList.emplace_back( _( "Pos Y" ), aFrame->MessageTextFromValue( pinpos.y, true ) );
} }
else else
{ {
@ -1755,8 +1757,6 @@ BOX2I SCH_PIN::GetBoundingBox( bool aIncludeLabelsOnInvisiblePins, bool aInclude
BOX2I r = m_libPin->GetBoundingBox( aIncludeLabelsOnInvisiblePins, aIncludeNameAndNumber, BOX2I r = m_libPin->GetBoundingBox( aIncludeLabelsOnInvisiblePins, aIncludeNameAndNumber,
aIncludeElectricalType ); aIncludeElectricalType );
r.RevertYAxis();
r = symbol->GetTransform().TransformCoordinate( r ); r = symbol->GetTransform().TransformCoordinate( r );
r.Offset( symbol->GetPosition() ); r.Offset( symbol->GetPosition() );
r.Normalize(); r.Normalize();
@ -1835,17 +1835,17 @@ BOX2I SCH_PIN::GetBoundingBox( bool aIncludeLabelsOnInvisiblePins, bool aInclude
{ {
// pin name is inside the body (or invisible) // pin name is inside the body (or invisible)
// pin number is above the line // pin number is above the line
begin.y = std::max( minsizeV, numberTextHeight ); begin.y = std::min( -minsizeV, -numberTextHeight );
begin.x = std::min( -typeTextLength, GetLength() - ( numberTextLength / 2 ) ); begin.x = std::min( -typeTextLength, GetLength() - ( numberTextLength / 2 ) );
end.x = GetLength() + nameTextLength; end.x = GetLength() + nameTextLength;
end.y = std::min( -minsizeV, -nameTextHeight / 2 ); end.y = std::max( minsizeV, nameTextHeight / 2 );
} }
else else
{ {
// pin name is above pin line // pin name is above pin line
// pin number is below line // pin number is below line
begin.y = std::max( minsizeV, nameTextHeight ); begin.y = std::min( -minsizeV, -nameTextHeight );
begin.x = -typeTextLength; begin.x = -typeTextLength;
begin.x = std::min( begin.x, ( GetLength() - numberTextLength ) / 2 ); begin.x = std::min( begin.x, ( GetLength() - numberTextLength ) / 2 );
begin.x = std::min( begin.x, ( GetLength() - nameTextLength ) / 2 ); begin.x = std::min( begin.x, ( GetLength() - nameTextLength ) / 2 );
@ -1853,7 +1853,7 @@ BOX2I SCH_PIN::GetBoundingBox( bool aIncludeLabelsOnInvisiblePins, bool aInclude
end.x = GetLength(); end.x = GetLength();
end.x = std::max( end.x, ( GetLength() + nameTextLength ) / 2 ); end.x = std::max( end.x, ( GetLength() + nameTextLength ) / 2 );
end.x = std::max( end.x, ( GetLength() + numberTextLength ) / 2 ); end.x = std::max( end.x, ( GetLength() + numberTextLength ) / 2 );
end.y = std::min( -minsizeV, -numberTextHeight ); end.y = std::max( minsizeV, numberTextHeight );
} }
// Now, calculate boundary box corners position for the actual pin orientation // Now, calculate boundary box corners position for the actual pin orientation
@ -1861,13 +1861,13 @@ BOX2I SCH_PIN::GetBoundingBox( bool aIncludeLabelsOnInvisiblePins, bool aInclude
{ {
case PIN_ORIENTATION::PIN_UP: case PIN_ORIENTATION::PIN_UP:
// Pin is rotated and texts positions are mirrored // Pin is rotated and texts positions are mirrored
RotatePoint( begin, VECTOR2I( 0, 0 ), -ANGLE_90 ); RotatePoint( begin, VECTOR2I( 0, 0 ), ANGLE_90 );
RotatePoint( end, VECTOR2I( 0, 0 ), -ANGLE_90 ); RotatePoint( end, VECTOR2I( 0, 0 ), ANGLE_90 );
break; break;
case PIN_ORIENTATION::PIN_DOWN: case PIN_ORIENTATION::PIN_DOWN:
RotatePoint( begin, VECTOR2I( 0, 0 ), ANGLE_90 ); RotatePoint( begin, VECTOR2I( 0, 0 ), -ANGLE_90 );
RotatePoint( end, VECTOR2I( 0, 0 ), ANGLE_90 ); RotatePoint( end, VECTOR2I( 0, 0 ), -ANGLE_90 );
begin.x = -begin.x; begin.x = -begin.x;
end.x = -end.x; end.x = -end.x;
break; break;
@ -1890,9 +1890,6 @@ BOX2I SCH_PIN::GetBoundingBox( bool aIncludeLabelsOnInvisiblePins, bool aInclude
bbox.Normalize(); bbox.Normalize();
bbox.Inflate( ( GetPenWidth() / 2 ) + 1 ); bbox.Inflate( ( GetPenWidth() / 2 ) + 1 );
// Draw Y axis is reversed in schematic:
bbox.RevertYAxis();
return bbox; return bbox;
} }

View File

@ -76,20 +76,15 @@ void SCH_SHAPE::Normalize()
{ {
if( GetShape() == SHAPE_T::RECTANGLE ) if( GetShape() == SHAPE_T::RECTANGLE )
{ {
bool invertY = m_layer == LAYER_DEVICE;
VECTOR2I size = GetEnd() - GetPosition(); VECTOR2I size = GetEnd() - GetPosition();
bool swapY = invertY ? size.y > 0
: size.y < 0;
bool swapX = size.x < 0;
if( swapY ) if( size.y < 0 )
{ {
SetStartY( GetStartY() + size.y ); SetStartY( GetStartY() + size.y );
SetEndY( GetStartY() - size.y ); SetEndY( GetStartY() - size.y );
} }
if( swapX ) if( size.x < 0 )
{ {
SetStartX( GetStartX() + size.x ); SetStartX( GetStartX() + size.x );
SetEndX( GetStartX() - size.x ); SetEndX( GetStartX() - size.x );
@ -112,27 +107,22 @@ void SCH_SHAPE::MirrorVertically( int aCenter )
void SCH_SHAPE::Rotate( const VECTOR2I& aCenter, bool aRotateCCW ) void SCH_SHAPE::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
{ {
rotate( aCenter, aRotateCCW ? ANGLE_270 : ANGLE_90 ); rotate( aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
} }
bool SCH_SHAPE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const bool SCH_SHAPE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
{ {
if( m_layer == LAYER_DEVICE ) return hitTest( aPosition, aAccuracy );
return hitTest( DefaultTransform.TransformCoordinate( aPosition ), aAccuracy );
else
return hitTest( aPosition, aAccuracy );
} }
bool SCH_SHAPE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const bool SCH_SHAPE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
{ {
if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) ) if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) )
return false; return false;
if( m_layer == LAYER_DEVICE ) return hitTest( aRect, aContained, aAccuracy );
return hitTest( DefaultTransform.TransformCoordinate( aRect ), aContained, aAccuracy );
else
return hitTest( aRect, aContained, aAccuracy );
} }
@ -298,12 +288,7 @@ int SCH_SHAPE::GetEffectiveWidth() const
const BOX2I SCH_SHAPE::GetBoundingBox() const const BOX2I SCH_SHAPE::GetBoundingBox() const
{ {
BOX2I bbox = getBoundingBox(); return getBoundingBox();
if( m_layer == LAYER_DEVICE ) // TODO: nuke symbol editor's upside-down coordinate system
bbox.RevertYAxis();
return bbox;
} }

View File

@ -1581,36 +1581,38 @@ void SCH_SYMBOL::SetOrientation( int aOrientation )
{ {
case SYM_ORIENT_0: case SYM_ORIENT_0:
case SYM_NORMAL: // default transform matrix case SYM_NORMAL: // default transform matrix
m_transform.x1 = 1; m_transform = TRANSFORM();
m_transform.y2 = -1;
m_transform.x2 = m_transform.y1 = 0;
break; break;
case SYM_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation) case SYM_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation)
temp.x1 = temp.y2 = 0; temp.x1 = 0;
temp.y1 = 1; temp.y1 = 1;
temp.x2 = -1; temp.x2 = -1;
temp.y2 = 0;
transform = true; transform = true;
break; break;
case SYM_ROTATE_CLOCKWISE: // Rotate - (incremental rotation) case SYM_ROTATE_CLOCKWISE: // Rotate - (incremental rotation)
temp.x1 = temp.y2 = 0; temp.x1 = 0;
temp.y1 = -1; temp.y1 = -1;
temp.x2 = 1; temp.x2 = 1;
temp.y2 = 0;
transform = true; transform = true;
break; break;
case SYM_MIRROR_Y: // Mirror Y (incremental rotation) case SYM_MIRROR_Y: // Mirror Y (incremental transform)
temp.x1 = -1; temp.x1 = -1;
temp.y1 = 0;
temp.x2 = 0;
temp.y2 = 1; temp.y2 = 1;
temp.y1 = temp.x2 = 0;
transform = true; transform = true;
break; break;
case SYM_MIRROR_X: // Mirror X (incremental rotation) case SYM_MIRROR_X: // Mirror X (incremental transform)
temp.x1 = 1; temp.x1 = 1;
temp.y1 = 0;
temp.x2 = 0;
temp.y2 = -1; temp.y2 = -1;
temp.y1 = temp.x2 = 0;
transform = true; transform = true;
break; break;
@ -1811,25 +1813,7 @@ BOX2I SCH_SYMBOL::doGetBoundingBox( bool aIncludePins, bool aIncludeFields ) con
else else
bBox = dummy()->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false ); bBox = dummy()->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
int x0 = bBox.GetX(); bBox = m_transform.TransformCoordinate( bBox );
int xm = bBox.GetRight();
// We must reverse Y values, because matrix orientation
// suppose Y axis normal for the library items coordinates,
// m_transform reverse Y values, but bBox is already reversed!
int y0 = -bBox.GetY();
int ym = -bBox.GetBottom();
// Compute the real Boundary box (rotated, mirrored ...)
int x1 = m_transform.x1 * x0 + m_transform.y1 * y0;
int y1 = m_transform.x2 * x0 + m_transform.y2 * y0;
int x2 = m_transform.x1 * xm + m_transform.y1 * ym;
int y2 = m_transform.x2 * xm + m_transform.y2 * ym;
bBox.SetX( x1 );
bBox.SetY( y1 );
bBox.SetWidth( x2 - x1 );
bBox.SetHeight( y2 - y1 );
bBox.Normalize(); bBox.Normalize();
bBox.Offset( m_pos ); bBox.Offset( m_pos );
@ -2037,9 +2021,9 @@ void SCH_SYMBOL::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
{ {
VECTOR2I prev = m_pos; VECTOR2I prev = m_pos;
RotatePoint( m_pos, aCenter, aRotateCCW ? ANGLE_270 : ANGLE_90 ); RotatePoint( m_pos, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
SetOrientation( aRotateCCW ? SYM_ROTATE_CLOCKWISE : SYM_ROTATE_COUNTERCLOCKWISE ); SetOrientation( aRotateCCW ? SYM_ROTATE_COUNTERCLOCKWISE : SYM_ROTATE_CLOCKWISE );
for( SCH_FIELD& field : m_fields ) for( SCH_FIELD& field : m_fields )
{ {

View File

@ -195,48 +195,13 @@ void SCH_TEXT::MirrorVertically( int aCenter )
void SCH_TEXT::Rotate( const VECTOR2I& aCenter, bool aRotateCCW ) void SCH_TEXT::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
{ {
if( m_layer == LAYER_DEVICE ) VECTOR2I pt = GetTextPos();
{ RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
NormalizeJustification( false ); VECTOR2I offset = pt - GetTextPos();
EDA_ANGLE rot_angle = aRotateCCW ? -ANGLE_90 : ANGLE_90;
VECTOR2I pt = GetTextPos(); Rotate90( false );
RotatePoint( pt, aCenter, rot_angle );
SetTextPos( pt );
if( GetTextAngle().IsHorizontal() ) SetTextPos( GetTextPos() + offset );
{
SetTextAngle( ANGLE_VERTICAL );
}
else
{
// 180° rotation is a mirror
if( GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
else if( GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
if( GetVertJustify() == GR_TEXT_V_ALIGN_TOP )
SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
else if( GetVertJustify() == GR_TEXT_V_ALIGN_BOTTOM )
SetVertJustify( GR_TEXT_V_ALIGN_TOP );
SetTextAngle( ANGLE_0 );
}
NormalizeJustification( true );
}
else
{
VECTOR2I pt = GetTextPos();
RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_270 : ANGLE_90 );
VECTOR2I offset = pt - GetTextPos();
Rotate90( false );
SetTextPos( GetTextPos() + offset );
}
} }
@ -384,10 +349,7 @@ void SCH_TEXT::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBody
* to calculate so the more easily way is to use no justifications (centered text) and * to calculate so the more easily way is to use no justifications (centered text) and
* use GetBoundingBox to know the text coordinate considered as centered * use GetBoundingBox to know the text coordinate considered as centered
*/ */
BOX2I bBox = GetBoundingBox(); BOX2I bBox = GetBoundingBox();
// convert coordinates from draw Y axis to symbol_editor Y axis:
bBox.RevertYAxis();
VECTOR2I txtpos = bBox.Centre(); VECTOR2I txtpos = bBox.Centre();
// Calculate pos according to mirror/rotation. // Calculate pos according to mirror/rotation.
@ -421,45 +383,22 @@ void SCH_TEXT::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBody
const BOX2I SCH_TEXT::GetBoundingBox() const const BOX2I SCH_TEXT::GetBoundingBox() const
{ {
if( m_layer == LAYER_DEVICE ) // TODO: nuke symbol editor's upside-down coordinate system BOX2I bbox = GetTextBox();
{
BOX2I bbox = GetTextBox( -1, true );
bbox.RevertYAxis();
// We are using now a bottom to top Y axis. if( !GetTextAngle().IsZero() ) // Rotate bbox.
VECTOR2I orig = bbox.GetOrigin(); {
VECTOR2I pos = bbox.GetOrigin();
VECTOR2I end = bbox.GetEnd(); VECTOR2I end = bbox.GetEnd();
RotatePoint( orig, GetTextPos(), -GetTextAngle() ); RotatePoint( pos, GetTextPos(), GetTextAngle() );
RotatePoint( end, GetTextPos(), -GetTextAngle() ); RotatePoint( end, GetTextPos(), GetTextAngle() );
bbox.SetOrigin( orig ); bbox.SetOrigin( pos );
bbox.SetEnd( end ); bbox.SetEnd( end );
// We are using now a top to bottom Y axis:
bbox.RevertYAxis();
return bbox;
} }
else
{
BOX2I bbox = GetTextBox();
if( !GetTextAngle().IsZero() ) // Rotate bbox. bbox.Normalize();
{ return bbox;
VECTOR2I pos = bbox.GetOrigin();
VECTOR2I end = bbox.GetEnd();
RotatePoint( pos, GetTextPos(), GetTextAngle() );
RotatePoint( end, GetTextPos(), GetTextAngle() );
bbox.SetOrigin( pos );
bbox.SetEnd( end );
}
bbox.Normalize();
return bbox;
}
} }
@ -525,26 +464,9 @@ BITMAPS SCH_TEXT::GetMenuImage() const
bool SCH_TEXT::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const bool SCH_TEXT::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
{ {
if( m_layer == LAYER_DEVICE ) // TODO: nuke symbol editor's upside-down coordinate system BOX2I bBox = GetBoundingBox();
{ bBox.Inflate( aAccuracy );
EDA_TEXT tmp_text( *this ); return bBox.Contains( aPosition );
tmp_text.SetTextPos( DefaultTransform.TransformCoordinate( GetTextPos() ) );
/* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped.
* this simple algo works only for schematic matrix (rot 90 or/and mirror)
*/
bool t1 = ( DefaultTransform.x1 != 0 ) ^ ( GetTextAngle() != ANGLE_HORIZONTAL );
tmp_text.SetTextAngle( t1 ? ANGLE_HORIZONTAL : ANGLE_VERTICAL );
return tmp_text.TextHitTest( aPosition, aAccuracy );
}
else
{
BOX2I bBox = GetBoundingBox();
bBox.Inflate( aAccuracy );
return bBox.Contains( aPosition );
}
} }
@ -554,28 +476,14 @@ bool SCH_TEXT::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) con
return false; return false;
BOX2I rect = aRect; BOX2I rect = aRect;
BOX2I bBox = GetBoundingBox();
rect.Inflate( aAccuracy ); rect.Inflate( aAccuracy );
if( m_layer == LAYER_DEVICE ) // TODO: nuke symbol editor's upside-down coordinate system if( aContained )
{ return aRect.Contains( bBox );
BOX2I bBox = GetTextBox();
bBox.RevertYAxis();
if( aContained ) return aRect.Intersects( bBox );
return rect.Contains( bBox );
return rect.Intersects( bBox, GetTextAngle() );
}
else
{
BOX2I bBox = GetBoundingBox();
if( aContained )
return aRect.Contains( bBox );
return aRect.Intersects( bBox );
}
} }
@ -645,8 +553,6 @@ void SCH_TEXT::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& a
if( m_layer == LAYER_DEVICE ) if( m_layer == LAYER_DEVICE )
{ {
BOX2I bBox = GetBoundingBox(); BOX2I bBox = GetBoundingBox();
// convert coordinates from draw Y axis to symbol_editor Y axis
bBox.RevertYAxis();
/* /*
* Calculate the text justification, according to the symbol orientation/mirror. This is * Calculate the text justification, according to the symbol orientation/mirror. This is

View File

@ -105,27 +105,26 @@ public:
case SCH_SHAPE_T: case SCH_SHAPE_T:
{ {
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem ); SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
bool invertY = shape->GetLayer() == LAYER_DEVICE;
switch( shape->GetShape() ) switch( shape->GetShape() )
{ {
case SHAPE_T::ARC: case SHAPE_T::ARC:
points->AddPoint( mapCoords( shape->GetPosition(), invertY ) ); points->AddPoint( shape->GetPosition() );
points->AddPoint( mapCoords( shape->GetStart(), invertY ) ); points->AddPoint( shape->GetStart() );
points->AddPoint( mapCoords( shape->GetEnd(), invertY ) ); points->AddPoint( shape->GetEnd() );
break; break;
case SHAPE_T::CIRCLE: case SHAPE_T::CIRCLE:
points->AddPoint( mapCoords( shape->GetPosition(), invertY ) ); points->AddPoint( shape->GetPosition() );
points->AddPoint( mapCoords( shape->GetEnd(), invertY ) ); points->AddPoint( shape->GetEnd() );
break; break;
case SHAPE_T::RECTANGLE: case SHAPE_T::RECTANGLE:
{ {
shape->Normalize(); shape->Normalize();
VECTOR2I topLeft = mapCoords( shape->GetPosition(), invertY ); VECTOR2I topLeft = shape->GetPosition();
VECTOR2I botRight = mapCoords( shape->GetEnd(), invertY ); VECTOR2I botRight = shape->GetEnd();
points->AddPoint( topLeft ); points->AddPoint( topLeft );
points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) ); points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
@ -146,15 +145,15 @@ public:
case SHAPE_T::POLY: case SHAPE_T::POLY:
for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() ) for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
points->AddPoint( mapCoords( pt, invertY ) ); points->AddPoint( pt );
break; break;
case SHAPE_T::BEZIER: case SHAPE_T::BEZIER:
points->AddPoint( mapCoords( shape->GetStart(), invertY ) ); points->AddPoint( shape->GetStart() );
points->AddPoint( mapCoords( shape->GetBezierC1(), invertY ) ); points->AddPoint( shape->GetBezierC1() );
points->AddPoint( mapCoords( shape->GetBezierC2(), invertY ) ); points->AddPoint( shape->GetBezierC2() );
points->AddPoint( mapCoords( shape->GetEnd(), invertY ) ); points->AddPoint( shape->GetEnd() );
break; break;
default: default:
@ -177,12 +176,11 @@ public:
case SCH_TEXTBOX_T: case SCH_TEXTBOX_T:
{ {
SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( aItem ); SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( aItem );
bool invertY = textbox->GetLayer() == LAYER_DEVICE;
textbox->Normalize(); textbox->Normalize();
VECTOR2I topLeft = mapCoords( textbox->GetPosition(), invertY ); VECTOR2I topLeft = textbox->GetPosition();
VECTOR2I botRight = mapCoords( textbox->GetEnd(), invertY ); VECTOR2I botRight = textbox->GetEnd();
points->AddPoint( topLeft ); points->AddPoint( topLeft );
points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) ); points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
@ -647,7 +645,6 @@ void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
case SCH_SHAPE_T: case SCH_SHAPE_T:
{ {
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item ); SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
bool invertY = shape->GetLayer() == LAYER_DEVICE;
switch( shape->GetShape() ) switch( shape->GetShape() )
{ {
@ -655,23 +652,23 @@ void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
if( getEditedPointIndex() == ARC_CENTER ) if( getEditedPointIndex() == ARC_CENTER )
{ {
shape->SetEditState( 4 ); shape->SetEditState( 4 );
shape->CalcEdit( mapCoords( m_editPoints->Point( ARC_CENTER ).GetPosition(), invertY ) ); shape->CalcEdit( m_editPoints->Point( ARC_CENTER ).GetPosition() );
} }
else if( getEditedPointIndex() == ARC_START ) else if( getEditedPointIndex() == ARC_START )
{ {
shape->SetEditState( 2 ); shape->SetEditState( 2 );
shape->CalcEdit( mapCoords( m_editPoints->Point( ARC_START ).GetPosition(), invertY ) ); shape->CalcEdit( m_editPoints->Point( ARC_START ).GetPosition() );
} }
else if( getEditedPointIndex() == ARC_END ) else if( getEditedPointIndex() == ARC_END )
{ {
shape->SetEditState( 3 ); shape->SetEditState( 3 );
shape->CalcEdit( mapCoords( m_editPoints->Point( ARC_END ).GetPosition(), invertY ) ); shape->CalcEdit( m_editPoints->Point( ARC_END ).GetPosition() );
} }
break; break;
case SHAPE_T::CIRCLE: case SHAPE_T::CIRCLE:
shape->SetPosition( mapCoords( m_editPoints->Point( CIRC_CENTER ).GetPosition(), invertY ) ); shape->SetPosition( m_editPoints->Point( CIRC_CENTER ).GetPosition() );
shape->SetEnd( mapCoords( m_editPoints->Point( CIRC_END ).GetPosition(), invertY ) ); shape->SetEnd( m_editPoints->Point( CIRC_END ).GetPosition() );
break; break;
case SHAPE_T::POLY: case SHAPE_T::POLY:
@ -680,7 +677,7 @@ void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
for( unsigned i = 0; i < m_editPoints->PointsSize(); ++i ) for( unsigned i = 0; i < m_editPoints->PointsSize(); ++i )
{ {
VECTOR2I pt = mapCoords( m_editPoints->Point( i ).GetPosition(), invertY ); VECTOR2I pt = m_editPoints->Point( i ).GetPosition();
shape->GetPolyShape().Append( pt.x, pt.y, -1, -1, true ); shape->GetPolyShape().Append( pt.x, pt.y, -1, -1, true );
} }
@ -704,24 +701,24 @@ void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
|| isModified( m_editPoints->Point( RECT_BOTRIGHT ) ) || isModified( m_editPoints->Point( RECT_BOTRIGHT ) )
|| isModified( m_editPoints->Point( RECT_BOTLEFT ) ) ) || isModified( m_editPoints->Point( RECT_BOTLEFT ) ) )
{ {
shape->SetPosition( mapCoords( topLeft, invertY ) ); shape->SetPosition( topLeft );
shape->SetEnd( mapCoords( botRight, invertY ) ); shape->SetEnd( botRight );
} }
else if( isModified( m_editPoints->Line( RECT_TOP ) ) ) else if( isModified( m_editPoints->Line( RECT_TOP ) ) )
{ {
shape->SetStartY( mapCoords( topLeft, invertY ).y ); shape->SetStartY( topLeft.y );
} }
else if( isModified( m_editPoints->Line( RECT_LEFT ) ) ) else if( isModified( m_editPoints->Line( RECT_LEFT ) ) )
{ {
shape->SetStartX( mapCoords( topLeft, invertY ).x ); shape->SetStartX( topLeft.x );
} }
else if( isModified( m_editPoints->Line( RECT_BOT ) ) ) else if( isModified( m_editPoints->Line( RECT_BOT ) ) )
{ {
shape->SetEndY( mapCoords( botRight, invertY ).y ); shape->SetEndY( botRight.y );
} }
else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) ) else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) )
{ {
shape->SetEndX( mapCoords( botRight, invertY ).x ); shape->SetEndX( botRight.x );
} }
for( unsigned i = 0; i < m_editPoints->LinesSize(); ++i ) for( unsigned i = 0; i < m_editPoints->LinesSize(); ++i )
@ -737,10 +734,10 @@ void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
} }
case SHAPE_T::BEZIER: case SHAPE_T::BEZIER:
shape->SetStart( mapCoords( m_editPoints->Point( BEZIER_START ).GetPosition(), invertY ) ); shape->SetStart( m_editPoints->Point( BEZIER_START ).GetPosition() );
shape->SetBezierC1( mapCoords( m_editPoints->Point( BEZIER_CTRL_PT1 ).GetPosition(), invertY ) ); shape->SetBezierC1( m_editPoints->Point( BEZIER_CTRL_PT1 ).GetPosition() );
shape->SetBezierC2( mapCoords( m_editPoints->Point( BEZIER_CTRL_PT2 ).GetPosition(), invertY ) ); shape->SetBezierC2( m_editPoints->Point( BEZIER_CTRL_PT2 ).GetPosition() );
shape->SetEnd( mapCoords( m_editPoints->Point( BEZIER_END ).GetPosition(), invertY ) ); shape->SetEnd( m_editPoints->Point( BEZIER_END ).GetPosition() );
shape->RebuildBezierToSegmentsPointsList( shape->GetWidth() ); shape->RebuildBezierToSegmentsPointsList( shape->GetWidth() );
break; break;
@ -755,7 +752,6 @@ void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
case SCH_TEXTBOX_T: case SCH_TEXTBOX_T:
{ {
SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item ); SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item );
bool invertY = textbox->GetLayer() == LAYER_DEVICE;
EE_GRID_HELPER gridHelper( m_toolMgr ); EE_GRID_HELPER gridHelper( m_toolMgr );
VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition(); VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition(); VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
@ -772,24 +768,24 @@ void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
|| isModified( m_editPoints->Point( RECT_BOTRIGHT ) ) || isModified( m_editPoints->Point( RECT_BOTRIGHT ) )
|| isModified( m_editPoints->Point( RECT_BOTLEFT ) ) ) || isModified( m_editPoints->Point( RECT_BOTLEFT ) ) )
{ {
textbox->SetPosition( mapCoords( topLeft, invertY ) ); textbox->SetPosition( topLeft );
textbox->SetEnd( mapCoords( botRight, invertY ) ); textbox->SetEnd( botRight );
} }
else if( isModified( m_editPoints->Line( RECT_TOP ) ) ) else if( isModified( m_editPoints->Line( RECT_TOP ) ) )
{ {
textbox->SetStartY( mapCoords( topLeft, invertY ).y ); textbox->SetStartY( topLeft.y );
} }
else if( isModified( m_editPoints->Line( RECT_LEFT ) ) ) else if( isModified( m_editPoints->Line( RECT_LEFT ) ) )
{ {
textbox->SetStartX( mapCoords( topLeft, invertY ).x ); textbox->SetStartX( topLeft.x );
} }
else if( isModified( m_editPoints->Line( RECT_BOT ) ) ) else if( isModified( m_editPoints->Line( RECT_BOT ) ) )
{ {
textbox->SetEndY( mapCoords( botRight, invertY ).y ); textbox->SetEndY( botRight.y );
} }
else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) ) else if( isModified( m_editPoints->Line( RECT_RIGHT ) ) )
{ {
textbox->SetEndX( mapCoords( botRight, invertY ).x ); textbox->SetEndX( botRight.x );
} }
for( unsigned i = 0; i < m_editPoints->LinesSize(); ++i ) for( unsigned i = 0; i < m_editPoints->LinesSize(); ++i )
@ -993,19 +989,18 @@ void EE_POINT_EDITOR::updatePoints()
case SCH_SHAPE_T: case SCH_SHAPE_T:
{ {
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item ); SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
bool invertY = shape->GetLayer() == LAYER_DEVICE;
switch( shape->GetShape() ) switch( shape->GetShape() )
{ {
case SHAPE_T::ARC: case SHAPE_T::ARC:
m_editPoints->Point( ARC_CENTER ).SetPosition( mapCoords( shape->GetPosition(), invertY ) ); m_editPoints->Point( ARC_CENTER ).SetPosition( shape->GetPosition() );
m_editPoints->Point( ARC_START ).SetPosition( mapCoords( shape->GetStart(), invertY ) ); m_editPoints->Point( ARC_START ).SetPosition( shape->GetStart() );
m_editPoints->Point( ARC_END ).SetPosition( mapCoords( shape->GetEnd(), invertY ) ); m_editPoints->Point( ARC_END ).SetPosition( shape->GetEnd() );
break; break;
case SHAPE_T::CIRCLE: case SHAPE_T::CIRCLE:
m_editPoints->Point( CIRC_CENTER ).SetPosition( mapCoords( shape->GetPosition(), invertY ) ); m_editPoints->Point( CIRC_CENTER ).SetPosition( shape->GetPosition() );
m_editPoints->Point( CIRC_END ).SetPosition( mapCoords( shape->GetEnd(), invertY ) ); m_editPoints->Point( CIRC_END ).SetPosition( shape->GetEnd() );
break; break;
case SHAPE_T::POLY: case SHAPE_T::POLY:
@ -1022,7 +1017,7 @@ void EE_POINT_EDITOR::updatePoints()
int ii = 0; int ii = 0;
for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() ) for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
m_editPoints->Point( ii++ ).SetPosition( mapCoords( pt, invertY ) ); m_editPoints->Point( ii++ ).SetPosition( pt );
} }
break; break;
@ -1034,8 +1029,8 @@ void EE_POINT_EDITOR::updatePoints()
// Some symbols can have rectangles with width or height < 0 // Some symbols can have rectangles with width or height < 0
// So normalize the size: // So normalize the size:
BOX2I dummy; BOX2I dummy;
dummy.SetOrigin( mapCoords( shape->GetPosition(), invertY ) ); dummy.SetOrigin( shape->GetPosition() );
dummy.SetEnd( mapCoords( shape->GetEnd(), invertY ) ); dummy.SetEnd( shape->GetEnd() );
dummy.Normalize(); dummy.Normalize();
VECTOR2I topLeft = dummy.GetPosition(); VECTOR2I topLeft = dummy.GetPosition();
VECTOR2I botRight = dummy.GetEnd(); VECTOR2I botRight = dummy.GetEnd();
@ -1048,10 +1043,10 @@ void EE_POINT_EDITOR::updatePoints()
} }
case SHAPE_T::BEZIER: case SHAPE_T::BEZIER:
m_editPoints->Point( BEZIER_START ).SetPosition( mapCoords( shape->GetStart(), invertY ) ); m_editPoints->Point( BEZIER_START ).SetPosition( shape->GetStart() );
m_editPoints->Point( BEZIER_CTRL_PT1 ).SetPosition( mapCoords( shape->GetBezierC1(), invertY ) ); m_editPoints->Point( BEZIER_CTRL_PT1 ).SetPosition( shape->GetBezierC1() );
m_editPoints->Point( BEZIER_CTRL_PT2 ).SetPosition( mapCoords( shape->GetBezierC2(), invertY ) ); m_editPoints->Point( BEZIER_CTRL_PT2 ).SetPosition( shape->GetBezierC2() );
m_editPoints->Point( BEZIER_END ).SetPosition( mapCoords( shape->GetEnd(), invertY ) ); m_editPoints->Point( BEZIER_END ).SetPosition( shape->GetEnd() );
break; break;
default: default:
@ -1064,14 +1059,13 @@ void EE_POINT_EDITOR::updatePoints()
case SCH_TEXTBOX_T: case SCH_TEXTBOX_T:
{ {
SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item ); SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item );
bool invertY = textbox->GetLayer() == LAYER_DEVICE;
// point editor works only with rectangles having width and height > 0 // point editor works only with rectangles having width and height > 0
// Some symbols can have rectangles with width or height < 0 // Some symbols can have rectangles with width or height < 0
// So normalize the size: // So normalize the size:
BOX2I dummy; BOX2I dummy;
dummy.SetOrigin( mapCoords( textbox->GetPosition(), invertY ) ); dummy.SetOrigin( textbox->GetPosition() );
dummy.SetEnd( mapCoords( textbox->GetEnd(), invertY ) ); dummy.SetEnd( textbox->GetEnd() );
dummy.Normalize(); dummy.Normalize();
VECTOR2I topLeft = dummy.GetPosition(); VECTOR2I topLeft = dummy.GetPosition();
VECTOR2I botRight = dummy.GetEnd(); VECTOR2I botRight = dummy.GetEnd();
@ -1173,7 +1167,6 @@ bool EE_POINT_EDITOR::removeCornerCondition( const SELECTION& )
} }
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() ); SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
bool invertY = shape->GetLayer() == LAYER_DEVICE;
if( shape->GetPolyShape().IsEmpty() ) if( shape->GetPolyShape().IsEmpty() )
return false; return false;
@ -1185,10 +1178,7 @@ bool EE_POINT_EDITOR::removeCornerCondition( const SELECTION& )
for( const VECTOR2I& pt : poly.CPoints() ) for( const VECTOR2I& pt : poly.CPoints() )
{ {
VECTOR2I adjustedPos = isRuleArea ? m_editedPoint->GetPosition() if( pt == m_editedPoint->GetPosition() )
: mapCoords( m_editedPoint->GetPosition(), invertY );
if( pt == adjustedPos )
return true; return true;
} }
@ -1225,14 +1215,12 @@ int EE_POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent )
return 0; return 0;
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() ); SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( m_editPoints->GetParent() );
bool invertY = shape->GetLayer() == LAYER_DEVICE;
SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 ); SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 );
SCH_COMMIT commit( m_toolMgr ); SCH_COMMIT commit( m_toolMgr );
commit.Modify( shape, m_frame->GetScreen() ); commit.Modify( shape, m_frame->GetScreen() );
VECTOR2I cursor = getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() ); VECTOR2I cursor = getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() );
VECTOR2I pos = mapCoords( cursor, invertY );
int currentMinDistance = INT_MAX; int currentMinDistance = INT_MAX;
int closestLineStart = 0; int closestLineStart = 0;
unsigned numPoints = poly.GetPointCount(); unsigned numPoints = poly.GetPointCount();
@ -1243,7 +1231,7 @@ int EE_POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent )
for( unsigned i = 0; i < numPoints; ++i ) for( unsigned i = 0; i < numPoints; ++i )
{ {
int distance = (int) DistanceLinePoint( poly.CPoint( i ), int distance = (int) DistanceLinePoint( poly.CPoint( i ),
poly.CPoint( i + 1 ), pos ); poly.CPoint( i + 1 ), cursor );
if( distance < currentMinDistance ) if( distance < currentMinDistance )
{ {
@ -1252,7 +1240,7 @@ int EE_POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent )
} }
} }
poly.Insert( closestLineStart + 1, pos ); poly.Insert( closestLineStart + 1, cursor );
updateItem( shape, true ); updateItem( shape, true );
updatePoints(); updatePoints();

View File

@ -1403,7 +1403,7 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
} }
// Find the closest item. (Note that at this point all hits are either exact or non-exact.) // Find the closest item. (Note that at this point all hits are either exact or non-exact.)
SEG poss( mapCoords( aPos, m_isSymbolEditor ), mapCoords( aPos, m_isSymbolEditor ) ); SEG poss( aPos, aPos );
EDA_ITEM* closest = nullptr; EDA_ITEM* closest = nullptr;
int closestDist = INT_MAX / 4; int closestDist = INT_MAX / 4;

View File

@ -202,22 +202,4 @@ protected:
}; };
//
// TODO: nuke symbol editor's upside-down coordinate system
//
inline VECTOR2I mapCoords( const wxPoint& aCoord, bool aInvertY )
{
return VECTOR2I( aCoord.x, aInvertY ? -aCoord.y : aCoord.y );
}
inline VECTOR2I mapCoords( const VECTOR2I& aCoord, bool aInvertY )
{
return VECTOR2I( aCoord.x, aInvertY ? -aCoord.y : aCoord.y );
}
inline VECTOR2I mapCoords( const int x, const int y, bool aInvertY )
{
return VECTOR2I( x, aInvertY ? -y : y );
}
#endif #endif

View File

@ -210,14 +210,13 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
{ {
case SCH_PIN_T: case SCH_PIN_T:
{ {
item = pinTool->CreatePin( VECTOR2I( cursorPos.x, -cursorPos.y ), symbol ); item = pinTool->CreatePin( cursorPos, symbol );
g_lastPinWeakPtr = item; g_lastPinWeakPtr = item;
break; break;
} }
case SCH_TEXT_T: case SCH_TEXT_T:
{ {
SCH_TEXT* text = new SCH_TEXT( VECTOR2I( cursorPos.x, -cursorPos.y ), SCH_TEXT* text = new SCH_TEXT( cursorPos, wxEmptyString, LAYER_DEVICE );
wxEmptyString, LAYER_DEVICE );
text->SetParent( symbol ); text->SetParent( symbol );
@ -487,7 +486,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::doDrawShape( const TOOL_EVENT& aEvent, std::opt
item->SetFillColor( m_lastFillColor ); item->SetFillColor( m_lastFillColor );
item->SetFlags( IS_NEW ); item->SetFlags( IS_NEW );
item->BeginEdit( VECTOR2I( cursorPos.x, -cursorPos.y ) ); item->BeginEdit( cursorPos );
if( m_drawSpecificUnit ) if( m_drawSpecificUnit )
item->SetUnit( m_frame->GetUnit() ); item->SetUnit( m_frame->GetUnit() );
@ -560,7 +559,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::doDrawShape( const TOOL_EVENT& aEvent, std::opt
} }
else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) ) else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
{ {
item->CalcEdit( VECTOR2I( cursorPos.x, -cursorPos.y ) ); item->CalcEdit( cursorPos );
m_view->ClearPreview(); m_view->ClearPreview();
m_view->AddToPreview( item->Clone() ); m_view->AddToPreview( item->Clone() );
} }
@ -632,15 +631,11 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::PlaceAnchor( const TOOL_EVENT& aEvent )
continue; continue;
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
VECTOR2I offset( -cursorPos.x, cursorPos.y );
symbol->Move( offset ); symbol->Move( -cursorPos );
// Refresh the view without changing the viewport // Refresh the view without changing the viewport
auto center = m_view->GetCenter(); m_view->SetCenter( m_view->GetCenter() + cursorPos );
center.x += offset.x;
center.y -= offset.y;
m_view->SetCenter( center );
m_view->RecacheAllItems(); m_view->RecacheAllItems();
m_frame->OnModify(); m_frame->OnModify();
} }
@ -779,7 +774,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::ImportGraphics( const TOOL_EVENT& aEvent )
} }
else if( evt->IsMotion() ) else if( evt->IsMotion() )
{ {
delta = VECTOR2I( cursorPos.x, -cursorPos.y ) - currentOffset; delta = cursorPos - currentOffset;
for( SCH_ITEM* item : selectedItems ) for( SCH_ITEM* item : selectedItems )
item->Move( delta ); item->Move( delta );

View File

@ -165,7 +165,7 @@ int SYMBOL_EDITOR_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
if( selection.GetSize() == 1 ) if( selection.GetSize() == 1 )
rotPoint = item->GetPosition(); rotPoint = item->GetPosition();
else else
rotPoint = m_frame->GetNearestHalfGridPosition( mapCoords( selection.GetCenter(), true ) ); rotPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
for( unsigned ii = 0; ii < selection.GetSize(); ii++ ) for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
{ {
@ -237,7 +237,7 @@ int SYMBOL_EDITOR_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
} }
else else
{ {
mirrorPoint = m_frame->GetNearestHalfGridPosition( mapCoords( selection.GetCenter(), true ) ); mirrorPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
for( unsigned ii = 0; ii < selection.GetSize(); ii++ ) for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
{ {
@ -920,7 +920,7 @@ int SYMBOL_EDITOR_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::clearSelection ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection );
m_toolMgr->RunAction<EDA_ITEMS*>( EE_ACTIONS::addItemsToSel, &newItems ); m_toolMgr->RunAction<EDA_ITEMS*>( EE_ACTIONS::addItemsToSel, &newItems );
selection.SetReferencePoint( mapCoords( getViewControls()->GetCursorPosition( true ), true ) ); selection.SetReferencePoint( getViewControls()->GetCursorPosition( true ) );
if( m_toolMgr->RunSynchronousAction( EE_ACTIONS::move, &commit ) ) if( m_toolMgr->RunSynchronousAction( EE_ACTIONS::move, &commit ) )
commit.Push( _( "Duplicate" ) ); commit.Push( _( "Duplicate" ) );

View File

@ -225,7 +225,7 @@ bool SYMBOL_EDITOR_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COM
if( lib_item->IsNew() ) if( lib_item->IsNew() )
{ {
m_anchorPos = selection.GetReferencePoint(); m_anchorPos = selection.GetReferencePoint();
VECTOR2I delta = m_cursor - mapCoords( m_anchorPos, true ); VECTOR2I delta = m_cursor - m_anchorPos;
// Drag items to the current cursor position // Drag items to the current cursor position
for( EDA_ITEM* item : selection ) for( EDA_ITEM* item : selection )
@ -385,7 +385,7 @@ int SYMBOL_EDITOR_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
[&]( EDA_ITEM* item, const VECTOR2I& delta ) [&]( EDA_ITEM* item, const VECTOR2I& delta )
{ {
commit.Modify( item, m_frame->GetScreen() ); commit.Modify( item, m_frame->GetScreen() );
static_cast<SCH_ITEM*>( item )->Move( mapCoords( delta, true ) ); static_cast<SCH_ITEM*>( item )->Move( delta );
updateItem( item, true ); updateItem( item, true );
}; };
@ -509,7 +509,7 @@ int SYMBOL_EDITOR_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
void SYMBOL_EDITOR_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta ) void SYMBOL_EDITOR_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
{ {
static_cast<SCH_ITEM*>( aItem )->Move( mapCoords( aDelta, true ) ); static_cast<SCH_ITEM*>( aItem )->Move( aDelta );
aItem->SetFlags( IS_MOVING ); aItem->SetFlags( IS_MOVING );
} }

View File

@ -288,12 +288,11 @@ public:
* locate functions....) * locate functions....)
* *
* @param aLine The line of text to consider. Pass -1 for all lines. * @param aLine The line of text to consider. Pass -1 for all lines.
* @param aInvertY Invert the Y axis when calculating bounding box.
* @return the rect containing the line of text (i.e. the position and the size of one line) * @return the rect containing the line of text (i.e. the position and the size of one line)
* this rectangle is calculated for 0 orient text. * this rectangle is calculated for 0 orient text.
* If orientation is not 0 the rect must be rotated to match the physical area * If orientation is not 0 the rect must be rotated to match the physical area
*/ */
BOX2I GetTextBox( int aLine = -1, bool aInvertY = false ) const; BOX2I GetTextBox( int aLine = -1 ) const;
/** /**
* Return the distance between two lines of text. * Return the distance between two lines of text.
@ -431,7 +430,6 @@ private:
mutable bool m_bounding_box_cache_valid; mutable bool m_bounding_box_cache_valid;
mutable VECTOR2I m_bounding_box_cache_pos; mutable VECTOR2I m_bounding_box_cache_pos;
mutable int m_bounding_box_cache_line; mutable int m_bounding_box_cache_line;
mutable bool m_bounding_box_cache_inverted;
mutable BOX2I m_bounding_box_cache; mutable BOX2I m_bounding_box_cache;
TEXT_ATTRIBUTES m_attributes; TEXT_ATTRIBUTES m_attributes;

View File

@ -718,16 +718,6 @@ public:
return bbox; return bbox;
} }
/**
* Mirror the rectangle from the X axis (negate Y pos and size).
*/
void RevertYAxis()
{
m_Pos.y = -m_Pos.y;
m_Size.y = -m_Size.y;
Normalize();
}
/** /**
* Return the area of the rectangle. * Return the area of the rectangle.
* *

View File

@ -57,7 +57,7 @@ public:
x1( 1 ), x1( 1 ),
y1( 0 ), y1( 0 ),
x2( 0 ), x2( 0 ),
y2( -1 ) y2( 1 )
{} {}
TRANSFORM( int ax1, int ay1, int ax2, int ay2 ) : TRANSFORM( int ax1, int ay1, int ax2, int ay2 ) :

View File

@ -29,7 +29,7 @@
#include <math/box2.h> #include <math/box2.h>
// a transform matrix, to display symbols in lib editor // a transform matrix, to display symbols in lib editor
TRANSFORM DefaultTransform = TRANSFORM( 1, 0, 0, -1 ); TRANSFORM DefaultTransform = TRANSFORM( 1, 0, 0, 1 );
bool TRANSFORM::operator==( const TRANSFORM& aTransform ) const bool TRANSFORM::operator==( const TRANSFORM& aTransform ) const

View File

@ -832,7 +832,7 @@ void PCB_IO_EASYEDA_PARSER::ParseToBoardItemContainer(
if( !font.IsEmpty() ) if( !font.IsEmpty() )
text->SetFont( KIFONT::FONT::GetFont( font ) ); text->SetFont( KIFONT::FONT::GetFont( font ) );
TransformTextToBaseline( text, wxEmptyString, false ); TransformTextToBaseline( text, wxEmptyString );
if( add ) if( add )
aContainer->Add( text, ADD_MODE::APPEND ); aContainer->Add( text, ADD_MODE::APPEND );

View File

@ -169,6 +169,13 @@
"via_dimensions": [], "via_dimensions": [],
"zones_allow_external_fillets": false "zones_allow_external_fillets": false
}, },
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [], "layer_presets": [],
"viewports": [] "viewports": []
}, },
@ -363,10 +370,12 @@
"duplicate_sheet_names": "error", "duplicate_sheet_names": "error",
"endpoint_off_grid": "warning", "endpoint_off_grid": "warning",
"extra_units": "error", "extra_units": "error",
"footprint_link_issues": "warning",
"global_label_dangling": "warning", "global_label_dangling": "warning",
"hier_label_mismatch": "error", "hier_label_mismatch": "error",
"label_dangling": "error", "label_dangling": "error",
"lib_symbol_issues": "warning", "lib_symbol_issues": "warning",
"lib_symbol_mismatch": "warning",
"missing_bidi_pin": "warning", "missing_bidi_pin": "warning",
"missing_input_pin": "warning", "missing_input_pin": "warning",
"missing_power_pin": "error", "missing_power_pin": "error",
@ -381,6 +390,7 @@
"power_pin_not_driven": "error", "power_pin_not_driven": "error",
"similar_labels": "warning", "similar_labels": "warning",
"simulation_model_issue": "error", "simulation_model_issue": "error",
"single_global_label": "ignore",
"unannotated": "error", "unannotated": "error",
"unit_value_mismatch": "error", "unit_value_mismatch": "error",
"unresolved_variable": "error", "unresolved_variable": "error",
@ -392,7 +402,7 @@
"pinned_symbol_libs": [] "pinned_symbol_libs": []
}, },
"meta": { "meta": {
"filename": "CliTest.kicad_pro", "filename": "basic_test.kicad_pro",
"version": 1 "version": 1
}, },
"net_settings": { "net_settings": {
@ -419,7 +429,14 @@
"version": 3 "version": 3
}, },
"net_colors": null, "net_colors": null,
"netclass_assignments": null, "netclass_assignments": {
"/IN": "",
"/OUT": "",
"/VCC": "",
"GND": "",
"Net-(U1-+)": "",
"Net-(U1--)": ""
},
"netclass_patterns": [] "netclass_patterns": []
}, },
"pcbnew": { "pcbnew": {
@ -427,14 +444,89 @@
"gencad": "", "gencad": "",
"idf": "", "idf": "",
"netlist": "", "netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "", "specctra_dsn": "",
"step": "", "step": "",
"svg": "",
"vrml": "" "vrml": ""
}, },
"page_layout_descr_file": "custom_ds.kicad_wks" "page_layout_descr_file": "custom_ds.kicad_wks"
}, },
"schematic": { "schematic": {
"annotate_start_num": 0, "annotate_start_num": 0,
"bom_export_filename": "${PROJECTNAME}.csv",
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "${QUANTITY}",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": true,
"label": "DNP",
"name": "${DNP}",
"show": true
},
{
"group_by": true,
"label": "Exclude from BOM",
"name": "${EXCLUDE_FROM_BOM}",
"show": true
},
{
"group_by": true,
"label": "Exclude from Board",
"name": "${EXCLUDE_FROM_BOARD}",
"show": true
},
{
"group_by": true,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
}
],
"filter_string": "",
"group_symbols": true,
"include_excluded_from_bom": true,
"name": "Default Editing",
"sort_asc": true,
"sort_field": "Reference"
},
"connection_grid_size": 50.0,
"drawing": { "drawing": {
"dashed_lines_dash_length_ratio": 12.0, "dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0, "dashed_lines_gap_length_ratio": 3.0,
@ -448,6 +540,11 @@
"intersheets_ref_suffix": "", "intersheets_ref_suffix": "",
"junction_size_choice": 3, "junction_size_choice": 3,
"label_size_ratio": 0.375, "label_size_ratio": 0.375,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"overbar_offset_ratio": 1.23,
"pin_symbol_size": 25.0, "pin_symbol_size": 25.0,
"text_offset_ratio": 0.15 "text_offset_ratio": 0.15
}, },
@ -463,6 +560,7 @@
"spice_external_command": "spice \"%I\"", "spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true, "spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false, "spice_save_all_currents": false,
"spice_save_all_dissipations": false,
"spice_save_all_voltages": false, "spice_save_all_voltages": false,
"subpart_first_id": 65, "subpart_first_id": 65,
"subpart_id_separator": 0 "subpart_id_separator": 0

View File

@ -43,7 +43,7 @@ public:
m_lib_pin->SetNumber( "42" ); m_lib_pin->SetNumber( "42" );
m_lib_pin->SetName( "pinname" ); m_lib_pin->SetName( "pinname" );
m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT ); m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT );
m_lib_pin->SetPosition( VECTOR2I( 1, -2 ) ); // local coord system is upside-down m_lib_pin->SetPosition( VECTOR2I( 1, 2 ) );
SCH_SHEET_PATH path; SCH_SHEET_PATH path;
m_parent_symbol = new SCH_SYMBOL( *m_parent_part, m_parent_part->GetLibId(), &path, 0, 0, m_parent_symbol = new SCH_SYMBOL( *m_parent_part, m_parent_part->GetLibId(), &path, 0, 0,
@ -80,8 +80,7 @@ BOOST_AUTO_TEST_CASE( DefaultProperties )
{ {
BOOST_CHECK_EQUAL( m_sch_pin->GetParentSymbol(), m_parent_symbol ); BOOST_CHECK_EQUAL( m_sch_pin->GetParentSymbol(), m_parent_symbol );
// Note: local coord system is upside-down; schematic coord system is not. BOOST_CHECK_EQUAL( m_sch_pin->GetLocalPosition(), VECTOR2I( 1, 2 ) );
BOOST_CHECK_EQUAL( m_sch_pin->GetLocalPosition(), VECTOR2I( 1, -2 ) );
BOOST_CHECK_EQUAL( m_sch_pin->GetPosition(), VECTOR2I( 2, 4 ) ); BOOST_CHECK_EQUAL( m_sch_pin->GetPosition(), VECTOR2I( 2, 4 ) );
BOOST_CHECK_EQUAL( m_sch_pin->IsVisible(), m_lib_pin->IsVisible() ); BOOST_CHECK_EQUAL( m_sch_pin->IsVisible(), m_lib_pin->IsVisible() );