Revert attempt to use drawing code to generate text bounding boxes.

This commit is contained in:
Jeff Young 2023-05-27 22:00:21 +01:00
parent b8986709bf
commit 95a09f686b
3 changed files with 94 additions and 37 deletions

View File

@ -535,37 +535,100 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
return m_bounding_box_cache; return m_bounding_box_cache;
} }
// We've tried a gazillion different ways of calculating bounding boxes for text; all of them BOX2I bbox;
// fail in one case or another and we end up with compensation hacks strewn throughout the wxArrayString strings;
// code. So I'm pulling the plug on it; we're just going to draw the damn text and see how wxString text = GetShownText( true );
// big it is. int thickness = GetEffectiveTextPenWidth();
BOX2I bbox;
BOX2I strokeBBox;
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
KIFONT::FONT* font = getDrawFont();
wxString shownText( GetShownText( true ) );
TEXT_ATTRIBUTES attrs = GetAttributes();
CALLBACK_GAL callback_gal( if( IsMultilineAllowed() )
empty_opts,
// Stroke callback
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
{
strokeBBox.Merge( aPt1 );
strokeBBox.Merge( aPt2 );
},
// Outline callback
[&]( const SHAPE_LINE_CHAIN& aPoly )
{
bbox.Merge( aPoly.BBox() );
} );
font->Draw( &callback_gal, shownText, drawPos, attrs );
if( strokeBBox.GetSizeMax() > 0 )
{ {
strokeBBox.Inflate( GetTextThickness() / 2 ); wxStringSplit( text, strings, '\n' );
bbox.Merge( strokeBBox );
if( strings.GetCount() ) // GetCount() == 0 for void strings with multilines allowed
{
if( aLine >= 0 && ( aLine < static_cast<int>( strings.GetCount() ) ) )
text = strings.Item( aLine );
else
text = strings.Item( 0 );
}
}
// calculate the H and V size
KIFONT::FONT* font = getDrawFont();
VECTOR2D fontSize( GetTextSize() );
bool bold = IsBold();
bool italic = IsItalic();
VECTOR2I extents = font->StringBoundaryLimits( text, fontSize, thickness, bold, italic );
int overbarOffset = 0;
// Creates bounding box (rectangle) for horizontal, left and top justified text. The
// bounding box will be moved later according to the actual text options
VECTOR2I textsize = VECTOR2I( extents.x, extents.y );
VECTOR2I pos = drawPos;
if( IsMultilineAllowed() && aLine > 0 && aLine < (int) strings.GetCount() )
pos.y -= KiROUND( aLine * font->GetInterline( fontSize.y ) );
if( text.Contains( wxT( "~{" ) ) )
overbarOffset = extents.y / 14;
if( aInvertY )
pos.y = -pos.y;
bbox.SetOrigin( pos );
// for multiline texts and aLine < 0, merge all rectangles (aLine == -1 signals all lines)
if( IsMultilineAllowed() && aLine < 0 && strings.GetCount() )
{
for( unsigned ii = 1; ii < strings.GetCount(); ii++ )
{
text = strings.Item( ii );
extents = font->StringBoundaryLimits( text, fontSize, thickness, bold, italic );
textsize.x = std::max( textsize.x, extents.x );
}
// interline spacing is only *between* lines, so total height is the height of the first
// line plus the interline distance (with interline spacing) for all subsequent lines
textsize.y += KiROUND( ( strings.GetCount() - 1 ) * font->GetInterline( fontSize.y ) );
}
bbox.SetSize( textsize );
/*
* At this point the rectangle origin is the text origin (m_Pos). This is correct only for
* left and top justified, non-mirrored, non-overbarred texts. Recalculate for all others.
*/
int italicOffset = IsItalic() ? KiROUND( fontSize.y * ITALIC_TILT ) : 0;
switch( GetHorizJustify() )
{
case GR_TEXT_H_ALIGN_LEFT:
if( IsMirrored() )
bbox.SetX( bbox.GetX() - ( bbox.GetWidth() - italicOffset ) );
break;
case GR_TEXT_H_ALIGN_CENTER:
bbox.SetX( bbox.GetX() - ( bbox.GetWidth() - italicOffset ) / 2 );
break;
case GR_TEXT_H_ALIGN_RIGHT:
if( !IsMirrored() )
bbox.SetX( bbox.GetX() - ( bbox.GetWidth() - italicOffset ) );
break;
}
switch( GetVertJustify() )
{
case GR_TEXT_V_ALIGN_TOP:
break;
case GR_TEXT_V_ALIGN_CENTER:
bbox.SetY( bbox.GetY() - ( bbox.GetHeight() + overbarOffset ) / 2 );
break;
case GR_TEXT_V_ALIGN_BOTTOM:
bbox.SetY( bbox.GetY() - ( bbox.GetHeight() + overbarOffset ) );
break;
} }
bbox.Normalize(); // Make h and v sizes always >= 0 bbox.Normalize(); // Make h and v sizes always >= 0

View File

@ -399,8 +399,8 @@ 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 const KIFONT::FONT* m_render_cache_font;
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;
mutable std::vector<std::unique_ptr<KIFONT::GLYPH>> m_render_cache; mutable std::vector<std::unique_ptr<KIFONT::GLYPH>> m_render_cache;

View File

@ -142,13 +142,7 @@ EDA_ANGLE PCB_TEXT::GetDrawRotation() const
const BOX2I PCB_TEXT::ViewBBox() const const BOX2I PCB_TEXT::ViewBBox() const
{ {
EDA_ANGLE angle = GetDrawRotation(); return GetBoundingBox();
BOX2I text_area = GetTextBox();
if( !angle.IsZero() )
text_area = text_area.GetBoundingBoxRotated( GetTextPos(), angle );
return BOX2I( text_area.GetPosition(), text_area.GetSize() );
} }