KiCad PCB EDA Suite
KIGFX::PCB_PAINTER Class Reference

Contains methods for drawing PCB-specific items. More...

#include <pcb_painter.h>

Inheritance diagram for KIGFX::PCB_PAINTER:
KIGFX::PAINTER KIGFX::PCB_PRINT_PAINTER

Public Member Functions

 PCB_PAINTER (GAL *aGal, FRAME_T aFrameType)
 
virtual PCB_RENDER_SETTINGSGetSettings () override
 Return a pointer to current settings that are going to be used when drawing items. More...
 
virtual bool Draw (const VIEW_ITEM *aItem, int aLayer) override
 Takes an instance of VIEW_ITEM and passes it to a function that knows how to draw the item. More...
 
void SetGAL (GAL *aGal)
 Changes Graphics Abstraction Layer used for drawing items for a new one. More...
 

Protected Member Functions

PCB_VIEWERS_SETTINGS_BASEviewer_settings ()
 
void draw (const PCB_TRACK *aTrack, int aLayer)
 
void draw (const PCB_ARC *aArc, int aLayer)
 
void draw (const PCB_VIA *aVia, int aLayer)
 
void draw (const PAD *aPad, int aLayer)
 
void draw (const PCB_SHAPE *aSegment, int aLayer)
 
void draw (const PCB_BITMAP *aBitmap, int aLayer)
 
void draw (const PCB_TEXT *aText, int aLayer)
 
void draw (const PCB_TEXTBOX *aText, int aLayer)
 
void draw (const FP_TEXT *aText, int aLayer)
 
void draw (const FP_TEXTBOX *aText, int aLayer)
 
void draw (const FOOTPRINT *aFootprint, int aLayer)
 
void draw (const PCB_GROUP *aGroup, int aLayer)
 
void draw (const ZONE *aZone, int aLayer)
 
void draw (const PCB_DIMENSION_BASE *aDimension, int aLayer)
 
void draw (const PCB_TARGET *aTarget)
 
void draw (const PCB_MARKER *aMarker, int aLayer)
 
int getLineThickness (int aActualThickness) const
 Get the thickness to draw for a line (e.g. More...
 
virtual int getDrillShape (const PAD *aPad) const
 Return drill shape of a pad. More...
 
virtual SHAPE_SEGMENT getPadHoleShape (const PAD *aPad) const
 Return hole shape for a pad (internal units). More...
 
virtual int getViaDrillSize (const PCB_VIA *aVia) const
 Return drill diameter for a via (internal units). More...
 
void strokeText (const wxString &aText, const VECTOR2I &aPosition, const TEXT_ATTRIBUTES &aAttrs)
 

Protected Attributes

PCB_RENDER_SETTINGS m_pcbSettings
 
FRAME_T m_frameType
 
int m_maxError
 
int m_holePlatingThickness
 
int m_lockedShadowMargin
 
GALm_gal
 Instance of graphic abstraction layer that gives an interface to call commands used to draw (eg. More...
 

Detailed Description

Contains methods for drawing PCB-specific items.

Definition at line 157 of file pcb_painter.h.

Constructor & Destructor Documentation

◆ PCB_PAINTER()

PCB_PAINTER::PCB_PAINTER ( GAL aGal,
FRAME_T  aFrameType 
)

Definition at line 448 of file pcb_painter.cpp.

448 :
449 PAINTER( aGal ),
450 m_frameType( aFrameType ),
454{
455}
constexpr int ARC_HIGH_DEF
Definition: base_units.h:121
PAINTER(GAL *aGal)
Initialize this object for painting on any of the polymorphic GRAPHICS_ABSTRACTION_LAYER* derivatives...
Definition: painter.cpp:32

Member Function Documentation

◆ draw() [1/16]

void PCB_PAINTER::draw ( const FOOTPRINT aFootprint,
int  aLayer 
)
protected

Definition at line 2261 of file pcb_painter.cpp.

2262{
2263 if( aLayer == LAYER_ANCHOR )
2264 {
2265 const COLOR4D color = m_pcbSettings.GetColor( aFootprint, aLayer );
2266
2267 // Keep the size and width constant, not related to the scale because the anchor
2268 // is just a marker on screen
2269 double anchorSize = 5.0 / m_gal->GetWorldScale(); // 5 pixels size
2270 double anchorThickness = 1.0 / m_gal->GetWorldScale(); // 1 pixels width
2271
2272 // Draw anchor
2273 m_gal->SetIsFill( false );
2274 m_gal->SetIsStroke( true );
2276 m_gal->SetLineWidth( anchorThickness );
2277
2278 VECTOR2D center = aFootprint->GetPosition();
2279 m_gal->DrawLine( center - VECTOR2D( anchorSize, 0 ), center + VECTOR2D( anchorSize, 0 ) );
2280 m_gal->DrawLine( center - VECTOR2D( 0, anchorSize ), center + VECTOR2D( 0, anchorSize ) );
2281 }
2282
2283 if( aLayer == LAYER_LOCKED_ITEM_SHADOW && m_frameType == FRAME_PCB_EDITOR ) // happens only if locked
2284 {
2285 const COLOR4D color = m_pcbSettings.GetColor( aFootprint, aLayer );
2286
2287 m_gal->SetIsFill( true );
2288 m_gal->SetIsStroke( false );
2290
2291#if 0 // GetBoundingHull() can be very slow, especially for logos imported from graphics
2292 const SHAPE_POLY_SET& poly = aFootprint->GetBoundingHull();
2293 m_gal->DrawPolygon( poly );
2294#else
2295 BOX2I bbox = aFootprint->GetBoundingBox( false, false );
2296 VECTOR2I topLeft = bbox.GetPosition();
2297 VECTOR2I botRight = bbox.GetPosition() + bbox.GetSize();
2298
2299 m_gal->DrawRectangle( topLeft, botRight );
2300
2301 // Use segments to produce a margin with rounded corners
2302 m_gal->DrawSegment( topLeft, VECTOR2I( botRight.x, topLeft.y ), m_lockedShadowMargin );
2303 m_gal->DrawSegment( VECTOR2I( botRight.x, topLeft.y ), botRight, m_lockedShadowMargin );
2304 m_gal->DrawSegment( botRight, VECTOR2I( topLeft.x, botRight.y ), m_lockedShadowMargin );
2305 m_gal->DrawSegment( VECTOR2I( topLeft.x, botRight.y ), topLeft, m_lockedShadowMargin );
2306#endif
2307 }
2308
2309 if( aLayer == LAYER_CONFLICTS_SHADOW )
2310 {
2311 const SHAPE_POLY_SET& frontpoly = aFootprint->GetCourtyard( F_CrtYd );
2312 const SHAPE_POLY_SET& backpoly = aFootprint->GetCourtyard( B_CrtYd );
2313
2314 const COLOR4D color = m_pcbSettings.GetColor( aFootprint, aLayer );
2315
2316 m_gal->SetIsFill( true );
2317 m_gal->SetIsStroke( false );
2319
2320 if( frontpoly.OutlineCount() > 0 )
2321 m_gal->DrawPolygon( frontpoly );
2322
2323 if( backpoly.OutlineCount() > 0 )
2324 m_gal->DrawPolygon( backpoly );
2325 }
2326}
int color
Definition: DXF_plotter.cpp:57
const Vec & GetPosition() const
Definition: box2.h:184
const Vec & GetSize() const
Definition: box2.h:179
SHAPE_POLY_SET GetBoundingHull() const
Return a bounding polygon for the shapes and pads in the footprint.
Definition: footprint.cpp:935
const SHAPE_POLY_SET & GetCourtyard(PCB_LAYER_ID aLayer) const
Used in DRC to test the courtyard area (a complex polygon).
Definition: footprint.cpp:2215
VECTOR2I GetPosition() const override
Definition: footprint.h:188
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: footprint.cpp:804
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
virtual void DrawPolygon(const std::deque< VECTOR2D > &aPointList)
Draw a polygon.
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
virtual void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a rectangle.
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
virtual void DrawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth)
Draw a rounded segment.
double GetWorldScale() const
Get the world scale.
GAL * m_gal
Instance of graphic abstraction layer that gives an interface to call commands used to draw (eg.
Definition: painter.h:101
PCB_RENDER_SETTINGS m_pcbSettings
Definition: pcb_painter.h:219
COLOR4D GetColor(const VIEW_ITEM *aItem, int aLayer) const override
Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer using curr...
Represent a set of closed polygons.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
@ FRAME_PCB_EDITOR
Definition: frame_type.h:40
@ LAYER_LOCKED_ITEM_SHADOW
shadow layer for locked items
Definition: layer_ids.h:239
@ LAYER_CONFLICTS_SHADOW
shadow layer for items flagged conficting
Definition: layer_ids.h:241
@ LAYER_ANCHOR
anchor of items having an anchor point (texts, footprints)
Definition: layer_ids.h:201
@ F_CrtYd
Definition: layer_ids.h:117
@ B_CrtYd
Definition: layer_ids.h:116
VECTOR2< double > VECTOR2D
Definition: vector2d.h:617
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References B_CrtYd, color, KIGFX::GAL::DrawLine(), KIGFX::GAL::DrawPolygon(), KIGFX::GAL::DrawRectangle(), KIGFX::GAL::DrawSegment(), F_CrtYd, FRAME_PCB_EDITOR, FOOTPRINT::GetBoundingBox(), FOOTPRINT::GetBoundingHull(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), FOOTPRINT::GetCourtyard(), BOX2< Vec >::GetPosition(), FOOTPRINT::GetPosition(), BOX2< Vec >::GetSize(), KIGFX::GAL::GetWorldScale(), LAYER_ANCHOR, LAYER_CONFLICTS_SHADOW, LAYER_LOCKED_ITEM_SHADOW, m_frameType, KIGFX::PAINTER::m_gal, m_lockedShadowMargin, m_pcbSettings, SHAPE_POLY_SET::OutlineCount(), KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ draw() [2/16]

void PCB_PAINTER::draw ( const FP_TEXT aText,
int  aLayer 
)
protected

Definition at line 2108 of file pcb_painter.cpp.

2109{
2110 wxString resolvedText( aText->GetShownText() );
2111
2112 if( resolvedText.Length() == 0 )
2113 return;
2114
2115 const COLOR4D& color = m_pcbSettings.GetColor( aText, aLayer );
2116 bool outline_mode = !viewer_settings()->m_ViewersDisplay.m_DisplayTextFill;
2117 TEXT_ATTRIBUTES attrs = aText->GetAttributes();
2118
2119 KIFONT::FONT* font = aText->GetFont();
2120
2121 if( !font )
2122 {
2124 aText->IsItalic() );
2125 }
2126
2129 attrs.m_Angle = aText->GetDrawRotation();
2130
2131 if( aText->IsKnockout() )
2132 {
2133 KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
2134 SHAPE_POLY_SET knockouts;
2135
2136 CALLBACK_GAL callback_gal( empty_opts,
2137 // Polygon callback
2138 [&]( const SHAPE_LINE_CHAIN& aPoly )
2139 {
2140 knockouts.AddOutline( aPoly );
2141 } );
2142
2144
2145 callback_gal.SetIsFill( font->IsOutline() );
2146 callback_gal.SetIsStroke( font->IsStroke() );
2147 callback_gal.SetLineWidth( attrs.m_StrokeWidth );
2148 font->Draw( &callback_gal, resolvedText, aText->GetDrawPos(), attrs );
2149
2150 SHAPE_POLY_SET finalPoly;
2151 int margin = attrs.m_StrokeWidth * 1.5
2152 + GetKnockoutTextMargin( attrs.m_Size, attrs.m_StrokeWidth );
2153
2154 aText->TransformBoundingBoxToPolygon( &finalPoly, margin );
2155 finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST );
2156 finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
2157
2158 m_gal->SetIsStroke( false );
2159 m_gal->SetIsFill( true );
2160 m_gal->DrawPolygon( finalPoly );
2161 }
2162 else
2163 {
2164 if( outline_mode )
2166 else
2168
2169 if( m_gal->IsFlippedX() && !( aText->GetLayerSet() & LSET::SideSpecificMask() ).any() )
2170 {
2171 attrs.m_Mirrored = !attrs.m_Mirrored;
2172 attrs.m_Halign = static_cast<GR_TEXT_H_ALIGN_T>( -attrs.m_Halign );
2173 }
2174
2175 std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
2176
2177 if( font->IsOutline() )
2178 cache = aText->GetRenderCache( font, resolvedText );
2179
2180 if( cache )
2181 m_gal->DrawGlyphs( *cache );
2182 else
2183 strokeText( resolvedText, aText->GetTextPos(), attrs );
2184 }
2185
2186 // Draw the umbilical line
2187 if( aText->IsSelected() )
2188 {
2191 m_gal->DrawLine( aText->GetTextPos(), aText->GetParent()->GetPosition() );
2192 }
2193}
virtual bool IsKnockout() const
Definition: board_item.h:250
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:185
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:163
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:249
bool IsSelected() const
Definition: eda_item.h:106
void TransformBoundingBoxToPolygon(SHAPE_POLY_SET *aBuffer, int aClearance) const
Convert the text bounding box to a rectangular polygon depending on the text orientation,...
Definition: eda_text.cpp:945
const VECTOR2I & GetTextPos() const
Definition: eda_text.h:208
bool IsItalic() const
Definition: eda_text.h:130
KIFONT::FONT * GetFont() const
Definition: eda_text.h:188
std::vector< std::unique_ptr< KIFONT::GLYPH > > * GetRenderCache(const KIFONT::FONT *aFont, const wxString &forResolvedText, const VECTOR2I &aOffset={ 0, 0 }) const
Definition: eda_text.cpp:451
virtual VECTOR2I GetDrawPos() const
Definition: eda_text.h:318
const TEXT_ATTRIBUTES & GetAttributes() const
Definition: eda_text.h:172
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition: eda_text.cpp:297
bool IsBold() const
Definition: eda_text.h:133
virtual EDA_ANGLE GetDrawRotation() const override
Definition: fp_text.cpp:247
virtual wxString GetShownText(int aDepth=0, bool aAllowExtraText=true) const override
Return the string actually shown after processing of the base text.
Definition: fp_text.cpp:415
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:105
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:65
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttrs) const
Draw a string.
Definition: font.cpp:159
virtual bool IsStroke() const
Definition: font.h:112
virtual bool IsOutline() const
Definition: font.h:113
virtual void DrawGlyphs(const std::vector< std::unique_ptr< KIFONT::GLYPH > > &aGlyphs)
Draw polygons representing font glyphs.
int getLineThickness(int aActualThickness) const
Get the thickness to draw for a line (e.g.
PCB_VIEWERS_SETTINGS_BASE * viewer_settings()
Definition: pcb_painter.cpp:80
void strokeText(const wxString &aText, const VECTOR2I &aPosition, const TEXT_ATTRIBUTES &aAttrs)
const wxString & GetDefaultFont() const
static LSET SideSpecificMask()
Definition: lset.cpp:908
VIEWERS_DISPLAY_OPTIONS m_ViewersDisplay
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset intersection For aFastMode meaning, see function booleanOp.
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
GR_TEXT_H_ALIGN_T m_Halign
int GetKnockoutTextMargin(const VECTOR2I &aSize, int aThickness)
Returns the margin for knocking out text.
Definition: gr_text.h:97
GR_TEXT_H_ALIGN_T

References SHAPE_POLY_SET::AddOutline(), SHAPE_POLY_SET::BooleanSubtract(), color, KIFONT::FONT::Draw(), KIGFX::GAL::DrawGlyphs(), KIGFX::GAL::DrawLine(), KIGFX::GAL::DrawPolygon(), SHAPE_POLY_SET::Fracture(), EDA_TEXT::GetAttributes(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), KIGFX::RENDER_SETTINGS::GetDefaultFont(), EDA_TEXT::GetDrawPos(), FP_TEXT::GetDrawRotation(), EDA_TEXT::GetEffectiveTextPenWidth(), EDA_TEXT::GetFont(), KIFONT::FONT::GetFont(), GetKnockoutTextMargin(), BOARD_ITEM::GetLayerSet(), getLineThickness(), BOARD_ITEM::GetParent(), EDA_ITEM::GetPosition(), EDA_TEXT::GetRenderCache(), FP_TEXT::GetShownText(), EDA_TEXT::GetTextPos(), EDA_TEXT::IsBold(), KIGFX::GAL::IsFlippedX(), EDA_TEXT::IsItalic(), BOARD_ITEM::IsKnockout(), KIFONT::FONT::IsOutline(), EDA_ITEM::IsSelected(), KIFONT::FONT::IsStroke(), LAYER_ANCHOR, TEXT_ATTRIBUTES::m_Angle, PCB_VIEWERS_SETTINGS_BASE::VIEWERS_DISPLAY_OPTIONS::m_DisplayTextFill, KIGFX::PAINTER::m_gal, TEXT_ATTRIBUTES::m_Halign, TEXT_ATTRIBUTES::m_Mirrored, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, TEXT_ATTRIBUTES::m_Size, TEXT_ATTRIBUTES::m_StrokeWidth, PCB_VIEWERS_SETTINGS_BASE::m_ViewersDisplay, SHAPE_POLY_SET::PM_FAST, KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), LSET::SideSpecificMask(), strokeText(), EDA_TEXT::TransformBoundingBoxToPolygon(), and viewer_settings().

