The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
7.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. BEGIN_JUCE_NAMESPACE
  19. //==============================================================================
  20. ColourGradient::ColourGradient() noexcept
  21. {
  22. #if JUCE_DEBUG
  23. point1.setX (987654.0f);
  24. #endif
  25. }
  26. ColourGradient::ColourGradient (const Colour& colour1, const float x1_, const float y1_,
  27. const Colour& colour2, const float x2_, const float y2_,
  28. const bool isRadial_)
  29. : point1 (x1_, y1_),
  30. point2 (x2_, y2_),
  31. isRadial (isRadial_)
  32. {
  33. colours.add (ColourPoint (0.0, colour1));
  34. colours.add (ColourPoint (1.0, colour2));
  35. }
  36. ColourGradient::~ColourGradient()
  37. {
  38. }
  39. bool ColourGradient::operator== (const ColourGradient& other) const noexcept
  40. {
  41. return point1 == other.point1 && point2 == other.point2
  42. && isRadial == other.isRadial
  43. && colours == other.colours;
  44. }
  45. bool ColourGradient::operator!= (const ColourGradient& other) const noexcept
  46. {
  47. return ! operator== (other);
  48. }
  49. //==============================================================================
  50. void ColourGradient::clearColours()
  51. {
  52. colours.clear();
  53. }
  54. int ColourGradient::addColour (const double proportionAlongGradient, const Colour& colour)
  55. {
  56. // must be within the two end-points
  57. jassert (proportionAlongGradient >= 0 && proportionAlongGradient <= 1.0);
  58. const double pos = jlimit (0.0, 1.0, proportionAlongGradient);
  59. int i;
  60. for (i = 0; i < colours.size(); ++i)
  61. if (colours.getReference(i).position > pos)
  62. break;
  63. colours.insert (i, ColourPoint (pos, colour));
  64. return i;
  65. }
  66. void ColourGradient::removeColour (int index)
  67. {
  68. jassert (index > 0 && index < colours.size() - 1);
  69. colours.remove (index);
  70. }
  71. void ColourGradient::multiplyOpacity (const float multiplier) noexcept
  72. {
  73. for (int i = 0; i < colours.size(); ++i)
  74. {
  75. Colour& c = colours.getReference(i).colour;
  76. c = c.withMultipliedAlpha (multiplier);
  77. }
  78. }
  79. //==============================================================================
  80. int ColourGradient::getNumColours() const noexcept
  81. {
  82. return colours.size();
  83. }
  84. double ColourGradient::getColourPosition (const int index) const noexcept
  85. {
  86. if (isPositiveAndBelow (index, colours.size()))
  87. return colours.getReference (index).position;
  88. return 0;
  89. }
  90. const Colour ColourGradient::getColour (const int index) const noexcept
  91. {
  92. if (isPositiveAndBelow (index, colours.size()))
  93. return colours.getReference (index).colour;
  94. return Colour();
  95. }
  96. void ColourGradient::setColour (int index, const Colour& newColour) noexcept
  97. {
  98. if (isPositiveAndBelow (index, colours.size()))
  99. colours.getReference (index).colour = newColour;
  100. }
  101. Colour ColourGradient::getColourAtPosition (const double position) const noexcept
  102. {
  103. jassert (colours.getReference(0).position == 0); // the first colour specified has to go at position 0
  104. if (position <= 0 || colours.size() <= 1)
  105. return colours.getReference(0).colour;
  106. int i = colours.size() - 1;
  107. while (position < colours.getReference(i).position)
  108. --i;
  109. const ColourPoint& p1 = colours.getReference (i);
  110. if (i >= colours.size() - 1)
  111. return p1.colour;
  112. const ColourPoint& p2 = colours.getReference (i + 1);
  113. return p1.colour.interpolatedWith (p2.colour, (float) ((position - p1.position) / (p2.position - p1.position)));
  114. }
  115. //==============================================================================
  116. int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlock <PixelARGB>& lookupTable) const
  117. {
  118. #if JUCE_DEBUG
  119. // trying to use the object without setting its co-ordinates? Have a careful read of
  120. // the comments for the constructors.
  121. jassert (point1.getX() != 987654.0f);
  122. #endif
  123. const int numEntries = jlimit (1, jmax (1, (colours.size() - 1) << 8),
  124. 3 * (int) point1.transformedBy (transform)
  125. .getDistanceFrom (point2.transformedBy (transform)));
  126. lookupTable.malloc ((size_t) numEntries);
  127. if (colours.size() >= 2)
  128. {
  129. jassert (colours.getReference(0).position == 0); // the first colour specified has to go at position 0
  130. PixelARGB pix1 (colours.getReference (0).colour.getPixelARGB());
  131. int index = 0;
  132. for (int j = 1; j < colours.size(); ++j)
  133. {
  134. const ColourPoint& p = colours.getReference (j);
  135. const int numToDo = roundToInt (p.position * (numEntries - 1)) - index;
  136. const PixelARGB pix2 (p.colour.getPixelARGB());
  137. for (int i = 0; i < numToDo; ++i)
  138. {
  139. jassert (index >= 0 && index < numEntries);
  140. lookupTable[index] = pix1;
  141. lookupTable[index].tween (pix2, (uint32) (i << 8) / numToDo);
  142. ++index;
  143. }
  144. pix1 = pix2;
  145. }
  146. while (index < numEntries)
  147. lookupTable [index++] = pix1;
  148. }
  149. else
  150. {
  151. jassertfalse; // no colours specified!
  152. }
  153. return numEntries;
  154. }
  155. bool ColourGradient::isOpaque() const noexcept
  156. {
  157. for (int i = 0; i < colours.size(); ++i)
  158. if (! colours.getReference(i).colour.isOpaque())
  159. return false;
  160. return true;
  161. }
  162. bool ColourGradient::isInvisible() const noexcept
  163. {
  164. for (int i = 0; i < colours.size(); ++i)
  165. if (! colours.getReference(i).colour.isTransparent())
  166. return false;
  167. return true;
  168. }
  169. bool ColourGradient::ColourPoint::operator== (const ColourPoint& other) const noexcept
  170. {
  171. return position == other.position && colour == other.colour;
  172. }
  173. bool ColourGradient::ColourPoint::operator!= (const ColourPoint& other) const noexcept
  174. {
  175. return position != other.position || colour != other.colour;
  176. }
  177. END_JUCE_NAMESPACE