diff --git a/common/gr_basic.cpp b/common/gr_basic.cpp index 6f82c4e207..c919ee9763 100644 --- a/common/gr_basic.cpp +++ b/common/gr_basic.cpp @@ -56,7 +56,7 @@ int g_DrawBgColor = WHITE; #define USE_CLIP_FILLED_POLYGONS #ifdef USE_CLIP_FILLED_POLYGONS -void ClipAndDrawFilledPoly( EDA_Rect * ClipBox, wxDC * DC, wxPoint Points[], int n ); +static void ClipAndDrawFilledPoly( EDA_Rect * ClipBox, wxDC * DC, wxPoint Points[], int n ); #endif /* These functions are used by corresponding functions @@ -1281,7 +1281,11 @@ static void GRSClosedPoly( EDA_Rect* ClipBox, { GRSMoveTo( aPoints[aPointCount - 1].x, aPoints[aPointCount - 1].y ); GRSetBrush( DC, BgColor, FILLED ); - DC->DrawPolygon( aPointCount, aPoints, 0, 0, wxODDEVEN_RULE ); +#ifdef USE_CLIP_FILLED_POLYGONS + ClipAndDrawFilledPoly( ClipBox, DC, aPoints, aPointCount ); +#else + DC->DrawPolygon( aPointCount, aPoints ); // does not work very well under linux +#endif } else { diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt index 86f28c2b6f..535cc9b1d7 100644 --- a/gerbview/CMakeLists.txt +++ b/gerbview/CMakeLists.txt @@ -26,6 +26,7 @@ set(GERBVIEW_SRCS dialog_print_using_printer.cpp dialog_print_using_printer_base.cpp dummy_functions.cpp + draw_gerber_screen.cpp edit.cpp export_to_pcbnew.cpp files.cpp @@ -46,8 +47,7 @@ set(GERBVIEW_SRCS rs274d.cpp rs274x.cpp select_layers_to_pcb.cpp - toolbars_gerber.cpp - tracepcb.cpp ) + toolbars_gerber.cpp ) ### # We need some extra sources from pcbnew diff --git a/gerbview/class_aperture_macro.cpp b/gerbview/class_aperture_macro.cpp index 4681b95a93..5949b4c4ac 100644 --- a/gerbview/class_aperture_macro.cpp +++ b/gerbview/class_aperture_macro.cpp @@ -139,7 +139,6 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, wxPoint curPos = aShapePos; D_CODE* tool = aParent->GetDcodeDescr(); - bool gerberMetric = m_GerbMetric; int rotation; if( mapExposure( aParent ) == false ) { @@ -155,9 +154,9 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, * type (1), exposure, diameter, pos.x, pos.y * type is not stored in parameters list, so the first parameter is exposure */ - curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), gerberMetric ); + curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric ); curPos = aParent->GetABPosition( curPos ); - int radius = scale( params[1].GetValue( tool ), gerberMetric ) / 2; + int radius = scale( params[1].GetValue( tool ), m_GerbMetric ) / 2; if( !aFilledShape ) GRCircle( aClipBox, aDC, curPos, radius, 0, aColor ); else @@ -173,7 +172,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, * type (2), exposure, width, start.x, start.y, end.x, end.y, rotation * type is not stored in parameters list, so the first parameter is exposure */ - ConvertShapeToPolygon( aParent, polybuffer, gerberMetric ); + ConvertShapeToPolygon( aParent, polybuffer ); // shape rotation: rotation = wxRound( params[6].GetValue( tool ) * 10.0 ); @@ -202,7 +201,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, * type (21), exposure, ,width, height, center pos.x, center pos.y, rotation * type is not stored in parameters list, so the first parameter is exposure */ - ConvertShapeToPolygon( aParent, polybuffer, gerberMetric ); + ConvertShapeToPolygon( aParent, polybuffer ); // shape rotation: rotation = wxRound( params[5].GetValue( tool ) * 10.0 ); @@ -231,7 +230,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, * type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation * type is not stored in parameters list, so the first parameter is exposure */ - ConvertShapeToPolygon( aParent, polybuffer, gerberMetric ); + ConvertShapeToPolygon( aParent, polybuffer ); // shape rotation: rotation = wxRound( params[5].GetValue( tool ) * 10.0 ); @@ -260,8 +259,8 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, * type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation * type is not stored in parameters list, so the first parameter is center.x */ - curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), gerberMetric ); - ConvertShapeToPolygon( aParent, polybuffer, gerberMetric ); + curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), m_GerbMetric ); + ConvertShapeToPolygon( aParent, polybuffer ); // shape rotation: rotation = wxRound( params[5].GetValue( tool ) * 10.0 ); @@ -293,16 +292,16 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, case AMP_MOIRE: // A cross hair with n concentric circles { curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), - gerberMetric ); + m_GerbMetric ); /* Generated by an aperture macro declaration like: * "6,0,0,0.125,.01,0.01,3,0.003,0.150,0" * type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness, crosshaire len, rotation * type is not stored in parameters list, so the first parameter is pos.x */ - int outerDiam = scale( params[2].GetValue( tool ), gerberMetric ); - int penThickness = scale( params[3].GetValue( tool ), gerberMetric ); - int gap = scale( params[4].GetValue( tool ), gerberMetric ); + int outerDiam = scale( params[2].GetValue( tool ), m_GerbMetric ); + int penThickness = scale( params[3].GetValue( tool ), m_GerbMetric ); + int gap = scale( params[4].GetValue( tool ), m_GerbMetric ); int numCircles = wxRound( params[5].GetValue( tool ) ); // Draw circles: @@ -327,7 +326,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, } // Draw the cross: - ConvertShapeToPolygon( aParent, polybuffer, gerberMetric ); + ConvertShapeToPolygon( aParent, polybuffer ); rotation = wxRound( params[8].GetValue( tool ) * 10.0 ); for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) @@ -358,8 +357,8 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, for( int i = 0; i& aBuffer, - bool aUnitsMetric ) + std::vector& aBuffer ) { D_CODE* tool = aParent->GetDcodeDescr(); @@ -439,11 +436,11 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, case AMP_LINE2: case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation) { - int width = scale( params[1].GetValue( tool ), aUnitsMetric ); + int width = scale( params[1].GetValue( tool ), m_GerbMetric ); wxPoint start = mapPt( params[2].GetValue( tool ), - params[3].GetValue( tool ), aUnitsMetric ); + params[3].GetValue( tool ), m_GerbMetric ); wxPoint end = mapPt( params[4].GetValue( tool ), - params[5].GetValue( tool ), aUnitsMetric ); + params[5].GetValue( tool ), m_GerbMetric ); wxPoint delta = end - start; int len = wxRound( hypot( delta.x, delta.y ) ); @@ -471,8 +468,8 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, case AMP_LINE_CENTER: { - wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric ); - wxPoint pos = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), aUnitsMetric ); + wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric ); + wxPoint pos = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), m_GerbMetric ); // Build poly: pos.x -= size.x / 2; @@ -489,9 +486,9 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, case AMP_LINE_LOWER_LEFT: { - wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric ); + wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric ); wxPoint lowerLeft = mapPt( params[3].GetValue( tool ), params[4].GetValue( - tool ), aUnitsMetric ); + tool ), m_GerbMetric ); // Build poly: aBuffer.push_back( lowerLeft ); @@ -509,9 +506,9 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first // rotated by 90, 180 and 270 deg. // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness - int outerRadius = scale( params[2].GetValue( tool ), aUnitsMetric ) / 2; - int innerRadius = scale( params[3].GetValue( tool ), aUnitsMetric ) / 2; - int halfthickness = scale( params[4].GetValue( tool ), aUnitsMetric ) / 2; + int outerRadius = scale( params[2].GetValue( tool ), m_GerbMetric ) / 2; + int innerRadius = scale( params[3].GetValue( tool ), m_GerbMetric ) / 2; + int halfthickness = scale( params[4].GetValue( tool ), m_GerbMetric ) / 2; int angle_start = wxRound( asin( (double) halfthickness / innerRadius ) * 1800 / M_PI ); @@ -560,8 +557,8 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, case AMP_MOIRE: // A cross hair with n concentric circles. Only the cros is build as polygon // because circles can be drawn easily { - int crossHairThickness = scale( params[6].GetValue( tool ), aUnitsMetric ); - int crossHairLength = scale( params[7].GetValue( tool ), aUnitsMetric ); + int crossHairThickness = scale( params[6].GetValue( tool ), m_GerbMetric ); + int crossHairLength = scale( params[7].GetValue( tool ), m_GerbMetric ); // Create cross. First create 1/4 of the shape. // Others point are the same, totated by 90, 180 and 270 deg @@ -594,7 +591,7 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, case AMP_POLYGON: // Creates a regular polygon { int vertexcount = wxRound( params[1].GetValue( tool ) ); - int radius = scale( params[4].GetValue( tool ), aUnitsMetric ) / 2; + int radius = scale( params[4].GetValue( tool ), m_GerbMetric ) / 2; // rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis if( vertexcount < 3 ) vertexcount = 3; @@ -615,6 +612,108 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, } } +/** GetShapeDim + * Calculate a value that can be used to evaluate the size of text + * when displaying the D-Code of an item + * due to the complexity of the shape of some primitives + * one cannot calculate the "size" of a shape (only abounding box) + * but here, the "dimension" of the shape is the diameter of the primitive + * or for lines the width of the line + * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn + * @return a dimension, or -1 if no dim to calculate + */ +int AM_PRIMITIVE::GetShapeDim( GERBER_DRAW_ITEM* aParent ) +{ + int dim = -1; + D_CODE* tool = aParent->GetDcodeDescr(); + + switch( primitive_id ) + { + case AMP_CIRCLE: + // params = exposure, diameter, pos.x, pos.y + dim = scale( params[1].GetValue( tool ), m_GerbMetric ); // Diameter + break; + + case AMP_LINE2: + case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation) + dim = scale( params[1].GetValue( tool ), m_GerbMetric ); // linne width + break; + + case AMP_LINE_CENTER: + { + wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric ); + dim = MIN(size.x, size.y); + } + break; + + case AMP_LINE_LOWER_LEFT: + { + wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric ); + dim = MIN(size.x, size.y); + } + break; + + case AMP_THERMAL: + { + // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first + // rotated by 90, 180 and 270 deg. + // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness + dim = scale( params[2].GetValue( tool ), m_GerbMetric ) / 2; // Outer diam + } + break; + + case AMP_MOIRE: // A cross hair with n concentric circles. + dim = scale( params[7].GetValue( tool ), m_GerbMetric ); // = cross hair len + break; + + case AMP_OUTLINE: // a free polygon : + // dim = min side of the bounding box (this is a poor criteria, but what is a good criteria b?) + { + // exposure, corners count, corner1.x, corner.1y, ..., rotation + int numPoints = (int) params[1].GetValue( tool ); + // Read points. numPoints does not include the starting point, so add 1. + // and calculate the bounding box; + wxSize pos_min, pos_max, pos; + for( int i = 0; i pos.x ) + pos_min.x = pos.x; + if( pos_min.y > pos.y ) + pos_min.y = pos.y; + // lower left corner: + if( pos_max.x < pos.x ) + pos_max.x = pos.x; + if( pos_max.y < pos.y ) + pos_max.y = pos.y; + } + } + // calculate dim + wxSize size; + size.x = pos_max.x - pos_min.x; + size.y = pos_max.y - pos_min.y; + dim = MIN( size.x, size.y ); + } + break; + + case AMP_POLYGON: // Regular polygon + dim = scale( params[4].GetValue( tool ), m_GerbMetric ) / 2; // Radius + break; + + case AMP_UNKNOWN: + case AMP_EOF: + break; + } + return dim; +} + /** function DrawApertureMacroShape * Draw the primitive shape for flashed items. @@ -634,3 +733,27 @@ void APERTURE_MACRO::DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, aFilledShape ); } } + +/** GetShapeDim + * Calculate a value that can be used to evaluate the size of text + * when displaying the D-Code of an item + * due to the complexity of a shape using many primitives + * one cannot calculate the "size" of a shape (only abounding box) + * but most of aperture macro are using one or few primitives + * and the "dimension" of the shape is the diameter of the primitive + * (or the max diameter of primitives) + * @return a dimension, or -1 if no dim to calculate + */ +int APERTURE_MACRO::GetShapeDim( GERBER_DRAW_ITEM* aParent ) +{ + int dim = -1; + for( AM_PRIMITIVES::iterator prim_macro = primitives.begin(); + prim_macro != primitives.end(); ++prim_macro ) + { + int pdim = prim_macro->GetShapeDim( aParent ); + if( dim < pdim ) + dim = pdim; + } + + return dim; +} diff --git a/gerbview/class_aperture_macro.h b/gerbview/class_aperture_macro.h index e91fca419a..36f61fef39 100644 --- a/gerbview/class_aperture_macro.h +++ b/gerbview/class_aperture_macro.h @@ -119,6 +119,18 @@ public: void DrawBasicShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC, int aColor, int aAltColor, wxPoint aShapePos, bool aFilledShape ); + /** GetShapeDim + * Calculate a value that can be used to evaluate the size of text + * when displaying the D-Code of an item + * due to the complexity of the shape of some primitives + * one cannot calculate the "size" of a shape (only a bounding box) + * but here, the "dimension" of the shape is the diameter of the primitive + * or for lines the width of the line + * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn + * @return a dimension, or -1 if no dim to calculate + */ + int GetShapeDim( GERBER_DRAW_ITEM* aParent ); + private: /** function ConvertShapeToPolygon @@ -127,7 +139,7 @@ private: * Useful when a shape is not a graphic primitive (shape with hole, * rotated shape ... ) and cannot be easily drawn. */ - void ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector& aBuffer, bool aUnitsMetric); + void ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector& aBuffer ); }; @@ -155,6 +167,19 @@ struct APERTURE_MACRO */ void DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC, int aColor, int aAltColor, wxPoint aShapePos, bool aFilledShape ); + + /** GetShapeDim + * Calculate a value that can be used to evaluate the size of text + * when displaying the D-Code of an item + * due to the complexity of a shape using many primitives + * one cannot calculate the "size" of a shape (only abounding box) + * but most of aperture macro are using one or few primitives + * and the "dimension" of the shape is the diameter of the primitive + * (or the max diameter of primitives) + * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn + * @return a dimension, or -1 if no dim to calculate + */ + int GetShapeDim( GERBER_DRAW_ITEM* aParent ); }; diff --git a/gerbview/dcode.cpp b/gerbview/dcode.cpp index 3761c72d71..1cba5f1189 100644 --- a/gerbview/dcode.cpp +++ b/gerbview/dcode.cpp @@ -98,6 +98,47 @@ const wxChar* D_CODE::ShowApertureType( APERTURE_T aType ) return ret; } +/** GetShapeDim + * Calculate a value that can be used to evaluate the size of text + * when displaying the D-Code of an item + * due to the complexity of some shapes, + * one cannot calculate the "size" of a shape (only a bounding box) + * but here, the "dimension" of the shape is the diameter of the primitive + * or for lines the width of the line if the shape is a line + * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn + * @return a dimension, or -1 if no dim to calculate + */ +int D_CODE::GetShapeDim( GERBER_DRAW_ITEM* aParent ) +{ + int dim = -1; + switch( m_Shape ) + { + case APT_CIRCLE: + case APT_LINE: + dim = m_Size.x; + break; + + case APT_RECT: + case APT_OVAL: + dim = MIN( m_Size.x, m_Size.y ); + break; + + case APT_POLYGON: + dim = MIN( m_Size.x, m_Size.y ); + break; + + case APT_MACRO: + if( m_Macro ) + dim = m_Macro->GetShapeDim( aParent ); + break; + + default: + break; + } + + return dim; +} + /** Function Read_D_Code_File * Can be useful only with old RS274D Gerber file format. diff --git a/gerbview/dcode.h b/gerbview/dcode.h index 1839cd5609..733954cbae 100644 --- a/gerbview/dcode.h +++ b/gerbview/dcode.h @@ -228,6 +228,18 @@ public: * rotated shape ... ) and cannot be easily drawn. */ void ConvertShapeToPolygon(); + + /** GetShapeDim + * Calculate a value that can be used to evaluate the size of text + * when displaying the D-Code of an item + * due to the complexity of some shapes, + * one cannot calculate the "size" of a shape (only a bounding box) + * but here, the "dimension" of the shape is the diameter of the primitive + * or for lines the width of the line if the shape is a line + * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn + * @return a dimension, or -1 if no dim to calculate + */ + int GetShapeDim( GERBER_DRAW_ITEM* aParent ); }; diff --git a/gerbview/tracepcb.cpp b/gerbview/draw_gerber_screen.cpp similarity index 92% rename from gerbview/tracepcb.cpp rename to gerbview/draw_gerber_screen.cpp index 5c1ccda223..a40c640f4a 100644 --- a/gerbview/tracepcb.cpp +++ b/gerbview/draw_gerber_screen.cpp @@ -177,19 +177,24 @@ void Show_Items_DCode_Value( WinEDA_DrawPanel* aPanel, wxDC* aDC, BOARD* aPcb, i Line.Printf( wxT( "D%d" ), gerb_item->m_DCode ); - width = MIN( gerb_item->m_Size.x, gerb_item->m_Size.y ); + if( gerb_item->GetDcodeDescr() ) + width = gerb_item->GetDcodeDescr()->GetShapeDim( gerb_item ); + else + width = MIN( gerb_item->m_Size.x, gerb_item->m_Size.y ); + orient = TEXT_ORIENT_HORIZ; if( gerb_item->m_Flashed ) { + // A reasonnable size for text is width/3 because most ot time this text has 3 chars. width /= 3; } - else // lines + else // this item is a line { - int dx, dy; - dx = gerb_item->m_Start.x - gerb_item->m_End.x; - dy = gerb_item->m_Start.y - gerb_item->m_End.y; - if( abs( dx ) < abs( dy ) ) + wxPoint delta = gerb_item->m_Start - gerb_item->m_End; + if( abs( delta.x ) < abs( delta.y ) ) orient = TEXT_ORIENT_VERT; + // A reasonnable size for text is width/2 because text needs margin below and above it. + // a margin = width/4 seems good width /= 2; } diff --git a/include/boost/polygon/detail/polygon_sort_adaptor.hpp b/include/boost/polygon/detail/polygon_sort_adaptor.hpp new file mode 100644 index 0000000000..33d5d99f06 --- /dev/null +++ b/include/boost/polygon/detail/polygon_sort_adaptor.hpp @@ -0,0 +1,67 @@ +/* + Copyright 2008 Intel Corporation + + Use, modification and distribution are subject to the Boost Software License, + Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt). +*/ +#ifndef BOOST_POLYGON_SORT_ADAPTOR_HPP +#define BOOST_POLYGON_SORT_ADAPTOR_HPP +#ifdef __ICC +#pragma warning(disable:2022) +#pragma warning(disable:2023) +#endif + +#include + +//! @brief gtlsort_adaptor default implementation that calls std::sort +namespace boost { + namespace polygon { + + template + struct dummy_to_delay_instantiation{ + typedef int unit_type; // default GTL unit + }; + + //! @brief gtlsort_adaptor default implementation that calls std::sort + template + struct gtlsort_adaptor { + //! @brief wrapper that mimics std::sort() function and takes + // the same arguments + template + static void sort(RandomAccessIterator_Type _First, + RandomAccessIterator_Type _Last) + { + std::sort(_First, _Last); + } + //! @brief wrapper that mimics std::sort() function overload and takes + // the same arguments + template + static void sort(RandomAccessIterator_Type _First, + RandomAccessIterator_Type _Last, + const Pred_Type& _Comp) + { + std::sort(_First, _Last, _Comp); + } + }; + + //! @brief user level wrapper for sorting quantities + template + void gtlsort(iter_type _b_, iter_type _e_) + { + gtlsort_adaptor::unit_type>::sort(_b_, _e_); + } + + //! @brief user level wrapper for sorting quantities that takes predicate + // as additional argument + template + void gtlsort(iter_type _b_, iter_type _e_, const pred_type& _pred_) + { + gtlsort_adaptor::unit_type>::sort(_b_, _e_, _pred_); + } + + + + } // namespace polygon +} // namespace boost +#endif