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, see <https://www.gnu.org/licenses/>.
19 */
20
21
22#include <wx/image.h>
23#include <wx/bitmap.h>
24#include <wx/gdicmn.h>
25#include <wx/mstream.h>
26#include <wx/menu.h>
27#include <wx/menuitem.h>
28#include <wx/aui/auibar.h>
29#include <wx/dcclient.h>
30#include <wx/dcmemory.h>
31
32#include <cstdint>
33#include <mutex>
34#include <unordered_map>
35
36#include <asset_archive.h>
37#include <bitmaps.h>
38#include <bitmap_store.h>
39#include <pgm_base.h>
40#include <paths.h>
41#include <kiplatform/ui.h>
42#include <math/util.h>
44
45static std::unique_ptr<BITMAP_STORE> s_BitmapStore;
46
47
50 int scale;
51
52 bool operator==( SCALED_BITMAP_ID const& other ) const noexcept
53 {
54 return bitmap == other.bitmap && scale == other.scale;
55 }
56};
57
58
59namespace std {
60 template<> struct hash<SCALED_BITMAP_ID>
61 {
63 typedef std::size_t result_type;
64
65 result_type operator()( argument_type const& id ) const noexcept
66 {
67 static const bool sz64 = sizeof( uintptr_t ) == 8;
68 static const size_t mask = sz64 ? 0xF000000000000000uLL : 0xF0000000uL;
69 static const size_t offset = sz64 ? 60 : 28;
70
71 // The hash only needs to be fast and simple, not necessarily accurate - a collision
72 // only makes things slower, not broken. BITMAPS is a pointer, so the most
73 // significant several bits are generally going to be the same for all. Just convert
74 // it to an integer and stuff the scale factor into those bits.
75 return
76 ( (uintptr_t)( id.bitmap ) & ~mask ) |
77 ( ( (uintptr_t)( id.scale ) & 0xF ) << offset );
78 }
79 };
80}
81
82
83static std::unordered_map<SCALED_BITMAP_ID, wxBitmap> s_ScaledBitmapCache;
84
85static std::mutex s_BitmapCacheMutex;
86
87
89{
90 if( !s_BitmapStore )
91 {
92 wxFileName path( PATHS::GetStockDataPath() + wxT( "/resources" ), wxT( "images.zip" ) );
93 s_BitmapStore = std::make_unique<BITMAP_STORE>();
94 }
95
96 return s_BitmapStore.get();
97}
98
99
100wxBitmap KiBitmap( BITMAPS aBitmap, int aHeightTag )
101{
102 return GetBitmapStore()->GetBitmap( aBitmap, aHeightTag );
103}
104
105
106wxBitmapBundle KiBitmapBundle( BITMAPS aBitmap, int aMinHeight )
107{
108 return GetBitmapStore()->GetBitmapBundle( aBitmap, aMinHeight );
109}
110
111
112wxBitmapBundle KiBitmapBundleDef( BITMAPS aBitmap, int aDefHeight )
113{
114 return GetBitmapStore()->GetBitmapBundleDef( aBitmap, aDefHeight );
115}
116
117
118wxBitmapBundle KiDisabledBitmapBundle( BITMAPS aBitmap, int aMinHeight )
119{
120 return GetBitmapStore()->GetDisabledBitmapBundle( aBitmap, aMinHeight );
121}
122
123
124KICOMMON_API wxBitmapBundle KiDisabledBitmapBundleDef( BITMAPS aBitmap, int aDefHeight )
125{
126 return GetBitmapStore()->GetDisabledBitmapBundleDef( aBitmap, aDefHeight );
127}
128
129
130int KiIconScale( wxWindow* aWindow )
131{
132 // For historical reasons, "4" here means unity (no scaling)
133
134#if defined( __WXMSW__)
135 // Basically don't try and scale within KiCad and let wx do its thing
136 // with wx introducing bitmap bundles, it will auto scale automatically with dpi
137 // the issue is, none of the scaling factors have any tie to system scaling
138 // this means wx is actually going to scale again causing even more distorted icons
139 return 4;
140#else
141 const int vert_size = aWindow->ConvertDialogToPixels( wxSize( 0, 8 ) ).y;
142
143 // Autoscale won't exceed unity until the system has quite high resolution,
144 // because we don't want the icons to look obviously scaled on a system
145 // where it's easy to see it.
146
147 if( vert_size > 34 ) return 8;
148 else if( vert_size > 29 ) return 7;
149 else if( vert_size > 24 ) return 6;
150 else return 4;
151#endif
152}
153
154
155wxBitmap KiScaledBitmap( BITMAPS aBitmap, wxWindow* aWindow, int aHeight, bool aQuantized )
156{
157 // Bitmap conversions are cached because they can be slow.
158 int scale = KiIconScale( aWindow );
159
160 if( aQuantized )
161 scale = KiROUND( (double) scale / 4.0 ) * 4;
162
163 SCALED_BITMAP_ID id = { static_cast<BITMAPS>( aBitmap ), scale };
164
165 std::lock_guard<std::mutex> guard( s_BitmapCacheMutex );
166 auto it = s_ScaledBitmapCache.find( id );
167
168 if( it != s_ScaledBitmapCache.end() )
169 {
170 return it->second;
171 }
172 else
173 {
174 wxBitmap bitmap = GetBitmapStore()->GetBitmapScaled( aBitmap, scale, aHeight );
175 return s_ScaledBitmapCache.emplace( id, bitmap ).first->second;
176 }
177}
178
179
181{
182 std::lock_guard<std::mutex> guard( s_BitmapCacheMutex );
183 s_ScaledBitmapCache.clear();
184}
185
186
187wxBitmap KiScaledBitmap( const wxBitmap& aBitmap, wxWindow* aWindow )
188{
189 const int scale = KiIconScale( aWindow );
190
191 if( scale == 4 )
192 {
193 return wxBitmap( aBitmap );
194 }
195 else
196 {
197 wxImage image = aBitmap.ConvertToImage();
198 image.Rescale( scale * image.GetWidth() / 4, scale * image.GetHeight() / 4,
199 wxIMAGE_QUALITY_BILINEAR );
200
201 return wxBitmap( image );
202 }
203}
204
205
206wxBitmap* KiBitmapNew( BITMAPS aBitmap )
207{
208 wxBitmap* bitmap = new wxBitmap( GetBitmapStore()->GetBitmap( aBitmap ) );
209
210 return bitmap;
211}
wxBitmap * KiBitmapNew(BITMAPS aBitmap)
Allocate a wxBitmap on heap from a memory record, held in a BITMAPS.
Definition bitmap.cpp:206
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:112
static std::unique_ptr< BITMAP_STORE > s_BitmapStore
Definition bitmap.cpp:45
void ClearScaledBitmapCache()
Wipes out the scaled bitmap cache so that the icon theme can be changed.
Definition bitmap.cpp:180
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:100
static std::mutex s_BitmapCacheMutex
Definition bitmap.cpp:85
int KiIconScale(wxWindow *aWindow)
Return the automatic scale factor that would be used for a given window by KiScaledBitmap and KiScale...
Definition bitmap.cpp:130
BITMAP_STORE * GetBitmapStore()
Definition bitmap.cpp:88
static std::unordered_map< SCALED_BITMAP_ID, wxBitmap > s_ScaledBitmapCache
Definition bitmap.cpp:83
KICOMMON_API wxBitmapBundle KiDisabledBitmapBundleDef(BITMAPS aBitmap, int aDefHeight)
Definition bitmap.cpp:124
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:155
wxBitmapBundle KiDisabledBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:118
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
BITMAPS
A list of all bitmap identifiers.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
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:233
#define KICOMMON_API
Definition kicommon.h:27
STL namespace.
see class PGM_BASE
const int scale
bool operator==(SCALED_BITMAP_ID const &other) const noexcept
Definition bitmap.cpp:52
BITMAPS bitmap
Definition bitmap.cpp:49
SCALED_BITMAP_ID argument_type
Definition bitmap.cpp:62
result_type operator()(argument_type const &id) const noexcept
Definition bitmap.cpp:65
std::string path