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
This commit is contained in:
Jeff Young 2023-05-27 16:30:12 +01:00
parent f2f014a27c
commit f35a88ce0b
16 changed files with 177 additions and 124 deletions

View File

@ -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++ )
{
if( j && ! IsInsidePage( j ) )
if( j > 0 && !IsInsidePage( j ) )
continue;
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 )
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
{
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 )
{
drawItem->SetPosition( GetStartPosUi( drawItem->GetIndexInPeer() ) );
drawItem->SetEnd( GetEndPosUi( drawItem->GetIndexInPeer() ) );
drawItem->SetPosition( GetStartPosIU( 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;
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 );
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();
VECTOR2D pos = GetStartPos( ii );
for( int kk = 0; kk < 1; kk++ )
for( const VECTOR2D& pos : { GetStartPos( ii ), GetEndPos( ii ) } )
{
if( model.m_RB_Corner.x < pos.x || model.m_LT_Corner.x > pos.x )
return false;
if( model.m_RB_Corner.y < pos.y || model.m_LT_Corner.y > pos.y )
return false;
pos = GetEndPos( ii );
}
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++ )
{
if( j && !IsInsidePage( j ) )
if( j > 0 && !IsInsidePage( j ) )
continue;
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 ] );
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 ) )
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 );
text->SetFlags( itemFlags[ j ] );
m_drawItems.push_back( text );
@ -595,14 +591,14 @@ void DS_DATA_ITEM_TEXT::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::VIE
if( aView )
aView->Add( text );
text->SetHorizJustify( m_Hjustify ) ;
text->SetHorizJustify( m_Hjustify );
text->SetVertJustify( m_Vjustify );
text->SetTextAngle( EDA_ANGLE( m_Orient, DEGREES_T ) );
text->SetMultilineAllowed( multilines );
// Increment label for the next text (has no meaning for multiline texts)
if( m_RepeatCount > 1 && !multilines )
IncrementLabel(( j + 1 ) * m_IncrementLabel );
IncrementLabel( ( j + 1 ) * m_IncrementLabel );
}
}
@ -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++ )
{
if( j && !IsInsidePage( j ) )
if( j > 0 && !IsInsidePage( j ) )
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 ] );
m_drawItems.push_back( bitmap );

View File

@ -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
{
return EDA_TEXT::GetTextBox();

View File

@ -253,10 +253,7 @@ 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
{
KIFONT::FONT* font = aItem->GetFont();
wxString shownText( aItem->GetShownText( true ) );
VECTOR2I text_offset = aItem->GetTextPos();
TEXT_ATTRIBUTES attrs = aItem->GetAttributes();
KIFONT::FONT* font = aItem->GetFont();
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->SetFillColor( color );
TEXT_ATTRIBUTES attrs = aItem->GetAttributes();
attrs.m_StrokeWidth = std::max( aItem->GetEffectiveTextPenWidth(),
m_renderSettings.GetDefaultPenWidth() );
std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
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 );
}
font->Draw( m_gal, aItem->GetShownText( true ), aItem->GetTextPos(), attrs );
}

View File

@ -126,8 +126,13 @@ void DS_PROXY_VIEW_ITEM::ViewDraw( int aLayer, VIEW* aView ) const
ws_settings->SetDefaultFont( settings->GetDefaultFont() );
// 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() )
ws_painter.Draw( item, LAYER_DRAWINGSHEET );
{
if( viewport.Intersects( item->GetApproxBBox() ) )
ws_painter.Draw( item, LAYER_DRAWINGSHEET );
}
// Draw gray line that outlines the sheet size
if( settings->GetShowPageLimits() )

View File