◆ draw() [3/16]

void PCB_PAINTER::draw ( const FP_TEXTBOX aText,
int  aLayer 
)
protected

Definition at line 2196 of file pcb_painter.cpp.

2197{
2198 const COLOR4D& color = m_pcbSettings.GetColor( aTextBox, aTextBox->GetLayer() );
2199 int thickness = getLineThickness( aTextBox->GetWidth() );
2200 PLOT_DASH_TYPE lineStyle = aTextBox->GetStroke().GetPlotStyle();
2201
2204 m_gal->SetIsFill( true );
2205 m_gal->SetIsStroke( false );
2206
2207 if( thickness > 0 )
2208 {
2209 if( lineStyle <= PLOT_DASH_TYPE::FIRST_TYPE )
2210 {
2211 std::vector<VECTOR2I> pts = aTextBox->GetCorners();
2212
2213 for( size_t ii = 0; ii < pts.size(); ++ii )
2214 m_gal->DrawSegment( pts[ ii ], pts[ (ii + 1) % pts.size() ], thickness );
2215 }
2216 else
2217 {
2218 std::vector<SHAPE*> shapes = aTextBox->MakeEffectiveShapes( true );
2219
2220 for( SHAPE* shape : shapes )
2221 {
2222 STROKE_PARAMS::Stroke( shape, lineStyle, thickness, &m_pcbSettings,
2223 [&]( const VECTOR2I& a, const VECTOR2I& b )
2224 {
2225 m_gal->DrawSegment( a, b, thickness );
2226 } );
2227 }
2228
2229 for( SHAPE* shape : shapes )
2230 delete shape;
2231 }
2232 }
2233
2234 wxString resolvedText( aTextBox->GetShownText() );
2235
2236 if( resolvedText.Length() == 0 )
2237 return;
2238
2239 TEXT_ATTRIBUTES attrs = aTextBox->GetAttributes();
2240 attrs.m_Angle = aTextBox->GetDrawRotation();
2241 attrs.m_StrokeWidth = getLineThickness( aTextBox->GetEffectiveTextPenWidth() );
2242
2243 if( m_gal->IsFlippedX() && !( aTextBox->GetLayerSet() & LSET::SideSpecificMask() ).any() )
2244 {
2245 attrs.m_Mirrored = !attrs.m_Mirrored;
2246 attrs.m_Halign = static_cast<GR_TEXT_H_ALIGN_T>( -attrs.m_Halign );
2247 }
2248
2249 std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
2250
2251 if( aTextBox->GetFont() && aTextBox->GetFont()->IsOutline() )
2252 cache = aTextBox->GetRenderCache( aTextBox->GetFont(), resolvedText );
2253
2254 if( cache )
2255 m_gal->DrawGlyphs( *cache );
2256 else
2257 strokeText( resolvedText, aTextBox->GetDrawPos(), attrs );
2258}
An abstract shape on 2D plane.
Definition: shape.h:123
static void Stroke(const SHAPE *aShape, PLOT_DASH_TYPE aLineStyle, int aWidth, const KIGFX::RENDER_SETTINGS *aRenderSettings, std::function< void(const VECTOR2I &a, const VECTOR2I &b)> aStroker)
PLOT_DASH_TYPE
Dashed line types.
Definition: stroke_params.h:48

References color, KIGFX::GAL::DrawGlyphs(), KIGFX::GAL::DrawSegment(), FIRST_TYPE, EDA_TEXT::GetAttributes(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), PCB_SHAPE::GetCorners(), FP_TEXTBOX::GetDrawPos(), FP_TEXTBOX::GetDrawRotation(), EDA_TEXT::GetEffectiveTextPenWidth(), EDA_TEXT::GetFont(), BOARD_ITEM::GetLayer(), BOARD_ITEM::GetLayerSet(), getLineThickness(), STROKE_PARAMS::GetPlotStyle(), EDA_TEXT::GetRenderCache(), FP_TEXTBOX::GetShownText(), PCB_SHAPE::GetStroke(), EDA_SHAPE::GetWidth(), KIGFX::GAL::IsFlippedX(), KIFONT::FONT::IsOutline(), TEXT_ATTRIBUTES::m_Angle, KIGFX::PAINTER::m_gal, TEXT_ATTRIBUTES::m_Halign, TEXT_ATTRIBUTES::m_Mirrored, m_pcbSettings, TEXT_ATTRIBUTES::m_StrokeWidth, EDA_SHAPE::MakeEffectiveShapes(), KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetStrokeColor(), LSET::SideSpecificMask(), STROKE_PARAMS::Stroke(), and strokeText().

◆ draw() [4/16]

void PCB_PAINTER::draw ( const PAD aPad,
int  aLayer 
)
protected

Definition at line 1075 of file pcb_painter.cpp.

