now has a special version of B_OP_OVER for solid patterns as well, accelerated the alpha blending for B_OP_OVER.... these are the first shy steps of rewriting the drawing mode stuff... :-)
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15532 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -17,6 +17,11 @@
|
||||
|
||||
class PatternHandler;
|
||||
|
||||
union pixel32 {
|
||||
uint32 data32;
|
||||
uint8 data8[4];
|
||||
};
|
||||
|
||||
// BLEND
|
||||
//
|
||||
// This macro assumes source alpha in range 0..255 and
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "DrawingModeMax.h"
|
||||
#include "DrawingModeMin.h"
|
||||
#include "DrawingModeOver.h"
|
||||
#include "DrawingModeOverSolid.h"
|
||||
#include "DrawingModeSelect.h"
|
||||
#include "DrawingModeSubtract.h"
|
||||
|
||||
@@ -30,6 +31,7 @@
|
||||
// constructor
|
||||
DrawingModeFactory::DrawingModeFactory()
|
||||
: fDrawingModeBGRA32Over(new DrawingModeBGRA32Over()),
|
||||
fDrawingModeBGRA32OverSolid(new DrawingModeBGRA32OverSolid()),
|
||||
fDrawingModeBGRA32Erase(new DrawingModeBGRA32Erase()),
|
||||
fDrawingModeBGRA32Invert(new DrawingModeBGRA32Invert()),
|
||||
fDrawingModeBGRA32Select(new DrawingModeBGRA32Select()),
|
||||
@@ -51,6 +53,7 @@ DrawingModeFactory::DrawingModeFactory()
|
||||
DrawingModeFactory::~DrawingModeFactory()
|
||||
{
|
||||
delete fDrawingModeBGRA32Over;
|
||||
delete fDrawingModeBGRA32OverSolid;
|
||||
delete fDrawingModeBGRA32Erase;
|
||||
delete fDrawingModeBGRA32Invert;
|
||||
delete fDrawingModeBGRA32Select;
|
||||
@@ -78,7 +81,10 @@ DrawingModeFactory::DrawingModeFor(drawing_mode mode,
|
||||
// these drawing modes discard source pixels
|
||||
// which have the current low color
|
||||
case B_OP_OVER:
|
||||
return fDrawingModeBGRA32Over;
|
||||
if (solid)
|
||||
return fDrawingModeBGRA32OverSolid;
|
||||
else
|
||||
return fDrawingModeBGRA32Over;
|
||||
break;
|
||||
case B_OP_ERASE:
|
||||
return fDrawingModeBGRA32Erase;
|
||||
|
||||
@@ -25,6 +25,7 @@ class DrawingModeFactory {
|
||||
bool solid = false);
|
||||
private:
|
||||
DrawingMode* fDrawingModeBGRA32Over;
|
||||
DrawingMode* fDrawingModeBGRA32OverSolid;
|
||||
DrawingMode* fDrawingModeBGRA32Erase;
|
||||
DrawingMode* fDrawingModeBGRA32Invert;
|
||||
DrawingMode* fDrawingModeBGRA32Select;
|
||||
|
||||
@@ -12,9 +12,14 @@
|
||||
#include "DrawingMode.h"
|
||||
|
||||
// BLEND_OVER
|
||||
#define BLEND_OVER(d1, d2, d3, da, s1, s2, s3, a) \
|
||||
#define BLEND_OVER(d, s1, s2, s3, a) \
|
||||
{ \
|
||||
BLEND(d1, d2, d3, da, s1, s2, s3, a); \
|
||||
pixel32 _p; \
|
||||
_p.data32 = *(uint32*)d; \
|
||||
d[0] = (((((s3) - _p.data8[0]) * (a)) + (_p.data8[0] << 8)) >> 8); \
|
||||
d[1] = (((((s2) - _p.data8[1]) * (a)) + (_p.data8[1] << 8)) >> 8); \
|
||||
d[2] = (((((s1) - _p.data8[2]) * (a)) + (_p.data8[2] << 8)) >> 8); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// ASSIGN_OVER
|
||||
@@ -46,8 +51,7 @@ class DrawingModeOver : public DrawingMode {
|
||||
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_OVER(p, color.red, color.green, color.blue, cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,8 +80,7 @@ class DrawingModeOver : public DrawingMode {
|
||||
rgb_color color = fPatternHandler->HighColor().GetColor32();
|
||||
do {
|
||||
if (fPatternHandler->IsHighColor(x, y)) {
|
||||
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
||||
color.red, color.green, color.blue, cover);
|
||||
BLEND_OVER(p, color.red, color.green, color.blue, cover);
|
||||
}
|
||||
x++;
|
||||
p += 4;
|
||||
@@ -105,8 +108,7 @@ printf("DrawingModeOver::blend_vline()\n");
|
||||
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);
|
||||
BLEND_OVER(p, color.red, color.green, color.blue, *covers);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,8 +133,7 @@ printf("DrawingModeOver::blend_vline()\n");
|
||||
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);
|
||||
BLEND_OVER(p, color.red, color.green, color.blue, *covers);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,8 +160,7 @@ if (*covers && (colors->a & 0xff)) {
|
||||
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);
|
||||
BLEND_OVER(p, colors->r, colors->g, colors->b, *covers);
|
||||
}
|
||||
}
|
||||
covers++;
|
||||
@@ -181,8 +181,7 @@ if (colors->a & 0xff) {
|
||||
// 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);
|
||||
BLEND_OVER(p, colors->r, colors->g, colors->b, cover);
|
||||
p += 4;
|
||||
++colors;
|
||||
} while(--len);
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright 2005, Stephan Aßmus <[email protected]>. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* DrawingMode implementing B_OP_OVER on B_RGBA32.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DRAWING_MODE_OVER_SOLID_H
|
||||
#define DRAWING_MODE_OVER_SOLID_H
|
||||
|
||||
#include "DrawingModeOver.h"
|
||||
|
||||
template<class Order>
|
||||
class DrawingModeOverSolid : public DrawingMode {
|
||||
public:
|
||||
// constructor
|
||||
DrawingModeOverSolid()
|
||||
: DrawingMode()
|
||||
{
|
||||
}
|
||||
|
||||
// blend_pixel
|
||||
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
|
||||
{
|
||||
if (fPatternHandler->IsSolidLow())
|
||||
return;
|
||||
|
||||
uint8* p = fBuffer->row(y) + (x << 2);
|
||||
if (cover == 255) {
|
||||
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
||||
c.r, c.g, c.b);
|
||||
} else {
|
||||
BLEND_OVER(p, c.r, c.g, c.b, cover);
|
||||
}
|
||||
}
|
||||
|
||||
// blend_hline
|
||||
virtual void blend_hline(int x, int y, unsigned len,
|
||||
const color_type& c, uint8 cover)
|
||||
{
|
||||
if (fPatternHandler->IsSolidLow())
|
||||
return;
|
||||
|
||||
if(cover == 255) {
|
||||
uint32 v;
|
||||
uint8* p8 = (uint8*)&v;
|
||||
p8[Order::R] = (uint8)c.r;
|
||||
p8[Order::G] = (uint8)c.g;
|
||||
p8[Order::B] = (uint8)c.b;
|
||||
p8[Order::A] = 255;
|
||||
uint32* p32 = (uint32*)(fBuffer->row(y)) + x;
|
||||
do {
|
||||
*p32 = v;
|
||||
p32++;
|
||||
x++;
|
||||
} while(--len);
|
||||
} else {
|
||||
uint8* p = fBuffer->row(y) + (x << 2);
|
||||
do {
|
||||
BLEND_OVER(p, c.r, c.g, c.b, cover);
|
||||
x++;
|
||||
p += 4;
|
||||
} while(--len);
|
||||
}
|
||||
}
|
||||
|
||||
// blend_vline
|
||||
virtual void blend_vline(int x, int y, unsigned len,
|
||||
const color_type& c, uint8 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 uint8* covers)
|
||||
{
|
||||
if (fPatternHandler->IsSolidLow())
|
||||
return;
|
||||
|
||||
uint8* p = fBuffer->row(y) + (x << 2);
|
||||
do {
|
||||
if (*covers) {
|
||||
if (*covers == 255) {
|
||||
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
||||
c.r, c.g, c.b);
|
||||
} else {
|
||||
BLEND_OVER(p, c.r, c.g, c.b, *covers);
|
||||
}
|
||||
}
|
||||
covers++;
|
||||
p += 4;
|
||||
x++;
|
||||
} while(--len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// blend_solid_vspan
|
||||
virtual void blend_solid_vspan(int x, int y, unsigned len,
|
||||
const color_type& c, const uint8* covers)
|
||||
{
|
||||
if (fPatternHandler->IsSolidLow())
|
||||
return;
|
||||
|
||||
uint8* p = fBuffer->row(y) + (x << 2);
|
||||
do {
|
||||
if (*covers) {
|
||||
if (*covers == 255) {
|
||||
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
||||
c.r, c.g, c.b);
|
||||
} else {
|
||||
BLEND_OVER(p, c.r, c.g, c.b, *covers);
|
||||
}
|
||||
}
|
||||
covers++;
|
||||
p += fBuffer->stride();
|
||||
y++;
|
||||
} while(--len);
|
||||
}
|
||||
|
||||
|
||||
// blend_color_hspan
|
||||
virtual void blend_color_hspan(int x, int y, unsigned len,
|
||||
const color_type* colors,
|
||||
const uint8* covers,
|
||||
uint8 cover)
|
||||
{
|
||||
uint8* p = fBuffer->row(y) + (x << 2);
|
||||
if (covers) {
|
||||
// non-solid opacity
|
||||
do {
|
||||
// if (*covers) {
|
||||
if (*covers && (colors->a & 0xff)) {
|
||||
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, colors->r, colors->g, colors->b, *covers);
|
||||
}
|
||||
}
|
||||
covers++;
|
||||
p += 4;
|
||||
++colors;
|
||||
} while(--len);
|
||||
} else {
|
||||
// solid full opcacity
|
||||
if (cover == 255) {
|
||||
do {
|
||||
if (colors->a & 0xff) {
|
||||
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, 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 uint8* covers,
|
||||
uint8 cover)
|
||||
{
|
||||
printf("DrawingModeOver::blend_color_vspan()\n");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef DrawingModeOverSolid<agg::order_rgba32> DrawingModeRGBA32OverSolid;
|
||||
typedef DrawingModeOverSolid<agg::order_argb32> DrawingModeARGB32OverSolid;
|
||||
typedef DrawingModeOverSolid<agg::order_abgr32> DrawingModeABGR32OverSolid;
|
||||
typedef DrawingModeOverSolid<agg::order_bgra32> DrawingModeBGRA32OverSolid;
|
||||
|
||||
#endif // DRAWING_MODE_OVER_H
|
||||
|
||||
Reference in New Issue
Block a user