diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp index e099060cce..214a80889e 100644 --- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp +++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp @@ -91,7 +91,8 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine font->Draw( &callback_gal, aText->GetShownText(), aText->GetDrawPos(), attrs ); SHAPE_POLY_SET finalPoly; - int margin = attrs.m_StrokeWidth * 1.5; + int margin = attrs.m_StrokeWidth * 1.5 + + GetKnockoutTextMargin( attrs.m_Size, attrs.m_StrokeWidth ); aText->TransformBoundingBoxWithClearanceToPolygon( &finalPoly, margin ); finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST ); diff --git a/include/gr_text.h b/include/gr_text.h index 1f37c217e5..f5b956d0aa 100644 --- a/include/gr_text.h +++ b/include/gr_text.h @@ -79,6 +79,19 @@ int GetPenSizeForBold( const wxSize& aTextSize ); int GetPenSizeForNormal( int aTextSize ); int GetPenSizeForNormal( const wxSize& aTextSize ); + +/** + * Returns the margin for knockout text. + * + * Note that this is not a perfect calculation as fonts (especially outline fonts) vary greatly + * in how well ascender and descender heights are enforced. + */ +inline int GetKnockoutTextMargin( const VECTOR2I& aSize, int aThickness ) +{ + return std::max( aThickness, KiROUND( aSize.y / 4.0 ) ); +} + + /** * The full X size is GraphicTextWidth + the thickness of graphic lines. * diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 6518e0d6d3..75730b2746 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -1681,7 +1681,8 @@ void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer ) font->Draw( &callback_gal, resolvedText, aText->GetDrawPos(), attrs ); SHAPE_POLY_SET finalPoly; - int margin = attrs.m_StrokeWidth * 2.5; + int margin = attrs.m_StrokeWidth * 1.5 + + GetKnockoutTextMargin( attrs.m_Size, attrs.m_StrokeWidth ); aText->TransformBoundingBoxWithClearanceToPolygon( &finalPoly, margin ); finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST ); @@ -1835,7 +1836,8 @@ void PCB_PAINTER::draw( const FP_TEXT* aText, int aLayer ) font->Draw( &callback_gal, resolvedText, aText->GetDrawPos(), attrs ); SHAPE_POLY_SET finalPoly; - int margin = attrs.m_StrokeWidth * 1.5; + int margin = attrs.m_StrokeWidth * 1.5 + + GetKnockoutTextMargin( attrs.m_Size, attrs.m_StrokeWidth ); aText->TransformBoundingBoxWithClearanceToPolygon( &finalPoly, margin ); finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST ); diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 366a5763a3..3c8dc21c94 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -825,7 +825,8 @@ void BRDITEMS_PLOTTER::PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, font->Draw( &callback_gal, shownText, aText->GetDrawPos(), attrs ); SHAPE_POLY_SET finalPoly; - int margin = attrs.m_StrokeWidth * 1.5; + int margin = attrs.m_StrokeWidth * 1.5 + + GetKnockoutTextMargin( attrs.m_Size, attrs.m_StrokeWidth ); aText->TransformBoundingBoxWithClearanceToPolygon( &finalPoly, margin ); finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST ); diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index f7998dff7f..e9a1e77fcd 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -521,33 +521,20 @@ void ZONE_FILLER::addHoleKnockout( PAD* aPad, int aGap, SHAPE_POLY_SET& aHoles ) void ZONE_FILLER::addKnockout( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int aGap, bool aIgnoreLineWidth, SHAPE_POLY_SET& aHoles ) { - // Text has a complicated relationship with its boudingBox due to ascenders, descenders, - // diacriticals, etc. Some things want a fairly tight bounding box, and some things don't. - // Since there's no uniformly "correct" answer, we pad the bounding box here to limit - // shorting as much as possible. (Note, however, that it will be caught by DRC either way, - // as it's not reliant on the bounding box.) + EDA_TEXT* text = nullptr; + switch( aItem->Type() ) { - case PCB_TEXT_T: - aGap += static_cast( aItem )->GetTextThickness(); - break; - - case PCB_TEXTBOX_T: - aGap += static_cast( aItem )->GetTextThickness(); - break; - - case PCB_FP_TEXT_T: - aGap += static_cast( aItem )->GetTextThickness(); - break; - - case PCB_FP_TEXTBOX_T: - aGap += static_cast( aItem )->GetTextThickness(); - break; - - default: - break; + case PCB_TEXT_T: text = static_cast( aItem ); break; + case PCB_TEXTBOX_T: text = static_cast( aItem ); break; + case PCB_FP_TEXT_T: text = static_cast( aItem ); break; + case PCB_FP_TEXTBOX_T: text = static_cast( aItem ); break; + default: break; } + if( text ) + aGap += GetKnockoutTextMargin( text->GetTextSize(), text->GetTextThickness() ); + switch( aItem->Type() ) { case PCB_SHAPE_T: @@ -561,17 +548,13 @@ void ZONE_FILLER::addKnockout( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int aGap, break; case PCB_FP_TEXT_T: - { - FP_TEXT* text = static_cast( aItem ); - if( text->IsVisible() ) { - text->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError, - ERROR_OUTSIDE, aIgnoreLineWidth ); + aItem->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError, + ERROR_OUTSIDE, aIgnoreLineWidth ); } break; - } default: break;