src/colors.h

Fri, 01 Jul 2022 16:46:43 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Fri, 01 Jul 2022 16:46:43 +0300
changeset 312
2637134bc37c
parent 308
daa8770b9d26
permissions
-rw-r--r--

Fix right click to delete not really working properly
Instead of removing the point that had been added, it would remove
the point that is being drawn, which would cause it to overwrite the
previous point using the new point, causing a bit of a delay

/*
 *  LDForge: LDraw parts authoring CAD
 *  Copyright (C) 2013 - 2020 Teemu Piippo
 *
 *  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 <http://www.gnu.org/licenses/>.
 */

#pragma once
#include <QColor>
#include "src/basics.h"

/**
 * @brief Represents an LDraw color index (e.g 16, 24, ...)
 * 
 * @details
 * This is essentially just an integer. It is its own structure for the sake
 * of type correctness. Commonly used color values are 16 for the main color
 * and 24 for the edge color.
 * 
 * Use @c ldraw::ColorTable to obtain rgb values for color indices.
 * 
 * Direct colors are colors whose index is at least 0x2000000. These colors
 * encode the rgb values directly in the index. The color table code also
 * handles these cases.
 * 
 * Note that it only makes sense to construct a color index from an integer
 * value if the integer comes from an external source (e.g. user or
 * LDConfig.ldr). Since this structure only contains an integer, it should be
 * passed by value to functions instead of l-value reference.
 */
struct ColorIndex
{
	qint32 index = 0;
	constexpr auto operator<=>(const ColorIndex&) const = default;
};

Q_DECLARE_METATYPE(ColorIndex)

//! \brief LDraw main color (16)
constexpr ColorIndex MAIN_COLOR{16};
//! \brief LDraw edge color (24)
constexpr ColorIndex EDGE_COLOR{24};

/**
 * @brief Contains the information about a specific color
 */
struct ColorDefinition
{
	//! @brief The face color. This is the color used for most objects.
	QColor faceColor;
	//! @brief The edge color, used for the edge lines of a subfile reference.
	//! Note that edges using a color actually use the face color. LDraw standards
	//! require edges to use color 24, however.
	QColor edgeColor;
	//! @brief Name of the color
	QString name;
	//! @brief A version of the name that can be shown to the user.
	QString displayName;
};

//extern const ColorDefinition unknownColor;
using ColorTable = std::map<ColorIndex, ColorDefinition>;
std::optional<ColorTable> loadColorTable(QIODevice& device, QTextStream& errors);
qreal luma(const QColor& color);
ColorIndex directColor(const QColor& color);
std::optional<QColor> colorFace(ColorIndex color, const ColorTable& colorTable);
std::optional<QColor> colorEdge(ColorIndex color, const ColorTable& colorTable);
std::optional<QString> colorDisplayName(ColorIndex color, const ColorTable& colorTable);
QDataStream& operator<<(QDataStream&, ColorIndex);
QDataStream& operator>>(QDataStream&, ColorIndex&);

//! @brief Calculates the luma-value for the given color.
//! @details c.f. https://en.wikipedia.org/wiki/Luma_(video)
template<typename T>
constexpr T luma(T r, T g, T b)
{
	return static_cast<T>(0.2126 * r + 0.7152 * g + 0.0722 * b);
}

//! @brief Checks whether or not the specified color index is a direct color
constexpr bool isDirectColor(ColorIndex color)
{
	return color.index >= 0x2000000;
}

//! @brief Returns a direct color index that codes the specified color value
constexpr ColorIndex directColor(int r, int g, int b)
{
	return ColorIndex{0x2000000 | (r << 16) | (g << 8) | b};
}

//! @brief Extracts the r, g and b color channel values from a direct color
//! index. Returns a default-constructed QColor in case a non-direct color is
//! given.
constexpr std::array<int, 3> directColorRgb(ColorIndex color)
{
	return {
		(color.index >> 16) & 0xff,
		(color.index >> 8) & 0xff,
		color.index & 0xff
	};
}

namespace ldraw
{
	using Color = ColorIndex;
}

mercurial