Fix text bounding boxes.

This commit is contained in:
Jeff Young 2022-02-03 22:35:42 +00:00
parent b9eb3e9b05
commit 7dadc9d2f0
2 changed files with 24 additions and 39 deletions

View File

@ -541,19 +541,17 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
// calculate the H and V size // calculate the H and V size
KIFONT::FONT* font = GetDrawFont(); KIFONT::FONT* font = GetDrawFont();
VECTOR2D fontSize( GetTextSize() ); VECTOR2D fontSize( GetTextSize() );
double penWidth( thickness );
bool bold = IsBold(); bool bold = IsBold();
bool italic = IsItalic(); bool italic = IsItalic();
int dx = font->StringBoundaryLimits( text, fontSize, penWidth, bold, italic ).x; VECTOR2I extents = font->StringBoundaryLimits( text, fontSize, thickness, bold, italic );
int dy = GetInterline();
// Creates bounding box (rectangle) for horizontal, left and top justified text. The // Creates bounding box (rectangle) for horizontal, left and top justified text. The
// bounding box will be moved later according to the actual text options // bounding box will be moved later according to the actual text options
wxSize textsize = wxSize( dx, fontSize.y ); wxSize textsize = wxSize( extents.x, extents.y );
VECTOR2I pos = drawPos; VECTOR2I pos = drawPos;
if( IsMultilineAllowed() && aLine > 0 && ( aLine < static_cast<int>( strings.GetCount() ) ) ) if( IsMultilineAllowed() && aLine > 0 && ( aLine < static_cast<int>( strings.GetCount() ) ) )
pos.y -= aLine * GetInterline(); pos.y -= KiROUND( aLine * font->GetInterline( fontSize.y ) );
if( aInvertY ) if( aInvertY )
pos.y = -pos.y; pos.y = -pos.y;
@ -566,10 +564,13 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
for( unsigned ii = 1; ii < strings.GetCount(); ii++ ) for( unsigned ii = 1; ii < strings.GetCount(); ii++ )
{ {
text = strings.Item( ii ); text = strings.Item( ii );
dx = font->StringBoundaryLimits( text, fontSize, penWidth, bold, italic ).x; extents = font->StringBoundaryLimits( text, fontSize, thickness, bold, italic );
textsize.x = std::max( textsize.x, dx ); textsize.x = std::max( textsize.x, extents.x );
textsize.y += dy;
} }
// 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 ) );
} }
rect.SetSize( textsize ); rect.SetSize( textsize );
@ -910,21 +911,7 @@ void EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( SHAPE_POLY_SET* aCorn
EDA_RECT rect = GetTextBox(); EDA_RECT rect = GetTextBox();
// This ugly hack is because this code used to be defined in the board polygon code rect.Inflate( aClearanceValue );
// file rather than in the EDA_TEXT source file where it belonged. Using the board
// default text width was dubious so this recreates the same code with the exception
// if for some reason a different default text width is require for some other object.
#if !defined( DEFAULT_TEXT_WIDTH )
#define LOCAL_DEFAULT_TEXT_WIDTH
#define DEFAULT_TEXT_WIDTH 0.15
#endif
rect.Inflate( aClearanceValue + Millimeter2iu( DEFAULT_TEXT_WIDTH ) );
#if defined( LOCAL_DEFAULT_TEXT_WIDTH )
#undef DEFAULT_TEXT_WIDTH
#undef LOCAL_DEFAULT_TEXT_WIDTH
#endif
corners[0].x = rect.GetOrigin().x; corners[0].x = rect.GetOrigin().x;
corners[0].y = rect.GetOrigin().y; corners[0].y = rect.GetOrigin().y;

View File

@ -214,26 +214,24 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
bool aMirror, const VECTOR2I& aOrigin, bool aMirror, const VECTOR2I& aOrigin,
TEXT_STYLE_FLAGS aTextStyle ) const TEXT_STYLE_FLAGS aTextStyle ) const
{ {
wxPoint cursor( aPosition ); constexpr double SPACE_WIDTH = 0.6;
constexpr double INTER_CHAR = 0.2;
constexpr double SUPER_SUB_SIZE_MULTIPLIER = 0.7;
constexpr double SUPER_HEIGHT_OFFSET = 0.5;
constexpr double SUB_HEIGHT_OFFSET = 0.3;
VECTOR2I cursor( aPosition );
VECTOR2D glyphSize( aSize ); VECTOR2D glyphSize( aSize );
double tilt = ( aTextStyle & TEXT_STYLE::ITALIC ) ? ITALIC_TILT : 0.0; double tilt = ( aTextStyle & TEXT_STYLE::ITALIC ) ? ITALIC_TILT : 0.0;
if( aTextStyle & TEXT_STYLE::SUBSCRIPT || aTextStyle & TEXT_STYLE::SUPERSCRIPT ) if( aTextStyle & TEXT_STYLE::SUBSCRIPT || aTextStyle & TEXT_STYLE::SUPERSCRIPT )
{ {
constexpr double subscriptSuperscriptMultiplier = 0.7; glyphSize = glyphSize * SUPER_SUB_SIZE_MULTIPLIER;
glyphSize.x *= subscriptSuperscriptMultiplier;
glyphSize.y *= subscriptSuperscriptMultiplier;
if( aTextStyle & TEXT_STYLE::SUBSCRIPT ) if( aTextStyle & TEXT_STYLE::SUBSCRIPT )
{ cursor.y += glyphSize.y * SUB_HEIGHT_OFFSET;
constexpr double subscriptVerticalMultiplier = 0.3;
cursor.y += glyphSize.y * subscriptVerticalMultiplier;
}
else else
{ cursor.y -= glyphSize.y * SUPER_HEIGHT_OFFSET;
constexpr double superscriptVerticalMultiplier = 0.5;
cursor.y -= glyphSize.y * superscriptVerticalMultiplier;
}
} }
for( wxUniChar c : aText ) for( wxUniChar c : aText )
@ -252,8 +250,7 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
if( dd == 0 ) if( dd == 0 )
{ {
// 'space' character - draw nothing, advance cursor position // 'space' character - draw nothing, advance cursor position
constexpr double spaceAdvance = 0.6; cursor.x += KiROUND( glyphSize.x * SPACE_WIDTH );
cursor.x += glyphSize.x * spaceAdvance;
} }
else else
{ {
@ -272,7 +269,7 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
if( tilt > 0.0 ) if( tilt > 0.0 )
glyphExtents.x -= glyphExtents.y * tilt; glyphExtents.x -= glyphExtents.y * tilt;
cursor.x += glyphExtents.x; cursor.x += KiROUND( glyphExtents.x );
} }
} }
@ -309,7 +306,8 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
if( aBBox ) if( aBBox )
{ {
aBBox->SetOrigin( aPosition ); aBBox->SetOrigin( aPosition );
aBBox->SetEnd( cursor.x + barOffset.x, cursor.y + std::max( glyphSize.y, barOffset.y ) ); aBBox->SetEnd( cursor.x + barOffset.x - KiROUND( glyphSize.x * INTER_CHAR ),
cursor.y + std::max( glyphSize.y, barOffset.y ) );
aBBox->Normalize(); aBBox->Normalize();
} }