@ -93,6 +93,7 @@ GR_TEXT_V_ALIGN_T EDA_TEXT::MapVertJustify( int aVertJustify )
EDA_TEXT::EDA_TEXT( const EDA_IU_SCALE& aIuScale, const wxString& aText ) :
m_text( aText ),
m_IuScale( aIuScale ),
m_render_cache_font( nullptr ),
m_bounding_box_cache_valid( false ),
m_bounding_box_cache_line( -1 ),
m_bounding_box_cache_inverted( false )
@ -113,8 +114,10 @@ EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
m_attributes = aText.m_attributes;
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_angle = aText.m_render_cache_angle;
m_render_cache_offset = aText.m_render_cache_offset;
m_render_cache.clear();
@ -147,8 +150,10 @@ EDA_TEXT& EDA_TEXT::operator=( const EDA_TEXT& aText )
m_attributes = aText.m_attributes;
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_angle = aText.m_render_cache_angle;
m_render_cache_offset = aText.m_render_cache_offset;
m_render_cache.clear();
@ -471,19 +476,21 @@ EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolved
EDA_ANGLE resolvedAngle = GetDrawRotation();
if( m_render_cache.empty()
|| m_render_cache_font != aFont
|| m_render_cache_text != forResolvedText
|| m_render_cache_angle != resolvedAngle
|| m_render_cache_offset != aOffset )
{
m_render_cache.clear();
KIFONT::OUTLINE_FONT* font = static_cast<KIFONT::OUTLINE_FONT*>( getDrawFont() );
TEXT_ATTRIBUTES attrs = GetAttributes();
const KIFONT::OUTLINE_FONT* font = static_cast<const KIFONT::OUTLINE_FONT*>( aFont );
TEXT_ATTRIBUTES attrs = GetAttributes();
attrs.m_Angle = resolvedAngle;
font->GetLinesAsGlyphs( &m_render_cache, forResolvedText, GetDrawPos() + aOffset,
attrs );
m_render_cache_font = aFont;
m_render_cache_angle = resolvedAngle;
m_render_cache_text = forResolvedText;
m_render_cache_offset = aOffset;
@ -529,7 +536,7 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
}
// We've tried a gazillion different ways of calculating bounding boxes for text; all of them
// fail in one case or another and we end up with compensation hacks strewed throughout the
// fail in one case or another and we end up with compensation hacks strewn throughout the
// code. So I'm pulling the plug on it; we're just going to draw the damn text and see how
// big it is.
BOX2I bbox;

View File

