Plotting (and some bug fixes) for knockout text.

This commit is contained in:
Jeff Young 2022-03-08 15:52:25 +00:00
parent b6aa5bd1ed
commit 40fd8860fe
7 changed files with 78 additions and 41 deletions

View File

@ -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 );
}
}

View File

@ -204,13 +204,19 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
break;
case PCB_TEXT_T:
itemplotter.PlotPcbText( static_cast<PCB_TEXT*>( item ), item->GetLayer() );
{
PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
itemplotter.PlotPcbText( text, text->GetLayer(), text->IsKnockout() );
break;
}
case PCB_TEXTBOX_T:
itemplotter.PlotPcbText( static_cast<PCB_TEXTBOX*>( item ), item->GetLayer() );
itemplotter.PlotPcbShape( static_cast<PCB_TEXTBOX*>( item ) );
{
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
itemplotter.PlotPcbText( textbox, textbox->GetLayer(), textbox->IsKnockout() );
itemplotter.PlotPcbShape( textbox );
break;
}
case PCB_DIM_ALIGNED_T:
case PCB_DIM_CENTER_T:

View File

@ -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<const FOOTPRINT*>( m_parent );
if( parentFootprint )
buffer.Rotate( -GetDrawRotation(), GetTextPos() );
buffer.Rotate( -GetDrawRotation(), GetTextPos() );
aCornerBuffer.Append( buffer );
}

View File

@ -47,9 +47,11 @@
#include <project/net_settings.h>
#include <settings/color_settings.h>
#include <settings/common_settings.h>
#include <pcbnew_settings.h>
#include <convert_basic_shapes_to_polygon.h>
#include <gal/graphics_abstraction_layer.h>
#include <callback_gal.h>
#include <geometry/geometry_utils.h>
#include <geometry/shape_line_chain.h>
#include <geometry/shape_rect.h>
@ -60,8 +62,6 @@
#include <kiface_base.h>
#include <gr_text.h>
#include <pgm_base.h>
#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 );

View File

@ -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 );
/**

View File

@ -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

View File

@ -37,6 +37,7 @@
#include <math/vector2d.h> // for VECTOR2I
#include <plotters/plotter_gerber.h>
#include <trigo.h>
#include <callback_gal.h>
#include <board_design_settings.h> // for BOARD_DESIGN_SETTINGS
#include <core/typeinfo.h> // 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<const PCB_TEXT*>( item ), item->GetLayer() );
{
const PCB_TEXT* text = static_cast<const PCB_TEXT*>( item );
PlotPcbText( text, text->GetLayer(), text->IsKnockout() );
break;
}
case PCB_TEXTBOX_T:
PlotPcbText( static_cast<const PCB_TEXTBOX*>( item ), item->GetLayer() );
PlotPcbShape( static_cast<const PCB_TEXTBOX*>( item ) );
{
const PCB_TEXTBOX* textbox = static_cast<const PCB_TEXTBOX*>( 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>& 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<VECTOR2I> 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