From 40fd8860fefce546e6e2fb77600f665e1dc830bd Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Tue, 8 Mar 2022 15:52:25 +0000 Subject: [PATCH] Plotting (and some bug fixes) for knockout text. --- common/eda_text.cpp | 6 +- pcbnew/exporters/gen_drill_report_files.cpp | 12 +++- pcbnew/fp_text.cpp | 8 +-- pcbnew/pcb_painter.cpp | 5 +- pcbnew/pcbplot.h | 5 +- pcbnew/plot_board_layers.cpp | 6 +- pcbnew/plot_brditems_plotter.cpp | 77 +++++++++++++++------ 7 files changed, 78 insertions(+), 41 deletions(-) diff --git a/common/eda_text.cpp b/common/eda_text.cpp index 8da0c7b343..a3c9d86d49 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -964,8 +964,10 @@ void EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( SHAPE_POLY_SET* aCorn for( VECTOR2I& corner : corners ) { - // Rotate polygon - RotatePoint( corner, GetDrawPos(), GetDrawRotation() ); + // Rotate if we're using GetEffectiveTextShape() + if( GetDrawFont()->IsOutline() ) + RotatePoint( corner, GetDrawPos(), GetDrawRotation() ); + aCornerBuffer->Append( corner.x, corner.y ); } } diff --git a/pcbnew/exporters/gen_drill_report_files.cpp b/pcbnew/exporters/gen_drill_report_files.cpp index dbb6a70148..9bce8e269a 100644 --- a/pcbnew/exporters/gen_drill_report_files.cpp +++ b/pcbnew/exporters/gen_drill_report_files.cpp @@ -204,13 +204,19 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_ break; case PCB_TEXT_T: - itemplotter.PlotPcbText( static_cast( item ), item->GetLayer() ); + { + PCB_TEXT* text = static_cast( item ); + itemplotter.PlotPcbText( text, text->GetLayer(), text->IsKnockout() ); break; + } case PCB_TEXTBOX_T: - itemplotter.PlotPcbText( static_cast( item ), item->GetLayer() ); - itemplotter.PlotPcbShape( static_cast( item ) ); + { + PCB_TEXTBOX* textbox = static_cast( item ); + itemplotter.PlotPcbText( textbox, textbox->GetLayer(), textbox->IsKnockout() ); + itemplotter.PlotPcbShape( textbox ); break; + } case PCB_DIM_ALIGNED_T: case PCB_DIM_CENTER_T: diff --git a/pcbnew/fp_text.cpp b/pcbnew/fp_text.cpp index ee581e2f01..afd8fbcd6e 100644 --- a/pcbnew/fp_text.cpp +++ b/pcbnew/fp_text.cpp @@ -481,13 +481,9 @@ void FP_TEXT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffe bool aIgnoreLineWidth ) const { SHAPE_POLY_SET buffer; + EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( &buffer, aClearance ); - - const FOOTPRINT* parentFootprint = static_cast( m_parent ); - - if( parentFootprint ) - buffer.Rotate( -GetDrawRotation(), GetTextPos() ); - + buffer.Rotate( -GetDrawRotation(), GetTextPos() ); aCornerBuffer.Append( buffer ); } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index cc773753b6..4e14347316 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -47,9 +47,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -60,8 +62,6 @@ #include #include #include -#include "pcbnew_settings.h" -#include "callback_gal.h" using namespace KIGFX; @@ -1752,6 +1752,7 @@ void PCB_PAINTER::draw( const FP_TEXT* aText, int aLayer ) int margin = attrs.m_StrokeWidth * 1.5; aText->TransformBoundingBoxWithClearanceToPolygon( &finalPoly, margin ); + finalPoly.Rotate( -aText->GetDrawRotation(), aText->GetTextPos() ); finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST ); finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST ); diff --git a/pcbnew/pcbplot.h b/pcbnew/pcbplot.h index b3729afc30..8f7b525eba 100644 --- a/pcbnew/pcbplot.h +++ b/pcbnew/pcbplot.h @@ -90,8 +90,9 @@ public: void PlotDimension( const PCB_DIMENSION_BASE* aDim ); void PlotPcbTarget( const PCB_TARGET* aMire ); - void PlotFilledAreas( const ZONE* aZone, const SHAPE_POLY_SET& aPolysList ); - void PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer ); + void PlotFilledAreas( const ZONE* aZone, PCB_LAYER_ID aLayer, + const SHAPE_POLY_SET& aPolysList ); + void PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, bool aIsKnockout ); void PlotPcbShape( const PCB_SHAPE* aShape ); /** diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 3a939bc587..c9f88b15e3 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -626,13 +626,13 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask, } } - itemplotter.PlotFilledAreas( zone, mainArea ); + itemplotter.PlotFilledAreas( zone, layer, mainArea ); if( !islands.IsEmpty() ) { ZONE dummy( *zone ); dummy.SetNet( &nonet ); - itemplotter.PlotFilledAreas( &dummy, islands ); + itemplotter.PlotFilledAreas( &dummy, layer, islands ); } } } @@ -973,7 +973,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask, areas.BooleanAdd( initialPolys, SHAPE_POLY_SET::PM_FAST ); areas.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); - itemplotter.PlotFilledAreas( &zone, areas ); + itemplotter.PlotFilledAreas( &zone, layer, areas ); #else // Remove initial shapes: each shape will be added later, as flashed item or region diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 1d8e49eec6..f6ba98f513 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -37,6 +37,7 @@ #include // for VECTOR2I #include #include +#include #include // for BOARD_DESIGN_SETTINGS #include // for dyn_cast, PCB_DIMENSION_T @@ -352,13 +353,19 @@ void BRDITEMS_PLOTTER::PlotPcbGraphicItem( const BOARD_ITEM* item ) break; case PCB_TEXT_T: - PlotPcbText( static_cast( item ), item->GetLayer() ); + { + const PCB_TEXT* text = static_cast( item ); + PlotPcbText( text, text->GetLayer(), text->IsKnockout() ); break; + } case PCB_TEXTBOX_T: - PlotPcbText( static_cast( item ), item->GetLayer() ); - PlotPcbShape( static_cast( item ) ); + { + const PCB_TEXTBOX* textbox = static_cast( item ); + PlotPcbText( textbox, textbox->GetLayer(), textbox->IsKnockout() ); + PlotPcbShape( textbox ); break; + } case PCB_DIM_ALIGNED_T: case PCB_DIM_CENTER_T: @@ -441,7 +448,7 @@ void BRDITEMS_PLOTTER::PlotDimension( const PCB_DIMENSION_BASE* aDim ) // the white items are not seen on a white paper or screen m_plotter->SetColor( color != WHITE ? color : LIGHTGRAY); - PlotPcbText( &aDim->Text(), aDim->GetLayer() ); + PlotPcbText( &aDim->Text(), aDim->GetLayer(), false ); for( const std::shared_ptr& shape : aDim->GetShapes() ) { @@ -559,7 +566,7 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItems( const FOOTPRINT* aFootprint ) if( m_layerMask[ textbox->GetLayer() ] ) { - PlotPcbText( textbox, textbox->GetLayer() ); + PlotPcbText( textbox, textbox->GetLayer(), textbox->IsKnockout() ); PlotFootprintShape( textbox ); } @@ -771,10 +778,11 @@ void BRDITEMS_PLOTTER::PlotFootprintShape( const FP_SHAPE* aShape ) } -void BRDITEMS_PLOTTER::PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer ) +void BRDITEMS_PLOTTER::PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, bool aIsKnockout ) { - wxString shownText( aText->GetShownText() ); - KIFONT::FONT* font = aText->GetDrawFont(); + wxString shownText( aText->GetShownText() ); + KIFONT::FONT* font = aText->GetDrawFont(); + TEXT_ATTRIBUTES attrs = aText->GetAttributes(); if( shownText.IsEmpty() ) return; @@ -792,20 +800,42 @@ void BRDITEMS_PLOTTER::PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer ) VECTOR2I size = aText->GetTextSize(); VECTOR2I pos = aText->GetTextPos(); - int thickness = aText->GetEffectiveTextPenWidth(); + + attrs.m_StrokeWidth = aText->GetEffectiveTextPenWidth(); if( aText->IsMirrored() ) size.x = -size.x; - // Non bold texts thickness is clamped at 1/6 char size by the low level draw function. - // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size - // (like bold text) and we manage the thickness. - // So we set bold flag to true - bool allow_bold = true; + m_plotter->SetCurrentLineWidth( attrs.m_StrokeWidth ); - m_plotter->SetCurrentLineWidth( thickness ); + if( aIsKnockout ) + { + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; + SHAPE_POLY_SET knockouts; - if( aText->IsMultilineAllowed() ) + CALLBACK_GAL callback_gal( empty_opts, + // Polygon callback + [&]( const SHAPE_LINE_CHAIN& aPoly ) + { + knockouts.AddOutline( aPoly ); + } ); + + callback_gal.SetIsFill( font->IsOutline() ); + callback_gal.SetIsStroke( font->IsStroke() ); + font->Draw( &callback_gal, shownText, aText->GetDrawPos(), attrs ); + + SHAPE_POLY_SET finalPoly; + int margin = attrs.m_StrokeWidth * 1.5; + + aText->TransformBoundingBoxWithClearanceToPolygon( &finalPoly, margin ); + finalPoly.Rotate( -aText->GetDrawRotation(), aText->GetTextPos() ); + finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST ); + finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST ); + + for( int ii = 0; ii < finalPoly.OutlineCount(); ++ii ) + m_plotter->PlotPoly( finalPoly.Outline( ii ), FILL_T::FILLED_SHAPE, 0, &gbr_metadata ); + } + else if( aText->IsMultilineAllowed() ) { std::vector positions; wxArrayString strings_list; @@ -818,20 +848,21 @@ void BRDITEMS_PLOTTER::PlotPcbText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer ) { wxString& txt = strings_list.Item( ii ); m_plotter->Text( positions[ii], color, txt, aText->GetDrawRotation(), size, - aText->GetHorizJustify(), aText->GetVertJustify(), thickness, - aText->IsItalic(), allow_bold, false, font, &gbr_metadata ); + attrs.m_Halign, attrs.m_Valign, attrs.m_StrokeWidth, attrs.m_Italic, + attrs.m_Bold, false, font, &gbr_metadata ); } } else { - m_plotter->Text( pos, color, shownText, aText->GetDrawRotation(), size, - aText->GetHorizJustify(), aText->GetVertJustify(), thickness, - aText->IsItalic(), allow_bold, false, font, &gbr_metadata ); + m_plotter->Text( pos, color, shownText, aText->GetDrawRotation(), size, attrs.m_Halign, + attrs.m_Valign, attrs.m_StrokeWidth, attrs.m_Italic, attrs.m_Bold, false, + font, &gbr_metadata ); } } -void BRDITEMS_PLOTTER::PlotFilledAreas( const ZONE* aZone, const SHAPE_POLY_SET& polysList ) +void BRDITEMS_PLOTTER::PlotFilledAreas( const ZONE* aZone, PCB_LAYER_ID aLayer, + const SHAPE_POLY_SET& polysList ) { if( polysList.IsEmpty() ) return; @@ -860,7 +891,7 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( const ZONE* aZone, const SHAPE_POLY_SET& } } - m_plotter->SetColor( getColor( aZone->GetLayer() ) ); + m_plotter->SetColor( getColor( aLayer ) ); m_plotter->StartBlock( nullptr ); // Clean current object attributes