Improve text hittesting in schematics.
Text has a fairly big bounding box to account for descenders, overbars, etc., but it makes it feel too sloppy for hittesting. This change allows selection disambiguation to look at the actual strokes of the text when deciding what's "closest". Fixes https://gitlab.com/kicad/code/kicad/issues/9506
This commit is contained in:
parent
bf85ddd577
commit
40b4052ad4
|
@ -624,15 +624,15 @@ std::vector<wxPoint> EDA_TEXT::TransformToSegmentList() const
|
|||
for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
|
||||
{
|
||||
wxString txt = strings_list.Item( ii );
|
||||
GRText( nullptr, positions[ii], color, txt, GetDrawRotation(), size, GetHorizJustify(),
|
||||
GetVertJustify(), penWidth, IsItalic(), forceBold, addTextSegmToBuffer,
|
||||
&cornerBuffer );
|
||||
GRText( nullptr, positions[ii], color, txt, GetDrawRotation(), size,
|
||||
GetDrawHorizJustify(), GetDrawVertJustify(), penWidth, IsItalic(), forceBold,
|
||||
addTextSegmToBuffer, &cornerBuffer );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GRText( nullptr, GetTextPos(), color, GetShownText(), GetDrawRotation(), size,
|
||||
GetHorizJustify(), GetVertJustify(), penWidth, IsItalic(), forceBold,
|
||||
GRText( nullptr, GetDrawPos(), color, GetShownText(), GetDrawRotation(), size,
|
||||
GetDrawHorizJustify(), GetDrawVertJustify(), penWidth, IsItalic(), forceBold,
|
||||
addTextSegmToBuffer, &cornerBuffer );
|
||||
}
|
||||
|
||||
|
@ -653,12 +653,6 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( ) const
|
|||
}
|
||||
|
||||
|
||||
double EDA_TEXT::GetDrawRotation() const
|
||||
{
|
||||
return GetTextAngle();
|
||||
}
|
||||
|
||||
|
||||
int EDA_TEXT::Compare( const EDA_TEXT* aOther ) const
|
||||
{
|
||||
#define TEST( a, b ) { if( a != b ) return a - b; }
|
||||
|
|
|
@ -262,6 +262,46 @@ void SCH_FIELD::SwapData( SCH_ITEM* aItem )
|
|||
}
|
||||
|
||||
|
||||
double SCH_FIELD::GetDrawRotation() const
|
||||
{
|
||||
// Calculate the text orientation according to the symbol orientation.
|
||||
int orient = GetTextAngle();
|
||||
|
||||
if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
|
||||
|
||||
if( parentSymbol && parentSymbol->GetTransform().y1 ) // Rotate symbol 90 degrees.
|
||||
{
|
||||
if( orient == TEXT_ANGLE_HORIZ )
|
||||
orient = TEXT_ANGLE_VERT;
|
||||
else
|
||||
orient = TEXT_ANGLE_HORIZ;
|
||||
}
|
||||
}
|
||||
|
||||
return orient;
|
||||
}
|
||||
|
||||
|
||||
wxPoint SCH_FIELD::GetDrawPos() const
|
||||
{
|
||||
return GetBoundingBox().Centre();
|
||||
}
|
||||
|
||||
|
||||
EDA_TEXT_HJUSTIFY_T SCH_FIELD::GetDrawHorizJustify() const
|
||||
{
|
||||
return GR_TEXT_HJUSTIFY_CENTER;
|
||||
}
|
||||
|
||||
|
||||
EDA_TEXT_VJUSTIFY_T SCH_FIELD::GetDrawVertJustify() const
|
||||
{
|
||||
return GR_TEXT_VJUSTIFY_CENTER;
|
||||
}
|
||||
|
||||
|
||||
const EDA_RECT SCH_FIELD::GetBoundingBox() const
|
||||
{
|
||||
// Calculate the text bounding box:
|
||||
|
|
|
@ -116,6 +116,14 @@ public:
|
|||
|
||||
wxString GetShownText( int aDepth = 0 ) const override;
|
||||
|
||||
/**
|
||||
* Adjusters to allow EDA_TEXT to draw/print/etc. text in absolute coords.
|
||||
*/
|
||||
double GetDrawRotation() const override;
|
||||
wxPoint GetDrawPos() const override;
|
||||
EDA_TEXT_HJUSTIFY_T GetDrawHorizJustify() const override;
|
||||
EDA_TEXT_VJUSTIFY_T GetDrawVertJustify() const override;
|
||||
|
||||
const EDA_RECT GetBoundingBox() const override;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1783,7 +1783,7 @@ SCH_SYMBOL& SCH_SYMBOL::operator=( const SCH_ITEM& aItem )
|
|||
|
||||
bool SCH_SYMBOL::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
||||
{
|
||||
EDA_RECT bBox = GetBodyBoundingBox();
|
||||
EDA_RECT bBox = GetBoundingBox();
|
||||
bBox.Inflate( aAccuracy );
|
||||
|
||||
if( bBox.Contains( aPosition ) )
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <bitmaps.h>
|
||||
#include <core/typeinfo.h>
|
||||
#include <core/kicad_algo.h>
|
||||
#include <geometry/shape_compound.h>
|
||||
#include <ee_actions.h>
|
||||
#include <ee_collectors.h>
|
||||
#include <ee_selection_tool.h>
|
||||
|
@ -1011,13 +1012,15 @@ 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.)
|
||||
wxPoint pos( aPos );
|
||||
SEG poss( aPos, aPos );
|
||||
EDA_ITEM* closest = nullptr;
|
||||
int closestDist = INT_MAX;
|
||||
int closestDist = INT_MAX / 2;
|
||||
|
||||
for( EDA_ITEM* item : collector )
|
||||
{
|
||||
EDA_RECT bbox = item->GetBoundingBox();
|
||||
int dist;
|
||||
int dist = INT_MAX / 2;
|
||||
|
||||
if( exactHits.count( item ) )
|
||||
{
|
||||
|
@ -1027,23 +1030,39 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
|||
break;
|
||||
}
|
||||
|
||||
wxPoint pos( aPos );
|
||||
SCH_LINE* line = dynamic_cast<SCH_LINE*>( item );
|
||||
EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item );
|
||||
SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( item );
|
||||
|
||||
if( line )
|
||||
{
|
||||
dist = DistanceLinePoint( line->GetStartPoint(), line->GetEndPoint(), pos );
|
||||
}
|
||||
else if( text )
|
||||
{
|
||||
text->GetEffectiveTextShape()->Collide( poss, closestDist, &dist );
|
||||
}
|
||||
else if( symbol )
|
||||
{
|
||||
bbox = symbol->GetBodyBoundingBox();
|
||||
SHAPE_RECT rect( bbox.GetPosition(), bbox.GetWidth(), bbox.GetHeight() );
|
||||
|
||||
if( bbox.Contains( pos ) )
|
||||
dist = EuclideanNorm( bbox.GetCenter() - pos );
|
||||
else
|
||||
dist = EuclideanNorm( bbox.GetCenter() - pos ) * 2;
|
||||
rect.Collide( poss, closestDist, &dist );
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = EuclideanNorm( bbox.GetCenter() - pos );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SHAPE_RECT rect( bbox.GetPosition(), bbox.GetWidth(), bbox.GetHeight() );
|
||||
rect.Collide( SEG( aPos, aPos ), collector.m_Threshold, &dist );
|
||||
rect.Collide( poss, collector.m_Threshold, &dist );
|
||||
}
|
||||
|
||||
if( item->IsType( EE_COLLECTOR::FieldOwners ) )
|
||||
dist += INT_MAX / 4;
|
||||
|
||||
if( dist < closestDist )
|
||||
{
|
||||
closestDist = dist;
|
||||
|
|
|
@ -385,7 +385,10 @@ public:
|
|||
*/
|
||||
virtual void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const;
|
||||
|
||||
virtual double GetDrawRotation() const;
|
||||
virtual double GetDrawRotation() const { return GetTextAngle(); }
|
||||
virtual wxPoint GetDrawPos() const { return GetTextPos(); }
|
||||
virtual EDA_TEXT_HJUSTIFY_T GetDrawHorizJustify() const { return GetHorizJustify(); };
|
||||
virtual EDA_TEXT_VJUSTIFY_T GetDrawVertJustify() const { return GetVertJustify(); };
|
||||
|
||||
int Compare( const EDA_TEXT* aOther ) const;
|
||||
|
||||
|
|
Loading…
Reference in New Issue