/archive/olddraw/Painter/Image.cpp
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
- #include "Painter.h"
-
- NAMESPACE_UPP
-
- #if 0 // does not seem to help...
-
- Image MipMap(const Image& img)
- {
- Size ssz = img.GetSize() / 2;
- Size msz = (img.GetSize() + 1) / 2;
- ImageBuffer ib(msz);
- for(int y = 0; y < ssz.cy; y++) {
- const RGBA *s1 = img[2 * y];
- const RGBA *s2 = img[2 * y + 1];
- const RGBA *e = s1 + 2 * ssz.cx;
- RGBA *t = ib[y];
- while(s1 < e) {
- t->r = (s1[0].r + s1[1].r + s2[0].r + s2[1].r) >> 2;
- t->g = (s1[0].g + s1[1].g + s2[0].g + s2[1].g) >> 2;
- t->b = (s1[0].b + s1[1].b + s2[0].b + s2[1].b) >> 2;
- t->a = (s1[0].a + s1[1].a + s2[0].a + s2[1].a) >> 2;
- t++;
- s1 += 2;
- s2 += 2;
- }
- if(ssz.cx < msz.cx) {
- t->r = (s1[0].r + s2[0].r) >> 2;
- t->g = (s1[0].g + s2[0].g) >> 2;
- t->b = (s1[0].b + s2[0].b) >> 2;
- t->a = (s1[0].a + s2[0].a) >> 2;
- }
- }
- if(ssz.cy < msz.cy) {
- const RGBA *s1 = img[img.GetSize().cy - 1];
- const RGBA *e = s1 + 2 * ssz.cx;
- RGBA *t = ib[msz.cy - 1];
- while(s1 < e) {
- t->r = (s1[0].r + s1[1].r) >> 2;
- t->g = (s1[0].g + s1[1].g) >> 2;
- t->b = (s1[0].b + s1[1].b) >> 2;
- t->a = (s1[0].a + s1[1].a) >> 2;
- t++;
- s1 += 2;
- }
- if(ssz.cx < msz.cx) {
- t->r = s1[0].r >> 2;
- t->g = s1[0].g >> 2;
- t->b = s1[0].b >> 2;
- t->a = s1[0].a >> 2;
- }
- }
- return ib;
- }
-
- Image MakeMipMap(const Image& m, int level);
-
- struct MipMapMaker : ImageMaker {
- int level;
- Image image;
-
- virtual String Key() const {
- String h;
- RawCat(h, image.GetSerialId());
- RawCat(h, level);
- return h;
- }
- virtual Image Make() const {
- Size sz = image.GetSize();
- if(sz.cx && sz.cx) {
- if(level <= 0)
- return image;
- return MipMap(MakeMipMap(image, level - 1));
- }
- return Image();
- }
- };
-
- Image MakeMipMap(const Image& img, int level)
- {
- MipMapMaker m;
- m.image = img;
- m.level = level;
- return MakeImage(m);
- }
-
- #endif
-
- struct PainterImageSpan : SpanSource {
- struct RGBAV {
- dword r, g, b, a;
-
- void Set(dword v) { r = g = b = a = v; }
- void Put(dword weight, const RGBA& src) {
- r += weight * src.r;
- g += weight * src.g;
- b += weight * src.b;
- a += weight * src.a;
- }
- };
-
- LinearInterpolator interpolator;
- int ax, ay, cx, cy, maxx, maxy;
- byte style;
- byte hstyle, vstyle;
- bool fast;
- bool fixed;
- Image image;
-
- void Set(const Xform2D& m, const Image& img) {
- int level = 0;
- #if 0 // no mipmap for now
- double q = 1;
- if(!fast) {
- double q = 1;
- Pointf sc = m.GetScaleXY();
- if(sc.x >= 0.01 && sc.y >= 0.01)
- while(sc.x < 0.5 && sc.y < 0.5) {
- level++;
- sc.x *= 2;
- sc.y *= 2;
- q /= 2;
- }
- }
- if(q != 1)
- interpolator.Set(Inverse(m) * Xform2D::Scale(q));
- else
- #endif
- interpolator.Set(Inverse(m));
- image = img;
- // image = MakeMipMap(img, level);
- cx = image.GetWidth();
- cy = image.GetHeight();
- maxx = cx - 1;
- maxy = cy - 1;
- ax = 6000000 / cx * cx * 2;
- ay = 6000000 / cy * cy * 2;
- }
-
- RGBA Pixel(int x, int y) { return image[y][x]; }
-
- RGBA GetPixel(int x, int y) {
- if(hstyle == FILL_HPAD)
- x = minmax(x, 0, maxx);
- else
- if(hstyle == FILL_HREFLECT)
- x = (x + ax) / cx & 1 ? (ax - x - 1) % cx : (x + ax) % cx;
- else
- if(hstyle == FILL_HREPEAT)
- x = (x + ax) % cx;
- if(vstyle == FILL_VPAD)
- y = minmax(y, 0, maxy);
- else
- if(vstyle == FILL_VREFLECT)
- y = (y + ay) / cy & 1 ? (ay - y - 1) % cy : (y + ay) % cy;
- else
- if(vstyle == FILL_VREPEAT)
- y = (y + ay) % cy;
- return fixed || (x >= 0 && x < cx && y >= 0 && y < cy) ? image[y][x] : RGBAZero();
- }
-
- virtual void Get(RGBA *span, int x, int y, unsigned len)
- {
- interpolator.Begin(x, y, len);
- fixed = hstyle && vstyle;
- while(len--) {
- Point h = interpolator.Get();
- // h -= 128;
- Point l = h >> 8;
- if(hstyle == FILL_HREPEAT)
- l.x = (l.x + ax) % cx;
- if(vstyle == FILL_VREPEAT)
- l.y = (l.y + ay) % cy;
- if(fast) {
- if(l.x > 0 && l.x < maxx && l.y > 0 && l.y < maxy)
- *span = Pixel(l.x, l.y);
- else
- if(style == 0 && (l.x < -1 || l.x > cx || l.y < -1 || l.y > cy))
- *span = RGBAZero();
- else
- *span = GetPixel(l.x, l.y);
- }
- else {
- RGBAV v;
- v.Set(0);
- // v.Set(256 * 256 / 2);
- h.x &= 255;
- h.y &= 255;
- Point u = -h + 256;
- if(l.x > 0 && l.x < maxx && l.y > 0 && l.y < maxy) {
- v.Put(u.x * u.y, Pixel(l.x, l.y));
- v.Put(h.x * u.y, Pixel(l.x + 1, l.y));
- v.Put(u.x * h.y, Pixel(l.x, l.y + 1));
- v.Put(h.x * h.y, Pixel(l.x + 1, l.y + 1));
- }
- else
- if(style == 0 && (l.x < -1 || l.x > cx || l.y < -1 || l.y > cy))
- v.Set(0);
- else {
- v.Put(u.x * u.y, GetPixel(l.x, l.y));
- v.Put(h.x * u.y, GetPixel(l.x + 1, l.y));
- v.Put(u.x * h.y, GetPixel(l.x, l.y + 1));
- v.Put(h.x * h.y, GetPixel(l.x + 1, l.y + 1));
- }
- span->r = byte(v.r >> 16);
- span->g = byte(v.g >> 16);
- span->b = byte(v.b >> 16);
- span->a = byte(v.a >> 16);
- }
- ++span;
- }
- }
- };
-
- void BufferPainter::RenderImage(double width, const Image& image, const Xform2D& transsrc, dword flags)
- {
- if(image.GetWidth() == 0 || image.GetHeight() == 0)
- return;
- PainterImageSpan ss;
- ss.style = byte(flags & 15);
- ss.hstyle = byte(flags & 3);
- ss.vstyle = byte(flags & 12);
- ss.fast = flags & FILL_FAST;
- Xform2D m = transsrc * pathattr.mtx;
- ss.Set(m, image);
- RenderPath(width, &ss, RGBAZero());
- }
-
- void BufferPainter::FillOp(const Image& image, const Xform2D& transsrc, dword flags)
- {
- Close();
- RenderImage(-1, image, transsrc, flags);
- }
-
- void BufferPainter::StrokeOp(double width, const Image& image, const Xform2D& transsrc, dword flags)
- {
- RenderImage(width, image, transsrc, flags);
- }
-
- END_UPP_NAMESPACE