PageRenderTime 73ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/archive/olddraw/Painter/RadialGradient.cpp

http://upp-mirror.googlecode.com/
C++ | 82 lines | 74 code | 8 blank | 0 comment | 10 complexity | ea9cf218bf8272d057230f07c23d484d MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, BSD-2-Clause, BSD-3-Clause, LGPL-3.0, GPL-3.0
  1. #include "Painter.h"
  2. NAMESPACE_UPP
  3. struct PainterRadialSpan : SpanSource {
  4. LinearInterpolator interpolator;
  5. double cx, cy, r, fx, fy;
  6. int style;
  7. int alpha;
  8. const RGBA *gradient;
  9. double C;
  10. void Set(double _x, double _y, double _r, double _fx, double _fy)
  11. {
  12. cx = _x;
  13. cy = _y;
  14. r = _r;
  15. fx = _fx;
  16. fy = _fy;
  17. fx -= cx;
  18. fy -= cy;
  19. double fx2 = double(fx) * double(fx);
  20. double fy2 = double(fy) * double(fy);
  21. C = fx * fx + fy * fy - r * r;
  22. }
  23. void Get(RGBA *_span, int x, int y, unsigned len)
  24. {
  25. if(r <= 0)
  26. return;
  27. interpolator.Begin(x, y, len);
  28. RGBA *span = (RGBA *)_span;
  29. while(len--) {
  30. Point p = interpolator.Get();
  31. int h;
  32. const double q256 = 1 / 256.0;
  33. double dx = q256 * p.x - cx - fx;
  34. double dy = q256 * p.y - cy - fy;
  35. if(dx == 0 && dy == 0)
  36. h = 0;
  37. else {
  38. double A = dx * dx + dy * dy;
  39. double b = (fx * dx + fy * dy);
  40. double t = (sqrt(b * b - A * C) - b) / (A);
  41. h = t >= 0.001 ? int(2047 / t) : 2047;
  42. }
  43. if(style == GRADIENT_REPEAT)
  44. h = h & 2047;
  45. else
  46. if(style == GRADIENT_REFLECT)
  47. h = (h & 2048) ? (2047 - h & 2047) : (h & 2047);
  48. else
  49. h = minmax(h, 0, 2047);
  50. *span++ = gradient[h];
  51. }
  52. }
  53. };
  54. void BufferPainter::RenderRadial(double width, const Pointf& f, const RGBA& color1,
  55. const Pointf& c, double r, const RGBA& color2, int style)
  56. {
  57. PainterRadialSpan sg;
  58. Xform2D m = pathattr.mtx;
  59. sg.interpolator.Set(Inverse(m));
  60. sg.style = style;
  61. sg.Set(c.x, c.y, r, f.x, f.y);
  62. MakeGradient(color1, color2, 2048);
  63. sg.gradient = gradient[0];
  64. RenderPath(width, &sg, RGBAZero());
  65. }
  66. void BufferPainter::FillOp(const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style)
  67. {
  68. RenderRadial(-1, f, color1, c, r, color2, style);
  69. }
  70. void BufferPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style)
  71. {
  72. RenderRadial(width, f, color1, c, r, color2, style);
  73. }
  74. END_UPP_NAMESPACE