Rework bitmap system to load from archived PNGs

Bitmaps are now identified by an enum class instead of by pointers.
Bitmap loading and caching is now handled by a class in common, and
we no longer compile most bitmaps into the binary, so there is no
longer a bitmaps static library.

Instead, bitmaps are archived to a .tar.gz file which is installed
in ${KICAD_DATA}/resources/images.tar.gz

The source PNGs are checked in to Git as the original CPP files were,
so that people can build without the required dependencies to convert
SVGs to PNGs.

Initial support is also added for dark theme icons, although this
is not yet exposed in the GUI.

Stubs are present for multi-resolution image resources, but this is
not fully-baked yet and could use some refinement.
This commit is contained in:
Jon Evans
2021-03-11 08:37:35 -05:00
parent 4db10d419d
commit 18037e2f65
1642 changed files with 3723 additions and 25013 deletions
+36 -21
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2011 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
* Copyright (C) 2017-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -29,7 +29,6 @@
#include <wx/menu.h>
#include <wx/menuitem.h>
#include <wx/aui/auibar.h>
#include <wx/dc.h>
#include <wx/dcclient.h>
#include <wx/dcmemory.h>
@@ -37,15 +36,22 @@
#include <mutex>
#include <unordered_map>
#include <asset_archive.h>
#include <bitmaps.h>
#include <bitmap_store.h>
#include <bitmaps/bitmap_opaque.h> // for pcb_calculator compatibility shim
#include <pgm_base.h>
#include <eda_base_frame.h>
#include <eda_draw_frame.h>
#include <paths.h>
#include <settings/common_settings.h>
static std::unique_ptr<BITMAP_STORE> s_BitmapStore;
struct SCALED_BITMAP_ID {
BITMAP_DEF bitmap;
BITMAPS bitmap;
int scale;
bool operator==( SCALED_BITMAP_ID const& other ) const noexcept
@@ -68,7 +74,7 @@ namespace std {
static const size_t offset = sz64 ? 60 : 28;
// The hash only needs to be fast and simple, not necessarily accurate - a collision
// only makes things slower, not broken. BITMAP_DEF is a pointer, so the most
// only makes things slower, not broken. BITMAPS is a pointer, so the most
// significant several bits are generally going to be the same for all. Just convert
// it to an integer and stuff the scale factor into those bits.
return
@@ -79,7 +85,26 @@ namespace std {
}
wxBitmap KiBitmap( BITMAP_DEF aBitmap )
BITMAP_STORE* GetStore()
{
if( !s_BitmapStore )
{
wxFileName path( PATHS::GetStockDataPath() + wxT( "/resources" ), wxT( "images.zip" ) );
s_BitmapStore = std::make_unique<BITMAP_STORE>();
}
return s_BitmapStore.get();
}
wxBitmap KiBitmap( BITMAPS aBitmap )
{
return GetStore()->GetBitmap( aBitmap );
}
// TODO: Remove this once pcb_calculator images are moved into the main bitmap system
wxBitmap KiBitmap( const BITMAP_OPAQUE* aBitmap )
{
wxMemoryInputStream is( aBitmap->png, aBitmap->byteCount );
wxImage image( is, wxBITMAP_TYPE_PNG );
@@ -115,14 +140,14 @@ static int get_scale_factor( wxWindow* aWindow )
}
wxBitmap KiScaledBitmap( BITMAP_DEF aBitmap, wxWindow* aWindow )
wxBitmap KiScaledBitmap( BITMAPS aBitmap, wxWindow* aWindow, int aHeight )
{
// Bitmap conversions are cached because they can be slow.
static std::unordered_map<SCALED_BITMAP_ID, wxBitmap> bitmap_cache;
static std::mutex bitmap_cache_mutex;
const int scale = get_scale_factor( aWindow );
SCALED_BITMAP_ID id = { aBitmap, scale };
SCALED_BITMAP_ID id = { static_cast<BITMAPS>( aBitmap ), scale };
std::lock_guard<std::mutex> guard( bitmap_cache_mutex );
auto it = bitmap_cache.find( id );
@@ -133,16 +158,8 @@ wxBitmap KiScaledBitmap( BITMAP_DEF aBitmap, wxWindow* aWindow )
}
else
{
wxMemoryInputStream is( aBitmap->png, aBitmap->byteCount );
wxImage image( is, wxBITMAP_TYPE_PNG );
// Bilinear seems to genuinely look better for these line-drawing icons
// than bicubic, despite claims in the wx documentation that bicubic is
// "highest quality". I don't recommend changing this. Bicubic looks
// blurry and makes me want an eye exam.
image.Rescale( scale * image.GetWidth() / 4, scale * image.GetHeight() / 4,
wxIMAGE_QUALITY_BILINEAR );
return bitmap_cache.emplace( id, wxBitmap( image ) ).first->second;
wxBitmap bitmap = GetStore()->GetBitmapScaled( aBitmap, scale, aHeight );
return bitmap_cache.emplace( id, bitmap ).first->second;
}
}
@@ -166,11 +183,9 @@ wxBitmap KiScaledBitmap( const wxBitmap& aBitmap, wxWindow* aWindow )
}
wxBitmap* KiBitmapNew( BITMAP_DEF aBitmap )
wxBitmap* KiBitmapNew( BITMAPS aBitmap )
{
wxMemoryInputStream is( aBitmap->png, aBitmap->byteCount );
wxImage image( is, wxBITMAP_TYPE_PNG );
wxBitmap* bitmap = new wxBitmap( image );
wxBitmap* bitmap = new wxBitmap( GetStore()->GetBitmap( aBitmap ) );
return bitmap;
}