From 236feeb59283ac3fe0589c1655cd270dd584b10c Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 10 Jan 2022 14:03:53 +0000 Subject: [PATCH] Cleanup GRText APIs, 3D Viewer <-> board APIs, and Plotter APIs. Also fixes a bug where outline fonts weren't being handled for footprint text in 3D Viewer, and a copy/paste error in stroke font handling for both PCB and footprint text in 3D Viewer. Fixes https://gitlab.com/kicad/code/kicad/issues/10319 --- 3d-viewer/3d_canvas/board_adapter.h | 29 +-- .../3d_canvas/create_3Dgraphic_brd_items.cpp | 209 ++++++++---------- 3d-viewer/3d_canvas/create_layer_items.cpp | 43 ++-- common/eda_text.cpp | 54 ++--- common/gr_text.cpp | 57 +---- common/plotters/plotter.cpp | 15 +- include/gr_text.h | 27 --- pcbnew/fp_text.cpp | 14 +- pcbnew/pcb_text.cpp | 15 +- 9 files changed, 165 insertions(+), 298 deletions(-) diff --git a/3d-viewer/3d_canvas/board_adapter.h b/3d-viewer/3d_canvas/board_adapter.h index 07f7e47885..244c435dbd 100644 --- a/3d-viewer/3d_canvas/board_adapter.h +++ b/3d-viewer/3d_canvas/board_adapter.h @@ -465,32 +465,25 @@ private: void destroyLayers(); // Helper functions to create the board - void createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer, - int aClearanceValue ); + void createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer ); - void createPadWithClearance( const PAD *aPad, CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayer, const VECTOR2I& aClearanceValue ) const; + void createPadWithMargin( const PAD *aPad, CONTAINER_2D_BASE* aDstContainer, + PCB_LAYER_ID aLayer, const VECTOR2I& aMargin ) const; OBJECT_2D* createPadWithDrill( const PAD* aPad, int aInflateValue ); - void addPadsWithClearance( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayerId, int aInflateValue, - bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads, - bool aSkipNonPlatedPads ); + void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer, + PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads, + bool aSkipNonPlatedPads ); - void addFootprintShapesWithClearance( const FOOTPRINT* aFootprint, - CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayerId, int aInflateValue ); + void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer, + PCB_LAYER_ID aLayerId ); - void addShapeWithClearance( const PCB_TEXT* aText, CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayerId, int aClearanceValue ); + void addShape( const PCB_TEXT* aText, CONTAINER_2D_BASE* aDstContainer ); - void addShapeWithClearance( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayerId, int aClearanceValue ); + void addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aDstContainer ); - void addShapeWithClearance( const PCB_DIMENSION_BASE* aDimension, - CONTAINER_2D_BASE* aDstContainer, PCB_LAYER_ID aLayerId, - int aClearanceValue ); + void addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D_BASE* aDstContainer ); void addSolidAreasShapes( const ZONE* aZoneContainer, CONTAINER_2D_BASE* aDstContainer, PCB_LAYER_ID aLayerId ); diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp index 31b961cec5..c9f800a759 100644 --- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp +++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp @@ -49,50 +49,31 @@ #include #include #include -#include #include #include #include #include +#include - -// Based on -// void PCB_TEXT::TransformTextShapeWithClearanceToPolygon -// board_items_to_polygon_shape_transform.cpp -void BOARD_ADAPTER::addShapeWithClearance( const PCB_TEXT* aText, CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayerId, int aClearanceValue ) +void BOARD_ADAPTER::addShape( const PCB_TEXT* aText, CONTAINER_2D_BASE* aDstContainer ) { - VECTOR2I size = aText->GetTextSize(); + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; + KIFONT::FONT* font = aText->GetDrawFont(); + int penWidth = aText->GetEffectiveTextPenWidth() * m_biuTo3Dunits; - if( aText->IsMirrored() ) - size.x = -size.x; - - // Use the actual text width to generate segments. The segment position depend on - // text thickness and justification - int penWidth = aText->GetEffectiveTextPenWidth(); - int adjustedWidth = penWidth + ( 2 * aClearanceValue ); - - GRText( aText->GetTextPos(), aText->GetShownText(), aText->GetTextAngle(), size, - aText->GetHorizJustify(), aText->GetVertJustify(), penWidth, aText->IsItalic(), - aText->IsBold(), aText->GetDrawFont(), + CALLBACK_GAL callback_gal( empty_opts, + // Stroke callback [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) { - const SFVEC2F start3DU( aPt1.x * m_biuTo3Dunits, -aPt1.y * m_biuTo3Dunits ); - const SFVEC2F end3DU ( aPt1.x * m_biuTo3Dunits, -aPt2.y * m_biuTo3Dunits ); + const SFVEC2F a3DU( aPt1.x * m_biuTo3Dunits, -aPt1.y * m_biuTo3Dunits ); + const SFVEC2F b3DU( aPt2.x * m_biuTo3Dunits, -aPt2.y * m_biuTo3Dunits ); - if( Is_segment_a_circle( start3DU, end3DU ) ) - { - aDstContainer->Add( new FILLED_CIRCLE_2D( start3DU, - adjustedWidth * m_biuTo3Dunits / 2, - *aText ) ); - } + if( Is_segment_a_circle( a3DU, b3DU ) ) + aDstContainer->Add( new FILLED_CIRCLE_2D( a3DU, penWidth / 2, *aText ) ); else - { - aDstContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, - adjustedWidth * m_biuTo3Dunits, - *aText ) ); - } + aDstContainer->Add( new ROUND_SEGMENT_2D( a3DU, b3DU, penWidth, *aText ) ); }, + // Triangulation callback [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) { const SFVEC2F a3DU( aPt1.x * m_biuTo3Dunits, -aPt1.y * m_biuTo3Dunits ); @@ -101,16 +82,17 @@ void BOARD_ADAPTER::addShapeWithClearance( const PCB_TEXT* aText, CONTAINER_2D_B aDstContainer->Add( new TRIANGLE_2D( a3DU, b3DU, c3DU, *aText ) ); } ); + + font->Draw( &callback_gal, aText->GetShownText(), aText->GetTextPos(), aText->GetAttributes() ); } -void BOARD_ADAPTER::addShapeWithClearance( const PCB_DIMENSION_BASE* aDimension, - CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayerId, int aClearanceValue ) +void BOARD_ADAPTER::addShape( const PCB_DIMENSION_BASE* aDimension, + CONTAINER_2D_BASE* aDstContainer ) { - addShapeWithClearance( &aDimension->Text(), aDstContainer, aLayerId, aClearanceValue ); + addShape( &aDimension->Text(), aDstContainer ); - const int linewidth = aDimension->GetLineThickness() + ( 2 * aClearanceValue ); + const int linewidth = aDimension->GetLineThickness(); for( const std::shared_ptr& shape : aDimension->GetShapes() ) { @@ -118,11 +100,9 @@ void BOARD_ADAPTER::addShapeWithClearance( const PCB_DIMENSION_BASE* aDimension, { case SH_SEGMENT: { - const SEG& seg = static_cast( shape.get() )->GetSeg(); - + const SEG& seg = static_cast( shape.get() )->GetSeg(); const SFVEC2F start3DU( seg.A.x * m_biuTo3Dunits, -seg.A.y * m_biuTo3Dunits ); - - const SFVEC2F end3DU( seg.B.x * m_biuTo3Dunits, -seg.B.y * m_biuTo3Dunits ); + const SFVEC2F end3DU ( seg.B.x * m_biuTo3Dunits, -seg.B.y * m_biuTo3Dunits ); aDstContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, linewidth * m_biuTo3Dunits, *aDimension ) ); @@ -132,13 +112,13 @@ void BOARD_ADAPTER::addShapeWithClearance( const PCB_DIMENSION_BASE* aDimension, case SH_CIRCLE: { int radius = static_cast( shape.get() )->GetRadius(); - int deltar = aDimension->GetLineThickness(); + int delta = aDimension->GetLineThickness() / 2; SFVEC2F center( shape->Centre().x * m_biuTo3Dunits, shape->Centre().y * m_biuTo3Dunits ); - aDstContainer->Add( new RING_2D( center, ( radius - deltar ) * m_biuTo3Dunits, - ( radius + deltar ) * m_biuTo3Dunits, *aDimension ) ); + aDstContainer->Add( new RING_2D( center, ( radius - delta ) * m_biuTo3Dunits, + ( radius + delta ) * m_biuTo3Dunits, *aDimension ) ); break; } @@ -150,14 +130,41 @@ void BOARD_ADAPTER::addShapeWithClearance( const PCB_DIMENSION_BASE* aDimension, } -// Based on -// void FOOTPRINT::TransformFPShapesWithClearanceToPolygonSet -// board_items_to_polygon_shape_transform.cpp#L204 -void BOARD_ADAPTER::addFootprintShapesWithClearance( const FOOTPRINT* aFootprint, - CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayerId, int aInflateValue ) +void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, + CONTAINER_2D_BASE* aDstContainer, PCB_LAYER_ID aLayerId ) { - std::vector texts; // List of FP_TEXT to convert + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; + std::vector textItems; + FP_TEXT* textItem = nullptr; + float penWidth = 0; + + CALLBACK_GAL callback_gal( empty_opts, + // Stroke callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) + { + const SFVEC2F a3DU( aPt1.x * m_biuTo3Dunits, -aPt1.y * m_biuTo3Dunits ); + const SFVEC2F b3DU( aPt2.x * m_biuTo3Dunits, -aPt2.y * m_biuTo3Dunits ); + + if( Is_segment_a_circle( a3DU, b3DU ) ) + aDstContainer->Add( new FILLED_CIRCLE_2D( a3DU, penWidth / 2, *textItem ) ); + else + aDstContainer->Add( new ROUND_SEGMENT_2D( a3DU, b3DU, penWidth, *textItem ) ); + }, + // Triangulation callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) + { + const SFVEC2F a3DU( aPt1.x * m_biuTo3Dunits, -aPt1.y * m_biuTo3Dunits ); + const SFVEC2F b3DU( aPt2.x * m_biuTo3Dunits, -aPt2.y * m_biuTo3Dunits ); + const SFVEC2F c3DU( aPt3.x * m_biuTo3Dunits, -aPt3.y * m_biuTo3Dunits ); + + aDstContainer->Add( new TRIANGLE_2D( a3DU, b3DU, c3DU, *textItem ) ); + } ); + + if( aFootprint->Reference().GetLayer() == aLayerId && aFootprint->Reference().IsVisible() ) + textItems.push_back( &aFootprint->Reference() ); + + if( aFootprint->Value().GetLayer() == aLayerId && aFootprint->Value().IsVisible() ) + textItems.push_back( &aFootprint->Value() ); for( BOARD_ITEM* item : aFootprint->GraphicalItems() ) { @@ -168,7 +175,7 @@ void BOARD_ADAPTER::addFootprintShapesWithClearance( const FOOTPRINT* aFootprint FP_TEXT* text = static_cast( item ); if( text->GetLayer() == aLayerId && text->IsVisible() ) - texts.push_back( text ); + textItems.push_back( text ); break; } @@ -182,7 +189,7 @@ void BOARD_ADAPTER::addFootprintShapesWithClearance( const FOOTPRINT* aFootprint PCB_DIMENSION_BASE* dimension = static_cast( item ); if( dimension->GetLayer() == aLayerId ) - addShapeWithClearance( dimension, aDstContainer, aLayerId, 0 ); + addShape( dimension, aDstContainer ); break; } @@ -192,7 +199,7 @@ void BOARD_ADAPTER::addFootprintShapesWithClearance( const FOOTPRINT* aFootprint FP_SHAPE* shape = static_cast( item ); if( shape->GetLayer() == aLayerId ) - addShapeWithClearance( (const PCB_SHAPE*) shape, aDstContainer, aLayerId, 0 ); + addShape( static_cast( shape ), aDstContainer ); break; } @@ -202,53 +209,20 @@ void BOARD_ADAPTER::addFootprintShapesWithClearance( const FOOTPRINT* aFootprint } } - // Convert texts for footprints - if( aFootprint->Reference().GetLayer() == aLayerId && aFootprint->Reference().IsVisible() ) - texts.push_back( &aFootprint->Reference() ); - - if( aFootprint->Value().GetLayer() == aLayerId && aFootprint->Value().IsVisible() ) - texts.push_back( &aFootprint->Value() ); - - for( FP_TEXT* text : texts ) + for( FP_TEXT* text : textItems ) { - VECTOR2I size = text->GetTextSize(); - int penWidth = text->GetEffectiveTextPenWidth(); - int adjustedWidth = penWidth + ( 2 * aInflateValue ); + textItem = text; + penWidth = textItem->GetEffectiveTextPenWidth() * m_biuTo3Dunits; - if( text->IsMirrored() ) - size.x = -size.x; + KIFONT::FONT* font = textItem->GetDrawFont(); - GRText( text->GetTextPos(), text->GetShownText(), text->GetTextAngle(), size, - text->GetHorizJustify(), text->GetVertJustify(), penWidth, text->IsItalic(), - text->IsBold(), text->GetDrawFont(), - [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) - { - const SFVEC2F start3DU( aPt1.x * m_biuTo3Dunits, -aPt1.y * m_biuTo3Dunits ); - const SFVEC2F end3DU ( aPt1.x * m_biuTo3Dunits, -aPt2.y * m_biuTo3Dunits ); - - if( Is_segment_a_circle( start3DU, end3DU ) ) - { - aDstContainer->Add( new FILLED_CIRCLE_2D( start3DU, - adjustedWidth * m_biuTo3Dunits / 2, - aFootprint->Value() ) ); - } - else - { - aDstContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, - adjustedWidth * m_biuTo3Dunits, - aFootprint->Value() ) ); - } - }, - [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) - { - //FONT TODO: add triangle to container - } ); + font->Draw( &callback_gal, textItem->GetShownText(), textItem->GetTextPos(), + textItem->GetAttributes() ); } } -void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer, - int aClearanceValue ) +void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer ) { SFVEC2F start3DU( aTrack->GetStart().x * m_biuTo3Dunits, -aTrack->GetStart().y * m_biuTo3Dunits ); // y coord is inverted @@ -257,7 +231,7 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs { case PCB_VIA_T: { - const float radius = ( ( aTrack->GetWidth() / 2 ) + aClearanceValue ) * m_biuTo3Dunits; + const float radius = ( aTrack->GetWidth() / 2 ) * m_biuTo3Dunits; aDstContainer->Add( new FILLED_CIRCLE_2D( start3DU, radius, *aTrack ) ); break; } @@ -274,7 +248,9 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs // We need a circle to segment count. However, the arc angle can be small, and the // radius very big. so we calculate a reasonable value for circlesegcount. if( arcsegcount <= 1 ) // The arc will be approximated by a segment + { circlesegcount = 1; + } else { double cnt = arcsegcount * 3600/std::abs( arc_angle ); @@ -293,9 +269,8 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs } } - transformArcToSegments( VECTOR2I( center.x, center.y ), arc->GetStart(), - arc_angle, circlesegcount, - arc->GetWidth() + 2 * aClearanceValue, aDstContainer, *arc ); + transformArcToSegments( VECTOR2I( center.x, center.y ), arc->GetStart(), arc_angle, + circlesegcount, arc->GetWidth(), aDstContainer, *arc ); break; } @@ -306,13 +281,13 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs // Cannot add segments that have the same start and end point if( Is_segment_a_circle( start3DU, end3DU ) ) { - const float radius = ((aTrack->GetWidth() / 2) + aClearanceValue) * m_biuTo3Dunits; + const float radius = ( aTrack->GetWidth() / 2 ) * m_biuTo3Dunits; aDstContainer->Add( new FILLED_CIRCLE_2D( start3DU, radius, *aTrack ) ); } else { - const float width = (aTrack->GetWidth() + 2 * aClearanceValue ) * m_biuTo3Dunits; + const float width = aTrack->GetWidth() * m_biuTo3Dunits; aDstContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, width, *aTrack ) ); } @@ -326,20 +301,19 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs } -void BOARD_ADAPTER::createPadWithClearance( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayer, - const VECTOR2I& aClearanceValue ) const +void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer, + PCB_LAYER_ID aLayer, const VECTOR2I& aMargin ) const { SHAPE_POLY_SET poly; int maxError = GetBoard()->GetDesignSettings().m_MaxError; - VECTOR2I clearance = aClearanceValue; + VECTOR2I clearance = aMargin; // Our shape-based builder can't handle negative or differing x:y clearance values (the // former are common for solder paste while the later get generated when a relative paste // margin is used with an oblong pad). So we apply this huge hack and fake a larger pad to // run the general-purpose polygon builder on. // Of course being a hack it falls down when dealing with custom shape pads (where the size - // is only the size of the anchor), so for those we punt and just use aClearanceValue.x. + // is only the size of the anchor), so for those we punt and just use aMargin.x. if( ( clearance.x < 0 || clearance.x != clearance.y ) && aPad->GetShape() != PAD_SHAPE::CUSTOM ) @@ -506,11 +480,9 @@ OBJECT_2D* BOARD_ADAPTER::createPadWithDrill( const PAD* aPad, int aInflateValue } -void BOARD_ADAPTER::addPadsWithClearance( const FOOTPRINT* aFootprint, - CONTAINER_2D_BASE* aDstContainer, - PCB_LAYER_ID aLayerId, int aInflateValue, - bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads, - bool aSkipNonPlatedPads ) +void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer, + PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper, + bool aSkipPlatedPads, bool aSkipNonPlatedPads ) { for( PAD* pad : aFootprint->Pads() ) { @@ -556,7 +528,7 @@ void BOARD_ADAPTER::addPadsWithClearance( const FOOTPRINT* aFootprint, if( aSkipNonPlatedPads && !isPlated ) continue; - VECTOR2I margin( aInflateValue, aInflateValue ); + VECTOR2I margin( 0, 0 ); switch( aLayerId ) { @@ -575,7 +547,7 @@ void BOARD_ADAPTER::addPadsWithClearance( const FOOTPRINT* aFootprint, break; } - createPadWithClearance( pad, aDstContainer, aLayerId, margin ); + createPadWithMargin( pad, aDstContainer, aLayerId, margin ); } } @@ -648,16 +620,11 @@ void BOARD_ADAPTER::transformArcToSegments( const VECTOR2I& aCentre, const VECTO } -// Based on -// TransformShapeWithClearanceToPolygon -// board_items_to_polygon_shape_transform.cpp#L431 -void BOARD_ADAPTER::addShapeWithClearance( const PCB_SHAPE* aShape, - CONTAINER_2D_BASE* aDstContainer, PCB_LAYER_ID aLayerId, - int aClearanceValue ) +void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aDstContainer ) { // The full width of the lines to create // The extra 1 protects the inner/outer radius values from degeneracy - const int linewidth = aShape->GetWidth() + ( 2 * aClearanceValue ) + 1; + const int linewidth = aShape->GetWidth() + 1; switch( aShape->GetShape() ) { @@ -684,7 +651,7 @@ void BOARD_ADAPTER::addShapeWithClearance( const PCB_SHAPE* aShape, { SHAPE_POLY_SET polyList; - aShape->TransformShapeWithClearanceToPolygon( polyList, aLayerId, 0, + aShape->TransformShapeWithClearanceToPolygon( polyList, UNDEFINED_LAYER, 0, ARC_HIGH_DEF, ERROR_INSIDE ); polyList.Simplify( SHAPE_POLY_SET::PM_FAST ); @@ -746,7 +713,7 @@ void BOARD_ADAPTER::addShapeWithClearance( const PCB_SHAPE* aShape, { SHAPE_POLY_SET polyList; - aShape->TransformShapeWithClearanceToPolygon( polyList, aLayerId, 0, + aShape->TransformShapeWithClearanceToPolygon( polyList, UNDEFINED_LAYER, 0, ARC_HIGH_DEF, ERROR_INSIDE ); polyList.Simplify( SHAPE_POLY_SET::PM_FAST ); diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp index 313f36562f..3838c66d80 100644 --- a/3d-viewer/3d_canvas/create_layer_items.cpp +++ b/3d-viewer/3d_canvas/create_layer_items.cpp @@ -247,7 +247,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) continue; // Add object item to layer container - createTrack( track, layerContainer, 0.0f ); + createTrack( track, layerContainer ); } } @@ -529,11 +529,11 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) { // Note: NPTH pads are not drawn on copper layers when the pad has the same shape // as its hole - addPadsWithClearance( footprint, layerContainer, curr_layer_id, 0, true, - renderPlatedPadsAsPlated, false ); + addPads( footprint, layerContainer, curr_layer_id, true, renderPlatedPadsAsPlated, + false ); // Micro-wave footprints may have items on copper layers - addFootprintShapesWithClearance( footprint, layerContainer, curr_layer_id, 0 ); + addFootprintShapes( footprint, layerContainer, curr_layer_id ); } } @@ -542,9 +542,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) // ADD PLATED PADS for( FOOTPRINT* footprint : m_board->Footprints() ) { - addPadsWithClearance( footprint, m_platedPadsFront, F_Cu, 0, true, false, true ); + addPads( footprint, m_platedPadsFront, F_Cu, true, false, true ); - addPadsWithClearance( footprint, m_platedPadsBack, B_Cu, 0, true, false, true ); + addPads( footprint, m_platedPadsBack, B_Cu, true, false, true ); } m_platedPadsFront->BuildBVH(); @@ -606,28 +606,25 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) switch( item->Type() ) { case PCB_SHAPE_T: - addShapeWithClearance( static_cast( item ), layerContainer, - curr_layer_id, 0 ); - break; + addShape( static_cast( item ), layerContainer ); + break; case PCB_TEXT_T: - addShapeWithClearance( static_cast( item ), layerContainer, - curr_layer_id, 0 ); - break; + addShape( static_cast( item ), layerContainer ); + break; case PCB_DIM_ALIGNED_T: case PCB_DIM_CENTER_T: case PCB_DIM_RADIAL_T: case PCB_DIM_ORTHOGONAL_T: case PCB_DIM_LEADER_T: - addShapeWithClearance( static_cast( item ), - layerContainer, curr_layer_id, 0 ); - break; + addShape( static_cast( item ), layerContainer ); + break; default: wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ), item->Type() ); - break; + break; } } } @@ -914,13 +911,11 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) switch( item->Type() ) { case PCB_SHAPE_T: - addShapeWithClearance( static_cast( item ), layerContainer, - curr_layer_id, 0 ); + addShape( static_cast( item ), layerContainer ); break; case PCB_TEXT_T: - addShapeWithClearance( static_cast( item ), layerContainer, - curr_layer_id, 0 ); + addShape( static_cast( item ), layerContainer ); break; case PCB_DIM_ALIGNED_T: @@ -928,8 +923,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) case PCB_DIM_RADIAL_T: case PCB_DIM_ORTHOGONAL_T: case PCB_DIM_LEADER_T: - addShapeWithClearance( static_cast( item ), layerContainer, - curr_layer_id, 0 ); + addShape( static_cast( item ), layerContainer ); break; default: @@ -981,11 +975,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) } else { - addPadsWithClearance( footprint, layerContainer, curr_layer_id, 0, - false, false, false ); + addPads( footprint, layerContainer, curr_layer_id, false, false, false ); } - addFootprintShapesWithClearance( footprint, layerContainer, curr_layer_id, 0 ); + addFootprintShapes( footprint, layerContainer, curr_layer_id ); } diff --git a/common/eda_text.cpp b/common/eda_text.cpp index 5da7791dcd..cfaa7127b3 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -826,50 +826,28 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl std::shared_ptr EDA_TEXT::GetEffectiveTextShape( ) const { std::shared_ptr shape = std::make_shared(); + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; KIFONT::FONT* font = GetDrawFont(); - wxSize size = GetTextSize(); int penWidth = GetEffectiveTextPenWidth(); - bool forceBold = true; - if( IsMirrored() ) - size.x = -size.x; + CALLBACK_GAL callback_gal( empty_opts, + // Stroke callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) + { + shape->AddShape( new SHAPE_SEGMENT( aPt1, aPt2, penWidth ) ); + }, + // Triangulation callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) + { + SHAPE_SIMPLE* triShape = new SHAPE_SIMPLE; - wxArrayString strings_list; - std::vector positions; + for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } ) + triShape->Append( point.x, point.y ); - if( IsMultilineAllowed() ) - { - wxStringSplit( GetShownText(), strings_list, wxChar('\n') ); - positions.reserve( strings_list.Count() ); - GetLinePositions( positions, strings_list.Count() ); - } - else - { - strings_list.Add( GetShownText() ); - positions.push_back( GetDrawPos() ); - } + shape->AddShape( triShape ); + } ); - for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) - { - GRText( positions[ii], strings_list.Item( ii ), GetDrawRotation(), size, - GetDrawHorizJustify(), GetDrawVertJustify(), penWidth, IsItalic(), forceBold, font, - // Stroke callback - [&]( const VECTOR2D& aPt1, const VECTOR2D& aPt2 ) - { - shape->AddShape( new SHAPE_SEGMENT( aPt1, aPt2, penWidth ) ); - }, - // Triangulation callback - [&]( const VECTOR2D& aPt1, const VECTOR2D& aPt2, const VECTOR2D& aPt3 ) - { - SHAPE_SIMPLE* triShape = new SHAPE_SIMPLE; - - triShape->Append( aPt1 ); - triShape->Append( aPt2 ); - triShape->Append( aPt3 ); - - shape->AddShape( triShape ); - } ); - } + font->Draw( &callback_gal, GetShownText(), GetTextPos(), GetAttributes() ); return shape; } diff --git a/common/gr_text.cpp b/common/gr_text.cpp index 5dc191d7b9..959669516a 100644 --- a/common/gr_text.cpp +++ b/common/gr_text.cpp @@ -129,7 +129,8 @@ void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, KIFONT::FONT* aFont ) { - bool fill_mode = true; + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; + bool fill_mode = true; if( !aFont ) aFont = KIFONT::FONT::GetFont(); @@ -143,7 +144,7 @@ void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const fill_mode = false; } - GRText( aPos, aText, aOrient, aSize, aH_justify, aV_justify, aWidth, aItalic, aBold, aFont, + CALLBACK_GAL callback_gal( empty_opts, // Stroke callback [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) { @@ -158,48 +159,6 @@ void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const VECTOR2I pts[3] = { aPt1, aPt2, aPt3 }; GRClosedPoly( nullptr, aDC, 3, pts, true, 0, aColor, aColor ); } ); -} - - -/** - * De-compose graphic text into either strokes and/or triangles. - * - * @param aPos is the text position (according to h_justify, v_justify). - * @param aText is the text to draw. - * @param aOrient is the angle. - * @param aSize is the text size (size.x or size.y can be < 0 for mirrored texts). - * @param aH_justify is the horizontal justification (Left, center, right). - * @param aV_justify is the vertical justification (bottom, center, top). - * @param aWidth is the line width (pen width) (use default width if aWidth = 0). - * if width < 0 : draw segments in sketch mode, width = abs(width) - * Use a value min(aSize.x, aSize.y) / 5 for a bold text. - * @param aItalic is the true to simulate an italic font. - * @param aBold use true to use a bold font. Useful only with default width value (aWidth = 0). - * @param aFont is the font to use, or nullptr for the KiCad stroke font - * @param aStrokeCallback is a two-point stroking callback - * @param aTriangleCallback is a three-point triangulation callback - */ -void GRText( const VECTOR2I& aPos, const wxString& aText, const EDA_ANGLE& aOrient, - const VECTOR2I& aSize, enum GR_TEXT_H_ALIGN_T aH_justify, - enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, - KIFONT::FONT* aFont, - std::function aStrokeCallback, - std::function aTriangleCallback ) -{ - if( !aFont ) - aFont = KIFONT::FONT::GetFont(); - - KIGFX::GAL_DISPLAY_OPTIONS empty_opts; - CALLBACK_GAL callback_gal( empty_opts, aStrokeCallback, aTriangleCallback ); - - if( aWidth == 0 && aBold ) // Use default values if aWidth == 0 - aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) ); - - if( aWidth < 0 ) - aWidth = -aWidth; TEXT_ATTRIBUTES attributes; attributes.m_Angle = aOrient; @@ -209,15 +168,7 @@ void GRText( const VECTOR2I& aPos, const wxString& aText, const EDA_ANGLE& aOrie attributes.m_Halign = aH_justify; attributes.m_Valign = aV_justify; - VECTOR2D size = aSize; - attributes.m_Mirrored = size.x < 0; - - if( size.x < 0 ) - size.x = - size.x; - - attributes.m_Size = size; - - aFont->Draw( &callback_gal, aText, VECTOR2D( aPos ), attributes ); + aFont->Draw( &callback_gal, aText, aPos, attributes ); } diff --git a/common/plotters/plotter.cpp b/common/plotters/plotter.cpp index de0cf6ea50..81f0a78321 100644 --- a/common/plotters/plotter.cpp +++ b/common/plotters/plotter.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include // for KiROUND @@ -666,6 +667,8 @@ void PLOTTER::Text( const VECTOR2I& aPos, KIFONT::FONT* aFont, void* aData ) { + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; + SetColor( aColor ); SetCurrentLineWidth( aPenWidth, aData ); @@ -675,7 +678,7 @@ void PLOTTER::Text( const VECTOR2I& aPos, if( aPenWidth < 0 ) aPenWidth = -aPenWidth; - GRText( aPos, aText, aOrient, aSize, aH_justify, aV_justify, aPenWidth, aItalic, aBold, aFont, + CALLBACK_GAL callback_gal( empty_opts, // Stroke callback [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) { @@ -694,4 +697,14 @@ void PLOTTER::Text( const VECTOR2I& aPos, PlotPoly( cornerList, FILL_T::FILLED_SHAPE, 0, aData ); } ); + + TEXT_ATTRIBUTES attributes; + attributes.m_Angle = aOrient; + attributes.m_StrokeWidth = aPenWidth; + attributes.m_Italic = aItalic; + attributes.m_Bold = aBold; + attributes.m_Halign = aH_justify; + attributes.m_Valign = aV_justify; + + aFont->Draw( &callback_gal, aText, aPos, attributes ); } diff --git a/include/gr_text.h b/include/gr_text.h index 3ed79e04de..1f37c217e5 100644 --- a/include/gr_text.h +++ b/include/gr_text.h @@ -110,32 +110,5 @@ void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const KIGFX::COLOR4D& aColor, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, KIFONT::FONT* aFont ); -/** - * De-compose graphic text into either strokes and/or triangles. - * - * @param aPos is the text position (according to h_justify, v_justify). - * @param aText is the text to draw. - * @param aOrient is the angle. - * @param aSize is the text size (size.x or size.y can be < 0 for mirrored texts). - * @param aH_justify is the horizontal justification (Left, center, right). - * @param aV_justify is the vertical justification (bottom, center, top). - * @param aWidth is the line width (pen width) (use default width if aWidth = 0). - * if width < 0 : draw segments in sketch mode, width = abs(width) - * Use a value min(aSize.x, aSize.y) / 5 for a bold text. - * @param aItalic is the true to simulate an italic font. - * @param aBold use true to use a bold font. Useful only with default width value (aWidth = 0). - * @param aFont is the font to use, or nullptr for the KiCad stroke font - * @param aStrokeCallback is a two-point stroking callback - * @param aTriangleCallback is a three-point triangulation callback - */ -void GRText( const VECTOR2I& aPos, const wxString& aText, const EDA_ANGLE& aOrient, - const VECTOR2I& aSize, enum GR_TEXT_H_ALIGN_T aH_justify, - enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, - KIFONT::FONT* aFont, - std::function aStrokeCallback, - std::function aTriangleCallback ); #endif /* GR_TEXT_H */ diff --git a/pcbnew/fp_text.cpp b/pcbnew/fp_text.cpp index ed171031cd..ccbf2fd686 100644 --- a/pcbnew/fp_text.cpp +++ b/pcbnew/fp_text.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include FP_TEXT::FP_TEXT( FOOTPRINT* aParentFootprint, TEXT_TYPE text_type ) : @@ -465,14 +466,11 @@ void FP_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc ) const { - wxSize size = GetTextSize(); - int penWidth = GetEffectiveTextPenWidth(); + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; + KIFONT::FONT* font = GetDrawFont(); + int penWidth = GetEffectiveTextPenWidth(); - if( IsMirrored() ) - size.x = -size.x; - - GRText( GetTextPos(), GetShownText(), GetDrawRotation(), size, GetHorizJustify(), - GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont(), + CALLBACK_GAL callback_gal( empty_opts, // Stroke callback [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) { @@ -487,6 +485,8 @@ void FP_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } ) aCornerBuffer.Append( point.x, point.y ); } ); + + font->Draw( &callback_gal, GetShownText(), GetTextPos(), GetAttributes() ); } diff --git a/pcbnew/pcb_text.cpp b/pcbnew/pcb_text.cpp index 12d8b67dee..f99992f90e 100644 --- a/pcbnew/pcb_text.cpp +++ b/pcbnew/pcb_text.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include using KIGFX::PCB_RENDER_SETTINGS; @@ -230,15 +231,11 @@ void PCB_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCorner PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc ) const { - wxSize size = GetTextSize(); + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; + KIFONT::FONT* font = GetDrawFont(); + int penWidth = GetEffectiveTextPenWidth(); - if( IsMirrored() ) - size.x = -size.x; - - int penWidth = GetEffectiveTextPenWidth(); - - GRText( GetTextPos(), GetShownText(), GetTextAngle(), size, GetHorizJustify(), - GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont(), + CALLBACK_GAL callback_gal( empty_opts, // Stroke callback [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) { @@ -253,6 +250,8 @@ void PCB_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCorner for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } ) aCornerBuffer.Append( point.x, point.y ); } ); + + font->Draw( &callback_gal, GetShownText(), GetTextPos(), GetAttributes() ); }