PageRenderTime 297ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/archive/olddraw/Painter/Image.cpp

http://upp-mirror.googlecode.com/
C++ | 239 lines | 217 code | 19 blank | 3 comment | 61 complexity | 4228f9b24551122432ecb90db4b33d1b 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. #if 0 // does not seem to help...
  4. Image MipMap(const Image& img)
  5. {
  6. Size ssz = img.GetSize() / 2;
  7. Size msz = (img.GetSize() + 1) / 2;
  8. ImageBuffer ib(msz);
  9. for(int y = 0; y < ssz.cy; y++) {
  10. const RGBA *s1 = img[2 * y];
  11. const RGBA *s2 = img[2 * y + 1];
  12. const RGBA *e = s1 + 2 * ssz.cx;
  13. RGBA *t = ib[y];
  14. while(s1 < e) {
  15. t->r = (s1[0].r + s1[1].r + s2[0].r + s2[1].r) >> 2;
  16. t->g = (s1[0].g + s1[1].g + s2[0].g + s2[1].g) >> 2;
  17. t->b = (s1[0].b + s1[1].b + s2[0].b + s2[1].b) >> 2;
  18. t->a = (s1[0].a + s1[1].a + s2[0].a + s2[1].a) >> 2;
  19. t++;
  20. s1 += 2;
  21. s2 += 2;
  22. }
  23. if(ssz.cx < msz.cx) {
  24. t->r = (s1[0].r + s2[0].r) >> 2;
  25. t->g = (s1[0].g + s2[0].g) >> 2;
  26. t->b = (s1[0].b + s2[0].b) >> 2;
  27. t->a = (s1[0].a + s2[0].a) >> 2;
  28. }
  29. }
  30. if(ssz.cy < msz.cy) {
  31. const RGBA *s1 = img[img.GetSize().cy - 1];
  32. const RGBA *e = s1 + 2 * ssz.cx;
  33. RGBA *t = ib[msz.cy - 1];
  34. while(s1 < e) {
  35. t->r = (s1[0].r + s1[1].r) >> 2;
  36. t->g = (s1[0].g + s1[1].g) >> 2;
  37. t->b = (s1[0].b + s1[1].b) >> 2;
  38. t->a = (s1[0].a + s1[1].a) >> 2;
  39. t++;
  40. s1 += 2;
  41. }
  42. if(ssz.cx < msz.cx) {
  43. t->r = s1[0].r >> 2;
  44. t->g = s1[0].g >> 2;
  45. t->b = s1[0].b >> 2;
  46. t->a = s1[0].a >> 2;
  47. }
  48. }
  49. return ib;
  50. }
  51. Image MakeMipMap(const Image& m, int level);
  52. struct MipMapMaker : ImageMaker {
  53. int level;
  54. Image image;
  55. virtual String Key() const {
  56. String h;
  57. RawCat(h, image.GetSerialId());
  58. RawCat(h, level);
  59. return h;
  60. }
  61. virtual Image Make() const {
  62. Size sz = image.GetSize();
  63. if(sz.cx && sz.cx) {
  64. if(level <= 0)
  65. return image;
  66. return MipMap(MakeMipMap(image, level - 1));
  67. }
  68. return Image();
  69. }
  70. };
  71. Image MakeMipMap(const Image& img, int level)
  72. {
  73. MipMapMaker m;
  74. m.image = img;
  75. m.level = level;
  76. return MakeImage(m);
  77. }
  78. #endif
  79. struct PainterImageSpan : SpanSource {
  80. struct RGBAV {
  81. dword r, g, b, a;
  82. void Set(dword v) { r = g = b = a = v; }
  83. void Put(dword weight, const RGBA& src) {
  84. r += weight * src.r;
  85. g += weight * src.g;
  86. b += weight * src.b;
  87. a += weight * src.a;
  88. }
  89. };
  90. LinearInterpolator interpolator;
  91. int ax, ay, cx, cy, maxx, maxy;
  92. byte style;
  93. byte hstyle, vstyle;
  94. bool fast;
  95. bool fixed;
  96. Image image;
  97. void Set(const Xform2D& m, const Image& img) {
  98. int level = 0;
  99. #if 0 // no mipmap for now
  100. double q = 1;
  101. if(!fast) {
  102. double q = 1;
  103. Pointf sc = m.GetScaleXY();
  104. if(sc.x >= 0.01 && sc.y >= 0.01)
  105. while(sc.x < 0.5 && sc.y < 0.5) {
  106. level++;
  107. sc.x *= 2;
  108. sc.y *= 2;
  109. q /= 2;
  110. }
  111. }
  112. if(q != 1)
  113. interpolator.Set(Inverse(m) * Xform2D::Scale(q));
  114. else
  115. #endif
  116. interpolator.Set(Inverse(m));
  117. image = img;
  118. // image = MakeMipMap(img, level);
  119. cx = image.GetWidth();
  120. cy = image.GetHeight();
  121. maxx = cx - 1;
  122. maxy = cy - 1;
  123. ax = 6000000 / cx * cx * 2;
  124. ay = 6000000 / cy * cy * 2;
  125. }
  126. RGBA Pixel(int x, int y) { return image[y][x]; }
  127. RGBA GetPixel(int x, int y) {
  128. if(hstyle == FILL_HPAD)
  129. x = minmax(x, 0, maxx);
  130. else
  131. if(hstyle == FILL_HREFLECT)
  132. x = (x + ax) / cx & 1 ? (ax - x - 1) % cx : (x + ax) % cx;
  133. else
  134. if(hstyle == FILL_HREPEAT)
  135. x = (x + ax) % cx;
  136. if(vstyle == FILL_VPAD)
  137. y = minmax(y, 0, maxy);
  138. else
  139. if(vstyle == FILL_VREFLECT)
  140. y = (y + ay) / cy & 1 ? (ay - y - 1) % cy : (y + ay) % cy;
  141. else
  142. if(vstyle == FILL_VREPEAT)
  143. y = (y + ay) % cy;
  144. return fixed || (x >= 0 && x < cx && y >= 0 && y < cy) ? image[y][x] : RGBAZero();
  145. }
  146. virtual void Get(RGBA *span, int x, int y, unsigned len)
  147. {
  148. interpolator.Begin(x, y, len);
  149. fixed = hstyle && vstyle;
  150. while(len--) {
  151. Point h = interpolator.Get();
  152. // h -= 128;
  153. Point l = h >> 8;
  154. if(hstyle == FILL_HREPEAT)
  155. l.x = (l.x + ax) % cx;
  156. if(vstyle == FILL_VREPEAT)
  157. l.y = (l.y + ay) % cy;
  158. if(fast) {
  159. if(l.x > 0 && l.x < maxx && l.y > 0 && l.y < maxy)
  160. *span = Pixel(l.x, l.y);
  161. else
  162. if(style == 0 && (l.x < -1 || l.x > cx || l.y < -1 || l.y > cy))
  163. *span = RGBAZero();
  164. else
  165. *span = GetPixel(l.x, l.y);
  166. }
  167. else {
  168. RGBAV v;
  169. v.Set(0);
  170. // v.Set(256 * 256 / 2);
  171. h.x &= 255;
  172. h.y &= 255;
  173. Point u = -h + 256;
  174. if(l.x > 0 && l.x < maxx && l.y > 0 && l.y < maxy) {
  175. v.Put(u.x * u.y, Pixel(l.x, l.y));
  176. v.Put(h.x * u.y, Pixel(l.x + 1, l.y));
  177. v.Put(u.x * h.y, Pixel(l.x, l.y + 1));
  178. v.Put(h.x * h.y, Pixel(l.x + 1, l.y + 1));
  179. }
  180. else
  181. if(style == 0 && (l.x < -1 || l.x > cx || l.y < -1 || l.y > cy))
  182. v.Set(0);
  183. else {
  184. v.Put(u.x * u.y, GetPixel(l.x, l.y));
  185. v.Put(h.x * u.y, GetPixel(l.x + 1, l.y));
  186. v.Put(u.x * h.y, GetPixel(l.x, l.y + 1));
  187. v.Put(h.x * h.y, GetPixel(l.x + 1, l.y + 1));
  188. }
  189. span->r = byte(v.r >> 16);
  190. span->g = byte(v.g >> 16);
  191. span->b = byte(v.b >> 16);
  192. span->a = byte(v.a >> 16);
  193. }
  194. ++span;
  195. }
  196. }
  197. };
  198. void BufferPainter::RenderImage(double width, const Image& image, const Xform2D& transsrc, dword flags)
  199. {
  200. if(image.GetWidth() == 0 || image.GetHeight() == 0)
  201. return;
  202. PainterImageSpan ss;
  203. ss.style = byte(flags & 15);
  204. ss.hstyle = byte(flags & 3);
  205. ss.vstyle = byte(flags & 12);
  206. ss.fast = flags & FILL_FAST;
  207. Xform2D m = transsrc * pathattr.mtx;
  208. ss.Set(m, image);
  209. RenderPath(width, &ss, RGBAZero());
  210. }
  211. void BufferPainter::FillOp(const Image& image, const Xform2D& transsrc, dword flags)
  212. {
  213. Close();
  214. RenderImage(-1, image, transsrc, flags);
  215. }
  216. void BufferPainter::StrokeOp(double width, const Image& image, const Xform2D& transsrc, dword flags)
  217. {
  218. RenderImage(width, image, transsrc, flags);
  219. }
  220. END_UPP_NAMESPACE