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 The 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, int aMinHeight )
111{
112 return GetBitmapStore()->GetBitmapBundle( aBitmap, aMinHeight );
113}
114
115
116wxBitmapBundle KiBitmapBundleDef( BITMAPS aBitmap, int aDefHeight )
117{
118 return GetBitmapStore()->GetBitmapBundleDef( aBitmap, aDefHeight );
119}
120
121
122wxBitmapBundle KiDisabledBitmapBundle( BITMAPS aBitmap, int aMinHeight )
123{
124 return GetBitmapStore()->GetDisabledBitmapBundle( aBitmap, aMinHeight );
125}
126
127
128KICOMMON_API wxBitmapBundle KiDisabledBitmapBundleDef( BITMAPS aBitmap, int aDefHeight )
129{
130 return GetBitmapStore()->GetDisabledBitmapBundleDef( aBitmap, aDefHeight );
131}
132
133
134int KiIconScale( wxWindow* aWindow )
135{
136 // For historical reasons, "4" here means unity (no scaling)
137
138#if defined( __WXMSW__)
139 // Basically don't try and scale within KiCad and let wx do its thing
140 // with wx introducing bitmap bundles, it will auto scale automatically with dpi
141 // the issue is, none of the scaling factors have any tie to system scaling
142 // this means wx is actually going to scale again causing even more distorted icons
143 return 4;
144#else
145 const int vert_size = aWindow->ConvertDialogToPixels( wxSize( 0, 8 ) ).y;
146
147 // Autoscale won't exceed unity until the system has quite high resolution,
148 // because we don't want the icons to look obviously scaled on a system
149 // where it's easy to see it.
150
151 if( vert_size > 34 ) return 8;
152 else if( vert_size > 29 ) return 7;
153 else if( vert_size > 24 ) return 6;
154 else return 4;
155#endif
156}
157
158
159wxBitmap KiScaledBitmap( BITMAPS aBitmap, wxWindow* aWindow, int aHeight, bool aQuantized )
160{
161 // Bitmap conversions are cached because they can be slow.
162 int scale = KiIconScale( aWindow );
163
164 if( aQuantized )
165 scale = KiROUND( (double) scale / 4.0 ) * 4;
166
167 SCALED_BITMAP_ID id = { static_cast<BITMAPS>( aBitmap ), scale };
168
169 std::lock_guard<std::mutex> guard( s_BitmapCacheMutex );
170 auto it = s_ScaledBitmapCache.find( id );
171
172 if( it != s_ScaledBitmapCache.end() )
173 {
174 return it->second;
175 }
176 else
177 {
178 wxBitmap bitmap = GetBitmapStore()->GetBitmapScaled( aBitmap, scale, aHeight );
179 return s_ScaledBitmapCache.emplace( id, bitmap ).first->second;
180 }
181}
182
183
185{
186 std::lock_guard<std::mutex> guard( s_BitmapCacheMutex );
187 s_ScaledBitmapCache.clear();
188}
189
190
191wxBitmap KiScaledBitmap( const wxBitmap& aBitmap, wxWindow* aWindow )
192{
193 const int scale = KiIconScale( aWindow );
194
195 if( scale == 4 )
196 {
197 return wxBitmap( aBitmap );
198 }
199 else
200 {
201 wxImage image = aBitmap.ConvertToImage();
202 image.Rescale( scale * image.GetWidth() / 4, scale * image.GetHeight() / 4,
203 wxIMAGE_QUALITY_BILINEAR );
204
205 return wxBitmap( image );
206 }
207}
208
209
210wxBitmap* KiBitmapNew( BITMAPS aBitmap )
211{
212 wxBitmap* bitmap = new wxBitmap( GetBitmapStore()->GetBitmap( aBitmap ) );
213
214 return bitmap;
215}
wxBitmap * KiBitmapNew(BITMAPS aBitmap)
Allocate a wxBitmap on heap from a memory record, held in a BITMAPS.
Definition bitmap.cpp:210
wxBitmapBundle KiBitmapBundleDef(BITMAPS aBitmap, int aDefHeight)
Constructs and returns a bitmap bundle for the given icon ID, with the default bitmap size being aDef...
Definition bitmap.cpp:116
static std::unique_ptr< BITMAP_STORE > s_BitmapStore
Definition bitmap.cpp:49
void ClearScaledBitmapCache()
Wipes out the scaled bitmap cache so that the icon theme can be changed.
Definition bitmap.cpp:184
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:134
BITMAP_STORE * GetBitmapStore()
Definition bitmap.cpp:92
static std::unordered_map< SCALED_BITMAP_ID, wxBitmap > s_ScaledBitmapCache
Definition bitmap.cpp:87
KICOMMON_API wxBitmapBundle KiDisabledBitmapBundleDef(BITMAPS aBitmap, int aDefHeight)
Definition bitmap.cpp:128
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:159
wxBitmapBundle KiDisabledBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:122
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
BITMAPS
A list of all bitmap identifiers.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:990
Helper to retrieve bitmaps while handling icon themes and scaling.
wxBitmapBundle GetBitmapBundleDef(BITMAPS aBitmapId, int aDefHeight)
Constructs and returns a bitmap bundle for the given icon ID, with the default bitmap size being aDef...
wxBitmapBundle GetBitmapBundle(BITMAPS aBitmapId, int aMinHeight=-1)
Constructs and returns a bitmap bundle containing all available sizes of the given ID.
wxBitmapBundle GetDisabledBitmapBundleDef(BITMAPS aBitmapId, int aDefHeight)
Constructs and returns a bitmap bundle for the given icon ID, with the bitmaps converted to disabled ...
wxBitmapBundle GetDisabledBitmapBundle(BITMAPS aBitmapId, int aMinHeight=-1)
Constructs and returns a bitmap bundle for the given icon ID, with the bitmaps converted to disabled ...
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.
static wxString GetStockDataPath(bool aRespectRunFromBuildDir=true)
Gets the stock (install) data path, which is the base path for things like scripting,...
Definition paths.cpp:192
#define KICOMMON_API
Definition kicommon.h:28
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
std::string path