@ -2805,7 +2805,7 @@ void OPENGL_GAL::DrawGlyphs( const std::vector<std::unique_ptr<KIFONT::GLYPH>>&
// Optimized path for stroke fonts that pre-reserves glyph triangles.
int triangleCount = 0;
if( aGlyphs.size() > 2 )
if( aGlyphs.size() > 0 )
{
thread_pool& tp = GetKiCadThreadPool();

View File

@ -1208,28 +1208,49 @@ 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,
bool aIncludeElectricalType ) const
{
EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
KIFONT::FONT* font = KIFONT::FONT::GetFont( cfg->m_Appearance.default_font );
BOX2I bbox;
VECTOR2I begin;
VECTOR2I end;
int pinNameOffset = 0;
int nameTextLength = 0;
int nameTextHeight = 0;
int numberTextLength = 0;
int numberTextHeight = 0;
int typeTextLength = 0;
wxString name = GetShownName();
wxString number = GetShownNumber();
bool includeName = aIncludeNameAndNumber && !name.IsEmpty();
bool includeNumber = aIncludeNameAndNumber && !number.IsEmpty();
bool includeType = aIncludeElectricalType;
int minsizeV = TARGET_PIN_RADIUS;
int penWidth = GetPenWidth();
BOX2I bbox;
VECTOR2I begin;
VECTOR2I end;
int pinNameOffset = 0;
int nameTextLength = 0;
int nameTextHeight = 0;
int numberTextLength = 0;
int numberTextHeight = 0;
int typeTextLength = 0;
bool includeName = aIncludeNameAndNumber && !GetShownName().IsEmpty();
bool includeNumber = aIncludeNameAndNumber && !GetShownNumber().IsEmpty();
bool includeType = aIncludeElectricalType;
int minsizeV = TARGET_PIN_RADIUS;
if( !aIncludeInvisiblePins && !IsVisible() )
{
@ -1248,33 +1269,18 @@ const BOX2I LIB_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNa
includeNumber = false;
}
// Get maximum height including ascenders and descenders
wxString test = wxT( "Xg" );
if( includeNumber )
{
VECTOR2D fontSize( m_numTextSize, m_numTextSize );
numberTextLength = font->StringBoundaryLimits( number, fontSize, penWidth, false, false ).x;
numberTextHeight = font->StringBoundaryLimits( test, fontSize, penWidth, false, false ).y;
validateExtentsCache( font, m_numTextSize, GetShownNumber(), &m_numExtentsCache );
numberTextLength = m_numExtentsCache.m_Extents.x;
numberTextHeight = m_numExtentsCache.m_Extents.y;
}
if( includeName )
{
VECTOR2D fontSize( m_nameTextSize, m_nameTextSize );
nameTextLength = font->StringBoundaryLimits( name, fontSize, penWidth, false, false ).x
+ 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;
validateExtentsCache( font, m_nameTextSize, GetShownName(), &m_nameExtentsCache );
nameTextLength = m_nameExtentsCache.m_Extents.x + pinNameOffset;
nameTextHeight = m_nameExtentsCache.m_Extents.y + schIUScale.MilsToIU( PIN_TEXT_MARGIN );
}
if( includeType )
@ -1295,7 +1301,7 @@ const BOX2I LIB_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNa
// Attempt to mimic SCH_PAINTER's algorithm without actually knowing the schematic text
// 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)
if( pinNameOffset || !includeName )

View File

@ -122,6 +122,7 @@ public:
// pin name string does not support spaces
m_name.Replace( wxT( " " ), wxT( "_" ) );
m_nameExtentsCache.m_Extents = VECTOR2I();
}
const wxString& GetNumber() const { return m_number; }
@ -132,13 +133,22 @@ public:
// pin number string does not support spaces
m_number.Replace( wxT( " " ), wxT( "_" ) );
m_numExtentsCache.m_Extents = VECTOR2I();
}
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; }
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; }
@ -261,12 +271,22 @@ public:
static const wxString GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE aType );
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.
* If \a aColor != 0, draw with \a aColor, else with the normal pin color.
*/
void printPinSymbol( const RENDER_SETTINGS *aSettings, const VECTOR2I &aPos, int aOrientation,
bool aDimmed );
bool aDimmed );
/**
* Put the pin number and pin text info, given the pin line coordinates.
@ -303,22 +323,25 @@ private:
int compare( const LIB_ITEM& aOther, int aCompareFlags = 0 ) const override;
protected:
VECTOR2I m_position; // Position of the pin.
int m_length; // Length of the pin.
int m_orientation; // Pin orientation (Up, Down, Left, Right)
GRAPHIC_PINSHAPE m_shape; // Shape drawn around pin
ELECTRICAL_PINTYPE m_type; // Electrical type of the pin.
int m_attributes; // Set bit 0 to indicate pin is invisible.
VECTOR2I m_position; // Position of the pin.
int m_length; // Length of the pin.
int m_orientation; // Pin orientation (Up, Down, Left, Right)
GRAPHIC_PINSHAPE m_shape; // Shape drawn around pin
ELECTRICAL_PINTYPE m_type; // Electrical type of the pin.
int m_attributes; // Set bit 0 to indicate pin is invisible.
wxString m_name;
wxString m_number;
int m_numTextSize; // Pin num and Pin name sizes
int m_numTextSize; // Pin num and Pin name sizes
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
wxString m_operatingPoint; // No, LIB_PINs don't really have operating points.
// But we draw SCH_PINs through their LIB_PIN
// counterparts, so here we are....
wxString m_operatingPoint; // No, LIB_PINs don't really have simulation
// operating points. But we draw SCH_PINs through
// their LIB_PIN counterparts, so here we are....
mutable EXTENTS_CACHE m_numExtentsCache;
mutable EXTENTS_CACHE m_nameExtentsCache;
};

View File

@ -1621,15 +1621,14 @@ void SCH_PAINTER::draw( const LIB_PIN *aPin, int aLayer, bool aDimmed )
m_gal->SetFillColor( colour[i] );
TEXT_ATTRIBUTES attrs;
attrs.m_Font = KIFONT::FONT::GetFont( eeconfig()->m_Appearance.default_font );
attrs.m_Size = VECTOR2I( size[i], size[i] );
attrs.m_Halign = hAlign;
attrs.m_Valign = vAlign;
attrs.m_Angle = aAngle;
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 );
}
@ -2183,17 +2182,10 @@ void SCH_PAINTER::draw( const SCH_TEXT *aText, int aLayer )
void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
COLOR4D color = getRenderColor( aTextBox, aLayer, drawingShadows );
float borderWidth = getLineWidth( aTextBox, drawingShadows );
KIFONT::FONT* font = aTextBox->GetFont();
if( !font )
{
font = KIFONT::FONT::GetFont( m_schSettings.GetDefaultFont(), aTextBox->IsBold(),
aTextBox->IsItalic() );
}
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
COLOR4D color = getRenderColor( aTextBox, aLayer, drawingShadows );
float borderWidth = getLineWidth( aTextBox, drawingShadows );
KIFONT::FONT* font = getFont( aTextBox );
auto drawText =
[&]()

View File

@ -134,8 +134,8 @@ public:
void SetPage1Option( PAGE_OPTION aChoice ) { m_pageOption = aChoice; }
// Coordinate handling
const VECTOR2I GetStartPosUi( int ii = 0 ) const;
const VECTOR2I GetEndPosUi( int ii = 0 ) const;
const VECTOR2I GetStartPosIU( int ii = 0 ) const;
const VECTOR2I GetEndPosIU( int ii = 0 ) const;
const VECTOR2D GetStartPos( int ii = 0 ) const;
const VECTOR2D GetEndPos( int ii = 0 ) const;

View File

@ -84,6 +84,14 @@ public:
// 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;
// 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
// two HitTest() functions if they need something more specific.
const BOX2I GetBoundingBox() const override = 0;
@ -325,6 +333,8 @@ public:
VECTOR2I GetPosition() const override { return GetTextPos(); }
void SetPosition( const VECTOR2I& aPos ) override { SetTextPos( aPos ); }
virtual const BOX2I GetApproxBBox() override;
const BOX2I GetBoundingBox() const override;
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;

View File

@ -399,6 +399,7 @@ private:
std::reference_wrapper<const EDA_IU_SCALE> m_IuScale;
mutable const KIFONT::FONT* m_render_cache_font;
mutable wxString m_render_cache_text;
mutable EDA_ANGLE m_render_cache_angle;
mutable VECTOR2I m_render_cache_offset;

View File

@ -657,22 +657,22 @@ VECTOR2I PL_EDITOR_FRAME::ReturnCoordOriginCorner() const
case 1: // Origin = page Right Bottom corner
dummy.SetStart( 0, 0, RB_CORNER );
originCoord = dummy.GetStartPosUi();
originCoord = dummy.GetStartPosIU();
break;
case 2: // Origin = page Left Bottom corner
dummy.SetStart( 0, 0, LB_CORNER );
originCoord = dummy.GetStartPosUi();
originCoord = dummy.GetStartPosIU();
break;
case 3: // Origin = page Right Top corner
dummy.SetStart( 0, 0, RT_CORNER );
originCoord = dummy.GetStartPosUi();
originCoord = dummy.GetStartPosIU();
break;
case 4: // Origin = page Left Top corner
dummy.SetStart( 0, 0, LT_CORNER );
originCoord = dummy.GetStartPosUi();
originCoord = dummy.GetStartPosIU();
break;
}

View File

@ -169,7 +169,7 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent )
else
{
item->GetPeer()->MoveStartPointToUi( cursorPos );
item->SetPosition( item->GetPeer()->GetStartPosUi( 0 ) );
item->SetPosition( item->GetPeer()->GetStartPosIU( 0 ) );
item->ClearEditFlags();
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() ) )
{
item->GetPeer()->MoveStartPointToUi( cursorPos );
item->SetPosition( item->GetPeer()->GetStartPosUi( 0 ) );
item->SetPosition( item->GetPeer()->GetStartPosIU( 0 ) );
getView()->Update( item );
}
else
@ -306,7 +306,7 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
if( item )
{
item->GetPeer()->MoveEndPointToUi( cursorPos );
item->SetEnd( item->GetPeer()->GetEndPosUi( 0 ) );
item->SetEnd( item->GetPeer()->GetEndPosIU( 0 ) );
getView()->Update( item );
}
}

View File

@ -322,7 +322,7 @@ int PL_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
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() )
{

View File

@ -338,8 +338,8 @@ void PL_POINT_EDITOR::updateItem() const
VECTOR2I move_startpoint = m_editPoints->Point( LINE_START ).GetPosition() - line->GetStart();
VECTOR2I move_endpoint = m_editPoints->Point( LINE_END ).GetPosition() - line->GetEnd();
dataItem->MoveStartPointToUi( dataItem->GetStartPosUi() + move_startpoint );
dataItem->MoveEndPointToUi( dataItem->GetEndPosUi() + move_endpoint );
dataItem->MoveStartPointToUi( dataItem->GetStartPosIU() + move_startpoint );
dataItem->MoveEndPointToUi( dataItem->GetEndPosIU() + move_endpoint );
for( DS_DRAW_ITEM_BASE* draw_item : dataItem->GetDrawItems() )
{
@ -389,8 +389,8 @@ void PL_POINT_EDITOR::updateItem() const
end_delta.x = botRight.x - rect->GetEnd().x;
}
dataItem->MoveStartPointToUi( dataItem->GetStartPosUi() + start_delta );
dataItem->MoveEndPointToUi( dataItem->GetEndPosUi() + end_delta );
dataItem->MoveStartPointToUi( dataItem->GetStartPosIU() + start_delta );
dataItem->MoveEndPointToUi( dataItem->GetEndPosIU() + end_delta );
for( DS_DRAW_ITEM_BASE* draw_item : dataItem->GetDrawItems() )
{