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;
|
class PatternHandler;
|
||||||
|
|
||||||
|
union pixel32 {
|
||||||
|
uint32 data32;
|
||||||
|
uint8 data8[4];
|
||||||
|
};
|
||||||
|
|
||||||
// BLEND
|
// BLEND
|
||||||
//
|
//
|
||||||
// This macro assumes source alpha in range 0..255 and
|
// This macro assumes source alpha in range 0..255 and
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "DrawingModeMax.h"
|
#include "DrawingModeMax.h"
|
||||||
#include "DrawingModeMin.h"
|
#include "DrawingModeMin.h"
|
||||||
#include "DrawingModeOver.h"
|
#include "DrawingModeOver.h"
|
||||||
|
#include "DrawingModeOverSolid.h"
|
||||||
#include "DrawingModeSelect.h"
|
#include "DrawingModeSelect.h"
|
||||||
#include "DrawingModeSubtract.h"
|
#include "DrawingModeSubtract.h"
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
// constructor
|
// constructor
|
||||||
DrawingModeFactory::DrawingModeFactory()
|
DrawingModeFactory::DrawingModeFactory()
|
||||||
: fDrawingModeBGRA32Over(new DrawingModeBGRA32Over()),
|
: fDrawingModeBGRA32Over(new DrawingModeBGRA32Over()),
|
||||||
|
fDrawingModeBGRA32OverSolid(new DrawingModeBGRA32OverSolid()),
|
||||||
fDrawingModeBGRA32Erase(new DrawingModeBGRA32Erase()),
|
fDrawingModeBGRA32Erase(new DrawingModeBGRA32Erase()),
|
||||||
fDrawingModeBGRA32Invert(new DrawingModeBGRA32Invert()),
|
fDrawingModeBGRA32Invert(new DrawingModeBGRA32Invert()),
|
||||||
fDrawingModeBGRA32Select(new DrawingModeBGRA32Select()),
|
fDrawingModeBGRA32Select(new DrawingModeBGRA32Select()),
|
||||||
@@ -51,6 +53,7 @@ DrawingModeFactory::DrawingModeFactory()
|
|||||||
DrawingModeFactory::~DrawingModeFactory()
|
DrawingModeFactory::~DrawingModeFactory()
|
||||||
{
|
{
|
||||||
delete fDrawingModeBGRA32Over;
|
delete fDrawingModeBGRA32Over;
|
||||||
|
delete fDrawingModeBGRA32OverSolid;
|
||||||
delete fDrawingModeBGRA32Erase;
|
delete fDrawingModeBGRA32Erase;
|
||||||
delete fDrawingModeBGRA32Invert;
|
delete fDrawingModeBGRA32Invert;
|
||||||
delete fDrawingModeBGRA32Select;
|
delete fDrawingModeBGRA32Select;
|
||||||
@@ -78,7 +81,10 @@ DrawingModeFactory::DrawingModeFor(drawing_mode mode,
|
|||||||
// these drawing modes discard source pixels
|
// these drawing modes discard source pixels
|
||||||
// which have the current low color
|
// which have the current low color
|
||||||
case B_OP_OVER:
|
case B_OP_OVER:
|
||||||
return fDrawingModeBGRA32Over;
|
if (solid)
|
||||||
|
return fDrawingModeBGRA32OverSolid;
|
||||||
|
else
|
||||||
|
return fDrawingModeBGRA32Over;
|
||||||
break;
|
break;
|
||||||
case B_OP_ERASE:
|
case B_OP_ERASE:
|
||||||
return fDrawingModeBGRA32Erase;
|
return fDrawingModeBGRA32Erase;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class DrawingModeFactory {
|
|||||||
bool solid = false);
|
bool solid = false);
|
||||||
private:
|
private:
|
||||||
DrawingMode* fDrawingModeBGRA32Over;
|
DrawingMode* fDrawingModeBGRA32Over;
|
||||||
|
DrawingMode* fDrawingModeBGRA32OverSolid;
|
||||||
DrawingMode* fDrawingModeBGRA32Erase;
|
DrawingMode* fDrawingModeBGRA32Erase;
|
||||||
DrawingMode* fDrawingModeBGRA32Invert;
|
DrawingMode* fDrawingModeBGRA32Invert;
|
||||||
DrawingMode* fDrawingModeBGRA32Select;
|
DrawingMode* fDrawingModeBGRA32Select;
|
||||||
|
|||||||
@@ -12,9 +12,14 @@
|
|||||||
#include "DrawingMode.h"
|
#include "DrawingMode.h"
|
||||||
|
|
||||||
// BLEND_OVER
|
// 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
|
// ASSIGN_OVER
|
||||||
@@ -46,8 +51,7 @@ class DrawingModeOver : public DrawingMode {
|
|||||||
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
||||||
color.red, color.green, color.blue);
|
color.red, color.green, color.blue);
|
||||||
} else {
|
} else {
|
||||||
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
BLEND_OVER(p, color.red, color.green, color.blue, cover);
|
||||||
color.red, color.green, color.blue, cover);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,8 +80,7 @@ class DrawingModeOver : public DrawingMode {
|
|||||||
rgb_color color = fPatternHandler->HighColor().GetColor32();
|
rgb_color color = fPatternHandler->HighColor().GetColor32();
|
||||||
do {
|
do {
|
||||||
if (fPatternHandler->IsHighColor(x, y)) {
|
if (fPatternHandler->IsHighColor(x, y)) {
|
||||||
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
BLEND_OVER(p, color.red, color.green, color.blue, cover);
|
||||||
color.red, color.green, color.blue, cover);
|
|
||||||
}
|
}
|
||||||
x++;
|
x++;
|
||||||
p += 4;
|
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],
|
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
||||||
color.red, color.green, color.blue);
|
color.red, color.green, color.blue);
|
||||||
} else {
|
} else {
|
||||||
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
BLEND_OVER(p, color.red, color.green, color.blue, *covers);
|
||||||
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],
|
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
||||||
color.red, color.green, color.blue);
|
color.red, color.green, color.blue);
|
||||||
} else {
|
} else {
|
||||||
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
BLEND_OVER(p, color.red, color.green, color.blue, *covers);
|
||||||
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],
|
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
||||||
colors->r, colors->g, colors->b);
|
colors->r, colors->g, colors->b);
|
||||||
} else {
|
} else {
|
||||||
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
BLEND_OVER(p, colors->r, colors->g, colors->b, *covers);
|
||||||
colors->r, colors->g, colors->b, *covers);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
covers++;
|
covers++;
|
||||||
@@ -181,8 +181,7 @@ if (colors->a & 0xff) {
|
|||||||
// solid partial opacity
|
// solid partial opacity
|
||||||
} else if (cover) {
|
} else if (cover) {
|
||||||
do {
|
do {
|
||||||
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
|
BLEND_OVER(p, colors->r, colors->g, colors->b, cover);
|
||||||
colors->r, colors->g, colors->b, cover);
|
|
||||||
p += 4;
|
p += 4;
|
||||||
++colors;
|
++colors;
|
||||||
} while(--len);
|
} 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