KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_reference_image.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) 2011 jean-pierre.charras
5 * Copyright (C) 2022 Mike Williams
6 * Copyright (C) 2011-2023 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <pcb_draw_panel_gal.h>
27#include <plotters/plotter.h>
29#include <pcb_painter.h>
30#include <bitmaps.h>
31#include <base_units.h>
32#include <common.h>
33#include <eda_draw_frame.h>
34#include <core/mirror.h>
35#include <board.h>
36#include <pcb_reference_image.h>
37#include <trigo.h>
38#include <geometry/shape_rect.h>
39
40#include <wx/mstream.h>
41
44
45
46
48 PCB_LAYER_ID aLayer ) :
49 BOARD_ITEM( aParent, PCB_REFERENCE_IMAGE_T, aLayer )
50{
51 m_pos = pos;
54}
55
56
58 BOARD_ITEM( aPCBBitmap )
59{
60 m_pos = aPCBBitmap.m_pos;
61 m_bitmapBase = new BITMAP_BASE( *aPCBBitmap.m_bitmapBase );
63}
64
65
67{
68 wxCHECK_MSG( Type() == aItem.Type(), *this,
69 wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " )
70 + GetClass() );
71
72 if( &aItem != this )
73 {
74 BOARD_ITEM::operator=( aItem );
75
76 PCB_REFERENCE_IMAGE* bitmap = (PCB_REFERENCE_IMAGE*) &aItem;
77
78 delete m_bitmapBase;
79 m_bitmapBase = new BITMAP_BASE( *bitmap->m_bitmapBase );
80 m_pos = bitmap->m_pos;
82 }
83
84 return *this;
85}
86
87
88bool PCB_REFERENCE_IMAGE::ReadImageFile( const wxString& aFullFilename )
89{
90 if( m_bitmapBase->ReadImageFile( aFullFilename ) )
91 {
93 return true;
94 }
95
96 return false;
97}
98
99
100bool PCB_REFERENCE_IMAGE::ReadImageFile( wxMemoryBuffer& aBuffer )
101{
102 if( m_bitmapBase->ReadImageFile( aBuffer ) )
103 {
105 return true;
106 }
107
108 return false;
109}
110
111
113{
114 return new PCB_REFERENCE_IMAGE( *this );
115}
116
117
119{
120 wxCHECK_RET( aItem->Type() == PCB_REFERENCE_IMAGE_T,
121 wxString::Format( wxT( "% object cannot swap data with %s object." ),
122 GetClass(), aItem->GetClass() ) );
123
125 std::swap( m_layer, item->m_layer );
126 std::swap( m_isKnockout, item->m_isKnockout );
127 std::swap( m_isLocked, item->m_isLocked );
128 std::swap( m_flags, item->m_flags );
129 std::swap( m_parent, item->m_parent );
130 std::swap( m_forceVisible, item->m_forceVisible );
131 std::swap( m_pos, item->m_pos );
132 std::swap( m_bitmapBase, item->m_bitmapBase );
133}
134
135
136double PCB_REFERENCE_IMAGE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
137{
138 constexpr double HIDE = std::numeric_limits<double>::max();
139
140 PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
141 PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
142
143 // All bitmaps are drawn on LAYER_DRAW_BITMAPS, but their
144 // associated board layer controls their visibility.
145 if( !GetBoard()->IsLayerVisible( m_layer ) )
146 return HIDE;
147
148 if( renderSettings->GetHighContrast()
149 && renderSettings->m_ContrastModeDisplay == HIGH_CONTRAST_MODE::HIDDEN
150 && !renderSettings->GetLayerIsHighContrast( m_layer ) )
151 {
152 return HIDE;
153 }
154
155 return aView->IsLayerVisible( LAYER_DRAW_BITMAPS ) ? 0.0 : HIDE;
156}
157
158
160{
161 // Bitmaps are center origin, BOX2Is need top-left origin
162 VECTOR2I size = m_bitmapBase->GetSize();
163 VECTOR2I topLeft = { m_pos.x - size.x / 2, m_pos.y - size.y / 2 };
164
165 return BOX2I( topLeft, size );
166}
167
168
170 FLASHING aFlash ) const
171{
172 BOX2I box = GetBoundingBox();
173 return std::make_shared<SHAPE_RECT>( box.GetPosition(), box.GetWidth(), box.GetHeight() );
174}
175
176
178{
179 return m_bitmapBase->GetSize();
180}
181
182
183void PCB_REFERENCE_IMAGE::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
184{
185 if( aFlipLeftRight )
186 {
187 MIRROR( m_pos.x, aCentre.x );
188 m_bitmapBase->Mirror( false );
189 }
190 else
191 {
192 MIRROR( m_pos.y, aCentre.y );
193 m_bitmapBase->Mirror( true );
194 }
195}
196
197void PCB_REFERENCE_IMAGE::Rotate( const VECTOR2I& aCenter, const EDA_ANGLE& aAngle )
198{
199 EDA_ANGLE norm( aAngle.AsDegrees(), DEGREES_T );
200
201 RotatePoint( m_pos, aCenter, aAngle );
202
203 norm.Normalize();
204
205 // each call to m_bitmapBase->Rotate() rotates 90 degrees CCW
206 for( double ang = 45.0; ang < norm.AsDegrees(); ang += 90.0 )
207 m_bitmapBase->Rotate( false );
208}
209
210
211#if defined( DEBUG )
212void PCB_REFERENCE_IMAGE::Show( int nestLevel, std::ostream& os ) const
213{
214 // XML output:
215 wxString s = GetClass();
216
217 NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_pos << "/>\n";
218}
219#endif
220
221
222bool PCB_REFERENCE_IMAGE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
223{
224 BOX2I rect = GetBoundingBox();
225
226 rect.Inflate( aAccuracy );
227
228 return rect.Contains( aPosition );
229}
230
231
232bool PCB_REFERENCE_IMAGE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
233{
234 BOX2I rect = aRect;
235
236 rect.Inflate( aAccuracy );
237
238 if( aContained )
239 return rect.Contains( GetBoundingBox() );
240
241 return rect.Intersects( GetBoundingBox() );
242}
243
244
246{
247 return BITMAPS::image;
248}
249
250
252 std::vector<MSG_PANEL_ITEM>& aList )
253{
254 aList.emplace_back( _( "Reference Image" ), wxEmptyString );
255
256 aList.emplace_back( _( "PPI" ), wxString::Format( wxT( "%d "), GetImage()->GetPPI() ) );
257 aList.emplace_back( _( "Scale" ), wxString::Format( wxT( "%f "), GetImageScale() ) );
258
259 aList.emplace_back( _( "Width" ), aFrame->MessageTextFromValue( GetSize().x ) );
260 aList.emplace_back( _( "Height" ), aFrame->MessageTextFromValue( GetSize().y ) );
261 aList.emplace_back( _( "Layer" ), LayerName( m_layer ) );
262}
263
264
265void PCB_REFERENCE_IMAGE::ViewGetLayers( int aLayers[], int& aCount ) const
266{
267 aCount = 1;
268 aLayers[0] = BITMAP_LAYER_FOR( m_layer );
269}
270
271
273{
274 if( aOther.Type() != Type() )
275 return false;
276
277 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aOther );
278
279 if( m_layer != other.m_layer )
280 return false;
281
282 if( m_pos != other.m_pos )
283 return false;
284
285 if( m_bitmapBase->GetSize() != other.m_bitmapBase->GetSize() )
286 return false;
287
288 if( m_bitmapBase->GetPPI() != other.m_bitmapBase->GetPPI() )
289 return false;
290
291 if( m_bitmapBase->GetScale() != other.m_bitmapBase->GetScale() )
292 return false;
293
295 return false;
296
298 return false;
299
300 return true;
301}
302
303
304double PCB_REFERENCE_IMAGE::Similarity( const BOARD_ITEM& aOther ) const
305{
306 if( aOther.Type() != Type() )
307 return 0.0;
308
309 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aOther );
310
311 double similarity = 1.0;
312
313 if( m_layer != other.m_layer )
314 similarity *= 0.9;
315
316 if( m_pos != other.m_pos )
317 similarity *= 0.9;
318
319 if( m_bitmapBase->GetSize() != other.m_bitmapBase->GetSize() )
320 similarity *= 0.9;
321
322 if( m_bitmapBase->GetPPI() != other.m_bitmapBase->GetPPI() )
323 similarity *= 0.9;
324
325 if( m_bitmapBase->GetScale() != other.m_bitmapBase->GetScale() )
326 similarity *= 0.9;
327
329 similarity *= 0.9;
330
332 similarity *= 0.9;
333
334 return similarity;
335}
336
337
339{
341 {
345
346 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ),
349
350 const wxString groupImage = _HKI( "Image Properties" );
351
355 groupImage );
356
357 // For future use
358 const wxString greyscale = _HKI( "Greyscale" );
359 }
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
BOX2< VECTOR2I > BOX2I
Definition: box2.h:877
This class handle bitmap images in KiCad.
Definition: bitmap_base.h:48
void Rotate(bool aRotateCCW)
Rotate image CW or CCW.
double GetScale() const
Definition: bitmap_base.h:72
void Mirror(bool aVertically)
Mirror image vertically (i.e.
void SetPixelSizeIu(double aPixSize)
Definition: bitmap_base.h:65
bool ReadImageFile(const wxString &aFullFilename)
Reads and stores in memory an image file.
KIID GetImageID() const
Definition: bitmap_base.h:75
int GetPPI() const
Definition: bitmap_base.h:117
wxImage * GetImageData()
Definition: bitmap_base.h:67
VECTOR2I GetSize() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:77
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:226
bool m_isKnockout
Definition: board_item.h:389
PCB_LAYER_ID m_layer
Definition: board_item.h:388
bool m_isLocked
Definition: board_item.h:391
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:260
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:46
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:686
const Vec & GetPosition() const
Definition: box2.h:201
size_type GetHeight() const
Definition: box2.h:205
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:294
size_type GetWidth() const
Definition: box2.h:204
bool Contains(const Vec &aPoint) const
Definition: box2.h:158
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:541
EDA_ANGLE Normalize()
Definition: eda_angle.h:255
double AsDegrees() const
Definition: eda_angle.h:155
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:88
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
Definition: eda_item.cpp:258
bool m_forceVisible
Definition: eda_item.h:489
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:100
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:490
virtual wxString GetClass() const =0
Return the class name.
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:488
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:164
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
Definition: pcb_painter.h:169
PCB specific render settings.
Definition: pcb_painter.h:77
HIGH_CONTRAST_MODE m_ContrastModeDisplay
Definition: pcb_painter.h:131
bool GetHighContrast() const
bool GetLayerIsHighContrast(int aLayerId) const
Return information whether the queried layer is marked as high-contrast.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:412
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:215
Object to handle a bitmap image that can be inserted in a PCB.
void swapData(BOARD_ITEM *aItem) override
double Similarity(const BOARD_ITEM &aBoardItem) const override
Return a measure of how likely the other object is to represent the same object.
double GetImageScale() const
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
bool ReadImageFile(const wxString &aFullFilename)
Read and store an image file.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
const BITMAP_BASE * GetImage() const
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
void SetImageScale(double aScale)
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
wxString GetClass() const override
Return the class name.
void Rotate(const VECTOR2I &aCenter, const EDA_ANGLE &aAngle) override
Rotate this object.
bool operator==(const BOARD_ITEM &aBoardItem) const override
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
const VECTOR2I GetSize() const
PCB_REFERENCE_IMAGE(BOARD_ITEM *aParent, const VECTOR2I &pos=VECTOR2I(0, 0), PCB_LAYER_ID aLayer=F_Cu)
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
PCB_REFERENCE_IMAGE & operator=(const BOARD_ITEM &aItem)
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
The common library.
#define _HKI(x)
#define _(s)
@ DEGREES_T
Definition: eda_angle.h:31
wxString LayerName(int aLayer)
Returns the default display name for a given layer.
Definition: layer_id.cpp:30
#define BITMAP_LAYER_FOR(boardLayer)
Macros for getting the extra layers for a given board layer.
Definition: layer_ids.h:275
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition: layer_ids.h:149
@ LAYER_DRAW_BITMAPS
to handle and draw images bitmaps
Definition: layer_ids.h:227
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
static struct PCB_REFERENCE_IMAGE_DESC _PCB_REFERENCE_IMAGE_DESC
#define TYPE_HASH(x)
Definition: property.h:71
#define REGISTER_TYPE(x)
Definition: property_mgr.h:366
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:228
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
Definition: typeinfo.h:89