1076{
1077 const BOARD* board = aPad->GetBoard();
1078 COLOR4D color = m_pcbSettings.GetColor( aPad, aLayer );
1079
1080 if( IsNetnameLayer( aLayer ) )
1081 {
1082 PCBNEW_SETTINGS::DISPLAY_OPTIONS* displayOpts = pcbconfig() ? &pcbconfig()->m_Display : nullptr;
1083 wxString netname;
1084 wxString padNumber;
1085
1086 if( viewer_settings()->m_ViewersDisplay.m_DisplayPadNumbers )
1087 {
1088 padNumber = UnescapeString( aPad->GetNumber() );
1089
1090 if( dynamic_cast<CVPCB_SETTINGS*>( viewer_settings() ) )
1091 netname = aPad->GetUnescapedShortNetname();
1092 }
1093
1094 if( displayOpts )
1095 {
1096 if( displayOpts->m_NetNames == 1 || displayOpts->m_NetNames == 3 )
1097 netname = aPad->GetUnescapedShortNetname();
1098
1099 if( aPad->IsNoConnectPad() )
1100 netname = wxT( "x" );
1101 else if( aPad->IsFreePad() )
1102 netname = wxT( "*" );
1103 }
1104
1105 if( netname.IsEmpty() && padNumber.IsEmpty() )
1106 return;
1107
1108 BOX2I padBBox = aPad->GetBoundingBox();
1109 VECTOR2D position = padBBox.Centre();
1110 VECTOR2D padsize = VECTOR2D( padBBox.GetSize() );
1111
1112 if( aPad->GetFlags() & ENTERED )
1113 {
1114 FOOTPRINT* fp = static_cast<FOOTPRINT*>( aPad->GetParentFootprint() );
1115
1116 // Find the number box
1117 for( const BOARD_ITEM* aItem : fp->GraphicalItems() )
1118 {
1119 if( aItem->Type() == PCB_FP_SHAPE_T )
1120 {
1121 const FP_SHAPE* shape = static_cast<const FP_SHAPE*>( aItem );
1122
1123 if( shape->IsAnnotationProxy() )
1124 {
1125 position = shape->GetCenter();
1126 padsize = shape->GetBotRight() - shape->GetTopLeft();
1127
1128 // We normally draw a bit outside the pad, but this will be somewhat
1129 // unexpected when the user has drawn a box.
1130 padsize *= 0.9;
1131
1132 break;
1133 }
1134 }
1135 }
1136 }
1137 else if( aPad->GetShape() == PAD_SHAPE::CUSTOM )
1138 {
1139 // See if we have a number box
1140 for( const std::shared_ptr<PCB_SHAPE>& primitive : aPad->GetPrimitives() )
1141 {
1142 if( primitive->IsAnnotationProxy() )
1143 {
1144 position = aPad->GetPosition() + primitive->GetCenter();
1145 padsize.x = abs( primitive->GetBotRight().x - primitive->GetTopLeft().x );
1146 padsize.y = abs( primitive->GetBotRight().y - primitive->GetTopLeft().y );
1147
1148 // We normally draw a bit outside the pad, but this will be somewhat
1149 // unexpected when the user has drawn a box.
1150 padsize *= 0.9;
1151
1152 break;
1153 }
1154 }
1155 }
1156
1157 if( aPad->GetShape() != PAD_SHAPE::CUSTOM )
1158 {
1159 // Don't allow a 45° rotation to bloat a pad's bounding box unnecessarily
1160 double limit = std::min( aPad->GetSize().x, aPad->GetSize().y ) * 1.1;
1161
1162 if( padsize.x > limit && padsize.y > limit )
1163 {
1164 padsize.x = limit;
1165 padsize.y = limit;
1166 }
1167 }
1168
1169 double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
1170 double size = padsize.y;
1171
1172 m_gal->Save();
1173 m_gal->Translate( position );
1174
1175 // Keep the size ratio for the font, but make it smaller
1176 if( padsize.x < ( padsize.y * 0.95 ) )
1177 {
1179 size = padsize.x;
1180 std::swap( padsize.x, padsize.y );
1181 }
1182
1183 // Font size limits
1184 if( size > maxSize )
1185 size = maxSize;
1186
1187 // Default font settings
1191 m_gal->SetFontBold( false );
1192 m_gal->SetFontItalic( false );
1193 m_gal->SetFontUnderlined( false );
1194 m_gal->SetTextMirrored( false );
1195 m_gal->SetStrokeColor( m_pcbSettings.GetColor( aPad, aLayer ) );
1196 m_gal->SetIsStroke( true );
1197 m_gal->SetIsFill( false );
1198
1199 // We have already translated the GAL to be centered at the center of the pad's
1200 // bounding box
1201 VECTOR2I textpos( 0, 0 );
1202
1203 // Divide the space, to display both pad numbers and netnames and set the Y text
1204 // position to display 2 lines
1205 if( !netname.IsEmpty() && !padNumber.IsEmpty() )
1206 {
1207 size = size / 2.2;
1208 textpos.y = size / 1.7;
1209 }
1210
1211 if( !netname.IsEmpty() )
1212 {
1213 // approximate the size of net name text:
1214 double tsize = 1.5 * padsize.x / std::max( PrintableCharCount( netname ), 1 );
1215 tsize = std::min( tsize, size );
1216
1217 // Use a smaller text size to handle interline, pen size...
1218 tsize *= 0.85;
1219 VECTOR2D namesize( tsize, tsize );
1220
1221 m_gal->SetGlyphSize( namesize );
1222 m_gal->SetLineWidth( namesize.x / 6.0 );
1223 m_gal->SetFontBold( true );
1224 m_gal->BitmapText( netname, textpos, ANGLE_HORIZONTAL );
1225 }
1226
1227 if( !padNumber.IsEmpty() )
1228 {
1229 textpos.y = -textpos.y;
1230
1231 // approximate the size of the pad number text:
1232 double tsize = 1.5 * padsize.x / std::max( PrintableCharCount( padNumber ), 1 );
1233 tsize = std::min( tsize, size );
1234
1235 // Use a smaller text size to handle interline, pen size...
1236 tsize *= 0.85;
1237 tsize = std::min( tsize, size );
1238 VECTOR2D numsize( tsize, tsize );
1239
1240 m_gal->SetGlyphSize( numsize );
1241 m_gal->SetLineWidth( numsize.x / 6.0 );
1242 m_gal->SetFontBold( true );
1243 m_gal->BitmapText( padNumber, textpos, ANGLE_HORIZONTAL );
1244 }
1245
1246 m_gal->Restore();
1247
1248 return;
1249 }
1250 else if( aLayer == LAYER_PAD_HOLEWALLS )
1251 {
1252 m_gal->SetIsFill( false );
1253 m_gal->SetIsStroke( true );
1256
1257 std::shared_ptr<SHAPE_SEGMENT> slot = aPad->GetEffectiveHoleShape();
1258 int holeSize = slot->GetWidth() + m_holePlatingThickness;
1259
1260 if( slot->GetSeg().A == slot->GetSeg().B ) // Circular hole
1261 m_gal->DrawCircle( slot->GetSeg().A, KiROUND( holeSize / 2.0 ) );
1262 else
1263 m_gal->DrawSegment( slot->GetSeg().A, slot->GetSeg().B, holeSize );
1264
1265 return;
1266 }
1267
1268 bool outline_mode = !viewer_settings()->m_ViewersDisplay.m_DisplayPadFill;
1269
1271 outline_mode = true;
1272
1273 if( outline_mode )
1274 {
1275 // Outline mode
1276 m_gal->SetIsFill( false );
1277 m_gal->SetIsStroke( true );
1280 }
1281 else
1282 {
1283 // Filled mode
1284 m_gal->SetIsFill( true );
1285 m_gal->SetIsStroke( false );
1287 }
1288
1289 bool drawShape = false;
1290
1291 if( aLayer == LAYER_PAD_PLATEDHOLES || aLayer == LAYER_NON_PLATEDHOLES )
1292 {
1293 SHAPE_SEGMENT slot = getPadHoleShape( aPad );
1294
1295 if( slot.GetSeg().A == slot.GetSeg().B ) // Circular hole
1296 m_gal->DrawCircle( slot.GetSeg().A, slot.GetWidth() / 2.0 );
1297 else
1298 m_gal->DrawSegment( slot.GetSeg().A, slot.GetSeg().B, slot.GetWidth() );
1299 }
1300 else if( m_pcbSettings.IsPrinting() )
1301 {
1302 drawShape = aPad->FlashLayer( m_pcbSettings.GetPrintLayers() );
1303 }
1304 else if( aPad->FlashLayer( board->GetVisibleLayers() & board->GetEnabledLayers() ) )
1305 {
1306 drawShape = true;
1307 }
1308 else if( aPad->IsSelected() )
1309 {
1310 drawShape = true;
1311 outline_mode = true;
1312 }
1313
1314 if( outline_mode )
1315 {
1316 // Outline mode
1317 m_gal->SetIsFill( false );
1318 m_gal->SetIsStroke( true );
1321 }
1322
1323 if( drawShape )
1324 {
1325 VECTOR2I pad_size = aPad->GetSize();
1326 VECTOR2I margin;
1327
1328 switch( aLayer )
1329 {
1330 case F_Mask:
1331 case B_Mask:
1332 margin.x = margin.y = aPad->GetSolderMaskExpansion();
1333 break;
1334
1335 case F_Paste:
1336 case B_Paste:
1337 margin = aPad->GetSolderPasteMargin();
1338 break;
1339
1340 default:
1341 margin.x = margin.y = 0;
1342 break;
1343 }
1344
1345 std::unique_ptr<PAD> dummyPad;
1346 std::shared_ptr<SHAPE_COMPOUND> shapes;
1347
1348 // Drawing components of compound shapes in outline mode produces a mess.
1349 bool simpleShapes = !outline_mode;
1350
1351 if( simpleShapes )
1352 {
1353 if( ( margin.x != margin.y && aPad->GetShape() != PAD_SHAPE::CUSTOM )
1354 || ( aPad->GetShape() == PAD_SHAPE::ROUNDRECT && ( margin.x < 0 || margin.y < 0 ) ) )
1355 {
1356 // Our algorithms below (polygon inflation in particular) can't handle differential
1357 // inflation along separate axes. So for those cases we build a dummy pad instead,
1358 // and inflate it.
1359
1360 // Margin is added to both sides. If the total margin is larger than the pad
1361 // then don't display this layer
1362 if( pad_size.x + 2 * margin.x <= 0 || pad_size.y + 2 * margin.y <= 0 )
1363 return;
1364
1365 dummyPad.reset( static_cast<PAD*>( aPad->Duplicate() ) );
1366
1367 if( dummyPad->GetParentGroup() )
1368 dummyPad->GetParentGroup()->RemoveItem( dummyPad.get() );
1369
1370 int initial_radius = dummyPad->GetRoundRectCornerRadius();
1371
1372 dummyPad->SetSize( pad_size + margin + margin );
1373
1374 if( dummyPad->GetShape() == PAD_SHAPE::ROUNDRECT )
1375 {
1376 // To keep the right margin around the corners, we need to modify the corner radius.
1377 // We must have only one radius correction, so use the smallest absolute margin.
1378 int radius_margin = std::max( margin.x, margin.y ); // radius_margin is < 0
1379 dummyPad->SetRoundRectCornerRadius( std::max( initial_radius + radius_margin, 0 ) );
1380 }
1381
1382 shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( dummyPad->GetEffectiveShape() );
1383 margin.x = margin.y = 0;
1384 }
1385 else
1386 {
1387 shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
1388 }
1389
1390 if( aPad->GetShape() == PAD_SHAPE::CUSTOM && ( margin.x || margin.y ) )
1391 {
1392 // We can't draw as shapes because we don't know which edges are internal and which
1393 // are external (so we don't know when to apply the margin and when not to).
1394 simpleShapes = false;
1395 }
1396
1397 for( const SHAPE* shape : shapes->Shapes() )
1398 {
1399 if( !simpleShapes )
1400 break;
1401
1402 switch( shape->Type() )
1403 {
1404 case SH_SEGMENT:
1405 case SH_CIRCLE:
1406 case SH_RECT:
1407 case SH_SIMPLE:
1408 // OK so far
1409 break;
1410
1411 default:
1412 // Not OK
1413 simpleShapes = false;
1414 break;
1415 }
1416 }
1417 }
1418
1419 if( simpleShapes )
1420 {
1421 for( const SHAPE* shape : shapes->Shapes() )
1422 {
1423 switch( shape->Type() )
1424 {
1425 case SH_SEGMENT:
1426 {
1427 const SHAPE_SEGMENT* seg = (const SHAPE_SEGMENT*) shape;
1428 int effectiveWidth = seg->GetWidth() + 2 * margin.x;
1429
1430 if( effectiveWidth > 0 )
1431 m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, effectiveWidth );
1432
1433 break;
1434 }
1435
1436 case SH_CIRCLE:
1437 {
1438 const SHAPE_CIRCLE* circle = (const SHAPE_CIRCLE*) shape;
1439 int effectiveRadius = circle->GetRadius() + margin.x;
1440
1441 if( effectiveRadius > 0 )
1442 m_gal->DrawCircle( circle->GetCenter(), effectiveRadius );
1443
1444 break;
1445 }
1446
1447 case SH_RECT:
1448 {
1449 const SHAPE_RECT* r = (const SHAPE_RECT*) shape;
1450 VECTOR2I pos = r->GetPosition();
1451 VECTOR2I effectiveMargin = margin;
1452
1453 if( effectiveMargin.x < 0 )
1454 {
1455 // A negative margin just produces a smaller rect.
1456 VECTOR2I effectiveSize = r->GetSize() + effectiveMargin;
1457
1458 if( effectiveSize.x > 0 && effectiveSize.y > 0 )
1459 m_gal->DrawRectangle( pos - effectiveMargin, pos + effectiveSize );
1460 }
1461 else if( effectiveMargin.x > 0 )
1462 {
1463 // A positive margin produces a larger rect, but with rounded corners
1464 m_gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
1465
1466 // Use segments to produce the margin with rounded corners
1467 m_gal->DrawSegment( pos,
1468 pos + VECTOR2I( r->GetWidth(), 0 ),
1469 effectiveMargin.x * 2 );
1470 m_gal->DrawSegment( pos + VECTOR2I( r->GetWidth(), 0 ),
1471 pos + r->GetSize(),
1472 effectiveMargin.x * 2 );
1473 m_gal->DrawSegment( pos + r->GetSize(),
1474 pos + VECTOR2I( 0, r->GetHeight() ),
1475 effectiveMargin.x * 2 );
1476 m_gal->DrawSegment( pos + VECTOR2I( 0, r->GetHeight() ),
1477 pos,
1478 effectiveMargin.x * 2 );
1479 }
1480 else
1481 {
1482 m_gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
1483 }
1484
1485 break;
1486 }
1487
1488 case SH_SIMPLE:
1489 {
1490 const SHAPE_SIMPLE* poly = static_cast<const SHAPE_SIMPLE*>( shape );
1491
1492 if( poly->PointCount() < 2 ) // Careful of empty pads
1493 break;
1494
1495 if( margin.x < 0 ) // The poly shape must be deflated
1496 {
1497 int numSegs = GetArcToSegmentCount( -margin.x, m_maxError, FULL_CIRCLE );
1498 SHAPE_POLY_SET outline;
1499 outline.NewOutline();
1500
1501 for( int ii = 0; ii < poly->PointCount(); ++ii )
1502 outline.Append( poly->CPoint( ii ) );
1503
1504 outline.Deflate( -margin.x, numSegs );
1505
1506 m_gal->DrawPolygon( outline );
1507 }
1508 else
1509 {
1510 m_gal->DrawPolygon( poly->Vertices() );
1511 }
1512
1513 // Now add on a rounded margin (using segments) if the margin > 0
1514 if( margin.x > 0 )
1515 {
1516 for( size_t ii = 0; ii < poly->GetSegmentCount(); ++ii )
1517 {
1518 SEG seg = poly->GetSegment( ii );
1519 m_gal->DrawSegment( seg.A, seg.B, margin.x * 2 );
1520 }
1521 }
1522
1523 break;
1524 }
1525
1526 default:
1527 // Better not get here; we already pre-flighted the shapes...
1528 break;
1529 }
1530 }
1531 }
1532 else
1533 {
1534 // This is expensive. Avoid if possible.
1535 SHAPE_POLY_SET polySet;
1536 aPad->TransformShapeToPolygon( polySet, ToLAYER_ID( aLayer ), margin.x, m_maxError,
1537 ERROR_INSIDE );
1538 m_gal->DrawPolygon( polySet );
1539 }
1540 }
1541
1542 if( pcbconfig() && pcbconfig()->m_Display.m_PadClearance
1543 && ( aLayer == LAYER_PAD_FR || aLayer == LAYER_PAD_BK || aLayer == LAYER_PADS_TH )
1545 {
1546 /* Showing the clearance area is not obvious.
1547 * - A pad can be removed from some copper layers.
1548 * - For non copper layers, what is the clearance area?
1549 * So for copper layers, the clearance area is the shape if the pad is flashed on this
1550 * layer and the hole clearance area for other copper layers.
1551 * For other layers, use the pad shape, although one can use an other criteria,
1552 * depending on the non copper layer.
1553 */
1554 int activeLayer = m_pcbSettings.GetActiveLayer();
1555 bool flashActiveLayer = true;
1556
1557 if( IsCopperLayer( activeLayer ) )
1558 flashActiveLayer = aPad->FlashLayer( activeLayer );
1559
1560 if( !board->GetVisibleLayers().test( activeLayer ) )
1561 flashActiveLayer = false;
1562
1563 if( flashActiveLayer || aPad->GetDrillSize().x )
1564 {
1565 if( aPad->GetAttribute() == PAD_ATTRIB::NPTH )
1567
1569 m_gal->SetIsStroke( true );
1570 m_gal->SetIsFill( false );
1572
1573 int clearance = aPad->GetOwnClearance( m_pcbSettings.GetActiveLayer() );
1574
1575 if( flashActiveLayer && clearance > 0 )
1576 {
1577 auto shape = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
1578
1579 if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_SEGMENT )
1580 {
1581 const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape->Shapes()[0];
1582 m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,
1583 seg->GetWidth() + 2 * clearance );
1584 }
1585 else if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_CIRCLE )
1586 {
1587 const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape->Shapes()[0];
1588 m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + clearance );
1589 }
1590 else
1591 {
1592 SHAPE_POLY_SET polySet;
1593
1594 // Use ERROR_INSIDE because it avoids Clipper and is therefore much faster.
1595 aPad->TransformShapeToPolygon( polySet, ToLAYER_ID( aLayer ), clearance,
1597
1598 if( polySet.Outline( 0 ).PointCount() > 2 ) // Careful of empty pads
1599 m_gal->DrawPolygon( polySet );
1600 }
1601 }
1602 else if( aPad->GetEffectiveHoleShape() && clearance > 0 )
1603 {
1604 clearance += m_holePlatingThickness;
1605
1606 std::shared_ptr<SHAPE_SEGMENT> slot = aPad->GetEffectiveHoleShape();
1607 m_gal->DrawSegment( slot->GetSeg().A, slot->GetSeg().B,
1608 slot->GetWidth() + 2 * clearance );
1609 }
1610 }
1611 }
1612}
wxString GetUnescapedShortNetname() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:58
virtual BOARD_ITEM * Duplicate() const
Create a copy of this BOARD_ITEM.
Definition: board_item.cpp:184
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:43
BOARD_ITEM_CONTAINER * GetParentFootprint() const
Definition: board_item.cpp:239
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:565
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:579
Vec Centre() const
Definition: box2.h:70
double AsRadians() const
Definition: eda_angle.h:153
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:142
virtual VECTOR2I GetTopLeft() const
Definition: eda_shape.h:167
virtual VECTOR2I GetBotRight() const
Definition: eda_shape.h:168
bool IsAnnotationProxy() const
Definition: eda_shape.h:87
DRAWINGS & GraphicalItems()
Definition: footprint.h:173
virtual void Rotate(double aAngle)
Rotate the context.
void SetVerticalJustify(const GR_TEXT_V_ALIGN_T aVerticalJustify)
void SetFontBold(const bool aBold)
void SetFontUnderlined(bool aUnderlined)
void SetHorizontalJustify(const GR_TEXT_H_ALIGN_T aHorizontalJustify)
virtual void Translate(const VECTOR2D &aTranslation)
Translate the context.
virtual void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius)
Draw a circle using world coordinates.
virtual void Restore()
Restore the context.
void ResetTextAttributes()
Reset text attributes to default styling.
void SetTextMirrored(const bool aMirrored)
void SetGlyphSize(const VECTOR2I aSize)
void SetFontItalic(bool aItalic)
virtual void BitmapText(const wxString &aText, const VECTOR2I &aPosition, const EDA_ANGLE &aAngle)
Draw a text using a bitmap font.
virtual void Save()
Save the context.
virtual SHAPE_SEGMENT getPadHoleShape(const PAD *aPad) const
Return hole shape for a pad (internal units).
static const double MAX_FONT_SIZE
< Maximum font size for netnames (and other dynamically shown strings)
Definition: pcb_painter.h:131
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
PCB_LAYER_ID GetActiveLayer() const
Definition: pad.h:59
int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const override
Return an item's "own" clearance in internal units.
Definition: pad.cpp:823
bool FlashLayer(int aLayer, bool aOnlyCheckIfPermitted=false) const
Check to see whether the pad should be flashed on the specific layer.
Definition: pad.cpp:267
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
Definition: pad.cpp:650
int GetSolderMaskExpansion() const
Definition: pad.cpp:849
const VECTOR2I & GetDrillSize() const
Definition: pad.h:267
PAD_ATTRIB GetAttribute() const
Definition: pad.h:400
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
Definition: pad.cpp:1601
const wxString & GetNumber() const
Definition: pad.h:135
VECTOR2I GetPosition() const override
Definition: pad.h:202
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives() const
Accessor to the basic shape list for custom-shaped pads.
Definition: pad.h:330
bool IsNoConnectPad() const
Definition: pad.cpp:182
bool IsFreePad() const
Definition: pad.cpp:189
PAD_SHAPE GetShape() const
Definition: pad.h:194
VECTOR2I GetSolderPasteMargin() const
Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad size,...
Definition: pad.cpp:894
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING flashPTHPads=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pad.cpp:385
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
Definition: pad.cpp:422
const VECTOR2I & GetSize() const
Definition: pad.h:257
DISPLAY_OPTIONS m_Display
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:67
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
int GetRadius() const
Definition: shape_circle.h:108
const VECTOR2I GetCenter() const
Definition: shape_circle.h:113
int PointCount() const
Return the number of points (vertices) in this line chain.
void Deflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
SHAPE_LINE_CHAIN & Outline(int aIndex)
int NewOutline()
Creates a new hole in a given outline.
const int GetHeight() const
Definition: shape_rect.h:151
const int GetWidth() const
Definition: shape_rect.h:143
const VECTOR2I & GetPosition() const
Definition: shape_rect.h:127
const VECTOR2I GetSize() const
Definition: shape_rect.h:135
const SEG & GetSeg() const
int GetWidth() const
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
Definition: shape_simple.h:42
const SHAPE_LINE_CHAIN & Vertices() const
Return the list of vertices defining this simple polygon.
Definition: shape_simple.h:124
virtual const SEG GetSegment(int aIndex) const override
Definition: shape_simple.h:174
const VECTOR2I & CPoint(int aIndex) const
Return a const reference to a given point in the polygon.
Definition: shape_simple.h:102
int PointCount() const
Return the number of points (vertices) in this polygon.
Definition: shape_simple.h:88
virtual size_t GetSegmentCount() const override
Definition: shape_simple.h:176
static constexpr EDA_ANGLE & ANGLE_HORIZONTAL
Definition: eda_angle.h:408
static constexpr EDA_ANGLE & FULL_CIRCLE
Definition: eda_angle.h:410
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:414
#define ENTERED
indicates a group has been entered
@ ERROR_INSIDE
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:825
@ LAYER_NON_PLATEDHOLES
handle color for not plated holes (holes, not pads)
Definition: layer_ids.h:197
@ LAYER_PAD_FR
smd pads, front layer
Definition: layer_ids.h:202
@ LAYER_PAD_PLATEDHOLES
to draw pad holes (plated)
Definition: layer_ids.h:214
@ LAYER_PAD_BK
smd pads, back layer
Definition: layer_ids.h:203
@ LAYER_PADS_TH
multilayer pads, usually with holes
Definition: layer_ids.h:213
@ LAYER_PAD_HOLEWALLS
Definition: layer_ids.h:233
bool IsNetnameLayer(int aLayer)
Test whether a layer is a netname layer.
Definition: layer_ids.h:989
@ F_Paste
Definition: layer_ids.h:101
@ B_Mask
Definition: layer_ids.h:106
@ F_Mask
Definition: layer_ids.h:107
@ B_Paste
Definition: layer_ids.h:100
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:401
@ NPTH
like PAD_PTH, but not plated
PCBNEW_SETTINGS * pcbconfig()
Definition: pcb_painter.cpp:72
@ SH_RECT
axis-aligned rectangle
Definition: shape.h:44
@ SH_CIRCLE
circle
Definition: shape.h:47
@ SH_SIMPLE
simple polygon
Definition: shape.h:48
@ SH_SEGMENT
line segment
Definition: shape.h:45
wxString UnescapeString(const wxString &aSource)
int PrintableCharCount(const wxString &aString)
Return the number of printable (ie: non-formatting) chars.
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_CENTER
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85

