mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-03-30 05:56:55 +00:00
ADDED: Knockout text boxes.
This commit is contained in:
parent
7583c0e69d
commit
675624b926
@ -2079,6 +2079,8 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXTBOX* aTextBox ) const
|
||||
{
|
||||
KICAD_FORMAT::FormatBool( m_out, "border", aTextBox->IsBorderEnabled() );
|
||||
aTextBox->GetStroke().Format( m_out, pcbIUScale );
|
||||
|
||||
KICAD_FORMAT::FormatBool( m_out, "knockout", aTextBox->IsKnockout() );
|
||||
}
|
||||
|
||||
if( aTextBox->GetFont() && aTextBox->GetFont()->IsOutline() )
|
||||
|
@ -172,7 +172,9 @@ class PCB_IO_KICAD_SEXPR; // forward decl
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20241030 // Dimension arrow directions, suppress_zeroes normalization
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20241129 // Normalise keep_text_aligned and fill properties
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20241228 // Convert teardrop curve points to bool
|
||||
#define SEXPR_BOARD_FILE_VERSION 20241229 // Expand User layers to arbitrary count
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20241229 // Expand User layers to arbitrary count
|
||||
//----------------- Start of 10.0 development -----------------
|
||||
#define SEXPR_BOARD_FILE_VERSION 20250210 // Knockout for textboxes
|
||||
|
||||
|
||||
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
|
||||
|
@ -3649,6 +3649,20 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseTextBoxContent( PCB_TEXTBOX* aTextBox )
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_knockout:
|
||||
if( PCB_TABLECELL* cell = dynamic_cast<PCB_TABLECELL*>( aTextBox ) )
|
||||
{
|
||||
Expecting( "locked, start, pts, angle, width, margins, layer, effects, span, "
|
||||
"render_cache, uuid or tstamp" );
|
||||
}
|
||||
else
|
||||
{
|
||||
aTextBox->SetIsKnockout( parseBool() );
|
||||
}
|
||||
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_span:
|
||||
if( PCB_TABLECELL* cell = dynamic_cast<PCB_TABLECELL*>( aTextBox ) )
|
||||
{
|
||||
@ -3657,7 +3671,8 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseTextBoxContent( PCB_TEXTBOX* aTextBox )
|
||||
}
|
||||
else
|
||||
{
|
||||
Expecting( "angle, width, layer, effects, render_cache, uuid or tstamp" );
|
||||
Expecting( "locked, start, pts, angle, width, stroke, border, margins, knockout, "
|
||||
"layer, effects, render_cache, uuid or tstamp" );
|
||||
}
|
||||
|
||||
NeedRIGHT();
|
||||
@ -3680,9 +3695,15 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseTextBoxContent( PCB_TEXTBOX* aTextBox )
|
||||
|
||||
default:
|
||||
if( dynamic_cast<PCB_TABLECELL*>( aTextBox ) != nullptr )
|
||||
Expecting( "locked, start, pts, angle, width, layer, effects, span, render_cache, uuid or tstamp" );
|
||||
{
|
||||
Expecting( "locked, start, pts, angle, width, margins, layer, effects, span, "
|
||||
"render_cache, uuid or tstamp" );
|
||||
}
|
||||
else
|
||||
Expecting( "locked, start, pts, angle, width, layer, effects, render_cache, uuid or tstamp" );
|
||||
{
|
||||
Expecting( "locked, start, pts, angle, width, stroke, border, margins, knockout,"
|
||||
"layer, effects, render_cache, uuid or tstamp" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2425,33 +2425,46 @@ void PCB_PAINTER::draw( const PCB_TEXTBOX* aTextBox, int aLayer )
|
||||
#endif
|
||||
}
|
||||
|
||||
if( resolvedText.Length() == 0 )
|
||||
return;
|
||||
|
||||
const KIFONT::METRICS& metrics = aTextBox->GetFontMetrics();
|
||||
TEXT_ATTRIBUTES attrs = aTextBox->GetAttributes();
|
||||
attrs.m_StrokeWidth = getLineThickness( aTextBox->GetEffectiveTextPenWidth() );
|
||||
|
||||
if( m_gal->IsFlippedX() && !aTextBox->IsSideSpecific() )
|
||||
if( aTextBox->IsKnockout() )
|
||||
{
|
||||
attrs.m_Mirrored = !attrs.m_Mirrored;
|
||||
strokeText( resolvedText, aTextBox->GetDrawPos( true ), attrs, metrics );
|
||||
return;
|
||||
}
|
||||
SHAPE_POLY_SET finalPoly;
|
||||
aTextBox->TransformTextToPolySet( finalPoly, 0, m_maxError, ERROR_INSIDE );
|
||||
finalPoly.Fracture();
|
||||
|
||||
std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
|
||||
|
||||
if( font->IsOutline() )
|
||||
cache = aTextBox->GetRenderCache( font, resolvedText );
|
||||
|
||||
if( cache )
|
||||
{
|
||||
m_gal->SetLineWidth( attrs.m_StrokeWidth );
|
||||
m_gal->DrawGlyphs( *cache );
|
||||
m_gal->SetIsStroke( false );
|
||||
m_gal->SetIsFill( true );
|
||||
m_gal->DrawPolygon( finalPoly );
|
||||
}
|
||||
else
|
||||
{
|
||||
strokeText( resolvedText, aTextBox->GetDrawPos(), attrs, metrics );
|
||||
if( resolvedText.Length() == 0 )
|
||||
return;
|
||||
|
||||
const KIFONT::METRICS& metrics = aTextBox->GetFontMetrics();
|
||||
TEXT_ATTRIBUTES attrs = aTextBox->GetAttributes();
|
||||
attrs.m_StrokeWidth = getLineThickness( aTextBox->GetEffectiveTextPenWidth() );
|
||||
|
||||
if( m_gal->IsFlippedX() && !aTextBox->IsSideSpecific() )
|
||||
{
|
||||
attrs.m_Mirrored = !attrs.m_Mirrored;
|
||||
strokeText( resolvedText, aTextBox->GetDrawPos( true ), attrs, metrics );
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
|
||||
|
||||
if( font->IsOutline() )
|
||||
cache = aTextBox->GetRenderCache( font, resolvedText );
|
||||
|
||||
if( cache )
|
||||
{
|
||||
m_gal->SetLineWidth( attrs.m_StrokeWidth );
|
||||
m_gal->DrawGlyphs( *cache );
|
||||
}
|
||||
else
|
||||
{
|
||||
strokeText( resolvedText, aTextBox->GetDrawPos(), attrs, metrics );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -640,8 +640,6 @@ static struct PCB_TEXT_DESC
|
||||
propMgr.OverrideAvailability( TYPE_HASH( PCB_TEXT ), TYPE_HASH( EDA_TEXT ),
|
||||
_HKI( "Keep Upright" ), isFootprintText );
|
||||
|
||||
propMgr.OverrideAvailability( TYPE_HASH( PCB_TEXT ), TYPE_HASH( EDA_TEXT ),
|
||||
_HKI( "Hyperlink" ),
|
||||
[]( INSPECTABLE* aItem ) { return false; } );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TEXT ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
|
||||
}
|
||||
} _PCB_TEXT_DESC;
|
||||
|
@ -701,44 +701,57 @@ void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearanc
|
||||
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
|
||||
KIFONT::FONT* font = getDrawFont();
|
||||
int penWidth = GetEffectiveTextPenWidth();
|
||||
TEXT_ATTRIBUTES attrs = GetAttributes();
|
||||
wxString shownText = GetShownText( true );
|
||||
|
||||
// Note: this function is mainly used in 3D viewer.
|
||||
// the polygonal shape of a text can have many basic shapes,
|
||||
// so combining these shapes can be very useful to create a final shape
|
||||
// swith a lot less vertices to speedup calculations using this final shape
|
||||
// The polygonal shape of a text can have many basic shapes, so combining these shapes can
|
||||
// be very useful to create a final shape with a lot less vertices to speedup calculations.
|
||||
// Simplify shapes is not usually always efficient, but in this case it is.
|
||||
SHAPE_POLY_SET buffer;
|
||||
SHAPE_POLY_SET textShape;
|
||||
|
||||
CALLBACK_GAL callback_gal( empty_opts,
|
||||
// Stroke callback
|
||||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
|
||||
{
|
||||
TransformOvalToPolygon( buffer, aPt1, aPt2, penWidth, aMaxError, aErrorLoc );
|
||||
TransformOvalToPolygon( textShape, aPt1, aPt2, penWidth, aMaxError, aErrorLoc );
|
||||
},
|
||||
// Triangulation callback
|
||||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
|
||||
{
|
||||
buffer.NewOutline();
|
||||
textShape.NewOutline();
|
||||
|
||||
for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } )
|
||||
buffer.Append( point.x, point.y );
|
||||
textShape.Append( point.x, point.y );
|
||||
} );
|
||||
|
||||
font->Draw( &callback_gal, GetShownText( true ), GetDrawPos(), GetAttributes(), GetFontMetrics() );
|
||||
if( auto* cache = GetRenderCache( font, shownText ) )
|
||||
callback_gal.DrawGlyphs( *cache );
|
||||
else
|
||||
font->Draw( &callback_gal, shownText, GetDrawPos(), attrs, GetFontMetrics() );
|
||||
|
||||
if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
|
||||
textShape.Simplify();
|
||||
|
||||
if( IsKnockout() )
|
||||
{
|
||||
if( aErrorLoc == ERROR_OUTSIDE )
|
||||
aClearance += aMaxError;
|
||||
SHAPE_POLY_SET finalPoly;
|
||||
|
||||
buffer.Inflate( aClearance, CORNER_STRATEGY::ROUND_ALL_CORNERS, aMaxError, true );
|
||||
TransformShapeToPolygon( finalPoly, GetLayer(), aClearance, aMaxError, aErrorLoc );
|
||||
finalPoly.BooleanSubtract( textShape );
|
||||
|
||||
aBuffer.Append( finalPoly );
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.Simplify();
|
||||
}
|
||||
if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
|
||||
{
|
||||
if( aErrorLoc == ERROR_OUTSIDE )
|
||||
aClearance += aMaxError;
|
||||
|
||||
aBuffer.Append( buffer );
|
||||
textShape.Inflate( aClearance, CORNER_STRATEGY::ROUND_ALL_CORNERS, aMaxError, true );
|
||||
}
|
||||
|
||||
aBuffer.Append( textShape );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -890,6 +903,10 @@ static struct PCB_TEXTBOX_DESC
|
||||
propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Filled" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Color" ) );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, bool, BOARD_ITEM>( _HKI( "Knockout" ),
|
||||
&BOARD_ITEM::SetIsKnockout, &BOARD_ITEM::IsKnockout ),
|
||||
_HKI( "Text Properties" ) );
|
||||
|
||||
const wxString borderProps = _( "Border Properties" );
|
||||
|
||||
void ( PCB_TEXTBOX::*lineStyleSetter )( LINE_STYLE ) = &PCB_TEXTBOX::SetLineStyle;
|
||||
|
@ -729,11 +729,19 @@ void BRDITEMS_PLOTTER::PlotText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, boo
|
||||
|
||||
if( aIsKnockout )
|
||||
{
|
||||
const PCB_TEXT* text = static_cast<const PCB_TEXT*>( aText );
|
||||
SHAPE_POLY_SET finalPoly;
|
||||
|
||||
text->TransformTextToPolySet( finalPoly, 0, m_board->GetDesignSettings().m_MaxError,
|
||||
ERROR_INSIDE );
|
||||
if( const PCB_TEXT* text = dynamic_cast<const PCB_TEXT*>( aText) )
|
||||
{
|
||||
text->TransformTextToPolySet( finalPoly, 0, m_board->GetDesignSettings().m_MaxError,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
else if( const PCB_TEXTBOX* textbox = dynamic_cast<const PCB_TEXTBOX*>( aText ) )
|
||||
{
|
||||
textbox->TransformTextToPolySet( finalPoly, 0, m_board->GetDesignSettings().m_MaxError,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
|
||||
finalPoly.Fracture();
|
||||
|
||||
for( int ii = 0; ii < finalPoly.OutlineCount(); ++ii )
|
||||
|
Loading…
Reference in New Issue
Block a user