PageRenderTime 118ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/archive/Painter/Fill.cpp

http://upp-mirror.googlecode.com/
C++ | 215 lines | 196 code | 16 blank | 3 comment | 65 complexity | 6f0fb4cdc51b5d471eb76067b20a550a 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. // int agg_line_counter; _DBG_
  3. NAMESPACE_UPP
  4. void BufferPainter::FillOp(const RGBA& c)
  5. {
  6. PAINTER_TIMING("FillOp");
  7. // agg_line_counter = 0;
  8. if(inpath)
  9. path.close_polygon();
  10. pixf.noaa = pathattr.noaa;
  11. RGBA color = c;
  12. if(PathVisible(0) && color.a) {
  13. if(pathattr.opacity != 1.0) {
  14. color.a = int(color.a * pathattr.opacity);
  15. color.r = int(color.r * pathattr.opacity);
  16. color.g = int(color.g * pathattr.opacity);
  17. color.b = int(color.b * pathattr.opacity);
  18. }
  19. if(color.a) {
  20. rasterizer.reset();
  21. rasterizer.filling_rule(pathattr.evenodd ? agg::fill_even_odd : agg::fill_non_zero);
  22. rasterizer.add_path(curved_trans);
  23. if(clip.GetCount()) {
  24. agg::rendering_buffer mask_rbuf;
  25. mask_rbuf.attach(~clip.Top(), size.cx, size.cy, size.cx);
  26. agg::alpha_mask_gray8 mask(mask_rbuf);
  27. agg::scanline_u8_am<agg::alpha_mask_gray8> sl(mask);
  28. renderer.color(color);
  29. agg::render_scanlines(rasterizer, sl, renderer);
  30. }
  31. else {
  32. renderer.color(*(color_type *)&color);
  33. agg::render_scanlines(rasterizer, scanline_p, renderer);
  34. }
  35. rasterizer.reset();
  36. }
  37. }
  38. inpath = false;
  39. // DDUMP(agg_line_counter);
  40. }
  41. struct UppImageAggSpan {
  42. struct RGBAV {
  43. dword r, g, b, a;
  44. void Set(dword v) { r = g = b = a = v; }
  45. void Put(dword weight, const RGBA& src) {
  46. r += weight * src.r;
  47. g += weight * src.g;
  48. b += weight * src.b;
  49. a += weight * src.a;
  50. }
  51. };
  52. agg::span_interpolator_linear<> interpolator;
  53. int ax, ay, cx, cy, maxx, maxy;
  54. byte style;
  55. byte hstyle, vstyle;
  56. bool fast;
  57. bool fixed;
  58. const RGBA *image;
  59. int alpha;
  60. void SetImage(const Image& img) {
  61. image = ~img;
  62. cx = img.GetWidth();
  63. cy = img.GetHeight();
  64. maxx = cx - 1;
  65. maxy = cy - 1;
  66. ax = 6000000 / cx * cx;
  67. ay = 6000000 / cy * cy;
  68. }
  69. RGBA Pixel(int x, int y) { return image[cx * y + x]; }
  70. RGBA GetPixel(int x, int y) {
  71. if(hstyle == FILL_HPAD)
  72. x = minmax(x, 0, maxx);
  73. else
  74. if(hstyle == FILL_HREFLECT)
  75. x = (x + ax) / cx & 1 ? (ax - x - 1) % cx : (x + ax) % cx;
  76. else
  77. if(hstyle == FILL_HREPEAT)
  78. x = (x + ax) % cx;
  79. if(vstyle == FILL_VPAD)
  80. y = minmax(y, 0, maxy);
  81. else
  82. if(vstyle == FILL_VREFLECT)
  83. y = (y + ay) / cy & 1 ? (ay - y - 1) % cy : (y + ay) % cy;
  84. else
  85. if(vstyle == FILL_VREPEAT)
  86. y = (y + ay) % cy;
  87. return fixed || (x >= 0 && x < cx && y >= 0 && y < cy) ? image[cx * y + x] : RGBAZero();
  88. }
  89. void prepare() {}
  90. void generate(RGBA *_span, int x, int y, unsigned len)
  91. {
  92. interpolator.begin(x + 0.5, y + 0.5, len);
  93. RGBA *span = (RGBA *)_span;
  94. fixed = hstyle && vstyle;
  95. while(len--) {
  96. int x_hr;
  97. int y_hr;
  98. interpolator.coordinates(&x_hr, &y_hr);
  99. x_hr -= 128;
  100. y_hr -= 128;
  101. int x_lr = x_hr >> 8;
  102. int y_lr = y_hr >> 8;
  103. if(hstyle == FILL_HREPEAT)
  104. x_lr = (x_lr + ax) % cx;
  105. if(vstyle == FILL_VREPEAT)
  106. y_lr = (y_lr + ay) % cy;
  107. if(fast) {
  108. RGBA v;
  109. if(x_lr > 0 && x_lr < maxx && y_lr > 0 && y_lr < maxy)
  110. v = Pixel(x_lr, y_lr);
  111. if(style == 0 && (x_lr < -1 || x_lr > cx || y_lr < -1 || y_lr > cy))
  112. v == RGBAZero();
  113. else
  114. v = GetPixel(x_lr, y_lr);
  115. if(alpha == 256)
  116. *span = v;
  117. else {
  118. span->r = byte((alpha * v.r) >> 8);
  119. span->g = byte((alpha * v.g) >> 8);
  120. span->b = byte((alpha * v.b) >> 8);
  121. span->a = byte((alpha * v.a) >> 8);
  122. }
  123. }
  124. else {
  125. RGBAV v;
  126. v.Set(256 * 256 / 2);
  127. x_hr &= 255;
  128. y_hr &= 255;
  129. if(x_lr > 0 && x_lr < maxx && y_lr > 0 && y_lr < maxy) {
  130. v.Put((256 - x_hr) * (256 - y_hr), Pixel(x_lr, y_lr));
  131. v.Put(x_hr * (256 - y_hr), Pixel(x_lr + 1, y_lr));
  132. v.Put((256 - x_hr) * y_hr, Pixel(x_lr, y_lr + 1));
  133. v.Put(x_hr * y_hr, Pixel(x_lr + 1, y_lr + 1));
  134. }
  135. else
  136. if(style == 0 && (x_lr < -1 || x_lr > cx || y_lr < -1 || y_lr > cy))
  137. v.Set(0);
  138. else {
  139. v.Put((256 - x_hr) * (256 - y_hr), GetPixel(x_lr, y_lr));
  140. v.Put(x_hr * (256 - y_hr), GetPixel(x_lr + 1, y_lr));
  141. v.Put((256 - x_hr) * y_hr, GetPixel(x_lr, y_lr + 1));
  142. v.Put(x_hr * y_hr, GetPixel(x_lr + 1, y_lr + 1));
  143. }
  144. v.r >>= 16;
  145. v.g >>= 16;
  146. v.b >>= 16;
  147. v.a >>= 16;
  148. if(alpha == 256) {
  149. span->r = (byte)v.r;
  150. span->g = (byte)v.g;
  151. span->b = (byte)v.b;
  152. span->a = (byte)v.a;
  153. }
  154. else {
  155. span->r = byte((alpha * v.r) >> 8);
  156. span->g = byte((alpha * v.g) >> 8);
  157. span->b = byte((alpha * v.b) >> 8);
  158. span->a = byte((alpha * v.a) >> 8);
  159. }
  160. }
  161. ++span;
  162. ++interpolator;
  163. }
  164. }
  165. };
  166. void BufferPainter::FillOp(const Image& image, const Matrix2D& transsrc, dword flags)
  167. {
  168. if(image.GetWidth() == 0 || image.GetHeight() == 0)
  169. return;
  170. if(inpath)
  171. path.close_polygon();
  172. span_alloc sa;
  173. pixf.noaa = pathattr.noaa;
  174. Matrix2D m = transsrc * pathattr.mtx;
  175. m.invert();
  176. UppImageAggSpan sg;
  177. sg.interpolator.transformer(m);
  178. sg.alpha = int(pathattr.opacity * 256);
  179. sg.SetImage(image);
  180. sg.style = flags & 15;
  181. sg.hstyle = flags & 3;
  182. sg.vstyle = flags & 12;
  183. sg.fast = flags & FILL_FAST;
  184. rasterizer.reset();
  185. rasterizer.filling_rule(pathattr.evenodd ? agg::fill_even_odd : agg::fill_non_zero);
  186. rasterizer.add_path(curved_trans);
  187. if(clip.GetCount()) {
  188. agg::rendering_buffer mask_rbuf;
  189. mask_rbuf.attach(~clip.Top(), size.cx, size.cy, size.cx);
  190. agg::alpha_mask_gray8 mask(mask_rbuf);
  191. agg::scanline_u8_am<agg::alpha_mask_gray8> sl(mask);
  192. agg::render_scanlines_aa(rasterizer, sl, renb, sa, sg);
  193. }
  194. else
  195. agg::render_scanlines_aa(rasterizer, scanline_p, renb, sa, sg);
  196. rasterizer.reset();
  197. inpath = false;
  198. }
  199. END_UPP_NAMESPACE