References SEG::A, std::abs(), ANGLE_90, ANGLE_HORIZONTAL, SHAPE_POLY_SET::Append(), EDA_ANGLE::AsRadians(), SEG::B, B_Mask, B_Paste, KIGFX::GAL::BitmapText(), BOX2< Vec >::Centre(), color, SHAPE_SIMPLE::CPoint(), CUSTOM, SHAPE_POLY_SET::Deflate(), KIGFX::GAL::DrawCircle(), KIGFX::GAL::DrawPolygon(), KIGFX::GAL::DrawRectangle(), KIGFX::GAL::DrawSegment(), BOARD_ITEM::Duplicate(), ENTERED, ERROR_INSIDE, F_Mask, F_Paste, PAD::FlashLayer(), FULL_CIRCLE, KIGFX::RENDER_SETTINGS::GetActiveLayer(), GetArcToSegmentCount(), PAD::GetAttribute(), BOARD_ITEM::GetBoard(), EDA_SHAPE::GetBotRight(), PAD::GetBoundingBox(), SHAPE_CIRCLE::GetCenter(), PCB_SHAPE::GetCenter(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), PAD::GetDrillSize(), PAD::GetEffectiveHoleShape(), PAD::GetEffectiveShape(), BOARD::GetEnabledLayers(), EDA_ITEM::GetFlags(), SHAPE_RECT::GetHeight(), KIGFX::RENDER_SETTINGS::GetLayerColor(), PAD::GetNumber(), PAD::GetOwnClearance(), getPadHoleShape(), BOARD_ITEM::GetParentFootprint(), SHAPE_RECT::GetPosition(), PAD::GetPosition(), PAD::GetPrimitives(), KIGFX::RENDER_SETTINGS::GetPrintLayers(), SHAPE_CIRCLE::GetRadius(), SHAPE_SEGMENT::GetSeg(), SHAPE_SIMPLE::GetSegment(), SHAPE_SIMPLE::GetSegmentCount(), PAD::GetShape(), SHAPE_RECT::GetSize(), BOX2< Vec >::GetSize(), PAD::GetSize(), PAD::GetSolderMaskExpansion(), PAD::GetSolderPasteMargin(), EDA_SHAPE::GetTopLeft(), BOARD_CONNECTED_ITEM::GetUnescapedShortNetname(), BOARD::GetVisibleLayers(), SHAPE_RECT::GetWidth(), SHAPE_SEGMENT::GetWidth(), GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_CENTER, FOOTPRINT::GraphicalItems(), EDA_SHAPE::IsAnnotationProxy(), IsCopperLayer(), PAD::IsFreePad(), IsNetnameLayer(), PAD::IsNoConnectPad(), KIGFX::RENDER_SETTINGS::IsPrinting(), EDA_ITEM::IsSelected(), KiROUND(), LAYER_NON_PLATEDHOLES, LAYER_PAD_BK, LAYER_PAD_FR, LAYER_PAD_HOLEWALLS, LAYER_PAD_PLATEDHOLES, LAYER_PADS_TH, PCBNEW_SETTINGS::m_Display, PCB_VIEWERS_SETTINGS_BASE::VIEWERS_DISPLAY_OPTIONS::m_DisplayPadFill, KIGFX::PCB_RENDER_SETTINGS::m_ForcePadSketchModeOn, KIGFX::PAINTER::m_gal, m_holePlatingThickness, KIGFX::RENDER_SETTINGS::m_isPrinting, m_maxError, PCBNEW_SETTINGS::DISPLAY_OPTIONS::m_NetNames, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, PCB_VIEWERS_SETTINGS_BASE::m_ViewersDisplay, KIGFX::PCB_RENDER_SETTINGS::MAX_FONT_SIZE, SHAPE_POLY_SET::NewOutline(), NPTH, SHAPE_POLY_SET::Outline(), PCB_FP_SHAPE_T, pcbconfig(), SHAPE_LINE_CHAIN::PointCount(), SHAPE_SIMPLE::PointCount(), PrintableCharCount(), KIGFX::GAL::ResetTextAttributes(), KIGFX::GAL::Restore(), KIGFX::GAL::Rotate(), ROUNDRECT, KIGFX::GAL::Save(), KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetFontBold(), KIGFX::GAL::SetFontItalic(), KIGFX::GAL::SetFontUnderlined(), KIGFX::GAL::SetGlyphSize(), KIGFX::GAL::SetHorizontalJustify(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), KIGFX::GAL::SetTextMirrored(), KIGFX::GAL::SetVerticalJustify(), SH_CIRCLE, SH_RECT, SH_SEGMENT, SH_SIMPLE, ToLAYER_ID(), PAD::TransformShapeToPolygon(), KIGFX::GAL::Translate(), UnescapeString(), SHAPE_SIMPLE::Vertices(), viewer_settings(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ draw() [5/16]

void PCB_PAINTER::draw ( const PCB_ARC aArc,
int  aLayer 
)
protected

Definition at line 779 of file pcb_painter.cpp.

780{
781 VECTOR2D center( aArc->GetCenter() );
782 int width = aArc->GetWidth();
783 COLOR4D color = m_pcbSettings.GetColor( aArc, aLayer );
784 double radius = aArc->GetRadius();
785 EDA_ANGLE start_angle = aArc->GetArcAngleStart();
786 EDA_ANGLE angle = aArc->GetAngle();
787
788 if( IsNetnameLayer( aLayer ) )
789 {
790 // Ummm, yeah. Anyone fancy implementing text on a path?
791 return;
792 }
793 else if( IsCopperLayer( aLayer ) || aLayer == LAYER_LOCKED_ITEM_SHADOW )
794 {
795 // Draw a regular track
796 bool outline_mode = pcbconfig()
798 && aLayer != LAYER_LOCKED_ITEM_SHADOW;
801 m_gal->SetIsStroke( outline_mode );
802 m_gal->SetIsFill( not outline_mode );
804
805 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
806 width = width + m_lockedShadowMargin;
807
808 m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, width,
809 m_maxError );
810 }
811
812 // Clearance lines
813 if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
815 {
816 int clearance = aArc->GetOwnClearance( m_pcbSettings.GetActiveLayer() );
817
819 m_gal->SetIsFill( false );
820 m_gal->SetIsStroke( true );
822
823 m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle,
824 width + clearance * 2, m_maxError );
825 }
826
827// Debug only: enable this code only to test the TransformArcToPolygon function
828// and display the polygon outline created by it.
829// arcs on F_Cu are approximated with ERROR_INSIDE, others with ERROR_OUTSIDE
830#if 0
831 SHAPE_POLY_SET cornerBuffer;
833 TransformArcToPolygon( cornerBuffer, aArc->GetStart(), aArc->GetMid(), aArc->GetEnd(), width,
834 m_maxError, errorloc );
836 m_gal->SetIsFill( false );
837 m_gal->SetIsStroke( true );
838 m_gal->SetStrokeColor( COLOR4D( 0, 0, 1.0, 1.0 ) );
839 m_gal->DrawPolygon( cornerBuffer );
840#endif
841
842// Debug only: enable this code only to test the SHAPE_ARC::ConvertToPolyline function
843// and display the polyline created by it.
844#if 0
845 SHAPE_ARC arc( aArc->GetCenter(), aArc->GetStart(), aArc->GetAngle() / 10.0, aArc->GetWidth() );
846 SHAPE_LINE_CHAIN arcSpine = arc.ConvertToPolyline( m_maxError );
848 m_gal->SetIsFill( false );
849 m_gal->SetIsStroke( true );
850 m_gal->SetStrokeColor( COLOR4D( 0.3, 0.2, 0.5, 1.0 ) );
851
852 for( int idx = 1; idx < arcSpine.PointCount(); idx++ )
853 m_gal->DrawSegment( arcSpine.CPoint( idx-1 ), arcSpine.CPoint( idx ), aArc->GetWidth() );
854#endif
855}
virtual int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const
Return an item's "own" clearance in internal units.
virtual void DrawArcSegment(const VECTOR2D &aCenterPoint, double aRadius, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aEndAngle, double aWidth, double aMaxError)
Draw an arc segment.
EDA_ANGLE GetArcAngleStart() const
Definition: pcb_track.cpp:1161
double GetRadius() const
Definition: pcb_track.cpp:1146
EDA_ANGLE GetAngle() const
Definition: pcb_track.cpp:1152
const VECTOR2I & GetMid() const
Definition: pcb_track.h:312
virtual VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_track.h:321
int GetWidth() const
Definition: pcb_track.h:107
const VECTOR2I & GetStart() const
Definition: pcb_track.h:113
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:110
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void TransformArcToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arc to multiple straight segments.
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
@ ERROR_OUTSIDE
@ F_Cu
Definition: layer_ids.h:64
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
@ SHOW_WITH_VIA_ALWAYS

References PNS::angle(), color, SHAPE_ARC::ConvertToPolyline(), SHAPE_LINE_CHAIN::CPoint(), KIGFX::GAL::DrawArcSegment(), KIGFX::GAL::DrawPolygon(), KIGFX::GAL::DrawSegment(), ERROR_INSIDE, ERROR_OUTSIDE, F_Cu, KIGFX::RENDER_SETTINGS::GetActiveLayer(), PCB_ARC::GetAngle(), PCB_ARC::GetArcAngleStart(), PCB_ARC::GetCenter(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), PCB_TRACK::GetEnd(), PCB_ARC::GetMid(), BOARD_CONNECTED_ITEM::GetOwnClearance(), PCB_ARC::GetRadius(), PCB_TRACK::GetStart(), PCB_TRACK::GetWidth(), IsCopperLayer(), IsNetnameLayer(), LAYER_LOCKED_ITEM_SHADOW, PCBNEW_SETTINGS::m_Display, PCBNEW_SETTINGS::DISPLAY_OPTIONS::m_DisplayPcbTrackFill, KIGFX::PAINTER::m_gal, KIGFX::RENDER_SETTINGS::m_isPrinting, m_lockedShadowMargin, m_maxError, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, pcbconfig(), SHAPE_LINE_CHAIN::PointCount(), KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), SHOW_WITH_VIA_ALWAYS, and TransformArcToPolygon().

◆ draw() [6/16]

void PCB_PAINTER::draw ( const PCB_BITMAP aBitmap,
int  aLayer 
)
protected

Definition at line 1869 of file pcb_painter.cpp.

1870{
1871 m_gal->Save();
1872 m_gal->Translate( aBitmap->GetPosition() );
1873
1874 // When the image scale factor is not 1.0, we need to modify the actual as the image scale
1875 // factor is similar to a local zoom
1876 double img_scale = aBitmap->GetImageScale();
1877
1878 if( img_scale != 1.0 )
1879 m_gal->Scale( VECTOR2D( img_scale, img_scale ) );
1880
1881 if( aBitmap->IsSelected() || aBitmap->IsBrightened() )
1882 {
1884 m_gal->SetIsStroke( true );
1887 m_gal->SetIsFill( false );
1888
1889 // Draws a bounding box.
1890 VECTOR2D bm_size( aBitmap->GetSize() );
1891 // bm_size is the actual image size in UI.
1892 // but m_gal scale was previously set to img_scale
1893 // so recalculate size relative to this image size.
1894 bm_size.x /= img_scale;
1895 bm_size.y /= img_scale;
1896 VECTOR2D origin( -bm_size.x / 2.0, -bm_size.y / 2.0 );
1897 VECTOR2D end = origin + bm_size;
1898
1899 m_gal->DrawRectangle( origin, end );
1900
1901 // Hard code bitmaps as opaque when selected. Otherwise cached layers
1902 // will not be rendered under the selected bitmap because cached layers
1903 // are rendered after non-cached layers (e.g. bitmaps), which will have
1904 // a closer Z order.
1905 m_gal->DrawBitmap( *aBitmap->GetImage(), 1.0 );
1906 }
1907 else
1908 m_gal->DrawBitmap( *aBitmap->GetImage(),
1909 m_pcbSettings.GetColor( aBitmap, aBitmap->GetLayer() ).a );
1910
1911
1912 m_gal->Restore();
1913}
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:180
bool IsBrightened() const
Definition: eda_item.h:108
double a
Alpha component.
Definition: color4d.h:393
virtual void Scale(const VECTOR2D &aScale)
Scale the context.
virtual void DrawBitmap(const BITMAP_BASE &aBitmap, double alphaBlend=1.0)
Draw a bitmap image.
VECTOR2I GetPosition() const override
Definition: pcb_bitmap.h:117
double GetImageScale() const
Definition: pcb_bitmap.h:65
const VECTOR2I GetSize() const
Definition: pcb_bitmap.cpp:153
BITMAP_BASE * GetImage() const
Definition: pcb_bitmap.h:53

References KIGFX::COLOR4D::a, color, KIGFX::GAL::DrawBitmap(), KIGFX::GAL::DrawRectangle(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), PCB_BITMAP::GetImage(), PCB_BITMAP::GetImageScale(), BOARD_ITEM::GetLayer(), PCB_BITMAP::GetPosition(), PCB_BITMAP::GetSize(), EDA_ITEM::IsBrightened(), EDA_ITEM::IsSelected(), LAYER_ANCHOR, KIGFX::PAINTER::m_gal, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, KIGFX::GAL::Restore(), KIGFX::GAL::Save(), KIGFX::GAL::Scale(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), KIGFX::GAL::Translate(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ draw() [7/16]

void PCB_PAINTER::draw ( const PCB_DIMENSION_BASE aDimension,
int  aLayer 
)
protected

Definition at line 2499 of file pcb_painter.cpp.

2500{
2501 const COLOR4D& color = m_pcbSettings.GetColor( aDimension, aLayer );
2502
2505 m_gal->SetIsFill( false );
2506 m_gal->SetIsStroke( true );
2507
2509
2510 if( outline_mode )
2512 else
2514
2515 // Draw dimension shapes
2516 // TODO(JE) lift this out
2517 for( const std::shared_ptr<SHAPE>& shape : aDimension->GetShapes() )
2518 {
2519 switch( shape->Type() )
2520 {
2521 case SH_SEGMENT:
2522 {
2523 const SEG& seg = static_cast<const SHAPE_SEGMENT*>( shape.get() )->GetSeg();
2524 m_gal->DrawLine( seg.A, seg.B );
2525 break;
2526 }
2527
2528 case SH_CIRCLE:
2529 {
2530 int radius = static_cast<const SHAPE_CIRCLE*>( shape.get() )->GetRadius();
2531 m_gal->DrawCircle( shape->Centre(), radius );
2532 break;
2533 }
2534
2535 default:
2536 break;
2537 }
2538 }
2539
2540 // Draw text
2541 const PCB_TEXT& text = aDimension->Text();
2542 wxString resolvedText = text.GetShownText();
2543 TEXT_ATTRIBUTES attrs = text.GetAttributes();
2544
2545 if( m_gal->IsFlippedX() && !( aDimension->GetLayerSet() & LSET::SideSpecificMask() ).any() )
2546 attrs.m_Mirrored = !attrs.m_Mirrored;
2547
2548 if( outline_mode )
2550 else
2551 attrs.m_StrokeWidth = getLineThickness( text.GetEffectiveTextPenWidth() );
2552
2553 std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
2554
2555 if( text.GetFont() && text.GetFont()->IsOutline() )
2556 cache = text.GetRenderCache( text.GetFont(), resolvedText );
2557
2558 if( cache )
2559 {
2560 for( const std::unique_ptr<KIFONT::GLYPH>& glyph : *cache )
2561 m_gal->DrawGlyph( *glyph.get() );
2562 }
2563 else
2564 {
2565 strokeText( resolvedText, text.GetTextPos(), attrs );
2566 }
2567}
virtual void DrawGlyph(const KIFONT::GLYPH &aGlyph, int aNth=0, int aTotal=1)
Draw a polygon representing a font glyph.
int GetLineThickness() const
PCB_TEXT & Text()
const std::vector< std::shared_ptr< SHAPE > > & GetShapes() const

References SEG::A, SEG::B, color, KIGFX::GAL::DrawCircle(), KIGFX::GAL::DrawGlyph(), KIGFX::GAL::DrawLine(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), BOARD_ITEM::GetLayerSet(), PCB_DIMENSION_BASE::GetLineThickness(), getLineThickness(), PCB_DIMENSION_BASE::GetShapes(), KIGFX::GAL::IsFlippedX(), PCB_VIEWERS_SETTINGS_BASE::VIEWERS_DISPLAY_OPTIONS::m_DisplayGraphicsFill, KIGFX::PAINTER::m_gal, TEXT_ATTRIBUTES::m_Mirrored, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, TEXT_ATTRIBUTES::m_StrokeWidth, PCB_VIEWERS_SETTINGS_BASE::m_ViewersDisplay, KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), SH_CIRCLE, SH_SEGMENT, LSET::SideSpecificMask(), strokeText(), text, PCB_DIMENSION_BASE::Text(), and viewer_settings().

◆ draw() [8/16]

void PCB_PAINTER::draw ( const PCB_GROUP aGroup,
int  aLayer 
)
protected

Definition at line 2329 of file pcb_painter.cpp.

2330{
2331 if( aLayer == LAYER_ANCHOR )
2332 {
2333 if( aGroup->IsSelected() && !( aGroup->GetParent() && aGroup->GetParent()->IsSelected() ) )
2334 {
2335 // Selected on our own; draw enclosing box
2336 }
2337 else if( aGroup->IsEntered() )
2338 {
2339 // Entered group; draw enclosing box
2340 }
2341 else
2342 {
2343 // Neither selected nor entered; draw nothing at the group level (ie: only draw
2344 // its members)
2345 return;
2346 }
2347
2348 const COLOR4D color = m_pcbSettings.GetColor( aGroup, LAYER_ANCHOR );
2349
2352
2353 BOX2I bbox = aGroup->GetBoundingBox();
2354 VECTOR2I topLeft = bbox.GetPosition();
2355 VECTOR2I width = VECTOR2I( bbox.GetWidth(), 0 );
2356 VECTOR2I height = VECTOR2I( 0, bbox.GetHeight() );
2357
2358 m_gal->DrawLine( topLeft, topLeft + width );
2359 m_gal->DrawLine( topLeft + width, topLeft + width + height );
2360 m_gal->DrawLine( topLeft + width + height, topLeft + height );
2361 m_gal->DrawLine( topLeft + height, topLeft );
2362
2363 wxString name = aGroup->GetName();
2364
2365 if( name.IsEmpty() )
2366 return;
2367
2368 int ptSize = 12;
2369 int scaledSize = abs( KiROUND( m_gal->GetScreenWorldMatrix().GetScale().x * ptSize ) );
2370 int unscaledSize = pcbIUScale.MilsToIU( ptSize );
2371
2372 // Scale by zoom a bit, but not too much
2373 int textSize = ( scaledSize + ( unscaledSize * 2 ) ) / 3;
2374 VECTOR2I textOffset = VECTOR2I( width.x / 2, -KiROUND( textSize * 0.5 ) );
2375 VECTOR2I titleHeight = VECTOR2I( 0, KiROUND( textSize * 2.0 ) );
2376
2377 if( PrintableCharCount( name ) * textSize < bbox.GetWidth() )
2378 {
2379 m_gal->DrawLine( topLeft, topLeft - titleHeight );
2380 m_gal->DrawLine( topLeft - titleHeight, topLeft + width - titleHeight );
2381 m_gal->DrawLine( topLeft + width - titleHeight, topLeft + width );
2382
2383 TEXT_ATTRIBUTES attrs;
2384 attrs.m_Italic = true;
2387 attrs.m_Size = VECTOR2I( textSize, textSize );
2388 attrs.m_StrokeWidth = GetPenSizeForNormal( textSize );
2389
2390 KIFONT::FONT::GetFont()->Draw( m_gal, aGroup->GetName(), topLeft + textOffset, attrs );
2391 }
2392 }
2393}
const char * name
Definition: DXF_plotter.cpp:56
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
coord_type GetHeight() const
Definition: box2.h:188
coord_type GetWidth() const
Definition: box2.h:187
bool IsEntered() const
Definition: eda_item.h:107
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:295
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_group.cpp:276
wxString GetName() const
Definition: pcb_group.h:65
GR_TEXT_V_ALIGN_T m_Valign
int GetPenSizeForNormal(int aTextSize)
Definition: gr_text.cpp:52
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
@ GR_TEXT_V_ALIGN_BOTTOM

References std::abs(), color, KIFONT::FONT::Draw(), KIGFX::GAL::DrawLine(), PCB_GROUP::GetBoundingBox(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), KIFONT::FONT::GetFont(), BOX2< Vec >::GetHeight(), PCB_GROUP::GetName(), BOARD_ITEM::GetParent(), GetPenSizeForNormal(), BOX2< Vec >::GetPosition(), MATRIX3x3< T >::GetScale(), KIGFX::GAL::GetScreenWorldMatrix(), BOX2< Vec >::GetWidth(), GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_BOTTOM, EDA_ITEM::IsEntered(), EDA_ITEM::IsSelected(), KiROUND(), LAYER_ANCHOR, KIGFX::PAINTER::m_gal, TEXT_ATTRIBUTES::m_Halign, TEXT_ATTRIBUTES::m_Italic, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, TEXT_ATTRIBUTES::m_Size, TEXT_ATTRIBUTES::m_StrokeWidth, TEXT_ATTRIBUTES::m_Valign, EDA_IU_SCALE::MilsToIU(), name, pcbIUScale, PrintableCharCount(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), and VECTOR2< T >::x.

