File indexing completed on 2024-12-22 04:09:06

0001 /*
0002  *  SPDX-FileCopyrightText: 2022 Dmitry Kazakov <dimula73@gmail.com>
0003  *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy@amyspark.me>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 #ifndef KOFONTLIBRARYRESOURCEUTILS_H
0008 #define KOFONTLIBRARYRESOURCEUTILS_H
0009 
0010 #include <ft2build.h>
0011 #include FT_FREETYPE_H
0012 #include FT_MULTIPLE_MASTERS_H
0013 #include <fontconfig/fontconfig.h>
0014 
0015 #include <hb-ft.h>
0016 #include <hb-ot.h>
0017 #include <hb.h>
0018 
0019 #include <QSharedPointer>
0020 
0021 // Helper to clean up only if the pointer is non-null.
0022 template<typename T, void (*d)(T *)>
0023 inline void deleter(T *ptr)
0024 {
0025     if (ptr) {
0026         d(ptr);
0027     }
0028 }
0029 
0030 /**
0031  * Shared pointer that holds a standard allocated resource.
0032  * We use a wrapper because by C++ standards it calls the deleter
0033  * unconditionally. This leads to crashes on FontConfig:
0034  * https://invent.kde.org/graphics/krita/-/merge_requests/1607#note_567848
0035  */
0036 template<typename T, void (*P)(T *)>
0037 struct KisLibraryResourcePointer : private QSharedPointer<T> {
0038 public:
0039     KisLibraryResourcePointer()
0040         : QSharedPointer<T>(nullptr, deleter<T, P>)
0041     {
0042     }
0043 
0044     KisLibraryResourcePointer(T *ptr)
0045         : QSharedPointer<T>(ptr, deleter<T, P>)
0046     {
0047     }
0048 
0049     using QSharedPointer<T>::operator->;
0050     using QSharedPointer<T>::reset;
0051 
0052     auto data() const
0053     {
0054         return this->get();
0055     }
0056 };
0057 
0058 /**
0059  * Shared pointer that holds a standard allocated resource.
0060  * The only difference is in the signature of the deleter.
0061  */
0062 template<typename T, int (*P)(T *)>
0063 struct KisFreeTypeResourcePointer : private QSharedPointer<T> {
0064 public:
0065     KisFreeTypeResourcePointer()
0066         : QSharedPointer<T>(nullptr, P)
0067     {
0068     }
0069 
0070     KisFreeTypeResourcePointer(T *ptr)
0071         : QSharedPointer<T>(ptr, P)
0072     {
0073     }
0074 
0075     using QSharedPointer<T>::operator->;
0076     using QSharedPointer<T>::reset;
0077 
0078     auto data() const
0079     {
0080         return this->get();
0081     }
0082 };
0083 
0084 using FcConfigUP = KisLibraryResourcePointer<FcConfig, FcConfigDestroy>;
0085 using FcCharSetUP = KisLibraryResourcePointer<FcCharSet, FcCharSetDestroy>;
0086 using FcPatternUP = KisLibraryResourcePointer<FcPattern, FcPatternDestroy>;
0087 using FcFontSetUP = KisLibraryResourcePointer<FcFontSet, FcFontSetDestroy>;
0088 using FT_LibraryUP = KisFreeTypeResourcePointer<std::remove_pointer_t<FT_Library>, FT_Done_FreeType>;
0089 using FT_FaceUP = KisFreeTypeResourcePointer<std::remove_pointer_t<FT_Face>, FT_Done_Face>;
0090 
0091 using hb_font_t_up = KisLibraryResourcePointer<hb_font_t, hb_font_destroy>;
0092 
0093 #endif // KOFONTLIBRARYRESOURCEUTILS_H