KiCad PCB EDA Suite
class_bitmap_base.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 2011 jean-pierre.charras
9  * Copyright (C) 2011-2016 KiCad Developers, see change_log.txt for contributors.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, you may find one here:
23  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24  * or you may search the http://www.gnu.org website for the version 2 license,
25  * or you may write to the Free Software Foundation, Inc.,
26  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27  */
28 
29 #include "fctsys.h"
30 #include "gr_basic.h"
31 #include "macros.h"
32 #include "class_drawpanel.h"
33 #include "trigo.h"
34 #include "common.h"
35 #include "richio.h"
36 #include "plot_common.h"
37 
38 #include "class_bitmap_base.h"
39 
40 #include <wx/mstream.h>
41 
42 
43 /**********************/
44 /* class BITMAP_BASE */
45 /**********************/
46 
48 {
49  m_scale = 1.0; // 1.0 = original bitmap size
50  m_bitmap = NULL;
51  m_image = NULL;
52  m_ppi = 300; // the bitmap definition. the default is 300PPI
53  m_pixelScaleFactor = 1000.0 / m_ppi; // a value OK for bitmaps using 300 PPI
54  // for Eeschema which uses currently 1000PPI
55 }
56 
57 
59 {
60  m_scale = aSchBitmap.m_scale;
61  m_ppi = aSchBitmap.m_ppi;
63  m_image = new wxImage( *aSchBitmap.m_image );
64  m_bitmap = new wxBitmap( *m_image );
65 }
66 
67 
73 {
74  *m_image = *aItem->m_image;
75  *m_bitmap = *aItem->m_bitmap;
76  m_scale = aItem->m_scale;
77  m_ppi = aItem->m_ppi;
79 }
80 
81 
82 bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename )
83 {
84  wxImage* new_image = new wxImage();
85 
86  if( !new_image->LoadFile( aFullFilename ) )
87  {
88  delete new_image;
89  return false;
90  }
91 
92  delete m_image;
93  m_image = new_image;
94  m_bitmap = new wxBitmap( *m_image );
95 
96  return true;
97 }
98 
99 
100 bool BITMAP_BASE::SaveData( FILE* aFile ) const
101 {
102  if( m_image )
103  {
104  wxMemoryOutputStream stream;
105  m_image->SaveFile( stream, wxBITMAP_TYPE_PNG );
106 
107  // Write binary data in hexadecimal form (ASCII)
108  wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
109  char* begin = (char*) buffer->GetBufferStart();
110 
111  for( int ii = 0; begin < buffer->GetBufferEnd(); begin++, ii++ )
112  {
113  if( ii >= 32 )
114  {
115  ii = 0;
116 
117  if( fprintf( aFile, "\n" ) == EOF )
118  return false;
119  }
120 
121  if( fprintf( aFile, "%2.2X ", *begin & 0xFF ) == EOF )
122  return false;
123  }
124  }
125 
126  return true;
127 }
128 
129 
130 void BITMAP_BASE::SaveData( wxArrayString& aPngStrings ) const
131 {
132  if( m_image )
133  {
134  wxMemoryOutputStream stream;
135  m_image->SaveFile( stream, wxBITMAP_TYPE_PNG );
136 
137  // Write binary data in hexadecimal form (ASCII)
138  wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
139  char* begin = (char*) buffer->GetBufferStart();
140  wxString line;
141 
142  for( int ii = 0; begin < buffer->GetBufferEnd(); begin++, ii++ )
143  {
144  if( ii >= 32 )
145  {
146  ii = 0;
147  aPngStrings.Add( line );
148  line.Empty();
149  }
150 
151  line << wxString::Format( wxT( "%2.2X " ), *begin & 0xFF );
152  }
153 
154  // Add last line:
155  if( !line.IsEmpty() )
156  aPngStrings.Add( line );
157  }
158 }
159 
160 
161 bool BITMAP_BASE::LoadData( LINE_READER& aLine, wxString& aErrorMsg )
162 {
163  wxMemoryOutputStream stream;
164  char* line;
165 
166  while( true )
167  {
168  if( !aLine.ReadLine() )
169  {
170  aErrorMsg = wxT("Unexpected end of data");
171  return false;
172  }
173 
174  line = aLine.Line();
175 
176  if( strncasecmp( line, "EndData", 4 ) == 0 )
177  {
178  // all the PNG date is read.
179  // We expect here m_image and m_bitmap are void
180  m_image = new wxImage();
181  wxMemoryInputStream istream( stream );
182  m_image->LoadFile( istream, wxBITMAP_TYPE_PNG );
183  m_bitmap = new wxBitmap( *m_image );
184  break;
185  }
186 
187  // Read PNG data, stored in hexadecimal,
188  // each byte = 2 hexadecimal digits and a space between 2 bytes
189  // and put it in memory stream buffer
190  int len = strlen( line );
191 
192  for( ; len > 0; len -= 3, line += 3 )
193  {
194  int value = 0;
195 
196  if( sscanf( line, "%X", &value ) == 1 )
197  stream.PutC( (char) value );
198  else
199  break;
200  }
201  }
202 
203  return true;
204 }
205 
206 
208 {
209  EDA_RECT rect;
210 
211  wxSize size = GetSize();
212 
213  rect.Inflate( size.x / 2, size.y / 2 );
214 
215  return rect;
216 }
217 
218 
219 void BITMAP_BASE::DrawBitmap( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPos )
220 {
221  if( m_bitmap == NULL )
222  return;
223 
224  wxPoint pos = aPos;
225  wxSize size = GetSize();
226 
227  // This fixes a bug in OSX that should be fixed in the 3.0.3 version or later.
228  if( ( size.x == 0 ) || ( size.y == 0 ) )
229  return;
230 
231  // To draw the bitmap, pos is the upper left corner position
232  pos.x -= size.x / 2;
233  pos.y -= size.y / 2;
234 
235  double scale;
236  int logicalOriginX, logicalOriginY;
237  aDC->GetUserScale( &scale, &scale );
238  aDC->GetLogicalOrigin( &logicalOriginX, &logicalOriginY );
239  aDC->SetUserScale( scale * GetScalingFactor(), scale * GetScalingFactor() );
240  aDC->SetLogicalOrigin( logicalOriginX / GetScalingFactor(),
241  logicalOriginY / GetScalingFactor() );
242  aDC->DrawBitmap( *m_bitmap,
243  KiROUND( pos.x / GetScalingFactor() ),
244  KiROUND( pos.y / GetScalingFactor() ),
245  true );
246  aDC->SetUserScale( scale, scale );
247  aDC->SetLogicalOrigin( logicalOriginX, logicalOriginY );
248 }
249 
250 
251 wxSize BITMAP_BASE::GetSize() const
252 {
253  wxSize size;
254 
255  if( m_bitmap )
256  {
257  size.x = m_bitmap->GetWidth();
258  size.y = m_bitmap->GetHeight();
259 
260  size.x = KiROUND( size.x * GetScalingFactor() );
261  size.y = KiROUND( size.y * GetScalingFactor() );
262  }
263 
264  return size;
265 }
266 
267 
268 void BITMAP_BASE::Mirror( bool aVertically )
269 {
270  if( m_image )
271  {
272  *m_image = m_image->Mirror( not aVertically );
273  RebuildBitmap();
274  }
275 }
276 
277 
278 void BITMAP_BASE::Rotate( bool aRotateCCW )
279 {
280  if( m_image )
281  {
282  *m_image = m_image->Rotate90( aRotateCCW );
283  RebuildBitmap();
284  }
285 }
286 
287 
289  const wxPoint& aPos,
290  COLOR4D aDefaultColor,
291  int aDefaultPensize )
292 {
293  if( m_image == NULL )
294  return;
295 
296  // These 2 lines are useful only for plotters that cannot plot a bitmap
297  // and plot a rectangle instead of.
298  aPlotter->SetColor( aDefaultColor );
299  aPlotter->SetCurrentLineWidth( aDefaultPensize );
300  aPlotter->PlotImage( *m_image, aPos, GetScalingFactor() );
301 }
Class LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived...
Definition: richio.h:81
BITMAP_BASE(const wxPoint &pos=wxPoint(0, 0))
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
bool SaveData(FILE *aFile) const
writes the bitmap data to aFile The format is png, in Hexadecimal form: If the hexadecimal data is co...
virtual void SetColor(COLOR4D color)=0
wxSize GetSize() const
Function GetSize.
void RebuildBitmap()
void PlotImage(PLOTTER *aPlotter, const wxPoint &aPos, COLOR4D aDefaultColor, int aDefaultPensize)
Function PlotImage Plot bitmap on plotter.
const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
void Mirror(bool aVertically)
Function Mirror Mirror image vertically (i.e.
This file contains miscellaneous commonly used macros and functions.
This class handle bitmap images in KiCad.
char * Line() const
Function Line returns a pointer to the last line that was read in.
Definition: richio.h:139
wxBitmap * m_bitmap
Common plot library Plot settings, and plotting engines (Postscript, Gerber, HPGL and DXF) ...
double m_pixelScaleFactor
Base plotter engine class.
Definition: plot_common.h:86
virtual void PlotImage(const wxImage &aImage, const wxPoint &aPos, double aScaleFactor)
Function PlotImage Only Postscript plotters can plot bitmaps for plotters that cannot plot a bitmap...
void ImportData(BITMAP_BASE *aItem)
Function ImportData Copy aItem image to me and update m_bitmap.
const int scale
virtual char * ReadLine()=0
Function ReadLine reads a line of text into the buffer and increments the line number counter...
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
Class EDA_RECT handles the component boundary box.
bool LoadData(LINE_READER &aLine, wxString &aErrorMsg)
Load an image data saved by SaveData (png, in Hexadecimal form)
The common library.
double GetScalingFactor() const
Function GetScalingFactor.
bool ReadImageFile(const wxString &aFullFilename)
Function ReadImageFile Reads and stores in memory an image file.
void DrawBitmap(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPos)
void Rotate(bool aRotateCCW)
Function Rotate Rotate image CW or CCW.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
wxImage * m_image
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39