1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 1992-2016 <Jean-Pierre Charras>
5  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 /**
26  * @file gerber_draw_item.h
27  */
28 
29 #ifndef GERBER_DRAW_ITEM_H
30 #define GERBER_DRAW_ITEM_H
31 
32 #include <eda_item.h>
33 #include <layer_ids.h>
34 #include <gr_basic.h>
35 #include <gbr_netlist_metadata.h>
36 #include <dcode.h>
37 #include <geometry/shape_poly_set.h>
38 
39 class GERBER_FILE_IMAGE;
40 class GBR_LAYOUT;
41 class D_CODE;
42 class MSG_PANEL_ITEM;
43 class GBR_DISPLAY_OPTIONS;
44 class PCB_BASE_FRAME;
45 
46 namespace KIGFX
47 {
48     class VIEW;
49 }
50 
51 
52 /* Shapes id for basic shapes ( .m_Shape member ) */
53 enum Gbr_Basic_Shapes {
54     GBR_SEGMENT = 0,        // usual segment : line with rounded ends
55     GBR_ARC,                // Arcs (with rounded ends)
56     GBR_CIRCLE,             // ring
57     GBR_POLYGON,            // polygonal shape
58     GBR_SPOT_CIRCLE,        // flashed shape: round shape (can have hole)
59     GBR_SPOT_RECT,          // flashed shape: rectangular shape can have hole)
60     GBR_SPOT_OVAL,          // flashed shape: oval shape
61     GBR_SPOT_POLY,          // flashed shape: regular polygon, 3 to 12 edges
62     GBR_SPOT_MACRO,         // complex shape described by a macro
63     GBR_LAST                // last value for this list
64 };
65 
66 class GERBER_DRAW_ITEM : public EDA_ITEM
67 {
68 public:
69     GERBER_DRAW_ITEM( GERBER_FILE_IMAGE* aGerberparams );
70     ~GERBER_DRAW_ITEM();
71 
72     void SetNetAttributes( const GBR_NETLIST_METADATA& aNetAttributes );
GetNetAttributes()73     const GBR_NETLIST_METADATA& GetNetAttributes() const { return m_netAttributes; }
74 
75     /**
76      * Return the layer this item is on.
77      */
78     int GetLayer() const;
79 
GetLayerPolarity()80     bool GetLayerPolarity() const
81     {
82         return m_LayerNegative;
83     }
84 
85     /**
86      * Return the best size and orientation to display the D_Code on screen.
87      *
88      * @param aSize is a reference to return the text size
89      * @param aPos is a reference to return the text position
90      * @param aOrientation is a reference to return the text orientation
91      * @return true if the parameters can be calculated, false for unknown D_Code
92      */
93     bool GetTextD_CodePrms( int& aSize, wxPoint& aPos, double& aOrientation );
94 
95     /**
96      * Return the best size and orientation to display the D_Code in GAL
97      * aOrientation is returned in radians.
98      */
99     bool GetTextD_CodePrms( double& aSize, VECTOR2D& aPos, double& aOrientation );
100 
101     /**
102      * Optimize screen refresh (when no items are in background color refresh can be faster).
103      *
104      * @return true if this item or at least one shape (when using aperture macros
105      *         must be drawn in background color.
106      */
107     bool HasNegativeItems();
108 
109     /**
110      * Initialize parameters from Image and Layer parameters found in the gerber file:
111      *   m_UnitsMetric,
112      *   m_MirrorA, m_MirrorB,
113      *   m_DrawScale, m_DrawOffset
114      */
115     void SetLayerParameters();
116 
SetLayerPolarity(bool aNegative)117     void SetLayerPolarity( bool aNegative)
118     {
119         m_LayerNegative = aNegative;
120     }
121 
122     /**
123      * Move this object.
124      *
125      * @param aMoveVector the move vector for this object.
126      */
127     void MoveAB( const wxPoint& aMoveVector );
128 
129      /**
130       * Move this object.
131       *
132       * @param aMoveVector the move vector for this object, in XY gerber axis.
133       */
134     void MoveXY( const wxPoint& aMoveVector );
135 
136     /**
137      * Return the position of this object.
138      *
139      * This function exists mainly to satisfy the virtual GetPosition() in parent class
140      *
141      * @return The position of this object.
142      */
GetPosition()143     wxPoint GetPosition() const override                { return m_Start; }
SetPosition(const wxPoint & aPos)144     void SetPosition( const wxPoint& aPos ) override    {  m_Start = aPos; }
145 
146     /**
147      * Return the image position of aPosition for this object.
148      *
149      * Image position is the value of aPosition, modified by image parameters:
150      * offsets, axis selection, scale, rotation
151      *
152      * @param aXYPosition is position in X,Y gerber axis
153      * @return  The given position in plotter A,B axis.
154      */
155     wxPoint GetABPosition( const wxPoint& aXYPosition ) const;
156 
GetABPosition(const VECTOR2I & aXYPosition)157     VECTOR2I GetABPosition( const VECTOR2I& aXYPosition ) const
158     {
159         return VECTOR2I( GetABPosition( wxPoint( aXYPosition.x, aXYPosition.y ) ) );
160     }
161 
162     /**
163      * Return the image position of aPosition for this object.
164      *
165      * Image position is the value of aPosition, modified by image parameters:
166      * offsets, axis selection, scale, rotation
167      *
168      * @param aABPosition = position in A,B plotter axis
169      * @return The given position in X,Y axis.
170      */
171     wxPoint GetXYPosition( const wxPoint& aABPosition ) const;
172 
173     /**
174      * Return the GetDcodeDescr of this object, or NULL.
175      *
176      * @return a pointer to the DCode description (for flashed items).
177      */
178     D_CODE* GetDcodeDescr() const;
179 
180     const EDA_RECT GetBoundingBox() const override;
181 
182     void Print( wxDC* aDC, const wxPoint& aOffset, GBR_DISPLAY_OPTIONS* aOptions );
183 
184     /**
185      * Convert a line to an equivalent polygon.
186      *
187      * Useful when a line is plotted using a rectangular pen.
188      * In this case, the usual segment plot function cannot be used
189      * @param aPolygon is the SHAPE_POLY_SET to fill. If null (usual case),
190      * m_Polygon will be used
191      */
192     void ConvertSegmentToPolygon();
193     void ConvertSegmentToPolygon( SHAPE_POLY_SET* aPolygon ) const;
194 
195     /**
196      * Print the polygon stored in m_PolyCorners.
197      */
198     void PrintGerberPoly( wxDC* aDC, const COLOR4D& aColor, const wxPoint& aOffset,
199                           bool aFilledShape );
200 
Shape()201     int Shape() const { return m_Shape; }
202 
203     void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
204 
205     wxString ShowGBRShape() const;
206 
207     /**
208      * Test if the given wxPoint is within the bounds of this object.
209      *
210      * @param aRefPos a wxPoint to test
211      * @return bool - true if a hit, else false
212      */
213     bool HitTest( const wxPoint& aRefPos, int aAccuracy = 0 ) const override;
214 
215     /**
216      * Test if the given wxRect intersect this object.
217      *
218      * For now, an ending point must be inside this rect.
219      *
220      * @param aRefArea a wxPoint to test
221      * @return true if a hit, else false
222      */
223     bool HitTest( const EDA_RECT& aRefArea, bool aContained, int aAccuracy = 0 ) const override;
224 
225     /**
226      * @return the class name string.
227      */
GetClass()228     wxString GetClass() const override
229     {
230         return wxT( "GERBER_DRAW_ITEM" );
231     }
232 
233 #if defined(DEBUG)
234     void Show( int nestLevel, std::ostream& os ) const override;
235 #endif
236 
237     /// @copydoc VIEW_ITEM::ViewGetLayers()
238     virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
239 
240     /// @copydoc VIEW_ITEM::ViewBBox()
241     virtual const BOX2I ViewBBox() const override;
242 
243     /// @copydoc VIEW_ITEM::ViewGetLOD()
244     double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
245 
246     ///< @copydoc EDA_ITEM::Visit()
247     SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
248 
249     ///< @copydoc EDA_ITEM::GetSelectMenuText()
250     virtual wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
251 
252     ///< @copydoc EDA_ITEM::GetMenuImage()
253     BITMAPS GetMenuImage() const override;
254 
255     bool               m_UnitsMetric;       // store here the gerber units (inch/mm).  Used
256                                             // only to calculate aperture macros shapes sizes
257     int                m_Shape;             // Shape and type of this gerber item
258     wxPoint            m_Start;             // Line or arc start point or position of the shape
259                                             // for flashed items
260     wxPoint            m_End;               // Line or arc end point
261     wxPoint            m_ArcCentre;         // for arcs only: Center of arc
262     SHAPE_POLY_SET     m_Polygon;           // Polygon shape data (G36 to G37 coordinates)
263                                             // or for complex shapes which are converted to polygon
264     wxSize             m_Size;              // Flashed shapes: size of the shape
265                                             // Lines : m_Size.x = m_Size.y = line width
266     bool               m_Flashed;           // True for flashed items
267     int                m_DCode;             // DCode used to draw this item.
268                                             // Allowed values are >= 10. 0 when unknown
269                                             // values 0 to 9 can be used for special purposes
270                                             // Regions (polygons) do not use DCode,
271                                             // so it is set to 0
272     wxString           m_AperFunction;      // the aperture function set by a %TA.AperFunction, xxx
273                                             // (stores the xxx value). Used for regions that do
274                                             // not have a attached DCode, but
275                                             // have a TA.AperFunction defined
276     GERBER_FILE_IMAGE* m_GerberImageFile;   /* Gerber file image source of this item
277                                              * Note: some params stored in this class are common
278                                              * to the whole gerber file (i.e) the whole graphic
279                                              * layer and some can change when reading the file,
280                                              * so they are stored inside this item if there is no
281                                              * redundancy for these parameters
282                                              */
283 
284     // This polygon is to draw this item (mainly GBR_POLYGON), according to layer parameters
285     SHAPE_POLY_SET   m_AbsolutePolygon;     // the polygon to draw, in absolute coordinates
286 private:
287     // These values are used to draw this item, according to gerber layers parameters
288     // Because they can change inside a gerber image, they are stored here
289     // for each item
290     bool        m_LayerNegative;            // true = item in negative Layer
291     bool        m_swapAxis;                 // false if A = X, B = Y; true if A =Y, B = Y
292     bool        m_mirrorA;                  // true: mirror / axis A
293     bool        m_mirrorB;                  // true: mirror / ax's B
294     wxRealPoint m_drawScale;                // A and B scaling factor
295     wxPoint     m_layerOffset;              // Offset for A and B axis, from OF parameter
296     double      m_lyrRotation;              // Fine rotation, from OR parameter, in degrees
297     GBR_NETLIST_METADATA m_netAttributes;   ///< the string given by a %TO attribute set in aperture
298                                             ///< (dcode). Stored in each item, because %TO is
299                                             ///< a dynamic object attribute
300 };
301 
302 
303 class GERBER_NEGATIVE_IMAGE_BACKDROP : public EDA_ITEM
304 {
305 
306 };
307 
308 #endif /* GERBER_DRAW_ITEM_H */
309