#ifndef CImage_HPP_INCLUDED #define CImage_HPP_INCLUDED /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (c) 2018-2021 3Dconnexion. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ /** * @file CImage.hpp * @brief SiImage_t wrapper. */ // stdlib #include #include #include // 3dxware #include #if defined(_MSC_VER) && _MSC_VER<1800 // #pragma warning(1 : 4519) // convert error C4519 'default template arguments are only allowed on a class template' to warning #pragma warning(disable : 4519) // disable error C4519 #if _MSC_VER < 1700 #pragma warning(disable : 4482) // warning C4482: nonstandard extension used #endif #endif /// /// Determines whether a value is an integer identifier for a resource. /// /// /// The pointer to be tested whether it contains an integer resource identifier. /// /// /// true when id is an integer identifier for a resource, otherwise false when /// it is typically a pointer to a string __inline bool IsIntResource(const char *id) { #ifdef _WIN32 return ((reinterpret_cast(id)) >> 16) == 0; #else return false; #endif } namespace TDx { /// /// A class that represents the SiImage_t structure. /// class CImage { public: /// /// Initializes a new instance of the class. /// CImage() : m_type(SiImageType_t::e_none), m_index(0) { } /// /// Initializes a new instance of the class from a . /// /// explicit CImage(const SiImage_t &siImage) : m_id(siImage.id), m_type(siImage.type) { if (siImage.size != sizeof(SiImage_t)) { throw std::invalid_argument("Invalid SiImage_t structure."); } switch (m_type) { case SiImageType_t::e_image_file: m_source = siImage.file.file_name; m_index = siImage.file.index; break; case SiImageType_t::e_resource_file: m_source = siImage.resource.file_name; m_resourceId = siImage.resource.id; m_resourceType = siImage.resource.type; m_index = siImage.resource.index; break; case SiImageType_t::e_image: m_source.assign(reinterpret_cast(siImage.image.data), siImage.image.size); m_index = siImage.image.index; break; case SiImageType_t::e_none: default: break; } } #if USE_DECLSPEC_PROPERTY /// /// Gets or sets the image id. /// __declspec(property(get = GetId, put = PutId)) std::string Id; /// /// Gets or sets the resource id. /// __declspec(property(get = GetResourceId, put = PutResourceId)) std::string ResourceId; /// /// Gets the image type. /// __declspec(property(get = GetType)) SiImageType_t Type; #endif /// /// Sets the id of the image. /// /// A representing the name or id of the image. void PutId(std::string id) { m_id = std::move(id); } /// /// Gets the image id. /// /// A representing the name or id of the image. std::string GetId() const { return m_id; } /// /// Sets the id of the resource in the resource file. /// /// A representing the name or id of the image in the /// resource file. /// For example for Microsoft resource libraries MAKEINTRESOURCE(216) = "#216". void PutResourceId(std::string id) { m_resourceId = std::move(id); } /// /// Gets the resource id. /// /// A representing the name or id of the image. /// For example for Microsoft resource libraries MAKEINTRESOURCE(216) = "#216". std::string GetResourceId() const { return m_resourceId; } /// /// Gets the image type. /// /// One of . SiImageType_t GetType() const { return m_type; } /// /// Assigns image data to the instance. /// /// The image data. The image may be in any format that can be loaded by /// Gdiplus::Bitmap::FromStream() or is in a recognizable svg format. /// true if successful, otherwise false. /// The type is set to . bool AssignImage(std::string buffer, uint32_t index = 0) { m_source = std::move(buffer); m_type = e_image; m_index = index; m_resourceId.clear(); m_resourceType.clear(); return true; } /// /// Initializes a new instance of the class that contains the data for an /// image held in a resource file. /// /// The name of the resource file. /// The name or id of the image in the resource file. i.e. /// MAKEINTRESOURCE(216) = "#216". /// The type of the resource in the resource file. i.e. RT_BITMAP = /// "#2". /// The index in a multi-image resource. /// The id of the command to associate with this image. /// A instance. template static T FromResource(const std::string &resourceFile, const char *resourceId, const char *resourceType, uint32_t index = 0, const char *id = nullptr) { std::string r_id; if (resourceId != nullptr) { if (IsIntResource(resourceId)) { std::ostringstream stream; stream << "#" << reinterpret_cast(resourceId); r_id = stream.str(); } else { r_id = resourceId; } } std::string r_type; if (resourceType != nullptr) { if (IsIntResource(resourceType)) { std::ostringstream stream; stream << "#" << reinterpret_cast(resourceType); r_type = stream.str(); } else { r_type = resourceType; } } T image(resourceFile, r_id, r_type, id != nullptr ? id : "", e_resource_file, index); return image; } /// /// Initializes a new instance of the class that contains the data for an /// image in a file. /// /// The name of the image file. /// The index in a multi-image file. /// The id of the command to associate with this image. /// A instance. template static T FromFile(const std::string &filename, uint32_t index = 0, const char *id = nullptr) { T image(filename, id != nullptr ? id : "", e_image_file, index); return image; } /// /// Initializes a new instance of the CImage class that contains the data for an image in a file. /// /// The image data. The image may be in any format that can be loaded by /// Gdiplus::Bitmap::FromStream() or is in a recognizable svg format. /// The index in a multi-image file. /// The id of the command to associate with this image. /// A instance. template static T FromData(const std::string &buffer, uint32_t index = 0, const char *id = nullptr) { T image(buffer, id != nullptr ? id : "", e_image, index); return image; } /// /// Returns an view of the instance. /// /// A . operator SiImage_t() const { SiImage_t siImage = {sizeof(SiImage_t), m_type, m_id.c_str(), {nullptr, nullptr, nullptr, 0}}; switch (m_type) { case SiImageType_t::e_image_file: siImage.file.file_name = m_source.c_str(); siImage.file.index = m_index; break; case SiImageType_t::e_resource_file: siImage.resource.file_name = m_source.c_str(); siImage.resource.id = m_resourceId.c_str(); siImage.resource.type = m_resourceType.c_str(); siImage.resource.index = m_index; break; case SiImageType_t::e_image: siImage.image.data = reinterpret_cast(m_source.data()); siImage.image.size = m_source.size(); siImage.image.index = m_index; break; case SiImageType_t::e_none: break; default: siImage.type = SiImageType_t::e_none; break; } return siImage; } /// /// checks whether the image is empty. /// /// true if the image contains data, otherwise false. bool empty() const { return m_type == SiImageType_t::e_none || (m_type == SiImageType_t::e_image && m_source.empty()); } protected: CImage(std::string source, std::string id, SiImageType_t type, uint32_t index = 0) : m_source(std::move(source)), m_id(std::move(id)), m_type(type), m_index(index) { } CImage(std::string source, std::string resourceName, std::string resourceType, std::string id, SiImageType_t type, uint32_t index = 0) : m_source(std::move(source)), m_resourceId(std::move(resourceName)), m_resourceType(std::move(resourceType)), m_id(std::move(id)), m_type(type), m_index(index) { } protected: std::string m_source; std::string m_resourceId; std::string m_resourceType; std::string m_id; SiImageType_t m_type; uint32_t m_index; }; } // namespace TDx #endif // CImage_HPP_INCLUDED