KiCad PCB EDA Suite
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) 2017 jean-pierre.charras
9  * Copyright (C) 2011-2017 KiCad Developers, see AUTHORS.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 "trigo.h"
33 #include "common.h"
34 #include "richio.h"
35 #include "plotter.h"
36 
37 #include "bitmap_base.h"
38 
39 #include <wx/mstream.h>
40 
41 
42 /**********************/
43 /* class BITMAP_BASE */
44 /**********************/
45 
47 {
48  m_scale = 1.0; // 1.0 = original bitmap size
49  m_bitmap = NULL;
50  m_image = NULL;
51  m_ppi = 300; // the bitmap definition. the default is 300PPI
52  m_pixelScaleFactor = 1000.0 / m_ppi; // a value OK for bitmaps using 300 PPI
53  // for Eeschema which uses currently 1000PPI
54 }
55 
56 
58 {
59  m_scale = aSchBitmap.m_scale;
60  m_ppi = aSchBitmap.m_ppi;
62  m_image = new wxImage( *aSchBitmap.m_image );
63  m_bitmap = new wxBitmap( *m_image );
64 }
65 
66 
72 {
73  *m_image = *aItem->m_image;
74  *m_bitmap = *aItem->m_bitmap;
75  m_scale = aItem->m_scale;
76  m_ppi = aItem->m_ppi;
78 }
79 
80 
81 bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename )
82 {
83  wxImage* new_image = new wxImage();
84 
85  if( !new_image->LoadFile( aFullFilename ) )
86  {
87  delete new_image;
88  return false;
89  }
90 
91  delete m_image;
92  m_image = new_image;
93  m_bitmap = new wxBitmap( *m_image );
94 
95  return true;
96 }
97 
98 
99 bool BITMAP_BASE::SaveData( FILE* aFile ) const
100 {
101  if( m_image )
102  {
103  wxMemoryOutputStream stream;
104  m_image->SaveFile( stream, wxBITMAP_TYPE_PNG );
105 
106  // Write binary data in hexadecimal form (ASCII)
107  wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
108  char* begin = (char*) buffer->GetBufferStart();
109 
110  for( int ii = 0; begin < buffer->GetBufferEnd(); begin++, ii++ )
111  {
112  if( ii >= 32 )
113  {
114  ii = 0;
115 
116  if( fprintf( aFile, "\n" ) == EOF )
117  return false;
118  }
119 
120  if( fprintf( aFile, "%2.2X ", *begin & 0xFF ) == EOF )
121  return false;
122  }
123  }
124 
125  return true;
126 }
127 
128 
129 void BITMAP_BASE::SaveData( wxArrayString& aPngStrings ) const
130 {
131  if( m_image )
132  {
133  wxMemoryOutputStream stream;
134  m_image->SaveFile( stream, wxBITMAP_TYPE_PNG );
135 
136  // Write binary data in hexadecimal form (ASCII)
137  wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
138  char* begin = (char*) buffer->GetBufferStart();
139  wxString line;
140 
141  for( int ii = 0; begin < buffer->GetBufferEnd(); begin++, ii++ )
142  {
143  if( ii >= 32 )
144  {
145  ii = 0;
146  aPngStrings.Add( line );
147  line.Empty();
148  }
149 
150  line << wxString::Format( wxT( "%2.2X " ), *begin & 0xFF );
151  }
152 
153  // Add last line:
154  if( !line.IsEmpty() )
155  aPngStrings.Add( line );
156  }
157 }
158 
159 
160 bool BITMAP_BASE::LoadData( LINE_READER& aLine, wxString& aErrorMsg )
161 {
162  wxMemoryOutputStream stream;
163  char* line;
164 
165  while( true )
166  {
167  if( !aLine.ReadLine() )
168  {
169  aErrorMsg = wxT("Unexpected end of data");
170  return false;
171  }
172 
173  line = aLine.Line();
174 
175  if( strncasecmp( line, "EndData", 4 ) == 0 )
176  {
177  // all the PNG date is read.
178  // We expect here m_image and m_bitmap are void
179  m_image = new wxImage();
180  wxMemoryInputStream istream( stream );
181  m_image->LoadFile( istream, wxBITMAP_TYPE_PNG );
182  m_bitmap = new wxBitmap( *m_image );
183  break;
184  }
185 
186  // Read PNG data, stored in hexadecimal,
187  // each byte = 2 hexadecimal digits and a space between 2 bytes
188  // and put it in memory stream buffer
189  int len = strlen( line );
190 
191  for( ; len > 0; len -= 3, line += 3 )
192  {
193  int value = 0;
194 
195  if( sscanf( line, "%X", &value ) == 1 )
196  stream.PutC( (char) value );
197  else
198  break;
199  }
200  }
201 
202  return true;
203 }
204 
205 
207 {
208  EDA_RECT rect;
209 
210  wxSize size = GetSize();
211 
212  rect.Inflate( size.x / 2, size.y / 2 );
213 
214  return rect;
215 }
216 
217 
218 void BITMAP_BASE::DrawBitmap( wxDC* aDC, const wxPoint& aPos )
219 {
220  if( m_bitmap == NULL )
221  return;
222 
223  wxPoint pos = aPos;
224  wxSize size = GetSize();
225 
226  // This fixes a bug in OSX that should be fixed in the 3.0.3 version or later.
227  if( ( size.x == 0 ) || ( size.y == 0 ) )
228  return;
229 
230  // To draw the bitmap, pos is the upper left corner position
231  pos.x -= size.x / 2;
232  pos.y -= size.y / 2;
233 
234  double scale;
235  int logicalOriginX, logicalOriginY;
236  aDC->GetUserScale( &scale, &scale );
237  aDC->GetLogicalOrigin( &logicalOriginX, &logicalOriginY );
238  aDC->SetUserScale( scale * GetScalingFactor(), scale * GetScalingFactor() );
239  aDC->SetLogicalOrigin( logicalOriginX / GetScalingFactor(),
240  logicalOriginY / GetScalingFactor() );
241  aDC->DrawBitmap( *m_bitmap,
242  KiROUND( pos.x / GetScalingFactor() ),
243  KiROUND( pos.y / GetScalingFactor() ),
244  true );
245  aDC->SetUserScale( scale, scale );
246  aDC->SetLogicalOrigin( logicalOriginX, logicalOriginY );
247 }
248 
249 
250 wxSize BITMAP_BASE::GetSize() const
251 {
252  wxSize size;
253 
254  if( m_bitmap )
255  {
256  size.x = m_bitmap->GetWidth();
257  size.y = m_bitmap->GetHeight();
258 
259  size.x = KiROUND( size.x * GetScalingFactor() );
260  size.y = KiROUND( size.y * GetScalingFactor() );
261  }
262 
263  return size;
264 }
265 
266 
267 void BITMAP_BASE::Mirror( bool aVertically )
268 {
269  if( m_image )
270  {
271  *m_image = m_image->Mirror( not aVertically );
272  RebuildBitmap();
273  }
274 }
275 
276 
277 void BITMAP_BASE::Rotate( bool aRotateCCW )
278 {
279  if( m_image )
280  {
281  *m_image = m_image->Rotate90( aRotateCCW );
282  RebuildBitmap();
283  }
284 }
285 
286 
288  const wxPoint& aPos,
289  COLOR4D aDefaultColor,
290  int aDefaultPensize )
291 {
292  if( m_image == NULL )
293  return;
294 
295  // These 2 lines are useful only for plotters that cannot plot a bitmap
296  // and plot a rectangle instead of.
297  aPlotter->SetColor( aDefaultColor );
298  aPlotter->SetCurrentLineWidth( aDefaultPensize );
299  aPlotter->PlotImage( *m_image, aPos, GetScalingFactor() );
300 }
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))
Definition: bitmap_base.cpp:46
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:120
bool SaveData(FILE *aFile) const
writes the bitmap data to aFile The format is png, in Hexadecimal form: If the hexadecimal data is co...
Definition: bitmap_base.cpp:99
virtual void SetColor(COLOR4D color)=0
wxSize GetSize() const
Function GetSize.
void RebuildBitmap()
Definition: bitmap_base.h:92
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.
Definition: bitmap_base.h:46
double m_scale
Definition: bitmap_base.h:49
char * Line() const
Function Line returns a pointer to the last line that was read in.
Definition: richio.h:139
wxBitmap * m_bitmap
Definition: bitmap_base.h:52
double m_pixelScaleFactor
Definition: bitmap_base.h:53
Base plotter engine class.
Definition: plotter.h:97
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...
Definition: plotter.cpp:181
void ImportData(BITMAP_BASE *aItem)
Function ImportData Copy aItem image to me and update m_bitmap.
Definition: bitmap_base.cpp:71
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.
Definition: eda_rect.h:44
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.
Definition: bitmap_base.h:117
void DrawBitmap(wxDC *aDC, const wxPoint &aPos)
bool ReadImageFile(const wxString &aFullFilename)
Function ReadImageFile Reads and stores in memory an image file.
Definition: bitmap_base.cpp:81
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
Definition: bitmap_base.h:51
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