summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gui/theme.cpp4
-rw-r--r--src/resources/dye.cpp83
-rw-r--r--src/resources/dye.h8
3 files changed, 69 insertions, 26 deletions
diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp
index 8d447c2f..f42b0fc2 100644
--- a/src/gui/theme.cpp
+++ b/src/gui/theme.cpp
@@ -140,9 +140,7 @@ gcn::Color Theme::getProgressColor(int type, float progress)
DyePalette *dye = mInstance->mProgressColors[type];
int color[3] = {0, 0, 0};
- int intensity = (int) (255 * progress);
-
- dye->getColor(intensity, color);
+ dye->getColor(progress, color);
return gcn::Color(color[0], color[1], color[2]);
}
diff --git a/src/resources/dye.cpp b/src/resources/dye.cpp
index 85a87aa4..c0120bad 100644
--- a/src/resources/dye.cpp
+++ b/src/resources/dye.cpp
@@ -23,6 +23,7 @@
#include "log.h"
+#include <math.h>
#include <sstream>
DyePalette::DyePalette(const std::string &description)
@@ -89,29 +90,25 @@ void DyePalette::addLastColor(const int color[3])
void DyePalette::getColor(int intensity, int color[3]) const
{
- if (mColors.size() == 0)
- return;
-
- Color c0 = mColors[0];
-
- // Short circuit for black and single-color palettes
- if (intensity == 0 || mColors.size() == 1)
+ if (intensity == 0)
{
- color[0] = c0.value[0];
- color[1] = c0.value[1];
- color[2] = c0.value[2];
+ color[0] = 0;
+ color[1] = 0;
+ color[2] = 0;
+ return;
}
- int last = mColors.size() - 1;
+ int last = mColors.size();
+ if (last == 0) return;
int i = intensity * last / 255;
int t = intensity * last % 255;
int j = t != 0 ? i : i - 1;
// Get the exact color if any, the next color otherwise.
- int r2 = mColors[j + 1].value[0],
- g2 = mColors[j + 1].value[1],
- b2 = mColors[j + 1].value[2];
+ int r2 = mColors[j].value[0],
+ g2 = mColors[j].value[1],
+ b2 = mColors[j].value[2];
if (t == 0)
{
@@ -122,13 +119,13 @@ void DyePalette::getColor(int intensity, int color[3]) const
return;
}
- // Get the previous color.
- int r1 = c0.value[0], g1 = c0.value[1], b1 = c0.value[2];
+ // Get the previous color. First color is implicitly black.
+ int r1 = 0, g1 = 0, b1 = 0;
if (i > 0)
{
- r1 = mColors[i].value[0];
- g1 = mColors[i].value[1];
- b1 = mColors[i].value[2];
+ r1 = mColors[i - 1].value[0];
+ g1 = mColors[i - 1].value[1];
+ b1 = mColors[i - 1].value[2];
}
// Perform a linear interpolation.
@@ -137,10 +134,53 @@ void DyePalette::getColor(int intensity, int color[3]) const
color[2] = ((255 - t) * b1 + t * b2) / 255;
}
-Dye::Dye(const std::string &description)
+void DyePalette::getColor(double intensity, int color[3]) const
{
- static const int black[3] = {0, 0, 0};
+ // Nothing to do here
+ if (mColors.size() == 0)
+ return;
+
+ // Force range
+ if (intensity > 1.0)
+ intensity = 1.0;
+ else if (intensity < 0.0)
+ intensity = 0.0;
+
+ // Scale up
+ intensity = intensity * (mColors.size() - 1);
+ // Color indices
+ int i = (int) floor(intensity);
+ int j = (int) ceil(intensity);
+
+ if (i == j)
+ {
+ // Exact color.
+ color[0] = mColors[i].value[0];
+ color[1] = mColors[i].value[1];
+ color[2] = mColors[i].value[2];
+ return;
+ }
+
+ intensity -= i;
+ double rest = 1 - intensity;
+
+ // Get the colors
+ int r1 = mColors[i].value[0],
+ g1 = mColors[i].value[1],
+ b1 = mColors[i].value[2],
+ r2 = mColors[j].value[0],
+ g2 = mColors[j].value[1],
+ b2 = mColors[j].value[2];
+
+ // Perform the interpolation.
+ color[0] = (rest * r1 + intensity * r2);
+ color[1] = (rest * g1 + intensity * g2);
+ color[2] = (rest * b1 + intensity * b2);
+}
+
+Dye::Dye(const std::string &description)
+{
for (int i = 0; i < 7; ++i)
mDyePalettes[i] = 0;
@@ -179,7 +219,6 @@ Dye::Dye(const std::string &description)
}
mDyePalettes[i] = new DyePalette(description.substr(pos + 2,
next_pos - pos - 2));
- mDyePalettes[i]->addFirstColor(black); // First color is black
++next_pos;
}
while (next_pos < length);
diff --git a/src/resources/dye.h b/src/resources/dye.h
index 51d5d65c..e05f2d5e 100644
--- a/src/resources/dye.h
+++ b/src/resources/dye.h
@@ -44,10 +44,16 @@ class DyePalette
void addLastColor(const int color[3]);
/**
- * Gets a pixel color depending on its intensity.
+ * Gets a pixel color depending on its intensity. First color is
+ * implicitly black (0, 0, 0).
*/
void getColor(int intensity, int color[3]) const;
+ /**
+ * Gets a pixel color depending on its intensity.
+ */
+ void getColor(double intensity, int color[3]) const;
+
private:
struct Color { unsigned char value[3]; };