◆ draw() [9/16]

void PCB_PAINTER::draw ( const PCB_MARKER aMarker,
int  aLayer 
)
protected

Definition at line 2606 of file pcb_painter.cpp.

2607{
2608 bool isShadow = aLayer == LAYER_MARKER_SHADOWS;
2609
2610 // Don't paint shadows for invisible markers.
2611 // It would be nice to do this through layer dependencies but we can't do an "or" there today
2612 if( isShadow && aMarker->GetBoard()
2613 && !aMarker->GetBoard()->IsElementVisible( aMarker->GetColorLayer() ) )
2614 {
2615 return;
2616 }
2617
2618 const_cast<PCB_MARKER*>( aMarker )->SetZoom( 1.0 / sqrt( m_gal->GetZoomFactor() ) );
2619
2620 SHAPE_LINE_CHAIN polygon;
2621 aMarker->ShapeToPolygon( polygon );
2622
2624 : aMarker->GetColorLayer() );
2625
2626 m_gal->Save();
2627 m_gal->Translate( aMarker->GetPosition() );
2628
2629 if( isShadow )
2630 {
2632 m_gal->SetIsStroke( true );
2633 m_gal->SetLineWidth( aMarker->MarkerScale() );
2634 }
2635 else
2636 {
2638 m_gal->SetIsFill( true );
2639 }
2640
2641 m_gal->DrawPolygon( polygon );
2642 m_gal->Restore();
2643}
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition: board.cpp:631
double GetZoomFactor() const
int MarkerScale() const
The scaling factor to convert polygonal shape coordinates to internal units.
Definition: marker_base.h:68
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon, int aScale=-1) const
Return the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to the...
GAL_LAYER_ID GetColorLayer() const
Definition: pcb_marker.cpp:310
VECTOR2I GetPosition() const override
Definition: pcb_marker.h:68
@ LAYER_MARKER_SHADOWS
shadows for drc markers
Definition: layer_ids.h:237

References color, KIGFX::GAL::DrawPolygon(), BOARD_ITEM::GetBoard(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), PCB_MARKER::GetColorLayer(), PCB_MARKER::GetPosition(), KIGFX::GAL::GetZoomFactor(), BOARD::IsElementVisible(), LAYER_MARKER_SHADOWS, KIGFX::PAINTER::m_gal, m_pcbSettings, MARKER_BASE::MarkerScale(), KIGFX::GAL::Restore(), KIGFX::GAL::Save(), KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), MARKER_BASE::ShapeToPolygon(), and KIGFX::GAL::Translate().

◆ draw() [10/16]

void PCB_PAINTER::draw ( const PCB_SHAPE aSegment,
int  aLayer 
)
protected

Definition at line 1615 of file pcb_painter.cpp.

1616{
1617 COLOR4D color = m_pcbSettings.GetColor( aShape, aShape->GetLayer() );
1619 int thickness = getLineThickness( aShape->GetWidth() );
1620 PLOT_DASH_TYPE lineStyle = aShape->GetStroke().GetPlotStyle();
1621
1622 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
1623 {
1624 color = m_pcbSettings.GetColor( aShape, aLayer );
1625 thickness = thickness + m_lockedShadowMargin;
1626 }
1627
1628 if( outline_mode )
1629 {
1630 m_gal->SetIsFill( false );
1631 m_gal->SetIsStroke( true );
1633 }
1634
1637
1638 if( lineStyle <= PLOT_DASH_TYPE::FIRST_TYPE )
1639 {
1640 switch( aShape->GetShape() )
1641 {
1642 case SHAPE_T::SEGMENT:
1643 if( outline_mode )
1644 {
1645 m_gal->DrawSegment( aShape->GetStart(), aShape->GetEnd(), thickness );
1646 }
1647 else
1648 {
1649 m_gal->SetIsFill( true );
1650 m_gal->SetIsStroke( false );
1651
1652 m_gal->DrawSegment( aShape->GetStart(), aShape->GetEnd(), thickness );
1653 }
1654
1655 break;
1656
1657 case SHAPE_T::RECT:
1658 {
1659 std::vector<VECTOR2I> pts = aShape->GetRectCorners();
1660
1661 if( aShape->IsAnnotationProxy() )
1662 {
1663 m_gal->DrawSegment( pts[0], pts[1], thickness );
1664 m_gal->DrawSegment( pts[1], pts[2], thickness );
1665 m_gal->DrawSegment( pts[2], pts[3], thickness );
1666 m_gal->DrawSegment( pts[3], pts[0], thickness );
1667 m_gal->DrawSegment( pts[0], pts[2], thickness );
1668 m_gal->DrawSegment( pts[1], pts[3], thickness );
1669 }
1670 else if( outline_mode )
1671 {
1672 m_gal->DrawSegment( pts[0], pts[1], thickness );
1673 m_gal->DrawSegment( pts[1], pts[2], thickness );
1674 m_gal->DrawSegment( pts[2], pts[3], thickness );
1675 m_gal->DrawSegment( pts[3], pts[0], thickness );
1676 }
1677 else
1678 {
1679 m_gal->SetIsFill( true );
1680 m_gal->SetIsStroke( false );
1681
1682 if( thickness > 0 )
1683 {
1684 m_gal->DrawSegment( pts[0], pts[1], thickness );
1685 m_gal->DrawSegment( pts[1], pts[2], thickness );
1686 m_gal->DrawSegment( pts[2], pts[3], thickness );
1687 m_gal->DrawSegment( pts[3], pts[0], thickness );
1688 }
1689
1690 if( aShape->IsFilled() )
1691 {
1692 SHAPE_POLY_SET poly;
1693 poly.NewOutline();
1694
1695 for( const VECTOR2I& pt : pts )
1696 poly.Append( pt );
1697
1698 m_gal->DrawPolygon( poly );
1699 }
1700 }
1701
1702 break;
1703 }
1704
1705 case SHAPE_T::ARC:
1706 {
1707 EDA_ANGLE startAngle;
1708 EDA_ANGLE endAngle;
1709 aShape->CalcArcAngles( startAngle, endAngle );
1710
1711 if( outline_mode )
1712 {
1713 m_gal->DrawArcSegment( aShape->GetCenter(), aShape->GetRadius(), startAngle,
1714 endAngle, thickness, m_maxError );
1715 }
1716 else
1717 {
1718 m_gal->SetIsFill( true );
1719 m_gal->SetIsStroke( false );
1720
1721 m_gal->DrawArcSegment( aShape->GetCenter(), aShape->GetRadius(), startAngle,
1722 endAngle, thickness, m_maxError );
1723 }
1724 break;
1725 }
1726
1727 case SHAPE_T::CIRCLE:
1728 if( outline_mode )
1729 {
1730 m_gal->DrawCircle( aShape->GetStart(), aShape->GetRadius() - thickness / 2 );
1731 m_gal->DrawCircle( aShape->GetStart(), aShape->GetRadius() + thickness / 2 );
1732 }
1733 else
1734 {
1735 m_gal->SetIsFill( aShape->IsFilled() );
1736 m_gal->SetIsStroke( thickness > 0 );
1737 m_gal->SetLineWidth( thickness );
1738
1739 m_gal->DrawCircle( aShape->GetStart(), aShape->GetRadius() );
1740 }
1741 break;
1742
1743 case SHAPE_T::POLY:
1744 {
1745 SHAPE_POLY_SET& shape = const_cast<PCB_SHAPE*>( aShape )->GetPolyShape();
1746 const FOOTPRINT* parentFootprint = aShape->GetParentFootprint();
1747
1748 if( shape.OutlineCount() == 0 )
1749 break;
1750
1751 if( parentFootprint )
1752 {
1753 m_gal->Save();
1754 m_gal->Translate( parentFootprint->GetPosition() );
1755 m_gal->Rotate( -parentFootprint->GetOrientation().AsRadians() );
1756 }
1757
1758 if( outline_mode )
1759 {
1760 for( int ii = 0; ii < shape.OutlineCount(); ++ii )
1761 m_gal->DrawSegmentChain( shape.Outline( ii ), thickness );
1762 }
1763 else
1764 {
1765 m_gal->SetIsFill( true );
1766 m_gal->SetIsStroke( false );
1767
1768 if( thickness > 0 )
1769 {
1770 for( int ii = 0; ii < shape.OutlineCount(); ++ii )
1771 m_gal->DrawSegmentChain( shape.Outline( ii ), thickness );
1772 }
1773
1774 if( aShape->IsFilled() )
1775 {
1776 // On Opengl, a not convex filled polygon is usually drawn by using triangles
1777 // as primitives. CacheTriangulation() can create basic triangle primitives to
1778 // draw the polygon solid shape on Opengl. GLU tessellation is much slower,
1779 // so currently we are using our tessellation.
1780 if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() )
1781 shape.CacheTriangulation( true, true );
1782
1783 m_gal->DrawPolygon( shape );
1784 }
1785 }
1786
1787 if( parentFootprint )
1788 m_gal->Restore();
1789
1790 break;
1791 }
1792
1793 case SHAPE_T::BEZIER:
1794 if( outline_mode )
1795 {
1796 std::vector<VECTOR2D> output;
1797 std::vector<VECTOR2D> pointCtrl;
1798
1799 pointCtrl.push_back( aShape->GetStart() );
1800 pointCtrl.push_back( aShape->GetBezierC1() );
1801 pointCtrl.push_back( aShape->GetBezierC2() );
1802 pointCtrl.push_back( aShape->GetEnd() );
1803
1804 BEZIER_POLY converter( pointCtrl );
1805 converter.GetPoly( output, thickness );
1806
1807 m_gal->DrawSegmentChain( output, thickness );
1808 }
1809 else
1810 {
1811 m_gal->SetIsFill( aShape->IsFilled() );
1812 m_gal->SetIsStroke( thickness > 0 );
1813 m_gal->SetLineWidth( thickness );
1814
1815 // Use thickness as filter value to convert the curve to polyline when the curve
1816 // is not supported
1817 m_gal->DrawCurve( VECTOR2D( aShape->GetStart() ),
1818 VECTOR2D( aShape->GetBezierC1() ),
1819 VECTOR2D( aShape->GetBezierC2() ),
1820 VECTOR2D( aShape->GetEnd() ), thickness );
1821 }
1822
1823 break;
1824
1825 case SHAPE_T::LAST:
1826 break;
1827 }
1828 }
1829 else
1830 {
1831 if( !outline_mode )
1832 {
1833 m_gal->SetIsFill( true );
1834 m_gal->SetIsStroke( false );
1835 }
1836
1837 std::vector<SHAPE*> shapes = aShape->MakeEffectiveShapes( true );
1838
1839 for( SHAPE* shape : shapes )
1840 {
1841 STROKE_PARAMS::Stroke( shape, lineStyle, thickness, &m_pcbSettings,
1842 [&]( const VECTOR2I& a, const VECTOR2I& b )
1843 {
1844 m_gal->DrawSegment( a, b, thickness );
1845 } );
1846 }
1847
1848 for( SHAPE* shape : shapes )
1849 delete shape;
1850 }
1851}
Bezier curves to polygon converter.
Definition: bezier_curves.h:38
EDA_ANGLE GetOrientation() const
Definition: footprint.h:191
virtual bool IsOpenGlEngine()
Return true if the GAL engine is a OpenGL based type.
virtual void DrawCurve(const VECTOR2D &startPoint, const VECTOR2D &controlPointA, const VECTOR2D &controlPointB, const VECTOR2D &endPoint, double aFilterValue=0.0)
Draw a cubic bezier spline.
virtual void DrawSegmentChain(const std::vector< VECTOR2D > &aPointList, double aWidth)
Draw a chain of rounded segments.
bool IsTriangulationUpToDate() const
void CacheTriangulation(bool aPartition=true, bool aSimplify=false)
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
@ LAST
marker for list end

References SHAPE_POLY_SET::Append(), ARC, EDA_ANGLE::AsRadians(), BEZIER, SHAPE_POLY_SET::CacheTriangulation(), EDA_SHAPE::CalcArcAngles(), CIRCLE, color, KIGFX::GAL::DrawArcSegment(), KIGFX::GAL::DrawCircle(), KIGFX::GAL::DrawCurve(), KIGFX::GAL::DrawPolygon(), KIGFX::GAL::DrawSegment(), KIGFX::GAL::DrawSegmentChain(), FIRST_TYPE, EDA_SHAPE::GetBezierC1(), EDA_SHAPE::GetBezierC2(), PCB_SHAPE::GetCenter(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), EDA_SHAPE::GetEnd(), BOARD_ITEM::GetLayer(), getLineThickness(), FOOTPRINT::GetOrientation(), PCB_SHAPE::GetParentFootprint(), STROKE_PARAMS::GetPlotStyle(), BEZIER_POLY::GetPoly(), FOOTPRINT::GetPosition(), EDA_SHAPE::GetRadius(), EDA_SHAPE::GetRectCorners(), EDA_SHAPE::GetShape(), EDA_SHAPE::GetStart(), PCB_SHAPE::GetStroke(), EDA_SHAPE::GetWidth(), EDA_SHAPE::IsAnnotationProxy(), EDA_SHAPE::IsFilled(), KIGFX::GAL::IsOpenGlEngine(), SHAPE_POLY_SET::IsTriangulationUpToDate(), LAST, LAYER_LOCKED_ITEM_SHADOW, PCB_VIEWERS_SETTINGS_BASE::VIEWERS_DISPLAY_OPTIONS::m_DisplayGraphicsFill, KIGFX::PAINTER::m_gal, m_lockedShadowMargin, m_maxError, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, PCB_VIEWERS_SETTINGS_BASE::m_ViewersDisplay, EDA_SHAPE::MakeEffectiveShapes(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), POLY, RECT, KIGFX::GAL::Restore(), KIGFX::GAL::Rotate(), KIGFX::GAL::Save(), SEGMENT, KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), STROKE_PARAMS::Stroke(), KIGFX::GAL::Translate(), and viewer_settings().

◆ draw() [11/16]

void PCB_PAINTER::draw ( const PCB_TARGET aTarget)
protected

Definition at line 2570 of file pcb_painter.cpp.

2571{
2572 const COLOR4D& strokeColor = m_pcbSettings.GetColor( aTarget, aTarget->GetLayer() );
2573 VECTOR2D position( aTarget->GetPosition() );
2574 double size, radius;
2575
2576 m_gal->SetLineWidth( getLineThickness( aTarget->GetWidth() ) );
2577 m_gal->SetStrokeColor( strokeColor );
2578 m_gal->SetIsFill( false );
2579 m_gal->SetIsStroke( true );
2580
2581 m_gal->Save();
2582 m_gal->Translate( position );
2583
2584 if( aTarget->GetShape() )
2585 {
2586 // shape x
2587 m_gal->Rotate( M_PI / 4.0 );
2588 size = 2.0 * aTarget->GetSize() / 3.0;
2589 radius = aTarget->GetSize() / 2.0;
2590 }
2591 else
2592 {
2593 // shape +
2594 size = aTarget->GetSize() / 2.0;
2595 radius = aTarget->GetSize() / 3.0;
2596 }
2597
2598 m_gal->DrawLine( VECTOR2D( -size, 0.0 ), VECTOR2D( size, 0.0 ) );
2599 m_gal->DrawLine( VECTOR2D( 0.0, -size ), VECTOR2D( 0.0, size ) );
2600 m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), radius );
2601
2602 m_gal->Restore();
2603}
int GetShape() const
Definition: pcb_target.h:58
int GetWidth() const
Definition: pcb_target.h:64
int GetSize() const
Definition: pcb_target.h:61
VECTOR2I GetPosition() const override
Definition: pcb_target.h:55

References KIGFX::GAL::DrawCircle(), KIGFX::GAL::DrawLine(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), BOARD_ITEM::GetLayer(), getLineThickness(), PCB_TARGET::GetPosition(), PCB_TARGET::GetShape(), PCB_TARGET::GetSize(), PCB_TARGET::GetWidth(), KIGFX::PAINTER::m_gal, m_pcbSettings, KIGFX::GAL::Restore(), KIGFX::GAL::Rotate(), KIGFX::GAL::Save(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), and KIGFX::GAL::Translate().

◆ draw() [12/16]

void PCB_PAINTER::draw ( const PCB_TEXT aText,
int  aLayer 
)
protected

Definition at line 1916 of file pcb_painter.cpp.

