mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Reject colors with ambiguous alpha channel
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#ifndef RGBDS_GFX_RGBA_HPP
|
#ifndef RGBDS_GFX_RGBA_HPP
|
||||||
#define RGBDS_GFX_RGBA_HPP
|
#define RGBDS_GFX_RGBA_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct Rgba {
|
struct Rgba {
|
||||||
@@ -50,12 +51,10 @@ struct Rgba {
|
|||||||
*/
|
*/
|
||||||
static constexpr uint16_t transparent = 0b1'00000'00000'00000;
|
static constexpr uint16_t transparent = 0b1'00000'00000'00000;
|
||||||
|
|
||||||
/**
|
static constexpr uint8_t transparency_threshold = 0x10;
|
||||||
* All alpha values strictly below this will be considered transparent
|
bool isTransparent() const { return alpha < transparency_threshold; }
|
||||||
*/
|
static constexpr uint8_t opacity_threshold = 0xF0;
|
||||||
static constexpr uint8_t opacity_threshold = 0xF0; // TODO: adjust this
|
bool isOpaque() const { return alpha >= opacity_threshold; }
|
||||||
// TODO: also a transparency threshold, and error out on "middle" values
|
|
||||||
bool isTransparent() const { return alpha < opacity_threshold; }
|
|
||||||
/**
|
/**
|
||||||
* Computes the equivalent CGB color, respects the color curve depending on options
|
* Computes the equivalent CGB color, respects the color curve depending on options
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -323,10 +323,22 @@ public:
|
|||||||
// assigned, and conflicts always occur between that and another color.
|
// assigned, and conflicts always occur between that and another color.
|
||||||
// For the same reason, we don't need to worry about order, either.
|
// For the same reason, we don't need to worry about order, either.
|
||||||
std::vector<std::tuple<uint32_t, uint32_t>> conflicts;
|
std::vector<std::tuple<uint32_t, uint32_t>> conflicts;
|
||||||
|
// Holds colors whose alpha value is ambiguous
|
||||||
|
std::vector<uint32_t> indeterminates;
|
||||||
|
|
||||||
// Assign a color to the given position, and register it in the image palette as well
|
// Assign a color to the given position, and register it in the image palette as well
|
||||||
auto assignColor = [this, &conflicts](png_uint_32 x, png_uint_32 y, Rgba &&color) {
|
auto assignColor = [this, &conflicts, &indeterminates](png_uint_32 x, png_uint_32 y,
|
||||||
if (Rgba const *other = colors.registerColor(color); other) {
|
Rgba &&color) {
|
||||||
|
if (!color.isTransparent() && !color.isOpaque()) {
|
||||||
|
uint32_t css = color.toCSS();
|
||||||
|
if (std::find(indeterminates.begin(), indeterminates.end(), css)
|
||||||
|
== indeterminates.end()) {
|
||||||
|
error(
|
||||||
|
"Color #%08x is neither transparent (alpha < %u) nor opaque (alpha >= %u)",
|
||||||
|
css, Rgba::transparency_threshold, Rgba::opacity_threshold);
|
||||||
|
indeterminates.push_back(css);
|
||||||
|
}
|
||||||
|
} else if (Rgba const *other = colors.registerColor(color); other) {
|
||||||
std::tuple conflicting{color.toCSS(), other->toCSS()};
|
std::tuple conflicting{color.toCSS(), other->toCSS()};
|
||||||
// Do not report combinations twice
|
// Do not report combinations twice
|
||||||
if (std::find(conflicts.begin(), conflicts.end(), conflicting) == conflicts.end()) {
|
if (std::find(conflicts.begin(), conflicts.end(), conflicting) == conflicts.end()) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ uint16_t Rgba::cgbColor() const {
|
|||||||
if (isTransparent()) {
|
if (isTransparent()) {
|
||||||
return transparent;
|
return transparent;
|
||||||
}
|
}
|
||||||
|
assert(isOpaque());
|
||||||
|
|
||||||
uint8_t r = red, g = green, b = blue;
|
uint8_t r = red, g = green, b = blue;
|
||||||
if (options.useColorCurve) {
|
if (options.useColorCurve) {
|
||||||
|
|||||||
Reference in New Issue
Block a user