diff --git a/src/servers/app/server/Painter/drawing_modes/DrawingModeBlend.h b/src/servers/app/server/Painter/drawing_modes/DrawingModeBlend.h index e978faf29b..a63bdbdd01 100644 --- a/src/servers/app/server/Painter/drawing_modes/DrawingModeBlend.h +++ b/src/servers/app/server/Painter/drawing_modes/DrawingModeBlend.h @@ -27,12 +27,12 @@ assign_blend(uint8* d1, uint8* d2, uint8* d3, uint8* da, *d1 = (*d1 + s1) >> 1; *d2 = (*d2 + s2) >> 1; *d3 = (*d3 + s3) >> 1; + *da = 255; } namespace agg { - //====================================================DrawingModeBlend template class DrawingModeBlend : public DrawingMode { @@ -45,32 +45,27 @@ namespace agg { } - //-------------------------------------------------------------------- + // blend_pixel virtual void blend_pixel(int x, int y, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(cover) - { + if (cover == 255) { assign_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, cover); } } - //-------------------------------------------------------------------- + // blend_hline virtual void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); - if(cover == 255) - { - do - { + if (cover == 255) { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); assign_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], @@ -78,13 +73,9 @@ namespace agg p += 4; x++; - } - while(--len); - } - else - { - do - { + } while(--len); + } else { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); blend_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], @@ -92,35 +83,29 @@ namespace agg x++; p += 4; - } - while(--len); + } while(--len); } } - //-------------------------------------------------------------------- + // blend_vline virtual void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { printf("DrawingModeBlend::blend_vline()\n"); } - //-------------------------------------------------------------------- + // blend_solid_hspan virtual void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(*covers) - { - if(*covers == 255) - { + if (*covers) { + if (*covers == 255) { assign_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, *covers); } @@ -128,29 +113,23 @@ printf("DrawingModeBlend::blend_vline()\n"); covers++; p += 4; x++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_solid_vspan virtual void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(*covers) - { - if(*covers == 255) - { + if (*covers) { + if (*covers == 255) { assign_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, *covers); } @@ -158,39 +137,52 @@ printf("DrawingModeBlend::blend_vline()\n"); covers++; p += m_rbuf->stride(); y++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_color_hspan virtual void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { - uint8 alpha = covers ? *covers++ : cover; - - if(alpha) - { - if(alpha == 255) - { + if (covers) { + // non-solid opacity + do { + if (*covers) { + if (*covers == 255) { + assign_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b); + } else { + blend_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b, *covers); + } + } + covers++; + p += 4; + ++colors; + } while(--len); + } else { + // solid full opcacity + if (cover == 255) { + do { assign_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], colors->r, colors->g, colors->b); - } - else - { + p += 4; + ++colors; + } while(--len); + // solid partial opacity + } else if (cover) { + do { blend_blend(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], - colors->r, colors->g, colors->b, alpha); - } + colors->r, colors->g, colors->b, cover); + p += 4; + ++colors; + } while(--len); } - p += 4; - ++colors; } - while(--len); } diff --git a/src/servers/app/server/Painter/drawing_modes/DrawingModeCopy.h b/src/servers/app/server/Painter/drawing_modes/DrawingModeCopy.h index c8dbe25fc7..f73c65c9d6 100644 --- a/src/servers/app/server/Painter/drawing_modes/DrawingModeCopy.h +++ b/src/servers/app/server/Painter/drawing_modes/DrawingModeCopy.h @@ -4,235 +4,199 @@ #define DRAWING_MODE_COPY_H #include "DrawingMode.h" -#include "PatternHandler.h" + +// blend_copy +inline void +blend_copy(uint8* d1, uint8* d2, uint8* d3, uint8* da, + uint8 s1, uint8 s2, uint8 s3, uint8 a) +{ + blend(d1, d2, d3, da, s1, s2, s3, a); +} + +// assign_copy +inline void +assign_copy(uint8* d1, uint8* d2, uint8* d3, uint8* da, + uint8 s1, uint8 s2, uint8 s3) +{ + *d1 = s1; + *d2 = s2; + *d3 = s3; + *da = 255; +} + namespace agg { - //====================================================DrawingModeCopy template class DrawingModeCopy : public DrawingMode { public: typedef Order order_type; - //-------------------------------------------------------------------- + // constructor DrawingModeCopy() : DrawingMode() { } - //-------------------------------------------------------------------- + // blend_pixel virtual void blend_pixel(int x, int y, const color_type& c, int8u cover) { -//printf("DrawingModeCopy::blend_pixel()\n"); int8u* p = m_rbuf->row(y) + (x << 2); rgb_color color = fPatternHandler->R5ColorAt(x, y); -// int alpha = int(cover) * int(c.a); - int alpha = int(cover) * int(color.alpha); - if(alpha == 255*255) - { -// p[Order::R] = (int8u)c.r; -// p[Order::G] = (int8u)c.g; -// p[Order::B] = (int8u)c.b; -// p[Order::A] = (int8u)c.a; - - p[Order::R] = color.red; - p[Order::G] = color.green; - p[Order::B] = color.blue; - p[Order::A] = color.alpha; - } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; -// p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); -// p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); -// p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); -// p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - p[Order::R] = (int8u)((((color.red - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)((((color.green - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)((((color.blue - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); + if (cover == 255) { + assign_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue); + } else { + blend_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue, cover); } } - //-------------------------------------------------------------------- + // blend_hline virtual void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { -//printf("DrawingModeCopy::blend_hline()\n"); - int alpha = int(cover) * int(c.a); - int8u* p = m_rbuf->row(y) + (x << 2); - if(alpha == 255*255) - { - do - { - rgb_color color = fPatternHandler->R5ColorAt(x, y); - p[Order::R] = color.red; - p[Order::G] = color.green; - p[Order::B] = color.blue; - p[Order::A] = color.alpha; - p += 4; + if(cover == 255) { + // cache the low and high color as 32bit values + // high color + rgb_color color = fPatternHandler->HighColor().GetColor32(); + int32u vh; + int8u* p8 = (int8u*)&vh; + p8[Order::R] = (int8u)color.red; + p8[Order::G] = (int8u)color.green; + p8[Order::B] = (int8u)color.blue; + p8[Order::A] = 255; + // low color + color = fPatternHandler->LowColor().GetColor32(); + int32u vl; + p8 = (int8u*)&vl; + p8[Order::R] = (int8u)color.red; + p8[Order::G] = (int8u)color.green; + p8[Order::B] = (int8u)color.blue; + p8[Order::A] = 255; + // row offset as 32bit pointer + int32u* p32 = (int32u*)(m_rbuf->row(y)) + x; + do { + if (fPatternHandler->IsHighColor(x, y)) + *p32 = vh; + else + *p32 = vl; + p32++; x++; - } - while(--len); - } - else - { - do - { + } while(--len); + } else { + int8u* p = m_rbuf->row(y) + (x << 2); + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; -// p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); -// p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); -// p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); -// p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - p[Order::R] = (int8u)((((color.red - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)((((color.green - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)((((color.blue - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - p += 4; + blend_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue, cover); x++; - } - while(--len); + p += 4; + } while(--len); } } - //-------------------------------------------------------------------- + // blend_vline virtual void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { printf("DrawingModeCopy::blend_vline()\n"); } - //-------------------------------------------------------------------- + // blend_solid_hspan virtual void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { -//printf("DrawingModeCopy::blend_solid_hspan()\n"); int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); -// int alpha = int(*covers++) * c.a; - int alpha = int(*covers++) * color.alpha; -//int alpha = int(*covers++); - if(alpha) - { - if(alpha == 255*255) - { -// p[Order::R] = (int8u)c.r; -// p[Order::G] = (int8u)c.g; -// p[Order::B] = (int8u)c.b; -// p[Order::A] = (int8u)c.a; - p[Order::R] = color.red; - p[Order::G] = color.green; - p[Order::B] = color.blue; - p[Order::A] = color.alpha; + if (*covers) { + if(*covers == 255) { + assign_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue); + } else { + blend_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue, *covers); } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; -// p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); -// p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); -// p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); -// p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - p[Order::R] = (int8u)((((color.red - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)((((color.green - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)((((color.blue - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - } -/*if(alpha > 127) -{ - p[Order::R] = (int8u)c.r; - p[Order::G] = (int8u)c.g; - p[Order::B] = (int8u)c.b; - p[Order::A] = (int8u)c.a; -}*/ } + covers++; p += 4; x++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_solid_vspan virtual void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { -//printf("DrawingModeCopy::blend_solid_vspan()\n"); int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); -// int alpha = int(*covers++) * c.a; - int alpha = int(*covers++) * color.alpha; -//int alpha = int(*covers++); - - if(alpha) - { - if(alpha == 255*255) - { -// p[Order::R] = (int8u)c.r; -// p[Order::G] = (int8u)c.g; -// p[Order::B] = (int8u)c.b; -// p[Order::A] = (int8u)c.a; - p[Order::R] = color.red; - p[Order::G] = color.green; - p[Order::B] = color.blue; - p[Order::A] = color.alpha; + if (*covers) { + if (*covers == 255) { + assign_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue); + } else { + blend_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue, *covers); } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; -// p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); -// p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); -// p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); -// p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - p[Order::R] = (int8u)((((color.red - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)((((color.green - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)((((color.blue - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - } -/*if(alpha > 127) -{ - p[Order::R] = (int8u)c.r; - p[Order::G] = (int8u)c.g; - p[Order::B] = (int8u)c.b; - p[Order::A] = (int8u)c.a; -}*/ } + covers++; p += m_rbuf->stride(); y++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_color_hspan virtual void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { -printf("DrawingModeCopy::blend_color_hspan()\n"); + int8u* p = m_rbuf->row(y) + (x << 2); + if (covers) { + // non-solid opacity + do { + if(*covers) { + if(*covers == 255) { + assign_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b); + } else { + blend_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b, *covers); + } + } + covers++; + p += 4; + ++colors; + } while(--len); + } else { + // solid full opcacity + if (cover == 255) { + do { + assign_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b); + p += 4; + ++colors; + } while(--len); + // solid partial opacity + } else if (cover) { + do { + blend_copy(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b, cover); + p += 4; + ++colors; + } while(--len); + } + } } - //-------------------------------------------------------------------- + // blend_color_vspan virtual void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, diff --git a/src/servers/app/server/Painter/drawing_modes/DrawingModeInvert.h b/src/servers/app/server/Painter/drawing_modes/DrawingModeInvert.h index 0a17485bd1..1322177bfb 100644 --- a/src/servers/app/server/Painter/drawing_modes/DrawingModeInvert.h +++ b/src/servers/app/server/Painter/drawing_modes/DrawingModeInvert.h @@ -5,284 +5,171 @@ #include "DrawingMode.h" -#define BINARY 0 +// blend_invert +inline void +blend_invert(uint8* d1, uint8* d2, uint8* d3, uint8* da, uint8 a) +{ + blend(d1, d2, d3, da, 255 - *d1, 255 - *d2, 255 - *d3, a); +} + +// assign_invert +inline void +assign_invert(uint8* d1, uint8* d2, uint8* d3, uint8* da) +{ + *d1 = 255 - *d1; + *d2 = 255 - *d2; + *d3 = 255 - *d3; + *da = 255; +} + namespace agg { - //====================================================DrawingModeInvert template class DrawingModeInvert : public DrawingMode { public: typedef Order order_type; - //-------------------------------------------------------------------- + // constructor DrawingModeInvert() : DrawingMode() { } - //-------------------------------------------------------------------- + // blend_pixel virtual void blend_pixel(int x, int y, const color_type& c, int8u cover) { -//printf("DrawingModeInvert::blend_pixel()\n"); if (fPatternHandler->IsHighColor(x, y)) { int8u* p = m_rbuf->row(y) + (x << 2); -#if BINARY - int alpha = int(cover); - if(alpha > 127) - { - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; - // p[Order::A] = 255 - p[Order::A]; + if (cover == 255) { + assign_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A]); + } else { + blend_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], cover); } -#else - int alpha = int(cover) * int(c.a); - if(alpha == 255*255) - { - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; -// p[Order::A] = 255 - p[Order::A]; - } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; - p[Order::R] = (int8u)(((((255 - r) - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)(((((255 - g) - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)(((((255 - b) - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - } -#endif } } - //-------------------------------------------------------------------- + // blend_hline virtual void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { -//printf("DrawingModeInvert::blend_hline()\n"); -#if BINARY - if (cover > 127) { - int8u* p = m_rbuf->row(y) + (x << 2); - do - { + int8u* p = m_rbuf->row(y) + (x << 2); + if(cover == 255) { + do { if (fPatternHandler->IsHighColor(x, y)) { - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; -// p[Order::A] = 255 - p[Order::A]; - } - p += 4; - x++; - } - while(--len); - } -#else - int alpha = int(cover) * int(c.a); - if(alpha == 255*255) - { - int8u* p = m_rbuf->row(y) + (x << 2); - do - { - if (fPatternHandler->IsHighColor(x, y)) { - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; -// p[Order::A] = 255 - p[Order::A]; - } - p += 4; - x++; - } - while(--len); - } - else - { - int8u* p = m_rbuf->row(y) + (x << 2); - do - { - if (fPatternHandler->IsHighColor(x, y)) { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; - p[Order::R] = (int8u)(((((255 - r) - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)(((((255 - g) - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)(((((255 - b) - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); + assign_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A]); } x++; p += 4; - } - while(--len); + } while(--len); + } else { + do { + if (fPatternHandler->IsHighColor(x, y)) { + blend_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], cover); + } + x++; + p += 4; + } while(--len); } -#endif } - //-------------------------------------------------------------------- + // blend_vline virtual void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { printf("DrawingModeInvert::blend_vline()\n"); } - //-------------------------------------------------------------------- + // blend_solid_hspan virtual void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { -//printf("DrawingModeInvert::blend_solid_hspan()\n"); int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { if (fPatternHandler->IsHighColor(x, y)) { -#if BINARY - int alpha = int(*covers); - if(alpha > 127) - { - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; - // p[Order::A] = 255 - p[Order::A]; - } -#else - int alpha = int(*covers) * c.a; - if(alpha) - { - if(alpha == 255*255) - { - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; -// p[Order::A] = 255 - p[Order::A]; - } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; - p[Order::R] = (int8u)(((((255 - r) - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)(((((255 - g) - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)(((((255 - b) - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); + if (*covers) { + if(*covers == 255) { + assign_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A]); + } else { + blend_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], *covers); } } -#endif } covers++; p += 4; x++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_solid_vspan virtual void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { -//printf("DrawingModeInvert::blend_solid_vspan()\n"); int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { if (fPatternHandler->IsHighColor(x, y)) { -#if BINARY - int alpha = int(*covers); - if(alpha > 127) - { - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; - // p[Order::A] = 255 - p[Order::A]; - } -#else - int alpha = int(*covers) * c.a; - if(alpha) - { - if(alpha == 255*255) - { - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; -// p[Order::A] = 255 - p[Order::A]; - } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; - p[Order::R] = (int8u)(((((255 - r) - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)(((((255 - g) - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)(((((255 - b) - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); + if (*covers) { + if (*covers == 255) { + assign_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A]); + } else { + blend_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], *covers); } } -#endif } covers++; p += m_rbuf->stride(); y++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_color_hspan virtual void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { -//printf("DrawingModeInvert::blend_color_hspan()\n"); + // TODO: does the R5 app_server check for the + // appearance of the high color in the source bitmap? int8u* p = m_rbuf->row(y) + (x << 2); - rgb_color lowColor = fPatternHandler->LowColor().GetColor32(); - do - { - int alpha = colors->a * (covers ? int(*covers++) : int(cover)); - - if(alpha) - { -// if (colors->r != lowColor.red || -// colors->g != lowColor.green || -// colors->b != lowColor.blue) { - - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; -// } -/* if(alpha == 255*255) - { - p[Order::R] = 255 - p[Order::R]; - p[Order::G] = 255 - p[Order::G]; - p[Order::B] = 255 - p[Order::B]; -// p[Order::A] = 255 - p[Order::A]; + if (covers) { + // non-solid opacity + do { + if(*covers) { + if(*covers == 255) { + assign_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A]); + } else { + blend_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], *covers); + } } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; -// int a = p[Order::A]; - p[Order::R] = (int8u)(((((255 - r) - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)(((((255 - g) - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)(((((255 - b) - b) * alpha) + (b << 16)) >> 16); -// p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - }*/ + covers++; + p += 4; +// ++colors; + } while(--len); + } else { + // solid full opcacity + if (cover == 255) { + do { + assign_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A]); + p += 4; +// ++colors; + } while(--len); + // solid partial opacity + } else if (cover) { + do { + blend_invert(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], cover); + p += 4; +// ++colors; + } while(--len); } - p += 4; - ++colors; } - while(--len); } - //-------------------------------------------------------------------- + // blend_color_vspan virtual void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, diff --git a/src/servers/app/server/Painter/drawing_modes/DrawingModeMax.h b/src/servers/app/server/Painter/drawing_modes/DrawingModeMax.h index 34d6982226..1b5731803f 100644 --- a/src/servers/app/server/Painter/drawing_modes/DrawingModeMax.h +++ b/src/servers/app/server/Painter/drawing_modes/DrawingModeMax.h @@ -27,50 +27,45 @@ assign_max(uint8* d1, uint8* d2, uint8* d3, uint8* da, *d1 = max_c(*d1, s1); *d2 = max_c(*d2, s2); *d3 = max_c(*d3, s3); + *da = 255; } namespace agg { - //====================================================DrawingModeMax template class DrawingModeMax : public DrawingMode { public: typedef Order order_type; - //-------------------------------------------------------------------- + // constructor DrawingModeMax() : DrawingMode() { } - //-------------------------------------------------------------------- + // blend_pixel virtual void blend_pixel(int x, int y, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(cover) - { + if (cover == 255) { assign_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, cover); } } - //-------------------------------------------------------------------- + // blend_hline virtual void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); - if(cover == 255) - { - do - { + if (cover == 255) { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); assign_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], @@ -78,13 +73,9 @@ namespace agg p += 4; x++; - } - while(--len); - } - else - { - do - { + } while(--len); + } else { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); blend_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], @@ -92,12 +83,11 @@ namespace agg x++; p += 4; - } - while(--len); + } while(--len); } } - //-------------------------------------------------------------------- + // blend_vline virtual void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { @@ -109,18 +99,13 @@ printf("DrawingModeMax::blend_vline()\n"); const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(*covers) - { - if(*covers == 255) - { + if (*covers) { + if (*covers == 255) { assign_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, *covers); } @@ -128,29 +113,23 @@ printf("DrawingModeMax::blend_vline()\n"); covers++; p += 4; x++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_solid_vspan virtual void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(*covers) - { - if(*covers == 255) - { + if (*covers) { + if (*covers == 255) { assign_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, *covers); } @@ -158,39 +137,52 @@ printf("DrawingModeMax::blend_vline()\n"); covers++; p += m_rbuf->stride(); y++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_color_hspan virtual void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { - uint8 alpha = covers ? *covers++ : cover; - - if(alpha) - { - if(alpha == 255) - { + if (covers) { + // non-solid opacity + do { + if (*covers) { + if (*covers == 255) { + assign_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b); + } else { + blend_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b, *covers); + } + } + covers++; + p += 4; + ++colors; + } while(--len); + } else { + // solid full opcacity + if (cover == 255) { + do { assign_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], colors->r, colors->g, colors->b); - } - else - { + p += 4; + ++colors; + } while(--len); + // solid partial opacity + } else if (cover) { + do { blend_max(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], - colors->r, colors->g, colors->b, alpha); - } + colors->r, colors->g, colors->b, cover); + p += 4; + ++colors; + } while(--len); } - p += 4; - ++colors; } - while(--len); } diff --git a/src/servers/app/server/Painter/drawing_modes/DrawingModeMin.h b/src/servers/app/server/Painter/drawing_modes/DrawingModeMin.h index 6606044c3d..7f8f700ee3 100644 --- a/src/servers/app/server/Painter/drawing_modes/DrawingModeMin.h +++ b/src/servers/app/server/Painter/drawing_modes/DrawingModeMin.h @@ -27,50 +27,45 @@ assign_min(uint8* d1, uint8* d2, uint8* d3, uint8* da, *d1 = min_c(*d1, s1); *d2 = min_c(*d2, s2); *d3 = min_c(*d3, s3); + *da = 255; } namespace agg { - //====================================================DrawingModeMin template class DrawingModeMin : public DrawingMode { public: typedef Order order_type; - //-------------------------------------------------------------------- + // constructor DrawingModeMin() : DrawingMode() { } - //-------------------------------------------------------------------- + // blend_pixel virtual void blend_pixel(int x, int y, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(cover) - { + if (cover == 255) { assign_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, cover); } } - //-------------------------------------------------------------------- + // blend_hline virtual void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); - if(cover == 255) - { - do - { + if (cover == 255) { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); assign_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], @@ -78,13 +73,9 @@ namespace agg p += 4; x++; - } - while(--len); - } - else - { - do - { + } while(--len); + } else { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); blend_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], @@ -92,35 +83,29 @@ namespace agg x++; p += 4; - } - while(--len); + } while(--len); } } - //-------------------------------------------------------------------- + // blend_vline virtual void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { printf("DrawingModeMin::blend_vline()\n"); } - //-------------------------------------------------------------------- + // blend_solid_hspan virtual void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(*covers) - { - if(*covers == 255) - { + if (*covers) { + if (*covers == 255) { assign_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, *covers); } @@ -128,29 +113,23 @@ printf("DrawingModeMin::blend_vline()\n"); covers++; p += 4; x++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_solid_vspan virtual void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(*covers) - { - if(*covers == 255) - { + if (*covers) { + if (*covers == 255) { assign_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, *covers); } @@ -158,39 +137,52 @@ printf("DrawingModeMin::blend_vline()\n"); covers++; p += m_rbuf->stride(); y++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_color_hspan virtual void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { - uint8 alpha = covers ? *covers++ : cover; - - if(alpha) - { - if(alpha == 255) - { + if (covers) { + // non-solid opacity + do { + if (*covers) { + if (*covers == 255) { + assign_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b); + } else { + blend_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b, *covers); + } + } + covers++; + p += 4; + ++colors; + } while(--len); + } else { + // solid full opcacity + if (cover == 255) { + do { assign_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], colors->r, colors->g, colors->b); - } - else - { + p += 4; + ++colors; + } while(--len); + // solid partial opacity + } else if (cover) { + do { blend_min(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], - colors->r, colors->g, colors->b, alpha); - } + colors->r, colors->g, colors->b, cover); + p += 4; + ++colors; + } while(--len); } - p += 4; - ++colors; } - while(--len); } diff --git a/src/servers/app/server/Painter/drawing_modes/DrawingModeOver.h b/src/servers/app/server/Painter/drawing_modes/DrawingModeOver.h index 748772c50b..a6d851cd61 100644 --- a/src/servers/app/server/Painter/drawing_modes/DrawingModeOver.h +++ b/src/servers/app/server/Painter/drawing_modes/DrawingModeOver.h @@ -5,258 +5,193 @@ #include "DrawingMode.h" +// blend_over +inline void +blend_over(uint8* d1, uint8* d2, uint8* d3, uint8* da, + uint8 s1, uint8 s2, uint8 s3, uint8 a) +{ + blend(d1, d2, d3, da, s1, s2, s3, a); +} + +// assign_over +inline void +assign_over(uint8* d1, uint8* d2, uint8* d3, uint8* da, + uint8 s1, uint8 s2, uint8 s3) +{ + *d1 = s1; + *d2 = s2; + *d3 = s3; + *da = 255; +} + + namespace agg { - //====================================================DrawingModeOver template class DrawingModeOver : public DrawingMode { public: typedef Order order_type; - //-------------------------------------------------------------------- + // constructor DrawingModeOver() : DrawingMode() { } - //-------------------------------------------------------------------- + // blend_pixel virtual void blend_pixel(int x, int y, const color_type& c, int8u cover) { -//printf("DrawingModeOver::blend_pixel()\n"); if (fPatternHandler->IsHighColor(x, y)) { int8u* p = m_rbuf->row(y) + (x << 2); - rgb_color color = fPatternHandler->R5ColorAt(x, y); - // int alpha = int(cover) * int(c.a); - int alpha = int(cover) * int(color.alpha); - if(alpha == 255*255) - { - // p[Order::R] = (int8u)c.r; - // p[Order::G] = (int8u)c.g; - // p[Order::B] = (int8u)c.b; - // p[Order::A] = (int8u)c.a; - - p[Order::R] = color.red; - p[Order::G] = color.green; - p[Order::B] = color.blue; - p[Order::A] = color.alpha; - } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; - // p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); - // p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); - // p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); - // p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - p[Order::R] = (int8u)((((color.red - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)((((color.green - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)((((color.blue - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); + rgb_color color = fPatternHandler->HighColor().GetColor32(); + if (cover == 255) { + assign_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue); + } else { + blend_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue, cover); } } } - //-------------------------------------------------------------------- + // blend_hline virtual void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { -//printf("DrawingModeOver::blend_hline()\n"); - int alpha = int(cover) * int(c.a); - if(alpha == 255*255) - { + if(cover == 255) { + rgb_color color = fPatternHandler->HighColor().GetColor32(); int32u v; int8u* p8 = (int8u*)&v; - p8[Order::R] = (int8u)c.r; - p8[Order::G] = (int8u)c.g; - p8[Order::B] = (int8u)c.b; - p8[Order::A] = (int8u)c.a; + p8[Order::R] = (int8u)color.red; + p8[Order::G] = (int8u)color.green; + p8[Order::B] = (int8u)color.blue; + p8[Order::A] = 255; int32u* p32 = (int32u*)(m_rbuf->row(y)) + x; - do - { + do { if (fPatternHandler->IsHighColor(x, y)) *p32 = v; p32++; x++; - } - while(--len); - } - else - { + } while(--len); + } else { int8u* p = m_rbuf->row(y) + (x << 2); - do - { + rgb_color color = fPatternHandler->HighColor().GetColor32(); + do { if (fPatternHandler->IsHighColor(x, y)) { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; - p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); + blend_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue, cover); } x++; p += 4; - } - while(--len); + } while(--len); } } - //-------------------------------------------------------------------- + // blend_vline virtual void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { printf("DrawingModeOver::blend_vline()\n"); } - //-------------------------------------------------------------------- + // blend_solid_hspan virtual void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { -//printf("DrawingModeOver::blend_solid_hspan()\n"); int8u* p = m_rbuf->row(y) + (x << 2); - do - { + rgb_color color = fPatternHandler->HighColor().GetColor32(); + do { if (fPatternHandler->IsHighColor(x, y)) { - rgb_color color = fPatternHandler->R5ColorAt(x, y); - // int alpha = int(*covers++) * c.a; - int alpha = int(*covers) * color.alpha; - //int alpha = int(*covers++); - if(alpha) - { - if(alpha == 255*255) - { - // p[Order::R] = (int8u)c.r; - // p[Order::G] = (int8u)c.g; - // p[Order::B] = (int8u)c.b; - // p[Order::A] = (int8u)c.a; - p[Order::R] = color.red; - p[Order::G] = color.green; - p[Order::B] = color.blue; - p[Order::A] = color.alpha; - } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; - // p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); - // p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); - // p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); - // p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - p[Order::R] = (int8u)((((color.red - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)((((color.green - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)((((color.blue - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); + if (*covers) { + if(*covers == 255) { + assign_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue); + } else { + blend_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue, *covers); } } } covers++; p += 4; x++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_solid_vspan virtual void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { -//printf("DrawingModeOver::blend_solid_vspan()\n"); int8u* p = m_rbuf->row(y) + (x << 2); - do - { + rgb_color color = fPatternHandler->HighColor().GetColor32(); + do { if (fPatternHandler->IsHighColor(x, y)) { - rgb_color color = fPatternHandler->R5ColorAt(x, y); - // int alpha = int(*covers++) * c.a; - int alpha = int(*covers) * color.alpha; - //int alpha = int(*covers++); - - if(alpha) - { - if(alpha == 255*255) - { - // p[Order::R] = (int8u)c.r; - // p[Order::G] = (int8u)c.g; - // p[Order::B] = (int8u)c.b; - // p[Order::A] = (int8u)c.a; - p[Order::R] = color.red; - p[Order::G] = color.green; - p[Order::B] = color.blue; - p[Order::A] = color.alpha; - } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; - // p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); - // p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); - // p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); - // p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); - p[Order::R] = (int8u)((((color.red - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)((((color.green - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)((((color.blue - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); + if (*covers) { + if (*covers == 255) { + assign_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue); + } else { + blend_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + color.red, color.green, color.blue, *covers); } } - }; + } covers++; p += m_rbuf->stride(); y++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_color_hspan virtual void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { -//printf("DrawingModeOver::blend_color_hspan()\n"); int8u* p = m_rbuf->row(y) + (x << 2); - do - { - int alpha = colors->a * (covers ? int(*covers++) : int(cover)); - - if(alpha) - { - if(alpha == 255*255) - { - p[Order::R] = (int8u)colors->r; - p[Order::G] = (int8u)colors->g; - p[Order::B] = (int8u)colors->b; - p[Order::A] = (int8u)colors->a; - } - else - { - int r = p[Order::R]; - int g = p[Order::G]; - int b = p[Order::B]; - int a = p[Order::A]; - p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16); - p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16); - p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16); - p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); + if (covers) { + // non-solid opacity + do { + if (*covers) { + if (*covers == 255) { + assign_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b); + } else { + blend_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b, *covers); + } } + covers++; + p += 4; + ++colors; + } while(--len); + } else { + // solid full opcacity + if (cover == 255) { + do { + assign_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b); + p += 4; + ++colors; + } while(--len); + // solid partial opacity + } else if (cover) { + do { + blend_over(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b, cover); + p += 4; + ++colors; + } while(--len); } - p += 4; - ++colors; } - while(--len); } - //-------------------------------------------------------------------- + // blend_color_vspan virtual void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, diff --git a/src/servers/app/server/Painter/drawing_modes/DrawingModeSubtract.h b/src/servers/app/server/Painter/drawing_modes/DrawingModeSubtract.h index b71e121dd6..f7bda07856 100644 --- a/src/servers/app/server/Painter/drawing_modes/DrawingModeSubtract.h +++ b/src/servers/app/server/Painter/drawing_modes/DrawingModeSubtract.h @@ -8,7 +8,7 @@ #include "DrawingMode.h" #include "PatternHandler.h" - +// blend_subtract inline void blend_subtract(uint8* d1, uint8* d2, uint8* d3, uint8* da, uint8 s1, uint8 s2, uint8 s3, uint8 a) @@ -20,6 +20,7 @@ blend_subtract(uint8* d1, uint8* d2, uint8* d3, uint8* da, blend(d1, d2, d3, da, s1, s2, s3, a); } +// assign_subtract inline void assign_subtract(uint8* d1, uint8* d2, uint8* d3, uint8* da, uint8 s1, uint8 s2, uint8 s3) @@ -27,50 +28,45 @@ assign_subtract(uint8* d1, uint8* d2, uint8* d3, uint8* da, *d1 = max_c(0, *d1 - s1); *d2 = max_c(0, *d2 - s2); *d3 = max_c(0, *d3 - s3); + *da = 255; } namespace agg { - //====================================================DrawingModeSubtract template class DrawingModeSubtract : public DrawingMode { public: typedef Order order_type; - //-------------------------------------------------------------------- + // constructor DrawingModeSubtract() : DrawingMode() { } - //-------------------------------------------------------------------- + // blend_pixel virtual void blend_pixel(int x, int y, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(cover) - { + if (cover == 255) { assign_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, cover); } } - //-------------------------------------------------------------------- + // blend_hline virtual void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); - if(cover == 255) - { - do - { + if (cover == 255) { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); assign_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], @@ -78,13 +74,9 @@ namespace agg p += 4; x++; - } - while(--len); - } - else - { - do - { + } while(--len); + } else { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); blend_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], @@ -97,30 +89,25 @@ namespace agg } } - //-------------------------------------------------------------------- + // blend_vline virtual void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { printf("DrawingModeSubtract::blend_vline()\n"); } - //-------------------------------------------------------------------- + // blend_solid_hspan virtual void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(*covers) - { - if(*covers == 255) - { + if (*covers) { + if (*covers == 255) { assign_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, *covers); } @@ -128,29 +115,23 @@ printf("DrawingModeSubtract::blend_vline()\n"); covers++; p += 4; x++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_solid_vspan virtual void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { + do { rgb_color color = fPatternHandler->R5ColorAt(x, y); - if(*covers) - { - if(*covers == 255) - { + if (*covers) { + if (*covers == 255) { assign_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue); - } - else - { + } else { blend_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], color.red, color.green, color.blue, *covers); } @@ -158,43 +139,56 @@ printf("DrawingModeSubtract::blend_vline()\n"); covers++; p += m_rbuf->stride(); y++; - } - while(--len); + } while(--len); } - //-------------------------------------------------------------------- + // blend_color_hspan virtual void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); - do - { - uint8 alpha = covers ? *covers++ : cover; - - if(alpha) - { - if(alpha == 255) - { + if (covers) { + // non-solid opacity + do { + if (*covers) { + if (*covers == 255) { + assign_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b); + } else { + blend_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], + colors->r, colors->g, colors->b, *covers); + } + } + covers++; + p += 4; + ++colors; + } while(--len); + } else { + // solid full opcacity + if (cover == 255) { + do { assign_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], colors->r, colors->g, colors->b); - } - else - { + p += 4; + ++colors; + } while(--len); + // solid partial opacity + } else if (cover) { + do { blend_subtract(&p[Order::R], &p[Order::G], &p[Order::B], &p[Order::A], - colors->r, colors->g, colors->b, alpha); - } + colors->r, colors->g, colors->b, cover); + p += 4; + ++colors; + } while(--len); } - p += 4; - ++colors; } - while(--len); } - //-------------------------------------------------------------------- + // blend_color_vspan virtual void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers,