1 /*****************************************************************************
2 * Copyright 2003 - 2010 Craig Drummond <craig.p.drummond@gmail.com> *
3 * Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU Lesser General Public License as *
7 * published by the Free Software Foundation; either version 2.1 of the *
8 * License, or (at your option) version 3, or any later version accepted *
9 * by the membership of KDE e.V. (or its successor approved by the *
10 * membership of KDE e.V.), which shall act as a proxy defined in *
11 * Section 6 of version 3 of the license. *
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 GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library. If not, *
20 * see <http://www.gnu.org/licenses/>. *
21 *****************************************************************************/
22
23 #include "pixcache.h"
24 #include "check_on-png.h"
25 #include "check_x_on-png.h"
26 #include "blank16x16-png.h"
27 #include "qt_settings.h"
28
29 #include <qtcurve-utils/gtkutils.h>
30
31 #include <unordered_map>
32
33 namespace QtCurve {
34
35 struct PixKey {
36 GdkColor col;
37 double shade;
38 };
39
40 struct PixHash {
41 size_t
operator ()QtCurve::PixHash42 operator()(const PixKey &key) const
43 {
44 const GdkColor &col = key.col;
45 return (std::hash<int>()(col.red) ^
46 (std::hash<int>()(col.green) << 1) ^
47 (std::hash<int>()(col.blue) << 2) ^
48 (std::hash<double>()(key.shade) << 3));
49 }
50 };
51
52 struct PixEqual {
53 bool
operator ()QtCurve::PixEqual54 operator()(const PixKey &lhs, const PixKey &rhs) const
55 {
56 return memcmp(&lhs, &rhs, sizeof(PixKey)) == 0;
57 }
58 };
59
60 static std::unordered_map<PixKey, GObjPtr<GdkPixbuf>,
61 PixHash, PixEqual> pixbufMap;
62 #pragma GCC diagnostic push
63 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
64 // Replacement isn't available until the version it is deprecated
65 // (gdk-pixbuf-2.0 2.32)
66 static GObjPtr<GdkPixbuf> blankPixbuf =
67 gdk_pixbuf_new_from_inline(-1, blank16x16, true, nullptr);
68 #pragma GCC diagnostic pop
69
70 static GdkPixbuf*
pixbufCacheValueNew(const PixKey & key)71 pixbufCacheValueNew(const PixKey &key)
72 {
73 #pragma GCC diagnostic push
74 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
75 // Replacement isn't available until the version it is deprecated
76 // (gdk-pixbuf-2.0 2.32)
77 GdkPixbuf *res = gdk_pixbuf_new_from_inline(-1, opts.xCheck ? check_x_on :
78 check_on, true, nullptr);
79 #pragma GCC diagnostic pop
80 qtcAdjustPix(gdk_pixbuf_get_pixels(res), gdk_pixbuf_get_n_channels(res),
81 gdk_pixbuf_get_width(res), gdk_pixbuf_get_height(res),
82 gdk_pixbuf_get_rowstride(res),
83 key.col.red >> 8, key.col.green >> 8,
84 key.col.blue >> 8, key.shade, QTC_PIXEL_GDK);
85 return res;
86 }
87
88 GdkPixbuf*
getPixbuf(GdkColor * widgetColor,EPixmap p,double shade)89 getPixbuf(GdkColor *widgetColor, EPixmap p, double shade)
90 {
91 if (p != PIX_CHECK) {
92 return blankPixbuf.get();
93 }
94 const PixKey key = {*widgetColor, shade};
95 auto &pixbuf = pixbufMap[key];
96 if (pixbuf.get() == nullptr) {
97 pixbuf = pixbufCacheValueNew(key);
98 }
99 return pixbuf.get();
100 }
101
102 }
103