1917{
1918 wxString resolvedText( aText->GetShownText() );
1919
1920 if( resolvedText.Length() == 0 )
1921 return;
1922
1923 if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) // happens only if locked
1924 {
1925 const COLOR4D color = m_pcbSettings.GetColor( aText, aLayer );
1926
1927 m_gal->SetIsFill( true );
1928 m_gal->SetIsStroke( true );
1931
1932 SHAPE_POLY_SET poly;
1933 aText->TransformShapeToPolygon( poly, aText->GetLayer(), 0, m_maxError, ERROR_OUTSIDE );
1934 m_gal->DrawPolygon( poly );
1935
1936 return;
1937 }
1938
1939 TEXT_ATTRIBUTES attrs = aText->GetAttributes();
1940 const COLOR4D& color = m_pcbSettings.GetColor( aText, aText->GetLayer() );
1941 bool outline_mode = !viewer_settings()->m_ViewersDisplay.m_DisplayTextFill;
1942
1943 KIFONT::FONT* font = aText->GetFont();
1944
1945 if( !font )
1946 {
1948 aText->IsItalic() );
1949 }
1950
1953
1954 if( aText->IsKnockout() )
1955 {
1956 KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
1957 SHAPE_POLY_SET knockouts;
1958
1959 CALLBACK_GAL callback_gal( empty_opts,
1960 // Polygon callback
1961 [&]( const SHAPE_LINE_CHAIN& aPoly )
1962 {
1963 knockouts.AddOutline( aPoly );
1964 } );
1965
1967
1968 callback_gal.SetIsFill( font->IsOutline() );
1969 callback_gal.SetIsStroke( font->IsStroke() );
1970 callback_gal.SetLineWidth( attrs.m_StrokeWidth );
1971 font->Draw( &callback_gal, resolvedText, aText->GetDrawPos(), attrs );
1972
1973 SHAPE_POLY_SET finalPoly;
1974 int margin = attrs.m_StrokeWidth * 1.5
1975 + GetKnockoutTextMargin( attrs.m_Size, attrs.m_StrokeWidth );
1976
1977 aText->TransformBoundingBoxToPolygon( &finalPoly, margin );
1978 finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST );
1979 finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
1980
1981 m_gal->SetIsStroke( false );
1982 m_gal->SetIsFill( true );
1983 m_gal->DrawPolygon( finalPoly );
1984 }
1985 else
1986 {
1987 if( outline_mode )
1989 else
1991
1992 if( m_gal->IsFlippedX() && !( aText->GetLayerSet() & LSET::SideSpecificMask() ).any() )
1993 {
1994 attrs.m_Mirrored = !attrs.m_Mirrored;
1995 attrs.m_Halign = static_cast<GR_TEXT_H_ALIGN_T>( -attrs.m_Halign );
1996 }
1997
1998 std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
1999
2000 if( font->IsOutline() )
2001 cache = aText->GetRenderCache( font, resolvedText );
2002
2003 if( cache )
2004 m_gal->DrawGlyphs( *cache );
2005 else
2006 strokeText( resolvedText, aText->GetTextPos(), attrs );
2007 }
2008}
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth=false) const override
Convert the item shape to a closed polygon.
Definition: pcb_text.cpp:326
wxString GetShownText(int aDepth=0, bool aAllowExtraText=true) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:56

References SHAPE_POLY_SET::AddOutline(), SHAPE_POLY_SET::BooleanSubtract(), color, KIFONT::FONT::Draw(), KIGFX::GAL::DrawGlyphs(), KIGFX::GAL::DrawPolygon(), ERROR_OUTSIDE, SHAPE_POLY_SET::Fracture(), EDA_TEXT::GetAttributes(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), KIGFX::RENDER_SETTINGS::GetDefaultFont(), EDA_TEXT::GetDrawPos(), EDA_TEXT::GetEffectiveTextPenWidth(), EDA_TEXT::GetFont(), KIFONT::FONT::GetFont(), GetKnockoutTextMargin(), BOARD_ITEM::GetLayer(), BOARD_ITEM::GetLayerSet(), getLineThickness(), EDA_TEXT::GetRenderCache(), PCB_TEXT::GetShownText(), EDA_TEXT::GetTextPos(), EDA_TEXT::IsBold(), KIGFX::GAL::IsFlippedX(), EDA_TEXT::IsItalic(), BOARD_ITEM::IsKnockout(), KIFONT::FONT::IsOutline(), KIFONT::FONT::IsStroke(), LAYER_LOCKED_ITEM_SHADOW, PCB_VIEWERS_SETTINGS_BASE::VIEWERS_DISPLAY_OPTIONS::m_DisplayTextFill, KIGFX::PAINTER::m_gal, TEXT_ATTRIBUTES::m_Halign, m_lockedShadowMargin, m_maxError, TEXT_ATTRIBUTES::m_Mirrored, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, TEXT_ATTRIBUTES::m_Size, TEXT_ATTRIBUTES::m_StrokeWidth, PCB_VIEWERS_SETTINGS_BASE::m_ViewersDisplay, SHAPE_POLY_SET::PM_FAST, KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), LSET::SideSpecificMask(), strokeText(), EDA_TEXT::TransformBoundingBoxToPolygon(), PCB_TEXT::TransformShapeToPolygon(), and viewer_settings().

◆ draw() [13/16]

void PCB_PAINTER::draw ( const PCB_TEXTBOX aText,
int  aLayer 
)
protected

Definition at line 2011 of file pcb_painter.cpp.

2012{
2013 const COLOR4D& color = m_pcbSettings.GetColor( aTextBox, aLayer );
2014 int thickness = getLineThickness( aTextBox->GetWidth() );
2015 PLOT_DASH_TYPE lineStyle = aTextBox->GetStroke().GetPlotStyle();
2016 wxString resolvedText( aTextBox->GetShownText() );
2017
2018 KIFONT::FONT* font = aTextBox->GetFont();
2019
2020 if( !font )
2021 {
2022 font = KIFONT::FONT::GetFont( m_pcbSettings.GetDefaultFont(), aTextBox->IsBold(),
2023 aTextBox->IsItalic() );
2024 }
2025
2026 if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) // happens only if locked
2027 {
2028 const COLOR4D sh_color = m_pcbSettings.GetColor( aTextBox, aLayer );
2029
2030 m_gal->SetIsFill( true );
2031 m_gal->SetIsStroke( false );
2032 m_gal->SetFillColor( sh_color );
2033 m_gal->SetStrokeColor( sh_color );
2034
2035 // Draw the box with a larger thickness than box thickness to show
2036 // the shadow mask
2037 std::vector<VECTOR2I> pts = aTextBox->GetCorners();
2038 int line_thickness = std::max( thickness*3, pcbIUScale.mmToIU( 0.2 ) );
2039
2040 for( size_t ii = 0; ii < pts.size(); ++ii )
2041 m_gal->DrawSegment( pts[ ii ], pts[ (ii + 1) % pts.size() ], line_thickness );
2042 }
2043
2046 m_gal->SetIsFill( true );
2047 m_gal->SetIsStroke( false );
2048
2049 if( lineStyle <= PLOT_DASH_TYPE::FIRST_TYPE )
2050 {
2051 if( thickness > 0 )
2052 {
2053 std::vector<VECTOR2I> pts = aTextBox->GetCorners();
2054
2055 for( size_t ii = 0; ii < pts.size(); ++ii )
2056 m_gal->DrawSegment( pts[ ii ], pts[ (ii + 1) % pts.size() ], thickness );
2057 }
2058 }
2059 else
2060 {
2061 std::vector<SHAPE*> shapes = aTextBox->MakeEffectiveShapes( true );
2062
2063 for( SHAPE* shape : shapes )
2064 {
2065 STROKE_PARAMS::Stroke( shape, lineStyle, thickness, &m_pcbSettings,
2066 [&]( const VECTOR2I& a, const VECTOR2I& b )
2067 {
2068 m_gal->DrawSegment( a, b, thickness );
2069 } );
2070 }
2071
2072 for( SHAPE* shape : shapes )
2073 delete shape;
2074 }
2075
2076 if( resolvedText.Length() == 0 )
2077 return;
2078
2079 TEXT_ATTRIBUTES attrs = aTextBox->GetAttributes();
2080 attrs.m_StrokeWidth = getLineThickness( aTextBox->GetEffectiveTextPenWidth() );
2081
2082 if( m_gal->IsFlippedX() && !( aTextBox->GetLayerSet() & LSET::SideSpecificMask() ).any() )
2083 {
2084 attrs.m_Mirrored = !attrs.m_Mirrored;
2085 attrs.m_Halign = static_cast<GR_TEXT_H_ALIGN_T>( -attrs.m_Halign );
2086 }
2087
2088 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
2089 {
2090 const COLOR4D sh_color = m_pcbSettings.GetColor( aTextBox, aLayer );
2091 m_gal->SetFillColor( sh_color );
2092 m_gal->SetStrokeColor( sh_color );
2094 }
2095
2096 std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
2097
2098 if( font->IsOutline() )
2099 cache = aTextBox->GetRenderCache( font, resolvedText );
2100
2101 if( cache )
2102 m_gal->DrawGlyphs( *cache );
2103 else
2104 strokeText( resolvedText, aTextBox->GetDrawPos(), attrs );
2105}
constexpr int mmToIU(double mm) const
Definition: base_units.h:89

References color, KIGFX::GAL::DrawGlyphs(), KIGFX::GAL::DrawSegment(), FIRST_TYPE, EDA_TEXT::GetAttributes(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), PCB_SHAPE::GetCorners(), KIGFX::RENDER_SETTINGS::GetDefaultFont(), PCB_TEXTBOX::GetDrawPos(), EDA_TEXT::GetEffectiveTextPenWidth(), EDA_TEXT::GetFont(), KIFONT::FONT::GetFont(), BOARD_ITEM::GetLayerSet(), getLineThickness(), STROKE_PARAMS::GetPlotStyle(), EDA_TEXT::GetRenderCache(), PCB_TEXTBOX::GetShownText(), PCB_SHAPE::GetStroke(), EDA_SHAPE::GetWidth(), EDA_TEXT::IsBold(), KIGFX::GAL::IsFlippedX(), EDA_TEXT::IsItalic(), KIFONT::FONT::IsOutline(), LAYER_LOCKED_ITEM_SHADOW, KIGFX::PAINTER::m_gal, TEXT_ATTRIBUTES::m_Halign, m_lockedShadowMargin, TEXT_ATTRIBUTES::m_Mirrored, m_pcbSettings, TEXT_ATTRIBUTES::m_StrokeWidth, EDA_SHAPE::MakeEffectiveShapes(), EDA_IU_SCALE::mmToIU(), pcbIUScale, KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetStrokeColor(), LSET::SideSpecificMask(), STROKE_PARAMS::Stroke(), and strokeText().

◆ draw() [14/16]

void PCB_PAINTER::draw ( const PCB_TRACK aTrack,
int  aLayer 
)
protected

Definition at line 659 of file pcb_painter.cpp.

660{
661 VECTOR2I start( aTrack->GetStart() );
662 VECTOR2I end( aTrack->GetEnd() );
663 int track_width = aTrack->GetWidth();
664 COLOR4D color = m_pcbSettings.GetColor( aTrack, aLayer );
665
666 if( IsNetnameLayer( aLayer ) )
667 {
668 if( !pcbconfig() || pcbconfig()->m_Display.m_NetNames < 2 )
669 return;
670
671 if( aTrack->GetNetCode() <= NETINFO_LIST::UNCONNECTED )
672 return;
673
674 // When drawing netnames, clip the track to the viewport
675 BOX2D viewport;
676 VECTOR2D screenSize = m_gal->GetScreenPixelSize();
677 const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
678
679 viewport.SetOrigin( VECTOR2D( matrix * VECTOR2D( 0, 0 ) ) );
680 viewport.SetEnd( VECTOR2D( matrix * screenSize ) );
681 viewport.Normalize();
682
683 BOX2I clipBox( viewport.GetOrigin(), viewport.GetSize() );
684 SEG visibleSeg( start, end );
685
686 ClipLine( &clipBox, visibleSeg.A.x, visibleSeg.A.y, visibleSeg.B.x, visibleSeg.B.y );
687
688 wxString netName = aTrack->GetUnescapedShortNetname();
689 size_t num_char = netName.size();
690
691 // Check if the track is long enough to have a netname displayed
692 int seg_minlength = track_width * num_char;
693
694 if( visibleSeg.Length() < seg_minlength )
695 return;
696
697 double textSize = track_width;
698 double penWidth = textSize / 12.0;
699 EDA_ANGLE textOrientation;
700 int num_names = 1;
701
702 if( end.y == start.y ) // horizontal
703 {
704 textOrientation = ANGLE_HORIZONTAL;
705 num_names = std::max( num_names,
706 static_cast<int>( aTrack->GetLength() / viewport.GetWidth() ) );
707 }
708 else if( end.x == start.x ) // vertical
709 {
710 textOrientation = ANGLE_VERTICAL;
711 num_names = std::max( num_names,
712 static_cast<int>( aTrack->GetLength() / viewport.GetHeight() ) );
713 }
714 else
715 {
716 textOrientation = -EDA_ANGLE( visibleSeg.B - visibleSeg.A );
717 textOrientation.Normalize90();
718
719 double min_size = std::min( viewport.GetWidth(), viewport.GetHeight() );
720 num_names = std::max( num_names,
721 static_cast<int>( aTrack->GetLength() / ( M_SQRT2 * min_size ) ) );
722 }
723
724 m_gal->SetIsStroke( true );
725 m_gal->SetIsFill( false );
727 m_gal->SetLineWidth( penWidth );
728 m_gal->SetFontBold( false );
729 m_gal->SetFontItalic( false );
730 m_gal->SetFontUnderlined( false );
731 m_gal->SetTextMirrored( false );
732 m_gal->SetGlyphSize( VECTOR2D( textSize * 0.55, textSize * 0.55 ) );
735
736 for( int ii = 0; ii < num_names; ++ii )
737 {
738 VECTOR2I textPosition =
739 VECTOR2D( start ) * static_cast<double>( num_names - ii ) / ( num_names + 1 )
740 + VECTOR2D( end ) * static_cast<double>( ii + 1 ) / ( num_names + 1 );
741 m_gal->BitmapText( netName, textPosition, textOrientation );
742 }
743
744 return;
745 }
746 else if( IsCopperLayer( aLayer ) || aLayer == LAYER_LOCKED_ITEM_SHADOW )
747 {
748 // Draw a regular track
749 bool outline_mode = pcbconfig()
751 && aLayer != LAYER_LOCKED_ITEM_SHADOW;
754 m_gal->SetIsStroke( outline_mode );
755 m_gal->SetIsFill( not outline_mode );
757
758 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
759 track_width = track_width + m_lockedShadowMargin;
760
761 m_gal->DrawSegment( start, end, track_width );
762 }
763
764 // Clearance lines
765 if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
767 {
768 int clearance = aTrack->GetOwnClearance( m_pcbSettings.GetActiveLayer() );
769
771 m_gal->SetIsFill( false );
772 m_gal->SetIsStroke( true );
774 m_gal->DrawSegment( start, end, track_width + clearance * 2 );
775 }
776}
void SetOrigin(const Vec &pos)
Definition: box2.h:202
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:119
const Vec & GetOrigin() const
Definition: box2.h:183
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:255
EDA_ANGLE Normalize90()
Definition: eda_angle.h:260
const VECTOR2I & GetScreenPixelSize() const
Return GAL canvas size in pixels.
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:382
virtual double GetLength() const
Function GetLength returns the length of the track using the hypotenuse calculation.
Definition: pcb_track.cpp:315
static constexpr EDA_ANGLE & ANGLE_VERTICAL
Definition: eda_angle.h:409
bool ClipLine(const BOX2I *aClipBox, int &x1, int &y1, int &x2, int &y2)
Test if any part of a line falls within the bounds of a rectangle.

References SEG::A, ANGLE_HORIZONTAL, ANGLE_VERTICAL, SEG::B, KIGFX::GAL::BitmapText(), ClipLine(), color, KIGFX::GAL::DrawSegment(), KIGFX::RENDER_SETTINGS::GetActiveLayer(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), PCB_TRACK::GetEnd(), BOX2< Vec >::GetHeight(), PCB_TRACK::GetLength(), BOARD_CONNECTED_ITEM::GetNetCode(), BOX2< Vec >::GetOrigin(), BOARD_CONNECTED_ITEM::GetOwnClearance(), KIGFX::GAL::GetScreenPixelSize(), KIGFX::GAL::GetScreenWorldMatrix(), BOX2< Vec >::GetSize(), PCB_TRACK::GetStart(), BOARD_CONNECTED_ITEM::GetUnescapedShortNetname(), BOX2< Vec >::GetWidth(), PCB_TRACK::GetWidth(), GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_CENTER, IsCopperLayer(), IsNetnameLayer(), LAYER_LOCKED_ITEM_SHADOW, SEG::Length(), PCBNEW_SETTINGS::m_Display, PCBNEW_SETTINGS::DISPLAY_OPTIONS::m_DisplayPcbTrackFill, KIGFX::PAINTER::m_gal, KIGFX::RENDER_SETTINGS::m_isPrinting, m_lockedShadowMargin, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, BOX2< Vec >::Normalize(), EDA_ANGLE::Normalize90(), pcbconfig(), BOX2< Vec >::SetEnd(), KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetFontBold(), KIGFX::GAL::SetFontItalic(), KIGFX::GAL::SetFontUnderlined(), KIGFX::GAL::SetGlyphSize(), KIGFX::GAL::SetHorizontalJustify(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), BOX2< Vec >::SetOrigin(), KIGFX::GAL::SetStrokeColor(), KIGFX::GAL::SetTextMirrored(), KIGFX::GAL::SetVerticalJustify(), SHOW_WITH_VIA_ALWAYS, NETINFO_LIST::UNCONNECTED, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by draw(), and Draw().

