#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