diff options
author | Jared Adams <jaxad0127@gmail.com> | 2010-03-20 19:01:02 -0600 |
---|---|---|
committer | Jared Adams <jaxad0127@gmail.com> | 2010-03-21 20:49:11 -0600 |
commit | fa058a891352ab4f85bafbf4e819c013ddfe4df7 (patch) | |
tree | e171acfceab0135a2b811338448681ad0408200c | |
parent | a8273ca217ee08f718e6acb3786f3197dff7915c (diff) | |
download | mana-fa058a891352ab4f85bafbf4e819c013ddfe4df7.tar.gz mana-fa058a891352ab4f85bafbf4e819c013ddfe4df7.tar.bz2 mana-fa058a891352ab4f85bafbf4e819c013ddfe4df7.tar.xz mana-fa058a891352ab4f85bafbf4e819c013ddfe4df7.zip |
Make the Dye class more flexible and fix an issue in it
After the last change, it could go over the end of the colors array.
Reviewed-by: Chuck Miller
Reviewed-by: Freeyorp
-rw-r--r-- | src/gui/theme.cpp | 4 | ||||
-rw-r--r-- | src/resources/dye.cpp | 83 | ||||
-rw-r--r-- | src/resources/dye.h | 8 |
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]; }; |