◆ draw() [15/16]

void PCB_PAINTER::draw ( const PCB_VIA aVia,
int  aLayer 
)
protected

Definition at line 858 of file pcb_painter.cpp.

859{
860 const BOARD* board = aVia->GetBoard();
861 COLOR4D color = m_pcbSettings.GetColor( aVia, aLayer );
862 VECTOR2D center( aVia->GetStart() );
863
864 if( color == COLOR4D::CLEAR )
865 return;
866
867 // Draw description layer
868 if( IsNetnameLayer( aLayer ) )
869 {
870 VECTOR2D position( center );
871
872 // Is anything that we can display enabled (netname and/or layers ids)?
873 bool showNets = pcbconfig() && pcbconfig()->m_Display.m_NetNames != 0
874 && !aVia->GetNetname().empty();
875 bool showLayers = aVia->GetViaType() != VIATYPE::THROUGH;
876
877 if( !showNets && !showLayers )
878 return;
879
880 double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
881 double size = aVia->GetWidth();
882
883 // Font size limits
884 if( size > maxSize )
885 size = maxSize;
886
887 m_gal->Save();
888 m_gal->Translate( position );
889
890 // Default font settings
894 m_gal->SetFontBold( false );
895 m_gal->SetFontItalic( false );
896 m_gal->SetFontUnderlined( false );
897 m_gal->SetTextMirrored( false );
898 m_gal->SetStrokeColor( m_pcbSettings.GetColor( nullptr, aLayer ) );
899 m_gal->SetIsStroke( true );
900 m_gal->SetIsFill( false );
901
902 // Set the text position via position. if only one text, it is on the via position
903 // For 2 lines, the netname is slightly below the center, and the layer IDs above
904 // the netname
905 VECTOR2D textpos( 0.0, 0.0 );
906
907 wxString netname = aVia->GetUnescapedShortNetname();
908
909 int topLayer = aVia->TopLayer() + 1;
910 int bottomLayer = std::min( aVia->BottomLayer() + 1, board->GetCopperLayerCount() );
911
912 wxString layerIds;
913 layerIds.Printf( wxT( "%d-%d" ), topLayer, bottomLayer );
914
915 // a good size is set room for at least 6 chars, to be able to print 2 lines of text,
916 // or at least 3 chars for only the netname
917 // (The layerIds string has 5 chars max)
918 int minCharCnt = showLayers ? 6 : 3;
919
920 // approximate the size of netname and layerIds text:
921 double tsize = 1.5 * size / std::max( PrintableCharCount( netname ), minCharCnt );
922 tsize = std::min( tsize, size );
923
924 // Use a smaller text size to handle interline, pen size..
925 tsize *= 0.75;
926 VECTOR2D namesize( tsize, tsize );
927
928 // For 2 lines, adjust the text pos (move it a small amount to the bottom)
929 if( showLayers )
930 textpos.y += tsize/5;
931
932 m_gal->SetGlyphSize( namesize );
933 m_gal->SetLineWidth( namesize.x / 10.0 );
934
935 if( showNets )
936 m_gal->BitmapText( netname, textpos, ANGLE_HORIZONTAL );
937
938 if( showLayers )
939 {
940 if( showNets )
941 textpos.y -= tsize * 1.3;
942
943 m_gal->BitmapText( layerIds, textpos, ANGLE_HORIZONTAL );
944 }
945
946 m_gal->Restore();
947
948 return;
949 }
950
951 bool outline_mode = pcbconfig() && !pcbconfig()->m_Display.m_DisplayViaFill;
952
955 m_gal->SetIsStroke( true );
956 m_gal->SetIsFill( false );
957
958 if( outline_mode )
960
961 if( aLayer == LAYER_VIA_HOLEWALLS )
962 {
963 double radius = ( getViaDrillSize( aVia ) / 2.0 ) + m_holePlatingThickness;
964
965 if( !outline_mode )
966 {
968 radius -= m_holePlatingThickness / 2.0;
969 }
970
971 m_gal->DrawCircle( center, radius );
972 }
973 else if( aLayer == LAYER_VIA_HOLES )
974 {
975 m_gal->SetIsStroke( false );
976 m_gal->SetIsFill( true );
977 m_gal->DrawCircle( center, getViaDrillSize( aVia ) / 2.0 );
978 }
979 else if( aLayer == LAYER_VIA_THROUGH || m_pcbSettings.IsPrinting() )
980 {
981 int annular_width = ( aVia->GetWidth() - getViaDrillSize( aVia ) ) / 2.0;
982 double radius = aVia->GetWidth() / 2.0;
983 bool draw = false;
984
986 {
988 }
989 else if( aVia->FlashLayer( board->GetVisibleLayers() & board->GetEnabledLayers() ) )
990 {
991 draw = true;
992 }
993 else if( aVia->IsSelected() )
994 {
995 draw = true;
996 outline_mode = true;
998 }
999
1000 if( !outline_mode )
1001 {
1002 m_gal->SetLineWidth( annular_width );
1003 radius -= annular_width / 2.0;
1004 }
1005
1006 if( draw )
1007 m_gal->DrawCircle( center, radius );
1008 }
1009 else if( aLayer == LAYER_VIA_BBLIND || aLayer == LAYER_VIA_MICROVIA )
1010 {
1011 int annular_width = ( aVia->GetWidth() - getViaDrillSize( aVia ) ) / 2.0;
1012 double radius = aVia->GetWidth() / 2.0;
1013
1014 // Outer circles of blind/buried and micro-vias are drawn in a special way to indicate the
1015 // top and bottom layers
1016 PCB_LAYER_ID layerTop, layerBottom;
1017 aVia->LayerPair( &layerTop, &layerBottom );
1018
1019 if( !outline_mode )
1020 {
1021 m_gal->SetIsStroke( false );
1022 m_gal->SetIsFill( true );
1023 }
1024
1025 m_gal->SetStrokeColor( m_pcbSettings.GetColor( aVia, layerTop ) );
1026 m_gal->SetFillColor( m_pcbSettings.GetColor( aVia, layerTop ) );
1027 m_gal->DrawArc( center, radius, EDA_ANGLE( 240, DEGREES_T ), EDA_ANGLE( 300, DEGREES_T ) );
1028
1029 m_gal->SetStrokeColor( m_pcbSettings.GetColor( aVia, layerBottom ) );
1030 m_gal->SetFillColor( m_pcbSettings.GetColor( aVia, layerBottom ) );
1031 m_gal->DrawArc( center, radius, EDA_ANGLE( 60, DEGREES_T ), EDA_ANGLE( 120, DEGREES_T ) );
1032
1035 m_gal->SetIsStroke( true );
1036 m_gal->SetIsFill( false );
1037
1038 if( !outline_mode )
1039 {
1040 m_gal->SetLineWidth( annular_width );
1041 radius -= annular_width / 2.0;
1042 }
1043
1044 m_gal->DrawCircle( center, radius );
1045 }
1046 else if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) // draw a ring around the via
1047 {
1049
1050 m_gal->DrawCircle( center, ( aVia->GetWidth() + m_lockedShadowMargin ) / 2.0 );
1051 }
1052
1053 // Clearance lines
1055 && aLayer != LAYER_VIA_HOLES
1057 {
1059 double radius;
1060
1061 if( aVia->FlashLayer( activeLayer ) )
1062 radius = aVia->GetWidth() / 2.0;
1063 else
1064 radius = getViaDrillSize( aVia ) / 2.0 + m_holePlatingThickness;
1065
1067 m_gal->SetIsFill( false );
1068 m_gal->SetIsStroke( true );
1070 m_gal->DrawCircle( center, radius + aVia->GetOwnClearance( activeLayer ) );
1071 }
1072}
int GetCopperLayerCount() const
Definition: board.cpp:541
static const COLOR4D CLEAR
Definition: color4d.h:401
virtual void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aEndAngle)
Draw an arc.
void draw(const PCB_TRACK *aTrack, int aLayer)
virtual int getViaDrillSize(const PCB_VIA *aVia) const
Return drill diameter for a via (internal units).
PCB_LAYER_ID BottomLayer() const
Definition: pcb_track.cpp:600
bool FlashLayer(int aLayer) const
Checks to see whether the via should have a pad on the specific layer.
Definition: pcb_track.cpp:631
PCB_LAYER_ID TopLayer() const
Definition: pcb_track.cpp:594
VIATYPE GetViaType() const
Definition: pcb_track.h:393
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
Definition: pcb_track.cpp:572
@ DEGREES_T
Definition: eda_angle.h:31
@ LAYER_VIA_HOLEWALLS
Definition: layer_ids.h:234
@ LAYER_VIA_HOLES
to draw via holes (pad holes do not use this layer)
Definition: layer_ids.h:215
@ LAYER_VIA_MICROVIA
to draw micro vias
Definition: layer_ids.h:194
@ LAYER_VIA_THROUGH
to draw usual through hole vias
Definition: layer_ids.h:196
@ LAYER_VIA_BBLIND
to draw blind/buried vias
Definition: layer_ids.h:195
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
TRACK_CLEARANCE_MODE m_TrackClearance

