KiCad PCB EDA Suite
Loading...
Searching...
No Matches
bitmap.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 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
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 <wx/image.h>
27#include <wx/bitmap.h>
28#include <wx/gdicmn.h>
29#include <wx/mstream.h>
30#include <wx/menu.h>
31#include <wx/menuitem.h>
32#include <wx/aui/auibar.h>
33#include <wx/dcclient.h>
34#include <wx/dcmemory.h>
35
36#include <cstdint>
37#include <mutex>
38#include <unordered_map>
39
40#include <asset_archive.h>
41#include <bitmaps.h>
42#include <bitmap_store.h>
43#include <pgm_base.h>
44#include <paths.h>
45#include <kiplatform/ui.h>
46#include <math/util.h>
48
49static std::unique_ptr<BITMAP_STORE> s_BitmapStore;
50
51
54 int scale;
55
56 bool operator==( SCALED_BITMAP_ID const& other ) const noexcept
57 {
58 return bitmap == other.bitmap && scale == other.scale;
59 }
60};
61
62
63namespace std {
64 template<> struct hash<SCALED_BITMAP_ID>
65 {
67 typedef std::size_t result_type;
68
69 result_type operator()( argument_type const& id ) const noexcept
70 {
71 static const bool sz64 = sizeof( uintptr_t ) == 8;
72 static const size_t mask = sz64 ? 0xF000000000000000uLL : 0xF0000000uL;
73 static const size_t offset = sz64 ? 60 : 28;
74
75 // The hash only needs to be fast and simple, not necessarily accurate - a collision
76 // only makes things slower, not broken. BITMAPS is a pointer, so the most
77 // significant several bits are generally going to be the same for all. Just convert
78 // it to an integer and stuff the scale factor into those bits.
79 return
80 ( (uintptr_t)( id.bitmap ) & ~mask ) |
81 ( ( (uintptr_t)( id.scale ) & 0xF ) << offset );
82 }
83 };
84}
85
86
87static std::unordered_map<SCALED_BITMAP_ID, wxBitmap> s_ScaledBitmapCache;
88
89static std::mutex s_BitmapCacheMutex;
90
91
93{
94 if( !s_BitmapStore )
95 {
96 wxFileName path( PATHS::GetStockDataPath() + wxT( "/resources" ), wxT( "images.zip" ) );
97 s_BitmapStore = std::make_unique<BITMAP_STORE>();
98 }
99
100 return s_BitmapStore.get();
101}
102
103
104wxBitmap KiBitmap( BITMAPS aBitmap, int aHeightTag )
105{
106 return GetBitmapStore()->GetBitmap( aBitmap, aHeightTag );
107}
108
109
110wxBitmapBundle KiBitmapBundle( BITMAPS aBitmap )
111{
112 return GetBitmapStore()->GetBitmapBundle( aBitmap );
113}
114
115
116wxBitmapBundle KiDisabledBitmapBundle( BITMAPS aBitmap )
117{
118 return GetBitmapStore()->GetDisabledBitmapBundle( aBitmap );
119}
120
121
122int KiIconScale( wxWindow* aWindow )
123{
124 // For historical reasons, "4" here means unity (no scaling)
125
126 #if defined( __WXMSW__)
127 // Basically don't try and scale within kicad and let wx do its thing
128 // with wx introducing bitmap bundles, it will auto scale automatically with dpi
129 // the issue is, none of the scaling factors have any tie to system scaling
130 // this means wx is actually going to scale again causing even more distorted icons
131 return 4;
132 #else
133 const int vert_size = aWindow->ConvertDialogToPixels( wxSize( 0, 8 ) ).y;
134
135 // Autoscale won't exceed unity until the system has quite high resolution,
136 // because we don't want the icons to look obviously scaled on a system
137 // where it's easy to see it.
138
139 if( vert_size > 34 ) return 8;
140 else if( vert_size > 29 ) return 7;
141 else if( vert_size > 24 ) return 6;
142 else return 4;
143 #endif
144}
145
146
147wxBitmap KiScaledBitmap( BITMAPS aBitmap, wxWindow* aWindow, int aHeight, bool aQuantized )
148{
149 // Bitmap conversions are cached because they can be slow.
150 int scale = KiIconScale( aWindow );
151
152 if( aQuantized )
153 scale = KiROUND( (double) scale / 4.0 ) * 4;
154
155 SCALED_BITMAP_ID id = { static_cast<BITMAPS>( aBitmap ), scale };
156
157 std::lock_guard<std::mutex> guard( s_BitmapCacheMutex );
158 auto it = s_ScaledBitmapCache.find( id );
159
160 if( it != s_ScaledBitmapCache.end() )
161 {
162 return it->second;
163 }
164 else
165 {
166 wxBitmap bitmap = GetBitmapStore()->GetBitmapScaled( aBitmap, scale, aHeight );
167 return s_ScaledBitmapCache.emplace( id, bitmap ).first->second;
168 }
169}
170
171
173{
174 std::lock_guard<std::mutex> guard( s_BitmapCacheMutex );
175 s_ScaledBitmapCache.clear();
176}
177
178
179wxBitmap KiScaledBitmap( const wxBitmap& aBitmap, wxWindow* aWindow )
180{
181 const int scale = KiIconScale( aWindow );
182
183 if( scale == 4 )
184 {
185 return wxBitmap( aBitmap );
186 }
187 else
188 {
189 wxImage image = aBitmap.ConvertToImage();
190 image.Rescale( scale * image.GetWidth() / 4, scale * image.GetHeight() / 4,
191 wxIMAGE_QUALITY_BILINEAR );
192
193 return wxBitmap( image );
194 }
195}
196
197
198wxBitmap* KiBitmapNew( BITMAPS aBitmap )
199{
200 wxBitmap* bitmap = new wxBitmap( GetBitmapStore()->GetBitmap( aBitmap ) );
201
202 return bitmap;
203}
wxBitmap * KiBitmapNew(BITMAPS aBitmap)
Allocate a wxBitmap on heap from a memory record, held in a BITMAPS.
Definition: bitmap.cpp:198
static std::unique_ptr< BITMAP_STORE > s_BitmapStore
Definition: bitmap.cpp:49
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
void ClearScaledBitmapCache()
Wipes out the scaled bitmap cache so that the icon theme can be changed.
Definition: bitmap.cpp:172
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
static std::mutex s_BitmapCacheMutex
Definition: bitmap.cpp:89
int KiIconScale(wxWindow *aWindow)
Return the automatic scale factor that would be used for a given window by KiScaledBitmap and KiScale...
Definition: bitmap.cpp:122
BITMAP_STORE * GetBitmapStore()
Definition: bitmap.cpp:92
wxBitmapBundle KiDisabledBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:116
static std::unordered_map< SCALED_BITMAP_ID, wxBitmap > s_ScaledBitmapCache
Definition: bitmap.cpp:87
wxBitmap KiScaledBitmap(BITMAPS aBitmap, wxWindow *aWindow, int aHeight, bool aQuantized)
Construct a wxBitmap from a memory record, scaling it if device DPI demands it.
Definition: bitmap.cpp:147
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
Helper to retrieve bitmaps while handling icon themes and scaling.
Definition: bitmap_store.h:46
wxBitmap GetBitmap(BITMAPS aBitmapId, int aHeight=-1)
Retrieves a bitmap from the given bitmap id.
wxBitmap GetBitmapScaled(BITMAPS aBitmapId, int aScaleFactor, int aHeight=-1)
Retrieves a bitmap from the given bitmap id, scaled to a given factor.
wxBitmapBundle GetDisabledBitmapBundle(BITMAPS aBitmapId)
Constructs and returns a bitmap bundle for the given icon ID, with the bitmaps converted to disabled ...
wxBitmapBundle GetBitmapBundle(BITMAPS aBitmapId)
Constructs and returns a bitmap bundle containing all available sizes of the given ID.
static wxString GetStockDataPath(bool aRespectRunFromBuildDir=true)
Gets the stock (install) data path, which is the base path for things like scripting,...
Definition: paths.cpp:151
STL namespace.
see class PGM_BASE
const int scale
bool operator==(SCALED_BITMAP_ID const &other) const noexcept
Definition: bitmap.cpp:56
BITMAPS bitmap
Definition: bitmap.cpp:53
SCALED_BITMAP_ID argument_type
Definition: bitmap.cpp:66
result_type operator()(argument_type const &id) const noexcept
Definition: bitmap.cpp:69
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85