1 /*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018-2021 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "gerbview_draw_panel_gal.h"
21 #include <view/view.h>
22 #include <view/wx_view_controls.h>
23 #include <gerbview_painter.h>
24 #include <drawing_sheet/ds_proxy_view_item.h>
25 #include <zoom_defines.h>
26
27 #include <gerbview_frame.h>
28 #include <gal/graphics_abstraction_layer.h>
29 #include <pgm_base.h>
30 #include <settings/settings_manager.h>
31
32 #include <gerber_file_image.h>
33 #include <gerber_file_image_list.h>
34
35 #include <functional>
36 #include <memory>
37
38 using namespace std::placeholders;
39
40
GERBVIEW_DRAW_PANEL_GAL(wxWindow * aParentWindow,wxWindowID aWindowId,const wxPoint & aPosition,const wxSize & aSize,KIGFX::GAL_DISPLAY_OPTIONS & aOptions,GAL_TYPE aGalType)41 GERBVIEW_DRAW_PANEL_GAL::GERBVIEW_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
42 const wxPoint& aPosition, const wxSize& aSize,
43 KIGFX::GAL_DISPLAY_OPTIONS& aOptions,
44 GAL_TYPE aGalType ) :
45 EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalType )
46 {
47 m_view = new KIGFX::VIEW( true );
48 m_view->SetGAL( m_gal );
49 GetGAL()->SetWorldUnitLength( 1.0/IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
50
51 m_painter = std::make_unique<KIGFX::GERBVIEW_PAINTER>( m_gal );
52 m_view->SetPainter( m_painter.get() );
53
54 // This fixes the zoom in and zoom out limits:
55 m_view->SetScaleLimits( ZOOM_MAX_LIMIT_GERBVIEW, ZOOM_MIN_LIMIT_GERBVIEW );
56
57 m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this );
58
59 setDefaultLayerDeps();
60
61 // Load display options (such as filled/outline display of items).
62 auto frame = static_cast< GERBVIEW_FRAME* >( GetParentEDAFrame() );
63
64 if( frame )
65 {
66 auto& displ_opts = frame->GetDisplayOptions();
67 auto rs = static_cast<KIGFX::GERBVIEW_RENDER_SETTINGS*>(
68 m_view->GetPainter()->GetSettings() );
69
70 rs->LoadDisplayOptions( displ_opts );
71 rs->LoadColors( Pgm().GetSettingsManager().GetColorSettings() );
72 }
73 }
74
75
~GERBVIEW_DRAW_PANEL_GAL()76 GERBVIEW_DRAW_PANEL_GAL::~GERBVIEW_DRAW_PANEL_GAL()
77 {
78 }
79
80
SetHighContrastLayer(int aLayer)81 void GERBVIEW_DRAW_PANEL_GAL::SetHighContrastLayer( int aLayer )
82 {
83 // Set display settings for high contrast mode
84 KIGFX::RENDER_SETTINGS* rSettings = m_view->GetPainter()->GetSettings();
85
86 SetTopLayer( aLayer );
87
88 rSettings->ClearHighContrastLayers();
89 rSettings->SetLayerIsHighContrast( aLayer );
90 rSettings->SetLayerIsHighContrast( GERBER_DCODE_LAYER( aLayer ) );
91
92 m_view->UpdateAllLayersColor();
93 }
94
95
GetMsgPanelInfo(EDA_DRAW_FRAME * aFrame,std::vector<MSG_PANEL_ITEM> & aList)96 void GERBVIEW_DRAW_PANEL_GAL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame,
97 std::vector<MSG_PANEL_ITEM>& aList )
98 {
99
100 }
101
102
OnShow()103 void GERBVIEW_DRAW_PANEL_GAL::OnShow()
104 {
105 GERBVIEW_FRAME* frame = dynamic_cast<GERBVIEW_FRAME*>( GetParentEDAFrame() );
106
107 if( frame )
108 {
109 SetTopLayer( frame->GetActiveLayer() );
110 auto& displ_opts = frame->GetDisplayOptions();
111 static_cast<KIGFX::GERBVIEW_RENDER_SETTINGS*>(
112 m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts );
113 }
114
115 m_view->RecacheAllItems();
116 }
117
118
SwitchBackend(GAL_TYPE aGalType)119 bool GERBVIEW_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
120 {
121 bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend( aGalType );
122
123 // The next onPaint event will call m_view->UpdateItems() that is very time consuming
124 // after switching to opengl. Clearing m_view and rebuild it is much faster
125 if( aGalType == GAL_TYPE_OPENGL )
126 {
127 GERBVIEW_FRAME* frame = dynamic_cast<GERBVIEW_FRAME*>( GetParentEDAFrame() );
128
129 if( frame )
130 {
131 m_view->Clear();
132
133 for( int layer = GERBER_DRAWLAYERS_COUNT-1; layer>= 0; --layer )
134 {
135 GERBER_FILE_IMAGE* gerber = frame->GetImagesList()->GetGbrImage( layer );
136
137 if( gerber == nullptr ) // Graphic layer not yet used
138 continue;
139
140 for( GERBER_DRAW_ITEM* item : gerber->GetItems() )
141 {
142 m_view->Add (item );
143 }
144 }
145 }
146 }
147
148 setDefaultLayerDeps();
149
150 GetGAL()->SetWorldUnitLength( 1.0/IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
151
152 return rv;
153 }
154
155
setDefaultLayerDeps()156 void GERBVIEW_DRAW_PANEL_GAL::setDefaultLayerDeps()
157 {
158 // caching makes no sense for Cairo and other software renderers
159 auto target = m_backend == GAL_TYPE_OPENGL ? KIGFX::TARGET_CACHED : KIGFX::TARGET_NONCACHED;
160
161 for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; i++ )
162 m_view->SetLayerTarget( i, target );
163
164 m_view->SetLayerDisplayOnly( LAYER_DCODES );
165 m_view->SetLayerDisplayOnly( LAYER_NEGATIVE_OBJECTS );
166 m_view->SetLayerDisplayOnly( LAYER_GERBVIEW_GRID );
167 m_view->SetLayerDisplayOnly( LAYER_GERBVIEW_AXES );
168 m_view->SetLayerDisplayOnly( LAYER_GERBVIEW_BACKGROUND );
169 m_view->SetLayerDisplayOnly( LAYER_DRAWINGSHEET );
170
171 m_view->SetLayerTarget( LAYER_SELECT_OVERLAY, KIGFX::TARGET_OVERLAY );
172 m_view->SetLayerDisplayOnly( LAYER_SELECT_OVERLAY );
173
174 m_view->SetLayerTarget( LAYER_GP_OVERLAY, KIGFX::TARGET_OVERLAY );
175 m_view->SetLayerDisplayOnly( LAYER_GP_OVERLAY );
176 }
177
178
SetDrawingSheet(DS_PROXY_VIEW_ITEM * aDrawingSheet)179 void GERBVIEW_DRAW_PANEL_GAL::SetDrawingSheet( DS_PROXY_VIEW_ITEM* aDrawingSheet )
180 {
181 m_drawingSheet.reset( aDrawingSheet );
182 m_view->Add( m_drawingSheet.get() );
183 }
184
185
SetTopLayer(int aLayer)186 void GERBVIEW_DRAW_PANEL_GAL::SetTopLayer( int aLayer )
187 {
188 m_view->ClearTopLayers();
189
190 for( int i = 0; i < GERBER_DRAWLAYERS_COUNT; ++i )
191 {
192 m_view->SetLayerOrder( GERBER_DCODE_LAYER( GERBER_DRAW_LAYER( i ) ),
193 GERBER_DRAW_LAYER( 2 * i ) );
194 m_view->SetLayerOrder( GERBER_DRAW_LAYER( i ), GERBER_DRAW_LAYER( ( 2 * i ) + 1 ) );
195 }
196
197 m_view->SetTopLayer( aLayer );
198
199 // Move DCODE layer to the top
200 m_view->SetTopLayer( GERBER_DCODE_LAYER( aLayer ) );
201
202 m_view->SetTopLayer( LAYER_SELECT_OVERLAY );
203
204 m_view->SetTopLayer( LAYER_GP_OVERLAY );
205
206 m_view->UpdateAllLayersOrder();
207 }
208
209
GetDefaultViewBBox() const210 BOX2I GERBVIEW_DRAW_PANEL_GAL::GetDefaultViewBBox() const
211 {
212 // Even in Gervbview, LAYER_DRAWINGSHEET controls the visibility of the drawingsheet
213 if( m_drawingSheet && m_view->IsLayerVisible( LAYER_DRAWINGSHEET ) )
214 return m_drawingSheet->ViewBBox();
215
216 return BOX2I();
217 }
218