KiCad PCB EDA Suite
ws_painter.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
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 #include <fctsys.h>
27 #include <pgm_base.h>
28 #include <gr_basic.h>
29 #include <common.h>
30 #include <base_screen.h>
31 #include <eda_draw_frame.h>
32 #include <title_block.h>
33 #include <build_version.h>
34 #include <ws_draw_item.h>
36 
37 #include <ws_painter.h>
38 #include <ws_data_item.h>
39 
40 using namespace KIGFX;
41 
42 static const wxString productName = wxT( "KiCad E.D.A. " );
43 
45 {
46  m_backgroundColor = COLOR4D( 1.0, 1.0, 1.0, 1.0 );
49  m_brightenedColor = COLOR4D( 0.0, 1.0, 0.0, 0.9 );
50 
51  update();
52 }
53 
54 
55 const COLOR4D& WS_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const
56 {
57  const EDA_ITEM* item = dynamic_cast<const EDA_ITEM*>( aItem );
58 
59  if( item )
60  {
61  // Selection disambiguation
62  if( item->IsBrightened() )
63  return m_brightenedColor;
64 
65  if( item->IsSelected() )
66  return m_selectedColor;
67  }
68 
69  return m_normalColor;
70 }
71 
72 
73 // returns the full text corresponding to the aTextbase,
74 // after replacing format symbols by the corresponding value
75 wxString WS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase )
76 {
77  wxString msg;
78 
79  /* Known formats
80  * %% = replaced by %
81  * %K = Kicad version
82  * %Z = paper format name (A4, USLetter)
83  * %Y = company name
84  * %D = date
85  * %R = revision
86  * %S = sheet number
87  * %N = number of sheets
88  * %L = layer name
89  * %Cx = comment (x = 0 to 9 to identify the comment)
90  * %F = filename
91  * %P = sheet path (sheet full name)
92  * %T = title
93  */
94 
95  for( unsigned ii = 0; ii < aTextbase.Len(); ii++ )
96  {
97  if( aTextbase[ii] != '%' )
98  {
99  msg << aTextbase[ii];
100  continue;
101  }
102 
103  if( ++ii >= aTextbase.Len() )
104  break;
105 
106  wxChar format = aTextbase[ii];
107  switch( format )
108  {
109  case '%':
110  msg += '%';
111  break;
112 
113  case 'D':
114  if( m_titleBlock )
115  msg += m_titleBlock->GetDate();
116  break;
117 
118  case 'R':
119  if( m_titleBlock )
120  msg += m_titleBlock->GetRevision();
121  break;
122 
123  case 'K':
124  msg += productName + Pgm().App().GetAppName();
125  msg += wxT( " " ) + GetBuildVersion();
126  break;
127 
128  case 'Z':
129  if( m_paperFormat )
130  msg += *m_paperFormat;
131  break;
132 
133  case 'S':
134  msg << m_sheetNumber;
135  break;
136 
137  case 'N':
138  msg << m_sheetCount;
139  break;
140 
141  case 'F':
142  {
143  wxFileName fn( m_fileName );
144  msg += fn.GetFullName();
145  }
146  break;
147 
148  case 'L':
149  if( m_sheetLayer )
150  msg += *m_sheetLayer;
151  break;
152 
153  case 'P':
154  msg += m_sheetFullName;
155  break;
156 
157  case 'Y':
158  if( m_titleBlock )
159  msg += m_titleBlock->GetCompany();
160  break;
161 
162  case 'T':
163  if( m_titleBlock )
164  msg += m_titleBlock->GetTitle();
165  break;
166 
167  case 'C':
168  format = aTextbase[++ii];
169  switch( format )
170  {
171  case '0':
172  case '1':
173  case '2':
174  case '3':
175  case '4':
176  case '5':
177  case '6':
178  case '7':
179  case '8':
180  case '9':
181  if( m_titleBlock )
182  msg += m_titleBlock->GetComment( format - '0');
183  break;
184 
185  default:
186  break;
187  }
188 
189  default:
190  break;
191  }
192  }
193 
194  return msg;
195 }
196 
197 
198 void TITLE_BLOCK::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
199 
200 {
201  // Don't write the title block information if there is nothing to write.
202  bool isempty = true;
203  for( unsigned idx = 0; idx < m_tbTexts.GetCount(); idx++ )
204  {
205  if( ! m_tbTexts[idx].IsEmpty() )
206  {
207  isempty = false;
208  break;
209  }
210  }
211 
212  if( !isempty )
213  {
214  aFormatter->Print( aNestLevel, "(title_block\n" );
215 
216  if( !GetTitle().IsEmpty() )
217  aFormatter->Print( aNestLevel+1, "(title %s)\n",
218  aFormatter->Quotew( GetTitle() ).c_str() );
219 
220  if( !GetDate().IsEmpty() )
221  aFormatter->Print( aNestLevel+1, "(date %s)\n",
222  aFormatter->Quotew( GetDate() ).c_str() );
223 
224  if( !GetRevision().IsEmpty() )
225  aFormatter->Print( aNestLevel+1, "(rev %s)\n",
226  aFormatter->Quotew( GetRevision() ).c_str() );
227 
228  if( !GetCompany().IsEmpty() )
229  aFormatter->Print( aNestLevel+1, "(company %s)\n",
230  aFormatter->Quotew( GetCompany() ).c_str() );
231 
232  for( int ii = 0; ii < 9; ii++ )
233  {
234  if( !GetComment(ii).IsEmpty() )
235  aFormatter->Print( aNestLevel+1, "(comment %d %s)\n", ii+1,
236  aFormatter->Quotew( GetComment(ii) ).c_str() );
237  }
238 
239  aFormatter->Print( aNestLevel, ")\n\n" );
240  }
241 }
242 
243 
244 bool KIGFX::WS_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
245 {
246  auto item = static_cast<const EDA_ITEM*>( aItem );
247 
248  switch( item->Type() )
249  {
250  case WSG_LINE_T: draw( (WS_DRAW_ITEM_LINE*) item, aLayer ); break;
251  case WSG_POLY_T: draw( (WS_DRAW_ITEM_POLYPOLYGONS*) item, aLayer ); break;
252  case WSG_RECT_T: draw( (WS_DRAW_ITEM_RECT*) item, aLayer ); break;
253  case WSG_TEXT_T: draw( (WS_DRAW_ITEM_TEXT*) item, aLayer ); break;
254  case WSG_BITMAP_T: draw( (WS_DRAW_ITEM_BITMAP*) item, aLayer ); break;
255  case WSG_PAGE_T: draw( (WS_DRAW_ITEM_PAGE*) item, aLayer ); break;
256  default: return false;
257  }
258 
259  return true;
260 }
261 
262 
263 void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_LINE* aItem, int aLayer ) const
264 {
265  m_gal->SetIsStroke( true );
266  m_gal->SetIsFill( false );
267  m_gal->SetStrokeColor( m_renderSettings.GetColor( aItem, aLayer ) );
268  m_gal->SetLineWidth( aItem->GetPenWidth() );
269  m_gal->DrawLine( VECTOR2D( aItem->GetStart() ), VECTOR2D( aItem->GetEnd() ) );
270 }
271 
272 
273 void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_RECT* aItem, int aLayer ) const
274 {
275  m_gal->SetIsStroke( true );
276  m_gal->SetIsFill( false );
277  m_gal->SetStrokeColor( m_renderSettings.GetColor( aItem, aLayer ) );
278  m_gal->SetLineWidth( aItem->GetPenWidth() );
279  m_gal->DrawRectangle( VECTOR2D( aItem->GetStart() ), VECTOR2D( aItem->GetEnd() ) );
280 }
281 
282 
283 void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_POLYPOLYGONS* aItem, int aLayer ) const
284 {
285  m_gal->SetFillColor( m_renderSettings.GetColor( aItem, aLayer ) );
286  m_gal->SetIsFill( true );
287  m_gal->SetIsStroke( false );
288 
290 
291  for( int idx = 0; idx < item->GetPolygons().OutlineCount(); ++idx )
292  {
293  SHAPE_LINE_CHAIN& outline = item->GetPolygons().Outline( idx );
294  m_gal->DrawPolygon( outline );
295  }
296 }
297 
298 
299 void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_TEXT* aItem, int aLayer ) const
300 {
301  VECTOR2D position( aItem->GetTextPos().x, aItem->GetTextPos().y );
302 
303  m_gal->Save();
304  m_gal->Translate( position );
305  m_gal->Rotate( -aItem->GetTextAngle() * M_PI / 1800.0 );
306  m_gal->SetStrokeColor( m_renderSettings.GetColor( aItem, aLayer ) );
307  m_gal->SetLineWidth( aItem->GetThickness() );
308  m_gal->SetTextAttributes( aItem );
309  m_gal->SetIsFill( false );
310  m_gal->SetIsStroke( true );
311  m_gal->StrokeText( aItem->GetShownText(), VECTOR2D( 0, 0 ), 0.0 );
312  m_gal->Restore();
313 }
314 
315 
316 void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_BITMAP* aItem, int aLayer ) const
317 {
318  m_gal->Save();
319  VECTOR2D position = aItem->GetPosition();
320  m_gal->Translate( position );
321  auto* bitmap = static_cast<WS_DATA_ITEM_BITMAP*>( aItem->GetPeer() );
322 
323  // When the image scale factor is not 1.0, we need to modify the actual scale
324  // as the image scale factor is similar to a local zoom
325  double img_scale = bitmap->m_ImageBitmap->GetScale();
326 
327  if( img_scale != 1.0 )
328  m_gal->Scale( VECTOR2D( img_scale, img_scale ) );
329 
330  m_gal->DrawBitmap( *bitmap->m_ImageBitmap );
331  m_gal->Restore();
332 }
333 
334 
335 void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_PAGE* aItem, int aLayer ) const
336 {
337  VECTOR2D origin = VECTOR2D( 0.0, 0.0 );
338  VECTOR2D end = VECTOR2D( aItem->GetPageSize().x,
339  aItem->GetPageSize().y );
340 
341  m_gal->SetIsStroke( true );
342 
343  // Use a gray color for the border color
344  m_gal->SetStrokeColor( COLOR4D( 0.4, 0.4, 0.4, 1.0 ) );
345  m_gal->SetIsFill( false );
346  m_gal->DrawRectangle( origin, end );
347 
348  // Draw the corner marker
349  double marker_size = aItem->GetMarkerSize();
350 
351  m_gal->SetStrokeColor( COLOR4D( 0.4, 0.4, 1.0, 1.0 ) );
352  VECTOR2D pos = VECTOR2D( aItem->GetMarkerPos().x, aItem->GetMarkerPos().y );
353 
354  // Draw a cirle and a X
355  m_gal->DrawCircle( pos, marker_size );
356  m_gal->DrawLine( VECTOR2D( pos.x - marker_size, pos.y - marker_size),
357  VECTOR2D( pos.x + marker_size, pos.y + marker_size ) );
358  m_gal->DrawLine( VECTOR2D( pos.x + marker_size, pos.y - marker_size),
359  VECTOR2D( pos.x - marker_size, pos.y + marker_size ) );
360 }
361 
362 
363 void KIGFX::WS_PAINTER::DrawBorder( const PAGE_INFO* aPageInfo, int aScaleFactor ) const
364 {
365  VECTOR2D origin = VECTOR2D( 0.0, 0.0 );
366  VECTOR2D end = VECTOR2D( aPageInfo->GetWidthMils() * aScaleFactor,
367  aPageInfo->GetHeightMils() * aScaleFactor );
368 
369  m_gal->SetIsStroke( true );
370  // Use a gray color for the border color
371  m_gal->SetStrokeColor( COLOR4D( 0.4, 0.4, 0.4, 1.0 ) );
372  m_gal->SetIsFill( false );
373  m_gal->DrawRectangle( origin, end );
374 }
const wxPoint & GetStart() const
Definition: ws_draw_item.h:206
WS_DATA_ITEM * GetPeer() const
Definition: ws_draw_item.h:66
const wxPoint & GetEnd() const
Definition: ws_draw_item.h:208
int OutlineCount() const
Returns the number of outlines in the set
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:58
bool IsSelected() const
Definition: base_struct.h:233
const wxPoint & GetEnd() const
Definition: ws_draw_item.h:124
int GetHeightMils() const
Definition: page_info.h:140
SHAPE_POLY_SET & GetPolygons()
Definition: ws_draw_item.h:167
int GetPenWidth() const
Definition: ws_draw_item.h:205
VTBL_ENTRY wxApp & App()
Function App returns a bare naked wxApp, which may come from wxPython, SINGLE_TOP,...
Definition: pgm_base.cpp:164
double GetTextAngle() const
Definition: eda_text.h:158
Class OUTPUTFORMATTER is an important interface (abstract class) used to output 8 bit text in a conve...
Definition: richio.h:327
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:65
bool IsBrightened() const
Definition: base_struct.h:236
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:148
Class VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:84
COLOR4D Brightened(double aFactor) const
Function Brightened Returns a color that is brighter by a given factor, without modifying object.
Definition: color4d.h:199
VECTOR2< double > VECTOR2D
Definition: vector2d.h:586
void DrawBorder(const PAGE_INFO *aPageInfo, int aScaleFactor) const
Definition: ws_painter.cpp:363
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
virtual void update()
Function update Precalculates extra colors for layers (e.g.
Definition: painter.cpp:53
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
Class PAGE_INFO describes the page size and margins of a paper page on which to eventually print or p...
Definition: page_info.h:54
const wxPoint & GetStart() const
Definition: ws_draw_item.h:122
int GetPenWidth() const
Definition: ws_draw_item.h:121
void draw(const WS_DRAW_ITEM_LINE *aItem, int aLayer) const
Definition: ws_painter.cpp:263
Definition: colors.h:60
virtual void Format(OUTPUTFORMATTER *aFormatter, int aNestLevel, int aControlBits) const
Function Format outputs the object to aFormatter in s-expression form.
Definition: ws_painter.cpp:198
std::string Quotew(const wxString &aWrapee)
Definition: richio.cpp:472
wxSize GetPageSize() const
Definition: ws_draw_item.h:250
COLOR4D m_backgroundColor
The background color.
Definition: painter.h:297
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:370
see class PGM_BASE
wxString BuildFullText(const wxString &aTextbase)
Function BuildFullText returns the full text corresponding to the aTextbase, after replacing format s...
Definition: ws_painter.cpp:75
const wxPoint GetPosition() const override
Definition: ws_draw_item.h:330
Class SHAPE_LINE_CHAIN.
virtual const COLOR4D & GetColor(const VIEW_ITEM *aItem, int aLayer) const override
Function GetColor Returns the color that should be used to draw the specific VIEW_ITEM on the specifi...
Definition: ws_painter.cpp:55
double GetMarkerSize() const
Definition: ws_draw_item.h:253
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:163
The common library.
const wxPoint & GetTextPos() const
Definition: eda_text.h:232
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:129
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Function Print formats and writes text to the output stream.
Definition: richio.cpp:404
BASE_SCREEN class implementation.
virtual bool Draw(const VIEW_ITEM *, int) override
Function Draw Takes an instance of VIEW_ITEM and passes it to a function that know how to draw the it...
Definition: ws_painter.cpp:244
static const wxString productName
Definition: ws_painter.cpp:42
const wxPoint & GetMarkerPos() const
Definition: ws_draw_item.h:251
int GetWidthMils() const
Definition: page_info.h:137
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39