References ANGLE_HORIZONTAL, KIGFX::GAL::BitmapText(), PCB_VIA::BottomLayer(), KIGFX::COLOR4D::CLEAR, color, DEGREES_T, draw(), KIGFX::GAL::DrawArc(), KIGFX::GAL::DrawCircle(), PCB_VIA::FlashLayer(), KIGFX::RENDER_SETTINGS::GetActiveLayer(), BOARD_ITEM::GetBoard(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), BOARD::GetCopperLayerCount(), BOARD::GetEnabledLayers(), BOARD_CONNECTED_ITEM::GetNetname(), BOARD_CONNECTED_ITEM::GetOwnClearance(), KIGFX::RENDER_SETTINGS::GetPrintLayers(), PCB_TRACK::GetStart(), BOARD_CONNECTED_ITEM::GetUnescapedShortNetname(), getViaDrillSize(), PCB_VIA::GetViaType(), BOARD::GetVisibleLayers(), PCB_TRACK::GetWidth(), GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_CENTER, IsNetnameLayer(), KIGFX::RENDER_SETTINGS::IsPrinting(), EDA_ITEM::IsSelected(), LAYER_LOCKED_ITEM_SHADOW, LAYER_VIA_BBLIND, LAYER_VIA_HOLES, LAYER_VIA_HOLEWALLS, LAYER_VIA_MICROVIA, LAYER_VIA_THROUGH, PCB_VIA::LayerPair(), PCBNEW_SETTINGS::m_Display, PCBNEW_SETTINGS::DISPLAY_OPTIONS::m_DisplayViaFill, KIGFX::PAINTER::m_gal, m_holePlatingThickness, KIGFX::RENDER_SETTINGS::m_isPrinting, m_lockedShadowMargin, PCBNEW_SETTINGS::DISPLAY_OPTIONS::m_NetNames, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, PCBNEW_SETTINGS::DISPLAY_OPTIONS::m_TrackClearance, KIGFX::PCB_RENDER_SETTINGS::MAX_FONT_SIZE, pcbconfig(), PrintableCharCount(), KIGFX::GAL::ResetTextAttributes(), KIGFX::GAL::Restore(), KIGFX::GAL::Save(), KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetFontBold(), KIGFX::GAL::SetFontItalic(), KIGFX::GAL::SetFontUnderlined(), KIGFX::GAL::SetGlyphSize(), KIGFX::GAL::SetHorizontalJustify(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), KIGFX::GAL::SetTextMirrored(), KIGFX::GAL::SetVerticalJustify(), SHOW_WITH_VIA_ALWAYS, THROUGH, PCB_VIA::TopLayer(), KIGFX::GAL::Translate(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ Draw()

bool PCB_PAINTER::Draw ( const VIEW_ITEM aItem,
int  aLayer 
)
overridevirtual

Takes an instance of VIEW_ITEM and passes it to a function that knows how to draw the item.

Parameters
aItemis an item to be drawn.
aLayertells which layer is currently rendered so that draw functions may know what to draw (eg. for pads there are separate layers for holes, because they have other dimensions then the pad itself.

Implements KIGFX::PAINTER.

Definition at line 489 of file pcb_painter.cpp.

490{
491 const BOARD_ITEM* item = dynamic_cast<const BOARD_ITEM*>( aItem );
492
493 if( !item )
494 return false;
495
496 if( const BOARD* board = item->GetBoard() )
497 {
498 BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
502
503 if( item->GetParentFootprint() && !board->IsFootprintHolder() )
504 {
505 FOOTPRINT* parentFP = static_cast<FOOTPRINT*>( item->GetParentFootprint() );
506
507 // Never draw footprint bitmaps on board
508 if( item->Type() == PCB_BITMAP_T )
509 return false;
510 else if( item->GetLayerSet().count() > 1 )
511 {
512 // For multi-layer objects, exclude only those layers that are private
513 if( IsPcbLayer( aLayer ) && parentFP->GetPrivateLayers().test( aLayer ) )
514 return false;
515 }
516 else if( item->GetLayerSet().count() == 1 )
517 {
518 // For single-layer objects, exclude all layers including ancillary layers
519 // such as holes, netnames, etc.
520 PCB_LAYER_ID singleLayer = item->GetLayerSet().Seq()[0];
521
522 if( parentFP->GetPrivateLayers().test( singleLayer ) )
523 return false;
524 }
525 }
526 }
527 else
528 {
531 }
532
533 // the "cast" applied in here clarifies which overloaded draw() is called
534 switch( item->Type() )
535 {
536 case PCB_TRACE_T:
537 draw( static_cast<const PCB_TRACK*>( item ), aLayer );
538 break;
539
540 case PCB_ARC_T:
541 draw( static_cast<const PCB_ARC*>( item ), aLayer );
542 break;
543
544 case PCB_VIA_T:
545 draw( static_cast<const PCB_VIA*>( item ), aLayer );
546 break;
547
548 case PCB_PAD_T:
549 draw( static_cast<const PAD*>( item ), aLayer );
550 break;
551
552 case PCB_SHAPE_T:
553 case PCB_FP_SHAPE_T:
554 draw( static_cast<const PCB_SHAPE*>( item ), aLayer );
555 break;
556
557 case PCB_BITMAP_T:
558 draw( static_cast<const PCB_BITMAP*>( item ), aLayer );
559 break;
560
561 case PCB_TEXT_T:
562 draw( static_cast<const PCB_TEXT*>( item ), aLayer );
563 break;
564
565 case PCB_TEXTBOX_T:
566 draw( static_cast<const PCB_TEXTBOX*>( item ), aLayer );
567 break;
568
569 case PCB_FP_TEXT_T:
570 draw( static_cast<const FP_TEXT*>( item ), aLayer );
571 break;
572
573 case PCB_FP_TEXTBOX_T:
574 draw( static_cast<const FP_TEXTBOX*>( item ), aLayer );
575 break;
576
577 case PCB_FOOTPRINT_T:
578 draw( static_cast<const FOOTPRINT*>( item ), aLayer );
579 break;
580
581 case PCB_GROUP_T:
582 draw( static_cast<const PCB_GROUP*>( item ), aLayer );
583 break;
584
585 case PCB_ZONE_T:
586 case PCB_FP_ZONE_T:
587 draw( static_cast<const ZONE*>( item ), aLayer );
588 break;
589
591 case PCB_DIM_CENTER_T:
592 case PCB_DIM_RADIAL_T:
594 case PCB_DIM_LEADER_T:
600 draw( static_cast<const PCB_DIMENSION_BASE*>( item ), aLayer );
601 break;
602
603 case PCB_TARGET_T:
604 draw( static_cast<const PCB_TARGET*>( item ) );
605 break;
606
607 case PCB_MARKER_T:
608 draw( static_cast<const PCB_MARKER*>( item ), aLayer );
609 break;
610
611 default:
612 // Painter does not know how to draw the object
613 return false;
614 }
615
616 // Draw bounding boxes after drawing objects so they can be seen.
618 {
619 // Show bounding boxes of painted objects for debugging.
620 BOX2I box = item->GetBoundingBox();
621
622 m_gal->SetIsFill( false );
623 m_gal->SetIsStroke( true );
624
625 if( item->Type() == PCB_FOOTPRINT_T )
626 {
627 m_gal->SetStrokeColor( item->IsSelected() ? COLOR4D( 1.0, 0.2, 0.2, 1 ) :
628 COLOR4D( MAGENTA ) );
629 }
630 else
631 {
632 m_gal->SetStrokeColor( item->IsSelected() ? COLOR4D( 1.0, 0.2, 0.2, 1 ) :
633 COLOR4D( 0.4, 0.4, 0.4, 1 ) );
634 }
635
636 m_gal->SetLineWidth( 1 );
637 m_gal->DrawRectangle( box.GetOrigin(), box.GetEnd() );
638
639 if( item->Type() == PCB_FOOTPRINT_T )
640 {
641 m_gal->SetStrokeColor( item->IsSelected() ? COLOR4D( 1.0, 0.2, 0.2, 1 ) :
642 COLOR4D( CYAN ) );
643
644 const FOOTPRINT* fp = static_cast<const FOOTPRINT*>( item );
645
646 if( fp )
647 {
648 const SHAPE_POLY_SET& convex = fp->GetBoundingHull();
649
650 m_gal->DrawPolyline( convex.COutline( 0 ) );
651 }
652 }
653 }
654
655 return true;
656}
Container for design settings for a BOARD object.
int GetHolePlatingThickness() const
Pad & via drills are finish size.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
const Vec GetEnd() const
Definition: box2.h:185
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:74
LSET GetPrivateLayers() const
Definition: footprint.h:120
virtual void DrawPolyline(const std::deque< VECTOR2D > &aPointList)
Draw a polyline.
bool GetDrawBoundingBoxes() const
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
Object to handle a bitmap image that can be inserted in a PCB.
Definition: pcb_bitmap.h:42
Abstract dimension API.
Definition: pcb_dimension.h:96
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:51
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
@ MAGENTA
Definition: color4d.h:60
@ CYAN
Definition: color4d.h:58
bool IsPcbLayer(int aLayer)
Test whether a layer is a valid layer for Pcbnew.
Definition: layer_ids.h:814
@ F_SilkS
Definition: layer_ids.h:104
@ PCB_FP_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:95
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:110
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:107
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102
@ PCB_FP_TEXTBOX_T
class FP_TEXTBOX, wrapped text in a footprint
Definition: typeinfo.h:93
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:108
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:115
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:91
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:112
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:90
@ PCB_FP_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:97
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
Definition: typeinfo.h:104
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:111
@ PCB_FP_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:99
@ PCB_FP_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:96
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:106
@ PCB_FP_ZONE_T
class ZONE, managed by a footprint
Definition: typeinfo.h:100
@ PCB_BITMAP_T
class PCB_BITMAP, bitmap on a layer
Definition: typeinfo.h:89
@ PCB_FP_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:98
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:103
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:101
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:109

References ARC_HIGH_DEF, SHAPE_POLY_SET::COutline(), CYAN, draw(), KIGFX::GAL::DrawPolyline(), KIGFX::GAL::DrawRectangle(), F_SilkS, BOARD_ITEM::GetBoard(), EDA_ITEM::GetBoundingBox(), FOOTPRINT::GetBoundingHull(), KIGFX::RENDER_SETTINGS::GetDrawBoundingBoxes(), BOX2< Vec >::GetEnd(), BOARD_DESIGN_SETTINGS::GetHolePlatingThickness(), BOARD_ITEM::GetLayerSet(), BOARD_DESIGN_SETTINGS::GetLineThickness(), BOX2< Vec >::GetOrigin(), BOARD_ITEM::GetParentFootprint(), FOOTPRINT::GetPrivateLayers(), IsPcbLayer(), EDA_ITEM::IsSelected(), KIGFX::PAINTER::m_gal, m_holePlatingThickness, m_lockedShadowMargin, BOARD_DESIGN_SETTINGS::m_MaxError, m_maxError, m_pcbSettings, MAGENTA, PCB_ARC_T, PCB_BITMAP_T, PCB_DIM_ALIGNED_T, PCB_DIM_CENTER_T, PCB_DIM_LEADER_T, PCB_DIM_ORTHOGONAL_T, PCB_DIM_RADIAL_T, PCB_FOOTPRINT_T, PCB_FP_DIM_ALIGNED_T, PCB_FP_DIM_CENTER_T, PCB_FP_DIM_LEADER_T, PCB_FP_DIM_ORTHOGONAL_T, PCB_FP_DIM_RADIAL_T, PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PCB_FP_TEXTBOX_T, PCB_FP_ZONE_T, PCB_GROUP_T, PCB_MARKER_T, PCB_PAD_T, PCB_SHAPE_T, PCB_TARGET_T, PCB_TEXT_T, PCB_TEXTBOX_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, LSET::Seq(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), and EDA_ITEM::Type().

◆ draw() [16/16]

void PCB_PAINTER::draw ( const ZONE aZone,
int  aLayer 
)
protected

Definition at line 2396 of file pcb_painter.cpp.

2397{
2398 if( aLayer == LAYER_CONFLICTS_SHADOW )
2399 {
2400 COLOR4D color = m_pcbSettings.GetColor( aZone, aLayer );
2401
2402 m_gal->SetIsFill( true );
2403 m_gal->SetIsStroke( false );
2405
2406 m_gal->DrawPolygon( aZone->Outline()->Outline( 0 ) );
2407 return;
2408 }
2409
2410 /*
2411 * aLayer will be the virtual zone layer (LAYER_ZONE_START, ... in GAL_LAYER_ID)
2412 * This is used for draw ordering in the GAL.
2413 * The color for the zone comes from the associated copper layer ( aLayer - LAYER_ZONE_START )
2414 * and the visibility comes from the combination of that copper layer and LAYER_ZONES
2415 */
2416 PCB_LAYER_ID layer;
2417
2418 if( IsZoneFillLayer( aLayer ) )
2419 layer = ToLAYER_ID( aLayer - LAYER_ZONE_START );
2420 else
2421 layer = ToLAYER_ID( aLayer );
2422
2423 if( !aZone->IsOnLayer( layer ) )
2424 return;
2425
2426 COLOR4D color = m_pcbSettings.GetColor( aZone, layer );
2427 std::deque<VECTOR2D> corners;
2429
2430 // Draw the outline
2431 if( !IsZoneFillLayer( aLayer ) )
2432 {
2433 const SHAPE_POLY_SET* outline = aZone->Outline();
2434
2435 if( !m_pcbSettings.m_isPrinting && outline && outline->OutlineCount() > 0 )
2436 {
2437 m_gal->SetStrokeColor( color.a > 0.0 ? color.WithAlpha( 1.0 ) : color );
2438 m_gal->SetIsFill( false );
2439 m_gal->SetIsStroke( true );
2441
2442 // Draw each contour (main contour and holes)
2443
2444 /*
2445 * m_gal->DrawPolygon( *outline );
2446 * should be enough, but currently does not work to draw holes contours in a complex
2447 * polygon so each contour is draw as a simple polygon
2448 */
2449
2450 // Draw the main contour(s?)
2451 for( int ii = 0; ii < outline->OutlineCount(); ++ii )
2452 {
2453 m_gal->DrawPolyline( outline->COutline( ii ) );
2454
2455 // Draw holes
2456 int holes_count = outline->HoleCount( ii );
2457
2458 for( int jj = 0; jj < holes_count; ++jj )
2459 m_gal->DrawPolyline( outline->CHole( ii, jj ) );
2460 }
2461
2462 // Draw hatch lines
2463 for( const SEG& hatchLine : aZone->GetHatchLines() )
2464 m_gal->DrawLine( hatchLine.A, hatchLine.B );
2465 }
2466 }
2467
2468 // Draw the filling
2469 if( IsZoneFillLayer( aLayer )
2470 && ( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED
2472 || displayMode == ZONE_DISPLAY_MODE::SHOW_TRIANGULATION ) )
2473 {
2474 const std::shared_ptr<SHAPE_POLY_SET>& polySet = aZone->GetFilledPolysList( layer );
2475
2476 if( polySet->OutlineCount() == 0 ) // Nothing to draw
2477 return;
2478
2481 m_gal->SetLineWidth( 0 );
2482
2483 if( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED )
2484 {
2485 m_gal->SetIsFill( true );
2486 m_gal->SetIsStroke( false );
2487 }
2488 else
2489 {
2490 m_gal->SetIsFill( false );
2491 m_gal->SetIsStroke( true );
2492 }
2493
2494 m_gal->DrawPolygon( *polySet, displayMode == ZONE_DISPLAY_MODE::SHOW_TRIANGULATION );
2495 }
2496}
ZONE_DISPLAY_MODE m_ZoneDisplayMode
Definition: pcb_painter.h:124
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
const std::vector< SEG > & GetHatchLines() const
Definition: zone.h:761
const std::shared_ptr< SHAPE_POLY_SET > & GetFilledPolysList(PCB_LAYER_ID aLayer) const
Definition: zone.h:602
SHAPE_POLY_SET * Outline()
Definition: zone.h:312
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
Definition: zone.cpp:317
@ LAYER_ZONE_START
Virtual layers for stacking zones and tracks on a given copper layer.
Definition: layer_ids.h:253
bool IsZoneFillLayer(int aLayer)
Definition: layer_ids.h:995

References SHAPE_POLY_SET::CHole(), color, SHAPE_POLY_SET::COutline(), KIGFX::GAL::DrawLine(), KIGFX::GAL::DrawPolygon(), KIGFX::GAL::DrawPolyline(), KIGFX::PCB_RENDER_SETTINGS::GetColor(), ZONE::GetFilledPolysList(), ZONE::GetHatchLines(), SHAPE_POLY_SET::HoleCount(), ZONE::IsOnLayer(), IsZoneFillLayer(), LAYER_CONFLICTS_SHADOW, LAYER_ZONE_START, KIGFX::PAINTER::m_gal, KIGFX::RENDER_SETTINGS::m_isPrinting, KIGFX::RENDER_SETTINGS::m_outlineWidth, m_pcbSettings, KIGFX::PCB_RENDER_SETTINGS::m_ZoneDisplayMode, ZONE::Outline(), SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), KIGFX::GAL::SetFillColor(), KIGFX::GAL::SetIsFill(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), KIGFX::GAL::SetStrokeColor(), SHOW_FILLED, SHOW_FRACTURE_BORDERS, SHOW_TRIANGULATION, and ToLAYER_ID().

◆ getDrillShape()

int PCB_PAINTER::getDrillShape ( const PAD aPad) const
protectedvirtual

Return drill shape of a pad.

Reimplemented in KIGFX::PCB_PRINT_PAINTER.

Definition at line 470 of file pcb_painter.cpp.

471{
472 return aPad->GetDrillShape();
473}
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: pad.h:383

References PAD::GetDrillShape().

Referenced by KIGFX::PCB_PRINT_PAINTER::getDrillShape().

◆ getLineThickness()

int PCB_PAINTER::getLineThickness ( int  aActualThickness) const
protected

Get the thickness to draw for a line (e.g.

0 thickness lines get a minimum value).

Parameters
aActualThicknessline own thickness
Returns
the thickness to draw

Definition at line 458 of file pcb_painter.cpp.

459{
460 // if items have 0 thickness, draw them with the outline
461 // width, otherwise respect the set value (which, no matter
462 // how small will produce something)
463 if( aActualThickness == 0 )
465
466 return aActualThickness;
467}

References KIGFX::RENDER_SETTINGS::m_outlineWidth, and m_pcbSettings.

Referenced by draw().

◆ getPadHoleShape()

SHAPE_SEGMENT PCB_PAINTER::getPadHoleShape ( const PAD aPad) const
protectedvirtual

Return hole shape for a pad (internal units).

Reimplemented in KIGFX::PCB_PRINT_PAINTER.

Definition at line 476 of file pcb_painter.cpp.

477{
478 SHAPE_SEGMENT segm = *aPad->GetEffectiveHoleShape().get();
479 return segm;
480}

References PAD::GetEffectiveHoleShape().

Referenced by draw(), and KIGFX::PCB_PRINT_PAINTER::getPadHoleShape().

◆ GetSettings()

virtual PCB_RENDER_SETTINGS * KIGFX::PCB_PAINTER::GetSettings ( )
inlineoverridevirtual

Return a pointer to current settings that are going to be used when drawing items.

Returns
Current rendering settings.

Implements KIGFX::PAINTER.

Definition at line 163 of file pcb_painter.h.

164 {
165 return &m_pcbSettings;
166 }

References m_pcbSettings.

Referenced by PCB_BASE_FRAME::ActivateGalCanvas(), PCB_EDIT_FRAME::CommonSettingsChanged(), PCBNEW_PRINTOUT::setupPainter(), PAD::ViewGetLOD(), PCB_SHAPE::ViewGetLOD(), PCB_TEXT::ViewGetLOD(), PCB_TEXTBOX::ViewGetLOD(), PCB_TRACK::ViewGetLOD(), and PCB_VIA::ViewGetLOD().

◆ getViaDrillSize()

int PCB_PAINTER::getViaDrillSize ( const PCB_VIA aVia) const
protectedvirtual

Return drill diameter for a via (internal units).

Reimplemented in KIGFX::PCB_PRINT_PAINTER.

Definition at line 483 of file pcb_painter.cpp.

484{
485 return aVia->GetDrillValue();
486}
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Definition: pcb_track.cpp:222

References PCB_VIA::GetDrillValue().

Referenced by draw(), and KIGFX::PCB_PRINT_PAINTER::getViaDrillSize().

◆ SetGAL()

void KIGFX::PAINTER::SetGAL ( GAL aGal)
inlineinherited

Changes Graphics Abstraction Layer used for drawing items for a new one.

Parameters
aGalis the new GAL instance.

Definition at line 75 of file painter.h.

76 {
77 m_gal = aGal;
78 }

References KIGFX::PAINTER::m_gal.

◆ strokeText()

void PCB_PAINTER::strokeText ( const wxString &  aText,
const VECTOR2I aPosition,
const TEXT_ATTRIBUTES aAttrs 
)
protected

Definition at line 1854 of file pcb_painter.cpp.

1856{
1857 KIFONT::FONT* font = aAttrs.m_Font;
1858
1859 if( !font )
1860 font = KIFONT::FONT::GetFont( wxEmptyString, aAttrs.m_Bold, aAttrs.m_Italic );
1861
1862 m_gal->SetIsFill( font->IsOutline() );
1863 m_gal->SetIsStroke( font->IsStroke() );
1864
1865 font->Draw( m_gal, aText, aPosition, aAttrs );
1866}
KIFONT::FONT * m_Font

References KIFONT::FONT::Draw(), KIFONT::FONT::GetFont(), KIFONT::FONT::IsOutline(), KIFONT::FONT::IsStroke(), TEXT_ATTRIBUTES::m_Bold, TEXT_ATTRIBUTES::m_Font, KIGFX::PAINTER::m_gal, TEXT_ATTRIBUTES::m_Italic, KIGFX::GAL::SetIsFill(), and KIGFX::GAL::SetIsStroke().

Referenced by draw().

◆ viewer_settings()

PCB_VIEWERS_SETTINGS_BASE * PCB_PAINTER::viewer_settings ( )
protected

Definition at line 80 of file pcb_painter.cpp.

81{
82 switch( m_frameType )
83 {
88 default:
89 return Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
90
94 case FRAME_CVPCB:
96 return Pgm().GetSettingsManager().GetAppSettings<CVPCB_SETTINGS>();
97 }
98}
@ FRAME_FOOTPRINT_VIEWER_MODAL
Definition: frame_type.h:43
@ FRAME_CVPCB_DISPLAY
Definition: frame_type.h:49
@ FRAME_FOOTPRINT_VIEWER
Definition: frame_type.h:42
@ FRAME_FOOTPRINT_WIZARD
Definition: frame_type.h:44
@ FRAME_FOOTPRINT_PREVIEW
Definition: frame_type.h:46
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:41
@ FRAME_PCB_DISPLAY3D
Definition: frame_type.h:45
@ FRAME_CVPCB
Definition: frame_type.h:48
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111

References FRAME_CVPCB, FRAME_CVPCB_DISPLAY, FRAME_FOOTPRINT_EDITOR, FRAME_FOOTPRINT_PREVIEW, FRAME_FOOTPRINT_VIEWER, FRAME_FOOTPRINT_VIEWER_MODAL, FRAME_FOOTPRINT_WIZARD, FRAME_PCB_DISPLAY3D, FRAME_PCB_EDITOR, m_frameType, and Pgm().

Referenced by draw().

Member Data Documentation

◆ m_frameType

FRAME_T KIGFX::PCB_PAINTER::m_frameType
protected

Definition at line 220 of file pcb_painter.h.

Referenced by draw(), and viewer_settings().

◆ m_gal

GAL* KIGFX::PAINTER::m_gal
protectedinherited

Instance of graphic abstraction layer that gives an interface to call commands used to draw (eg.

DrawLine, DrawCircle, etc.)

Definition at line 101 of file painter.h.

Referenced by KIGFX::SCH_PAINTER::draw(), draw(), Draw(), KIGFX::GERBVIEW_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::drawApertureMacro(), KIGFX::GERBVIEW_PAINTER::drawFlashedShape(), KIGFX::GERBVIEW_PAINTER::drawPolygon(), KIGFX::SCH_PAINTER::getShadowWidth(), KIGFX::PAINTER::SetGAL(), and strokeText().

◆ m_holePlatingThickness

int KIGFX::PCB_PAINTER::m_holePlatingThickness
protected

Definition at line 223 of file pcb_painter.h.

Referenced by draw(), and Draw().

◆ m_lockedShadowMargin

int KIGFX::PCB_PAINTER::m_lockedShadowMargin
protected

Definition at line 224 of file pcb_painter.h.

Referenced by draw(), and Draw().

◆ m_maxError

int KIGFX::PCB_PAINTER::m_maxError
protected

Definition at line 222 of file pcb_painter.h.

Referenced by draw(), and Draw().

◆ m_pcbSettings

PCB_RENDER_SETTINGS KIGFX::PCB_PAINTER::m_pcbSettings
protected

Definition at line 219 of file pcb_painter.h.

Referenced by draw(), Draw(), getLineThickness(), and GetSettings().


The documentation for this class was generated from the following files: