Cache LIB_PIN text extents for performance.
Also fixes a bug where we didn't triangulate at all when the char
count didn't warrant the likely overhead of spinning up a
thread_pool.
And fix another bug where EDA_TEXT::GetRenderCache() wasn't using
the given font.
Also reverts using the cache for drawing-sheet text. The text
items are created from scratch from the data items each time
they're drawn, so there's never an existing cache to make use of.
Instead, we now check that the item is in the view, using a very
approximate bounding box generator (because even generating a
real bounding box shows up large in profiles).
And, lastly, fixes a bug where EndPos was never considered in
DS_DATA_ITEM::IsInsidePage().
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14822
(cherry picked from commit f35a88ce0b
)
This commit is contained in:
parent
45c7490180
commit
16f286735d
|
@ -106,13 +106,13 @@ void DS_DATA_ITEM::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::VIEW* aV
|
||||||
|
|
||||||
for( int j = 0; j < m_RepeatCount; j++ )
|
for( int j = 0; j < m_RepeatCount; j++ )
|
||||||
{
|
{
|
||||||
if( j && ! IsInsidePage( j ) )
|
if( j > 0 && !IsInsidePage( j ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( m_type == DS_SEGMENT )
|
if( m_type == DS_SEGMENT )
|
||||||
item = new DS_DRAW_ITEM_LINE( this, j, GetStartPosUi( j ), GetEndPosUi( j ), pensize );
|
item = new DS_DRAW_ITEM_LINE( this, j, GetStartPosIU( j ), GetEndPosIU( j ), pensize );
|
||||||
else if( m_type == DS_RECT )
|
else if( m_type == DS_RECT )
|
||||||
item = new DS_DRAW_ITEM_RECT( this, j, GetStartPosUi( j ), GetEndPosUi( j ), pensize );
|
item = new DS_DRAW_ITEM_RECT( this, j, GetStartPosIU( j ), GetEndPosIU( j ), pensize );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxFAIL_MSG( wxS( "Unknown drawing sheet item type" ) );
|
wxFAIL_MSG( wxS( "Unknown drawing sheet item type" ) );
|
||||||
|
@ -162,8 +162,8 @@ void DS_DATA_ITEM::MoveTo( const VECTOR2D& aPosition )
|
||||||
|
|
||||||
for( DS_DRAW_ITEM_BASE* drawItem : m_drawItems )
|
for( DS_DRAW_ITEM_BASE* drawItem : m_drawItems )
|
||||||
{
|
{
|
||||||
drawItem->SetPosition( GetStartPosUi( drawItem->GetIndexInPeer() ) );
|
drawItem->SetPosition( GetStartPosIU( drawItem->GetIndexInPeer() ) );
|
||||||
drawItem->SetEnd( GetEndPosUi( drawItem->GetIndexInPeer() ) );
|
drawItem->SetEnd( GetEndPosIU( drawItem->GetIndexInPeer() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ const VECTOR2D DS_DATA_ITEM::GetStartPos( int ii ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const VECTOR2I DS_DATA_ITEM::GetStartPosUi( int ii ) const
|
const VECTOR2I DS_DATA_ITEM::GetStartPosIU( int ii ) const
|
||||||
{
|
{
|
||||||
VECTOR2D pos = GetStartPos( ii ) * DS_DATA_MODEL::GetTheInstance().m_WSunits2Iu;
|
VECTOR2D pos = GetStartPos( ii ) * DS_DATA_MODEL::GetTheInstance().m_WSunits2Iu;
|
||||||
return VECTOR2I( KiROUND( pos.x ), KiROUND( pos.y ) );
|
return VECTOR2I( KiROUND( pos.x ), KiROUND( pos.y ) );
|
||||||
|
@ -331,7 +331,7 @@ const VECTOR2D DS_DATA_ITEM::GetEndPos( int ii ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const VECTOR2I DS_DATA_ITEM::GetEndPosUi( int ii ) const
|
const VECTOR2I DS_DATA_ITEM::GetEndPosIU( int ii ) const
|
||||||
{
|
{
|
||||||
VECTOR2D pos = GetEndPos( ii );
|
VECTOR2D pos = GetEndPos( ii );
|
||||||
pos = pos * DS_DATA_MODEL::GetTheInstance().m_WSunits2Iu;
|
pos = pos * DS_DATA_MODEL::GetTheInstance().m_WSunits2Iu;
|
||||||
|
@ -343,17 +343,13 @@ bool DS_DATA_ITEM::IsInsidePage( int ii ) const
|
||||||
{
|
{
|
||||||
DS_DATA_MODEL& model = DS_DATA_MODEL::GetTheInstance();
|
DS_DATA_MODEL& model = DS_DATA_MODEL::GetTheInstance();
|
||||||
|
|
||||||
VECTOR2D pos = GetStartPos( ii );
|
for( const VECTOR2D& pos : { GetStartPos( ii ), GetEndPos( ii ) } )
|
||||||
|
|
||||||
for( int kk = 0; kk < 1; kk++ )
|
|
||||||
{
|
{
|
||||||
if( model.m_RB_Corner.x < pos.x || model.m_LT_Corner.x > pos.x )
|
if( model.m_RB_Corner.x < pos.x || model.m_LT_Corner.x > pos.x )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( model.m_RB_Corner.y < pos.y || model.m_LT_Corner.y > pos.y )
|
if( model.m_RB_Corner.y < pos.y || model.m_LT_Corner.y > pos.y )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
pos = GetEndPos( ii );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -406,11 +402,11 @@ void DS_DATA_ITEM_POLYGONS::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX:
|
||||||
|
|
||||||
for( int j = 0; j < m_RepeatCount; j++ )
|
for( int j = 0; j < m_RepeatCount; j++ )
|
||||||
{
|
{
|
||||||
if( j && !IsInsidePage( j ) )
|
if( j > 0 && !IsInsidePage( j ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int pensize = GetPenSizeUi();
|
int pensize = GetPenSizeUi();
|
||||||
auto poly_shape = new DS_DRAW_ITEM_POLYPOLYGONS( this, j, GetStartPosUi( j ), pensize );
|
auto poly_shape = new DS_DRAW_ITEM_POLYPOLYGONS( this, j, GetStartPosIU( j ), pensize );
|
||||||
poly_shape->SetFlags( itemFlags[ j ] );
|
poly_shape->SetFlags( itemFlags[ j ] );
|
||||||
m_drawItems.push_back( poly_shape );
|
m_drawItems.push_back( poly_shape );
|
||||||
|
|
||||||
|
@ -584,7 +580,7 @@ void DS_DATA_ITEM_TEXT::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::VIE
|
||||||
if( j > 0 && !IsInsidePage( j ) )
|
if( j > 0 && !IsInsidePage( j ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
text = new DS_DRAW_ITEM_TEXT( this, j, m_FullText, GetStartPosUi( j ), textsize, pensize,
|
text = new DS_DRAW_ITEM_TEXT( this, j, m_FullText, GetStartPosIU( j ), textsize, pensize,
|
||||||
m_Font, m_Italic, m_Bold, m_TextColor );
|
m_Font, m_Italic, m_Bold, m_TextColor );
|
||||||
text->SetFlags( itemFlags[ j ] );
|
text->SetFlags( itemFlags[ j ] );
|
||||||
m_drawItems.push_back( text );
|
m_drawItems.push_back( text );
|
||||||
|
@ -746,10 +742,10 @@ void DS_DATA_ITEM_BITMAP::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::V
|
||||||
|
|
||||||
for( int j = 0; j < m_RepeatCount; j++ )
|
for( int j = 0; j < m_RepeatCount; j++ )
|
||||||
{
|
{
|
||||||
if( j && !IsInsidePage( j ) )
|
if( j > 0 && !IsInsidePage( j ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DS_DRAW_ITEM_BITMAP* bitmap = new DS_DRAW_ITEM_BITMAP( this, j, GetStartPosUi( j ) );
|
DS_DRAW_ITEM_BITMAP* bitmap = new DS_DRAW_ITEM_BITMAP( this, j, GetStartPosIU( j ) );
|
||||||
|
|
||||||
bitmap->SetFlags( itemFlags[ j ] );
|
bitmap->SetFlags( itemFlags[ j ] );
|
||||||
m_drawItems.push_back( bitmap );
|
m_drawItems.push_back( bitmap );
|
||||||
|
|
|
@ -174,6 +174,36 @@ void DS_DRAW_ITEM_TEXT::PrintWsItem( const RENDER_SETTINGS* aSettings, const VEC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const BOX2I DS_DRAW_ITEM_TEXT::GetApproxBBox()
|
||||||
|
{
|
||||||
|
// A really dumb approximation because doing it for real (even with the stroke font) shows
|
||||||
|
// up large in profiles.
|
||||||
|
|
||||||
|
const TEXT_ATTRIBUTES& attrs = GetAttributes();
|
||||||
|
const wxString text = GetShownText( true );
|
||||||
|
BOX2I bbox( GetTextPos() );
|
||||||
|
|
||||||
|
bbox.SetWidth( (int) text.length() * attrs.m_Size.x * 3 );
|
||||||
|
bbox.SetHeight( attrs.m_Size.y * 3 );
|
||||||
|
|
||||||
|
switch( attrs.m_Halign )
|
||||||
|
{
|
||||||
|
case GR_TEXT_H_ALIGN_LEFT: break;
|
||||||
|
case GR_TEXT_H_ALIGN_CENTER: bbox.Offset( -bbox.GetWidth() / 2, 0 ); break;
|
||||||
|
case GR_TEXT_H_ALIGN_RIGHT: bbox.Offset( -bbox.GetWidth(), 0 ); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( GetAttributes().m_Valign )
|
||||||
|
{
|
||||||
|
case GR_TEXT_V_ALIGN_TOP: break;
|
||||||
|
case GR_TEXT_V_ALIGN_CENTER: bbox.Offset( 0, -bbox.GetHeight() / 2 ); break;
|
||||||
|
case GR_TEXT_V_ALIGN_BOTTOM: bbox.Offset( 0, -bbox.GetHeight() ); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const BOX2I DS_DRAW_ITEM_TEXT::GetBoundingBox() const
|
const BOX2I DS_DRAW_ITEM_TEXT::GetBoundingBox() const
|
||||||
{
|
{
|
||||||
return EDA_TEXT::GetTextBox();
|
return EDA_TEXT::GetTextBox();
|
||||||
|
|
|
@ -254,9 +254,6 @@ void KIGFX::DS_PAINTER::draw( const DS_DRAW_ITEM_POLYPOLYGONS* aItem, int aLayer
|
||||||
void KIGFX::DS_PAINTER::draw( const DS_DRAW_ITEM_TEXT* aItem, int aLayer ) const
|
void KIGFX::DS_PAINTER::draw( const DS_DRAW_ITEM_TEXT* aItem, int aLayer ) const
|
||||||
{
|
{
|
||||||
KIFONT::FONT* font = aItem->GetFont();
|
KIFONT::FONT* font = aItem->GetFont();
|
||||||
wxString shownText( aItem->GetShownText( true ) );
|
|
||||||
VECTOR2I text_offset = aItem->GetTextPos();
|
|
||||||
TEXT_ATTRIBUTES attrs = aItem->GetAttributes();
|
|
||||||
|
|
||||||
if( !font )
|
if( !font )
|
||||||
{
|
{
|
||||||
|
@ -269,25 +266,11 @@ void KIGFX::DS_PAINTER::draw( const DS_DRAW_ITEM_TEXT* aItem, int aLayer ) const
|
||||||
m_gal->SetStrokeColor( color );
|
m_gal->SetStrokeColor( color );
|
||||||
m_gal->SetFillColor( color );
|
m_gal->SetFillColor( color );
|
||||||
|
|
||||||
|
TEXT_ATTRIBUTES attrs = aItem->GetAttributes();
|
||||||
attrs.m_StrokeWidth = std::max( aItem->GetEffectiveTextPenWidth(),
|
attrs.m_StrokeWidth = std::max( aItem->GetEffectiveTextPenWidth(),
|
||||||
m_renderSettings.GetDefaultPenWidth() );
|
m_renderSettings.GetDefaultPenWidth() );
|
||||||
|
|
||||||
std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
|
font->Draw( m_gal, aItem->GetShownText( true ), aItem->GetTextPos(), attrs );
|
||||||
|
|
||||||
if( font->IsOutline() )
|
|
||||||
cache = aItem->GetRenderCache( font, shownText, text_offset );
|
|
||||||
|
|
||||||
if( cache )
|
|
||||||
{
|
|
||||||
m_gal->SetLineWidth( attrs.m_StrokeWidth );
|
|
||||||
m_gal->DrawGlyphs( *cache );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_gal->SetIsFill( font->IsOutline() );
|
|
||||||
m_gal->SetIsStroke( font->IsStroke() );
|
|
||||||
font->Draw( m_gal, shownText, text_offset, attrs );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -126,8 +126,13 @@ void DS_PROXY_VIEW_ITEM::ViewDraw( int aLayer, VIEW* aView ) const
|
||||||
ws_settings->SetDefaultFont( settings->GetDefaultFont() );
|
ws_settings->SetDefaultFont( settings->GetDefaultFont() );
|
||||||
|
|
||||||
// Draw all the components that make the drawing sheet
|
// Draw all the components that make the drawing sheet
|
||||||
|
BOX2I viewport( aView->GetViewport().GetOrigin(), aView->GetViewport().GetSize() );
|
||||||
|
|
||||||
for( DS_DRAW_ITEM_BASE* item = drawList.GetFirst(); item; item = drawList.GetNext() )
|
for( DS_DRAW_ITEM_BASE* item = drawList.GetFirst(); item; item = drawList.GetNext() )
|
||||||
|
{
|
||||||
|
if( viewport.Intersects( item->GetApproxBBox() ) )
|
||||||
ws_painter.Draw( item, LAYER_DRAWINGSHEET );
|
ws_painter.Draw( item, LAYER_DRAWINGSHEET );
|
||||||
|
}
|
||||||
|
|
||||||
// Draw gray line that outlines the sheet size
|
// Draw gray line that outlines the sheet size
|
||||||
if( settings->GetShowPageLimits() )
|
if( settings->GetShowPageLimits() )
|
||||||
|
|
|
@ -91,6 +91,7 @@ GR_TEXT_V_ALIGN_T EDA_TEXT::MapVertJustify( int aVertJustify )
|
||||||
EDA_TEXT::EDA_TEXT( const EDA_IU_SCALE& aIuScale, const wxString& aText ) :
|
EDA_TEXT::EDA_TEXT( const EDA_IU_SCALE& aIuScale, const wxString& aText ) :
|
||||||
m_text( aText ),
|
m_text( aText ),
|
||||||
m_IuScale( aIuScale ),
|
m_IuScale( aIuScale ),
|
||||||
|
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 )
|
m_bounding_box_cache_inverted( false )
|
||||||
|
@ -111,8 +112,10 @@ EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
|
||||||
m_attributes = aText.m_attributes;
|
m_attributes = aText.m_attributes;
|
||||||
m_pos = aText.m_pos;
|
m_pos = aText.m_pos;
|
||||||
|
|
||||||
|
m_render_cache_font = aText.m_render_cache_font;
|
||||||
m_render_cache_text = aText.m_render_cache_text;
|
m_render_cache_text = aText.m_render_cache_text;
|
||||||
m_render_cache_angle = aText.m_render_cache_angle;
|
m_render_cache_angle = aText.m_render_cache_angle;
|
||||||
|
m_render_cache_offset = aText.m_render_cache_offset;
|
||||||
|
|
||||||
m_render_cache.clear();
|
m_render_cache.clear();
|
||||||
|
|
||||||
|
@ -145,8 +148,10 @@ EDA_TEXT& EDA_TEXT::operator=( const EDA_TEXT& aText )
|
||||||
m_attributes = aText.m_attributes;
|
m_attributes = aText.m_attributes;
|
||||||
m_pos = aText.m_pos;
|
m_pos = aText.m_pos;
|
||||||
|
|
||||||
|
m_render_cache_font = aText.m_render_cache_font;
|
||||||
m_render_cache_text = aText.m_render_cache_text;
|
m_render_cache_text = aText.m_render_cache_text;
|
||||||
m_render_cache_angle = aText.m_render_cache_angle;
|
m_render_cache_angle = aText.m_render_cache_angle;
|
||||||
|
m_render_cache_offset = aText.m_render_cache_offset;
|
||||||
|
|
||||||
m_render_cache.clear();
|
m_render_cache.clear();
|
||||||
|
|
||||||
|
@ -469,19 +474,21 @@ EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolved
|
||||||
EDA_ANGLE resolvedAngle = GetDrawRotation();
|
EDA_ANGLE resolvedAngle = GetDrawRotation();
|
||||||
|
|
||||||
if( m_render_cache.empty()
|
if( m_render_cache.empty()
|
||||||
|
|| m_render_cache_font != aFont
|
||||||
|| m_render_cache_text != forResolvedText
|
|| m_render_cache_text != forResolvedText
|
||||||
|| m_render_cache_angle != resolvedAngle
|
|| m_render_cache_angle != resolvedAngle
|
||||||
|| m_render_cache_offset != aOffset )
|
|| m_render_cache_offset != aOffset )
|
||||||
{
|
{
|
||||||
m_render_cache.clear();
|
m_render_cache.clear();
|
||||||
|
|
||||||
KIFONT::OUTLINE_FONT* font = static_cast<KIFONT::OUTLINE_FONT*>( getDrawFont() );
|
const KIFONT::OUTLINE_FONT* font = static_cast<const KIFONT::OUTLINE_FONT*>( aFont );
|
||||||
TEXT_ATTRIBUTES attrs = GetAttributes();
|
TEXT_ATTRIBUTES attrs = GetAttributes();
|
||||||
|
|
||||||
attrs.m_Angle = resolvedAngle;
|
attrs.m_Angle = resolvedAngle;
|
||||||
|
|
||||||
font->GetLinesAsGlyphs( &m_render_cache, forResolvedText, GetDrawPos() + aOffset,
|
font->GetLinesAsGlyphs( &m_render_cache, forResolvedText, GetDrawPos() + aOffset,
|
||||||
attrs );
|
attrs );
|
||||||
|
m_render_cache_font = aFont;
|
||||||
m_render_cache_angle = resolvedAngle;
|
m_render_cache_angle = resolvedAngle;
|
||||||
m_render_cache_text = forResolvedText;
|
m_render_cache_text = forResolvedText;
|
||||||
m_render_cache_offset = aOffset;
|
m_render_cache_offset = aOffset;
|
||||||
|
|
|
@ -2782,7 +2782,7 @@ void OPENGL_GAL::DrawGlyphs( const std::vector<std::unique_ptr<KIFONT::GLYPH>>&
|
||||||
// Optimized path for stroke fonts that pre-reserves glyph triangles.
|
// Optimized path for stroke fonts that pre-reserves glyph triangles.
|
||||||
int triangleCount = 0;
|
int triangleCount = 0;
|
||||||
|
|
||||||
if( aGlyphs.size() > 2 )
|
if( aGlyphs.size() > 0 )
|
||||||
{
|
{
|
||||||
thread_pool& tp = GetKiCadThreadPool();
|
thread_pool& tp = GetKiCadThreadPool();
|
||||||
|
|
||||||
|
|
|
@ -1203,6 +1203,30 @@ void LIB_PIN::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_PIN::validateExtentsCache( KIFONT::FONT* aFont, int aSize, const wxString& aText,
|
||||||
|
EXTENTS_CACHE* aCache ) const
|
||||||
|
{
|
||||||
|
if( aCache->m_Font == aFont
|
||||||
|
&& aCache->m_FontSize == aSize
|
||||||
|
&& aCache->m_Extents != VECTOR2I() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aCache->m_Font = aFont;
|
||||||
|
aCache->m_FontSize = aSize;
|
||||||
|
|
||||||
|
// Get maximum height including ascenders and descenders
|
||||||
|
static wxString hText = wxT( "Xg" );
|
||||||
|
|
||||||
|
VECTOR2D fontSize( aSize, aSize );
|
||||||
|
int penWidth = GetPenSizeForNormal( aSize );
|
||||||
|
|
||||||
|
aCache->m_Extents.x = aFont->StringBoundaryLimits( aText, fontSize, penWidth, false, false ).x;
|
||||||
|
aCache->m_Extents.y = aFont->StringBoundaryLimits( hText, fontSize, penWidth, false, false ).y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const BOX2I LIB_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNameAndNumber,
|
const BOX2I LIB_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNameAndNumber,
|
||||||
bool aIncludeElectricalType ) const
|
bool aIncludeElectricalType ) const
|
||||||
{
|
{
|
||||||
|
@ -1218,13 +1242,10 @@ const BOX2I LIB_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNa
|
||||||
int numberTextLength = 0;
|
int numberTextLength = 0;
|
||||||
int numberTextHeight = 0;
|
int numberTextHeight = 0;
|
||||||
int typeTextLength = 0;
|
int typeTextLength = 0;
|
||||||
wxString name = GetShownName();
|
bool includeName = aIncludeNameAndNumber && !GetShownName().IsEmpty();
|
||||||
wxString number = GetShownNumber();
|
bool includeNumber = aIncludeNameAndNumber && !GetShownNumber().IsEmpty();
|
||||||
bool includeName = aIncludeNameAndNumber && !name.IsEmpty();
|
|
||||||
bool includeNumber = aIncludeNameAndNumber && !number.IsEmpty();
|
|
||||||
bool includeType = aIncludeElectricalType;
|
bool includeType = aIncludeElectricalType;
|
||||||
int minsizeV = TARGET_PIN_RADIUS;
|
int minsizeV = TARGET_PIN_RADIUS;
|
||||||
int penWidth = GetPenWidth();
|
|
||||||
|
|
||||||
if( !aIncludeInvisiblePins && !IsVisible() )
|
if( !aIncludeInvisiblePins && !IsVisible() )
|
||||||
{
|
{
|
||||||
|
@ -1243,33 +1264,18 @@ const BOX2I LIB_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNa
|
||||||
includeNumber = false;
|
includeNumber = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get maximum height including ascenders and descenders
|
|
||||||
wxString test = wxT( "Xg" );
|
|
||||||
|
|
||||||
if( includeNumber )
|
if( includeNumber )
|
||||||
{
|
{
|
||||||
VECTOR2D fontSize( m_numTextSize, m_numTextSize );
|
validateExtentsCache( font, m_numTextSize, GetShownNumber(), &m_numExtentsCache );
|
||||||
numberTextLength = font->StringBoundaryLimits( number, fontSize, penWidth, false, false ).x;
|
numberTextLength = m_numExtentsCache.m_Extents.x;
|
||||||
numberTextHeight = font->StringBoundaryLimits( test, fontSize, penWidth, false, false ).y;
|
numberTextHeight = m_numExtentsCache.m_Extents.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( includeName )
|
if( includeName )
|
||||||
{
|
{
|
||||||
VECTOR2D fontSize( m_nameTextSize, m_nameTextSize );
|
validateExtentsCache( font, m_nameTextSize, GetShownName(), &m_nameExtentsCache );
|
||||||
|
nameTextLength = m_nameExtentsCache.m_Extents.x + pinNameOffset;
|
||||||
nameTextLength = font->StringBoundaryLimits( name, fontSize, penWidth, false, false ).x
|
nameTextHeight = m_nameExtentsCache.m_Extents.y + schIUScale.MilsToIU( PIN_TEXT_MARGIN );
|
||||||
+ pinNameOffset;
|
|
||||||
nameTextHeight = font->StringBoundaryLimits( test, fontSize, penWidth, false, false ).y
|
|
||||||
+ schIUScale.MilsToIU( PIN_TEXT_MARGIN );
|
|
||||||
}
|
|
||||||
|
|
||||||
// KIFONT has to be rather tight on boundary limits for knockout text in PCBNew, but in truth
|
|
||||||
// the stroke font returns a vertically under-sized bounding box (even though it *does* in fact
|
|
||||||
// attempt to account for the font size being stroke centre-point to stroke centre-point).
|
|
||||||
if( font->IsStroke() )
|
|
||||||
{
|
|
||||||
numberTextHeight += 2 * penWidth;
|
|
||||||
nameTextHeight += 2 * penWidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( includeType )
|
if( includeType )
|
||||||
|
@ -1290,7 +1296,7 @@ const BOX2I LIB_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNa
|
||||||
|
|
||||||
// Attempt to mimic SCH_PAINTER's algorithm without actually knowing the schematic text
|
// Attempt to mimic SCH_PAINTER's algorithm without actually knowing the schematic text
|
||||||
// offset ratio.
|
// offset ratio.
|
||||||
int PIN_TEXT_OFFSET = schIUScale.MilsToIU( 24 ) + 2 * penWidth;
|
int PIN_TEXT_OFFSET = schIUScale.MilsToIU( 24 );
|
||||||
|
|
||||||
// Calculate topLeft & bottomRight corner positions for the default pin orientation (PIN_RIGHT)
|
// Calculate topLeft & bottomRight corner positions for the default pin orientation (PIN_RIGHT)
|
||||||
if( pinNameOffset || !includeName )
|
if( pinNameOffset || !includeName )
|
||||||
|
|
|
@ -117,6 +117,7 @@ public:
|
||||||
|
|
||||||
// pin name string does not support spaces
|
// pin name string does not support spaces
|
||||||
m_name.Replace( wxT( " " ), wxT( "_" ) );
|
m_name.Replace( wxT( " " ), wxT( "_" ) );
|
||||||
|
m_nameExtentsCache.m_Extents = VECTOR2I();
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString& GetNumber() const { return m_number; }
|
const wxString& GetNumber() const { return m_number; }
|
||||||
|
@ -127,13 +128,22 @@ public:
|
||||||
|
|
||||||
// pin number string does not support spaces
|
// pin number string does not support spaces
|
||||||
m_number.Replace( wxT( " " ), wxT( "_" ) );
|
m_number.Replace( wxT( " " ), wxT( "_" ) );
|
||||||
|
m_numExtentsCache.m_Extents = VECTOR2I();
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetNameTextSize() const { return m_nameTextSize; }
|
int GetNameTextSize() const { return m_nameTextSize; }
|
||||||
void SetNameTextSize( int aSize ) { m_nameTextSize = aSize; }
|
void SetNameTextSize( int aSize )
|
||||||
|
{
|
||||||
|
m_nameTextSize = aSize;
|
||||||
|
m_nameExtentsCache.m_Extents = VECTOR2I();
|
||||||
|
}
|
||||||
|
|
||||||
int GetNumberTextSize() const { return m_numTextSize; }
|
int GetNumberTextSize() const { return m_numTextSize; }
|
||||||
void SetNumberTextSize( int aSize ) { m_numTextSize = aSize; }
|
void SetNumberTextSize( int aSize )
|
||||||
|
{
|
||||||
|
m_numTextSize = aSize;
|
||||||
|
m_numExtentsCache.m_Extents = VECTOR2I();
|
||||||
|
}
|
||||||
|
|
||||||
std::map<wxString, ALT>& GetAlternates() { return m_alternates; }
|
std::map<wxString, ALT>& GetAlternates() { return m_alternates; }
|
||||||
|
|
||||||
|
@ -250,6 +260,16 @@ public:
|
||||||
static const wxString GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE aType );
|
static const wxString GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE aType );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
struct EXTENTS_CACHE
|
||||||
|
{
|
||||||
|
KIFONT::FONT* m_Font = nullptr;
|
||||||
|
int m_FontSize = 0;
|
||||||
|
VECTOR2I m_Extents;
|
||||||
|
};
|
||||||
|
|
||||||
|
void validateExtentsCache( KIFONT::FONT* aFont, int aSize, const wxString& aText,
|
||||||
|
EXTENTS_CACHE* aCache ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print the pin symbol without text.
|
* Print the pin symbol without text.
|
||||||
* If \a aColor != 0, draw with \a aColor, else with the normal pin color.
|
* If \a aColor != 0, draw with \a aColor, else with the normal pin color.
|
||||||
|
@ -299,6 +319,9 @@ protected:
|
||||||
int m_nameTextSize;
|
int m_nameTextSize;
|
||||||
|
|
||||||
std::map<wxString, ALT> m_alternates; // Map of alternate name to ALT structure
|
std::map<wxString, ALT> m_alternates; // Map of alternate name to ALT structure
|
||||||
|
|
||||||
|
mutable EXTENTS_CACHE m_numExtentsCache;
|
||||||
|
mutable EXTENTS_CACHE m_nameExtentsCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1526,15 +1526,14 @@ void SCH_PAINTER::draw( const LIB_PIN *aPin, int aLayer, bool aDimmed )
|
||||||
m_gal->SetFillColor( colour[i] );
|
m_gal->SetFillColor( colour[i] );
|
||||||
|
|
||||||
TEXT_ATTRIBUTES attrs;
|
TEXT_ATTRIBUTES attrs;
|
||||||
|
attrs.m_Font = KIFONT::FONT::GetFont( eeconfig()->m_Appearance.default_font );
|
||||||
attrs.m_Size = VECTOR2I( size[i], size[i] );
|
attrs.m_Size = VECTOR2I( size[i], size[i] );
|
||||||
attrs.m_Halign = hAlign;
|
attrs.m_Halign = hAlign;
|
||||||
attrs.m_Valign = vAlign;
|
attrs.m_Valign = vAlign;
|
||||||
attrs.m_Angle = aAngle;
|
attrs.m_Angle = aAngle;
|
||||||
attrs.m_StrokeWidth = KiROUND( thickness[i] );
|
attrs.m_StrokeWidth = KiROUND( thickness[i] );
|
||||||
KIFONT::FONT* font = KIFONT::FONT::GetFont( eeconfig()->m_Appearance.default_font, attrs.m_Bold,
|
|
||||||
attrs.m_Italic );
|
|
||||||
|
|
||||||
if( drawingShadows && !font->IsOutline() )
|
if( drawingShadows && !attrs.m_Font->IsOutline() )
|
||||||
{
|
{
|
||||||
strokeText( text[i], aPos, attrs );
|
strokeText( text[i], aPos, attrs );
|
||||||
}
|
}
|
||||||
|
@ -2061,14 +2060,7 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer )
|
||||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||||
COLOR4D color = getRenderColor( aTextBox, aLayer, drawingShadows );
|
COLOR4D color = getRenderColor( aTextBox, aLayer, drawingShadows );
|
||||||
float borderWidth = getLineWidth( aTextBox, drawingShadows );
|
float borderWidth = getLineWidth( aTextBox, drawingShadows );
|
||||||
|
KIFONT::FONT* font = getFont( aTextBox );
|
||||||
KIFONT::FONT* font = aTextBox->GetFont();
|
|
||||||
|
|
||||||
if( !font )
|
|
||||||
{
|
|
||||||
font = KIFONT::FONT::GetFont( m_schSettings.GetDefaultFont(), aTextBox->IsBold(),
|
|
||||||
aTextBox->IsItalic() );
|
|
||||||
}
|
|
||||||
|
|
||||||
auto drawText =
|
auto drawText =
|
||||||
[&]()
|
[&]()
|
||||||
|
|
|
@ -134,8 +134,8 @@ public:
|
||||||
void SetPage1Option( PAGE_OPTION aChoice ) { m_pageOption = aChoice; }
|
void SetPage1Option( PAGE_OPTION aChoice ) { m_pageOption = aChoice; }
|
||||||
|
|
||||||
// Coordinate handling
|
// Coordinate handling
|
||||||
const VECTOR2I GetStartPosUi( int ii = 0 ) const;
|
const VECTOR2I GetStartPosIU( int ii = 0 ) const;
|
||||||
const VECTOR2I GetEndPosUi( int ii = 0 ) const;
|
const VECTOR2I GetEndPosIU( int ii = 0 ) const;
|
||||||
const VECTOR2D GetStartPos( int ii = 0 ) const;
|
const VECTOR2D GetStartPos( int ii = 0 ) const;
|
||||||
const VECTOR2D GetEndPos( int ii = 0 ) const;
|
const VECTOR2D GetEndPos( int ii = 0 ) const;
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,14 @@ public:
|
||||||
// More advanced version of DrawWsItem. This is what must be defined in the derived type.
|
// More advanced version of DrawWsItem. This is what must be defined in the derived type.
|
||||||
virtual void PrintWsItem( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset ) = 0;
|
virtual void PrintWsItem( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset ) = 0;
|
||||||
|
|
||||||
|
// We can't cache bounding boxes because we're recreated for each draw event. This method
|
||||||
|
// can be overridden by items whose real bounding boxes are expensive to calculate. It is
|
||||||
|
// used to determine if we're in the current view, so it can be sloppy.
|
||||||
|
virtual const BOX2I GetApproxBBox()
|
||||||
|
{
|
||||||
|
return GetBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
// Derived types must define GetBoundingBox() as a minimum, and can then override the
|
// Derived types must define GetBoundingBox() as a minimum, and can then override the
|
||||||
// two HitTest() functions if they need something more specific.
|
// two HitTest() functions if they need something more specific.
|
||||||
const BOX2I GetBoundingBox() const override = 0;
|
const BOX2I GetBoundingBox() const override = 0;
|
||||||
|
@ -325,6 +333,8 @@ public:
|
||||||
VECTOR2I GetPosition() const override { return GetTextPos(); }
|
VECTOR2I GetPosition() const override { return GetTextPos(); }
|
||||||
void SetPosition( const VECTOR2I& aPos ) override { SetTextPos( aPos ); }
|
void SetPosition( const VECTOR2I& aPos ) override { SetTextPos( aPos ); }
|
||||||
|
|
||||||
|
virtual const BOX2I GetApproxBBox() override;
|
||||||
|
|
||||||
const BOX2I GetBoundingBox() const override;
|
const BOX2I GetBoundingBox() const override;
|
||||||
|
|
||||||
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
|
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
|
||||||
|
|
|
@ -395,6 +395,7 @@ private:
|
||||||
|
|
||||||
std::reference_wrapper<const EDA_IU_SCALE> m_IuScale;
|
std::reference_wrapper<const EDA_IU_SCALE> m_IuScale;
|
||||||
|
|
||||||
|
mutable const KIFONT::FONT* m_render_cache_font;
|
||||||
mutable wxString m_render_cache_text;
|
mutable wxString m_render_cache_text;
|
||||||
mutable EDA_ANGLE m_render_cache_angle;
|
mutable EDA_ANGLE m_render_cache_angle;
|
||||||
mutable VECTOR2I m_render_cache_offset;
|
mutable VECTOR2I m_render_cache_offset;
|
||||||
|
|
|
@ -657,22 +657,22 @@ VECTOR2I PL_EDITOR_FRAME::ReturnCoordOriginCorner() const
|
||||||
|
|
||||||
case 1: // Origin = page Right Bottom corner
|
case 1: // Origin = page Right Bottom corner
|
||||||
dummy.SetStart( 0, 0, RB_CORNER );
|
dummy.SetStart( 0, 0, RB_CORNER );
|
||||||
originCoord = dummy.GetStartPosUi();
|
originCoord = dummy.GetStartPosIU();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // Origin = page Left Bottom corner
|
case 2: // Origin = page Left Bottom corner
|
||||||
dummy.SetStart( 0, 0, LB_CORNER );
|
dummy.SetStart( 0, 0, LB_CORNER );
|
||||||
originCoord = dummy.GetStartPosUi();
|
originCoord = dummy.GetStartPosIU();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // Origin = page Right Top corner
|
case 3: // Origin = page Right Top corner
|
||||||
dummy.SetStart( 0, 0, RT_CORNER );
|
dummy.SetStart( 0, 0, RT_CORNER );
|
||||||
originCoord = dummy.GetStartPosUi();
|
originCoord = dummy.GetStartPosIU();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // Origin = page Left Top corner
|
case 4: // Origin = page Left Top corner
|
||||||
dummy.SetStart( 0, 0, LT_CORNER );
|
dummy.SetStart( 0, 0, LT_CORNER );
|
||||||
originCoord = dummy.GetStartPosUi();
|
originCoord = dummy.GetStartPosIU();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->GetPeer()->MoveStartPointToUi( cursorPos );
|
item->GetPeer()->MoveStartPointToUi( cursorPos );
|
||||||
item->SetPosition( item->GetPeer()->GetStartPosUi( 0 ) );
|
item->SetPosition( item->GetPeer()->GetStartPosIU( 0 ) );
|
||||||
item->ClearEditFlags();
|
item->ClearEditFlags();
|
||||||
getView()->Update( item );
|
getView()->Update( item );
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent )
|
||||||
else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
|
else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
|
||||||
{
|
{
|
||||||
item->GetPeer()->MoveStartPointToUi( cursorPos );
|
item->GetPeer()->MoveStartPointToUi( cursorPos );
|
||||||
item->SetPosition( item->GetPeer()->GetStartPosUi( 0 ) );
|
item->SetPosition( item->GetPeer()->GetStartPosIU( 0 ) );
|
||||||
getView()->Update( item );
|
getView()->Update( item );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -306,7 +306,7 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
||||||
if( item )
|
if( item )
|
||||||
{
|
{
|
||||||
item->GetPeer()->MoveEndPointToUi( cursorPos );
|
item->GetPeer()->MoveEndPointToUi( cursorPos );
|
||||||
item->SetEnd( item->GetPeer()->GetEndPosUi( 0 ) );
|
item->SetEnd( item->GetPeer()->GetEndPosIU( 0 ) );
|
||||||
getView()->Update( item );
|
getView()->Update( item );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,7 +321,7 @@ int PL_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
void PL_EDIT_TOOL::moveItem( DS_DATA_ITEM* aItem, const VECTOR2I& aDelta )
|
void PL_EDIT_TOOL::moveItem( DS_DATA_ITEM* aItem, const VECTOR2I& aDelta )
|
||||||
{
|
{
|
||||||
aItem->MoveToUi( aItem->GetStartPosUi() + aDelta );
|
aItem->MoveToUi( aItem->GetStartPosIU() + aDelta );
|
||||||
|
|
||||||
for( DS_DRAW_ITEM_BASE* item : aItem->GetDrawItems() )
|
for( DS_DRAW_ITEM_BASE* item : aItem->GetDrawItems() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -337,8 +337,8 @@ void PL_POINT_EDITOR::updateItem() const
|
||||||
VECTOR2I move_startpoint = m_editPoints->Point( LINE_START ).GetPosition() - line->GetStart();
|
VECTOR2I move_startpoint = m_editPoints->Point( LINE_START ).GetPosition() - line->GetStart();
|
||||||
VECTOR2I move_endpoint = m_editPoints->Point( LINE_END ).GetPosition() - line->GetEnd();
|
VECTOR2I move_endpoint = m_editPoints->Point( LINE_END ).GetPosition() - line->GetEnd();
|
||||||
|
|
||||||
dataItem->MoveStartPointToUi( dataItem->GetStartPosUi() + move_startpoint );
|
dataItem->MoveStartPointToUi( dataItem->GetStartPosIU() + move_startpoint );
|
||||||
dataItem->MoveEndPointToUi( dataItem->GetEndPosUi() + move_endpoint );
|
dataItem->MoveEndPointToUi( dataItem->GetEndPosIU() + move_endpoint );
|
||||||
|
|
||||||
for( DS_DRAW_ITEM_BASE* draw_item : dataItem->GetDrawItems() )
|
for( DS_DRAW_ITEM_BASE* draw_item : dataItem->GetDrawItems() )
|
||||||
{
|
{
|
||||||
|
@ -388,8 +388,8 @@ void PL_POINT_EDITOR::updateItem() const
|
||||||
end_delta.x = botRight.x - rect->GetEnd().x;
|
end_delta.x = botRight.x - rect->GetEnd().x;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataItem->MoveStartPointToUi( dataItem->GetStartPosUi() + start_delta );
|
dataItem->MoveStartPointToUi( dataItem->GetStartPosIU() + start_delta );
|
||||||
dataItem->MoveEndPointToUi( dataItem->GetEndPosUi() + end_delta );
|
dataItem->MoveEndPointToUi( dataItem->GetEndPosIU() + end_delta );
|
||||||
|
|
||||||
for( DS_DRAW_ITEM_BASE* draw_item : dataItem->GetDrawItems() )
|
for( DS_DRAW_ITEM_BASE* draw_item : dataItem->GetDrawItems() )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue