/CS/migrated/branches/NEW_SHADERSYS/libs/csgfx/gradient.cpp

# · C++ · 129 lines · 87 code · 20 blank · 22 comment · 9 complexity · 7752f60964b92f122cd5e984500f6d84 MD5 · raw file

  1. /*
  2. Copyright (C) 2003 by Jorrit Tyberghein
  3. (C) 2003 by Frank Richter
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free
  14. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "cssysdef.h"
  17. #include "qint.h"
  18. #include "csgfx/gradient.h"
  19. csGradientShade::csGradientShade() :
  20. left (0, 0, 0), right (0, 0, 0), position (0)
  21. {
  22. }
  23. csGradientShade::csGradientShade (csColor left_color, csColor right_color,
  24. float pos) :
  25. left (left_color), right (right_color), position (pos)
  26. {
  27. }
  28. csGradientShade::csGradientShade (csColor color, float pos) :
  29. left (color), right (color), position (pos)
  30. {
  31. }
  32. csGradient::csGradient()
  33. {
  34. }
  35. csGradient::csGradient (csColor first, csColor last)
  36. {
  37. AddShade (csGradientShade (first, 0.0f));
  38. AddShade (csGradientShade (last, 1.0f));
  39. }
  40. void csGradient::AddShade (csGradientShade shade)
  41. {
  42. int lo = 0, hi = shades.Length() - 1;
  43. int mid = 0;
  44. while (lo <= hi)
  45. {
  46. mid = (lo + hi) / 2;
  47. if (shades[mid].position < shade.position)
  48. {
  49. lo = mid + 1;
  50. }
  51. else
  52. {
  53. hi = mid - 1;
  54. }
  55. }
  56. shades.Insert (lo, shade);
  57. }
  58. void csGradient::Clear ()
  59. {
  60. shades.DeleteAll ();
  61. }
  62. #define CLAMP(x) ((x<EPSILON)?0.0f:(((x-1.0f)>EPSILON)?1.0f:x))
  63. bool csGradient::Render (csRGBcolor* pal, int count,
  64. float begin, float end) const
  65. {
  66. if (shades.Length() == 0) return false;
  67. // current color
  68. csColor color = shades[0].left;
  69. // delta per palette item
  70. csColor delta (0, 0, 0);
  71. // step in the gradient per pal item
  72. float step = (end - begin) / (float)count;
  73. float gradpos = begin;
  74. // current shade index
  75. int csi = 0;
  76. const csGradientShade* currshade = 0;
  77. const csGradientShade* nextshade = &shades[0];
  78. for (int i = 0; i < count; i++)
  79. {
  80. while (csi < shades.Length() &&
  81. (gradpos >= nextshade->position))
  82. {
  83. currshade = nextshade;
  84. csi++;
  85. if (csi < shades.Length())
  86. {
  87. nextshade = &shades[csi];
  88. }
  89. color = (step > EPSILON)? currshade->right : currshade->left;
  90. delta = (((step > EPSILON)? nextshade->left : nextshade->right) - color);
  91. float diff = (nextshade->position - currshade->position);
  92. if (ABS (diff) > EPSILON)
  93. {
  94. color +=
  95. (delta * ((gradpos - currshade->position) / diff));
  96. delta *= (step / diff);
  97. }
  98. }
  99. pal[i].red = QInt (CLAMP (color.red) * 255.99f);
  100. pal[i].green = QInt (CLAMP (color.green) * 255.99f);
  101. pal[i].blue = QInt (CLAMP (color.blue) * 255.99f);
  102. color += delta;
  103. gradpos += step;
  104. }
  105. return true;
  106. }