first simplistic implementation of drag bitmaps, drawing modes need more work, drawing text into offscreen bitmaps seems to be broken for some weird reason, B_OP_COPY actually copies the alpha value of the color as well

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15671 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-12-25 22:17:17 +00:00
parent 5a077d3f0d
commit 9d909e2556
22 changed files with 266 additions and 40 deletions
+6
View File
@@ -1335,6 +1335,12 @@ BView::DragMessage(BMessage *message, BBitmap *image,
fOwner->fLink->Attach<BPoint>(offset); fOwner->fLink->Attach<BPoint>(offset);
fOwner->fLink->Attach<int32>(bufferSize); fOwner->fLink->Attach<int32>(bufferSize);
fOwner->fLink->Attach(buffer, bufferSize); fOwner->fLink->Attach(buffer, bufferSize);
// we need to wait for the server
// to actually process this message
// before we can delete the bitmap
int32 code;
fOwner->fLink->FlushWithReply(code);
delete [] buffer; delete [] buffer;
} else { } else {
+2
View File
@@ -612,6 +612,8 @@ printf(" sending message to previous mouse target\n");
fDragMessage.MakeEmpty(); fDragMessage.MakeEmpty();
fDragMessage.what = 0; fDragMessage.what = 0;
fDraggingMessage = false; fDraggingMessage = false;
fHWInterface->SetDragBitmap(NULL, B_ORIGIN);
} }
+6
View File
@@ -1710,9 +1710,15 @@ ServerWindow::_DispatchViewMessage(int32 code,
&& dragMessage.Unflatten(buffer) == B_OK) { && dragMessage.Unflatten(buffer) == B_OK) {
// ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken); // ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken);
fDesktop->EventDispatcher().SetDragMessage(dragMessage/*, bitmap*/); fDesktop->EventDispatcher().SetDragMessage(dragMessage/*, bitmap*/);
if (ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken)) {
fDesktop->HWInterface()->SetDragBitmap(bitmap, offset);
}
} }
delete[] buffer; delete[] buffer;
} }
// sync the client (it can now delete the bitmap)
fLink.StartMessage(B_OK);
fLink.Flush();
break; break;
} }
+204 -22
View File
@@ -15,6 +15,9 @@ HWInterface::HWInterface(bool doubleBuffered)
: MultiLocker("hw interface lock"), : MultiLocker("hw interface lock"),
fCursorAreaBackup(NULL), fCursorAreaBackup(NULL),
fCursor(NULL), fCursor(NULL),
fDragBitmap(NULL),
fDragBitmapOffset(0, 0),
fCursorAndDragBitmap(NULL),
fCursorVisible(false), fCursorVisible(false),
fCursorLocation(0, 0), fCursorLocation(0, 0),
fDoubleBuffered(doubleBuffered), fDoubleBuffered(doubleBuffered),
@@ -28,6 +31,7 @@ HWInterface::~HWInterface()
{ {
delete fCursorAreaBackup; delete fCursorAreaBackup;
delete fCursor; delete fCursor;
delete fCursorAndDragBitmap;
delete fUpdateExecutor; delete fUpdateExecutor;
} }
@@ -58,20 +62,25 @@ void
HWInterface::SetCursor(ServerCursor* cursor) HWInterface::SetCursor(ServerCursor* cursor)
{ {
if (WriteLock()) { if (WriteLock()) {
if (fDragBitmap) {
// if a bitmap is being dragged,
// we don't currently allow changing
// the cursor, part of the reason being
// that the original drag bitmap is not
// around anymore... but it could be
// considered iritating to the user to
// change cursor shapes while something
// is dragged anyways.
WriteUnlock();
return;
}
if (fCursor != cursor) { if (fCursor != cursor) {
BRect oldFrame = _CursorFrame(); BRect oldFrame = _CursorFrame();
delete fCursor; delete fCursor;
delete fCursorAreaBackup;
fCursor = cursor; fCursor = cursor;
Invalidate(oldFrame); Invalidate(oldFrame);
BRect r = _CursorFrame(); BRect r = _CursorFrame();
if (fCursor && !IsDoubleBuffered()) { _AdoptDragBitmap(fDragBitmap, fDragBitmapOffset);
BRect cursorBounds = fCursor->Bounds();
fCursorAreaBackup = new buffer_clip(cursorBounds.IntegerWidth() + 1,
cursorBounds.IntegerHeight() + 1);
_DrawCursor(r);
} else
fCursorAreaBackup = NULL;
Invalidate(r); Invalidate(r);
} }
WriteUnlock(); WriteUnlock();
@@ -142,6 +151,17 @@ HWInterface::GetCursorPosition()
return location; return location;
} }
// SetDragBitmap
void
HWInterface::SetDragBitmap(const ServerBitmap* bitmap,
const BPoint& offsetFromCursor)
{
if (WriteLock()) {
_AdoptDragBitmap(bitmap, offsetFromCursor);
WriteUnlock();
}
}
// DrawingBuffer // DrawingBuffer
RenderingBuffer* RenderingBuffer*
HWInterface::DrawingBuffer() const HWInterface::DrawingBuffer() const
@@ -294,8 +314,8 @@ HWInterface::_DrawCursor(BRect area) const
src += top * srcBPR + left * 4; src += top * srcBPR + left * 4;
// offset into cursor bitmap // offset into cursor bitmap
uint8* crs = (uint8*)fCursor->Bits(); uint8* crs = (uint8*)fCursorAndDragBitmap->Bits();
uint32 crsBPR = fCursor->BytesPerRow(); uint32 crsBPR = fCursorAndDragBitmap->BytesPerRow();
// since area is clipped to cf, // since area is clipped to cf,
// the diff between top and cf.top is always positive, // the diff between top and cf.top is always positive,
// same for diff between left and cf.left // same for diff between left and cf.left
@@ -320,13 +340,15 @@ HWInterface::_DrawCursor(BRect area) const
uint8* c = crs; uint8* c = crs;
uint8* d = dst; uint8* d = dst;
uint8* b = bup; uint8* b = bup;
for (int32 x = left; x <= right; x++) { for (int32 x = left; x <= right; x++) {
*(uint32*)b = *(uint32*)s; *(uint32*)b = *(uint32*)s;
// assumes backbuffer alpha = 255 // assumes backbuffer alpha = 255
uint8 a = c[3]; // assuming pre-multiplied cursor bitmap
d[0] = (((c[0] - b[0]) * a) + (b[0] << 8)) >> 8; uint8 a = 255 - c[3];
d[1] = (((c[1] - b[1]) * a) + (b[1] << 8)) >> 8; d[0] = ((b[0] * a) >> 8) + c[0];
d[2] = (((c[2] - b[2]) * a) + (b[2] << 8)) >> 8; d[1] = ((b[1] * a) >> 8) + c[1];
d[2] = ((b[2] * a) >> 8) + c[2];
s += 4; s += 4;
c += 4; c += 4;
d += 4; d += 4;
@@ -345,10 +367,11 @@ HWInterface::_DrawCursor(BRect area) const
uint8* d = dst; uint8* d = dst;
for (int32 x = left; x <= right; x++) { for (int32 x = left; x <= right; x++) {
// assumes backbuffer alpha = 255 // assumes backbuffer alpha = 255
uint8 a = c[3]; // assuming pre-multiplied cursor bitmap
d[0] = (((c[0] - s[0]) * a) + (s[0] << 8)) >> 8; uint8 a = 255 - c[3];
d[1] = (((c[1] - s[1]) * a) + (s[1] << 8)) >> 8; d[0] = ((s[0] * a) >> 8) + c[0];
d[2] = (((c[2] - s[2]) * a) + (s[2] << 8)) >> 8; d[1] = ((s[1] * a) >> 8) + c[1];
d[2] = ((s[2] * a) >> 8) + c[2];
s += 4; s += 4;
c += 4; c += 4;
d += 4; d += 4;
@@ -358,7 +381,6 @@ HWInterface::_DrawCursor(BRect area) const
dst += width * 4; dst += width * 4;
} }
} }
// copy result to front buffer // copy result to front buffer
_CopyToFront(buffer, width * 4, left, top, right, bottom); _CopyToFront(buffer, width * 4, left, top, right, bottom);
@@ -601,9 +623,9 @@ BRect
HWInterface::_CursorFrame() const HWInterface::_CursorFrame() const
{ {
BRect frame(0.0, 0.0, -1.0, -1.0); BRect frame(0.0, 0.0, -1.0, -1.0);
if (fCursor && fCursorVisible) { if (fCursorAndDragBitmap && fCursorVisible) {
frame = fCursor->Bounds(); frame = fCursorAndDragBitmap->Bounds();
frame.OffsetTo(fCursorLocation - fCursor->GetHotSpot()); frame.OffsetTo(fCursorLocation - fCursorAndDragBitmap->GetHotSpot());
} }
return frame; return frame;
} }
@@ -624,5 +646,165 @@ HWInterface::_RestoreCursorArea() const
} }
} }
// _AdoptDragBitmap
void
HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset)
{
// TODO: support other colorspaces/convert bitmap
if (bitmap && (bitmap->ColorSpace() != B_RGB32 && bitmap->ColorSpace() != B_RGBA32)) {
fprintf(stderr, "HWInterface::_AdoptDragBitmap() - bitmap has yet unsupported colorspace\n");
return;
}
_RestoreCursorArea();
if (fCursorAndDragBitmap != fCursor) {
delete fCursorAndDragBitmap;
fCursorAndDragBitmap = NULL;
}
if (bitmap) {
BRect bitmapFrame = bitmap->Bounds();
if (fCursor) {
// put bitmap frame and cursor frame into the same
// coordinate space (the cursor location is the origin)
bitmapFrame.OffsetTo(BPoint(-offset.x, -offset.y));
BRect cursorFrame(fCursor->Bounds());
BPoint hotspot(fCursor->GetHotSpot());
// the hotspot is at the origin
cursorFrame.OffsetTo(-hotspot.x, -hotspot.y);
BRect combindedBounds = bitmapFrame | cursorFrame;
BPoint shift;
shift.x = -combindedBounds.left;
shift.y = -combindedBounds.top;
combindedBounds.OffsetBy(shift);
cursorFrame.OffsetBy(shift);
bitmapFrame.OffsetBy(shift);
fCursorAndDragBitmap = new ServerCursor(combindedBounds,
bitmap->ColorSpace(), 0,
hotspot + shift);
// clear the combined buffer
uint8* dst = (uint8*)fCursorAndDragBitmap->Bits();
uint32 dstBPR = fCursorAndDragBitmap->BytesPerRow();
memset(dst, 0, fCursorAndDragBitmap->BitsLength());
// put drag bitmap into combined buffer
uint8* src = (uint8*)bitmap->Bits();
uint32 srcBPR = bitmap->BytesPerRow();
dst += (int32)bitmapFrame.top * dstBPR + (int32)bitmapFrame.left * 4;
uint32 width = bitmapFrame.IntegerWidth() + 1;
uint32 height = bitmapFrame.IntegerHeight() + 1;
for (uint32 y = 0; y < height; y++) {
memcpy(dst, src, srcBPR);
dst += dstBPR;
src += srcBPR;
}
// compose cursor into combined buffer
dst = (uint8*)fCursorAndDragBitmap->Bits();
dst += (int32)cursorFrame.top * dstBPR + (int32)cursorFrame.left * 4;
src = (uint8*)fCursor->Bits();
srcBPR = fCursor->BytesPerRow();
width = cursorFrame.IntegerWidth() + 1;
height = cursorFrame.IntegerHeight() + 1;
for (uint32 y = 0; y < height; y++) {
uint8* d = dst;
uint8* s = src;
for (uint32 x = 0; x < width; x++) {
// takes two semi-transparent pixels
// with unassociated alpha (not pre-multiplied)
// and produces a premultiplied
if (s[3] > 0) {
if (s[3] == 255) {
d[0] = s[0];
d[1] = s[1];
d[2] = s[2];
d[3] = 255;
} else {
uint8 alphaRest = 255 - s[3];
uint32 alphaTemp = (65025 - alphaRest * (255 - d[3]));
uint32 alphaDest = d[3] * alphaRest;
uint32 alphaSrc = 255 * s[3];
d[0] = (d[0] * alphaDest + s[0] * alphaSrc) / alphaTemp;
d[1] = (d[1] * alphaDest + s[1] * alphaSrc) / alphaTemp;
d[2] = (d[2] * alphaDest + s[2] * alphaSrc) / alphaTemp;
d[3] = alphaTemp / 255;
}
}
// TODO: make sure the alpha is always upside down,
// then it doesn't need to be done when drawing the cursor
// (see _DrawCursor())
// d[3] = 255 - d[3];
d += 4;
s += 4;
}
dst += dstBPR;
src += srcBPR;
}
// handle pre-multiplication with alpha
// for faster compositing during cursor drawing
width = combindedBounds.IntegerWidth() + 1;
height = combindedBounds.IntegerHeight() + 1;
dst = (uint8*)fCursorAndDragBitmap->Bits();
for (uint32 y = 0; y < height; y++) {
uint8* d = dst;
for (uint32 x = 0; x < width; x++) {
d[0] = (d[0] * d[3]) >> 8;
d[1] = (d[1] * d[3]) >> 8;
d[2] = (d[2] * d[3]) >> 8;
d += 4;
}
dst += dstBPR;
}
} else {
fCursorAndDragBitmap = new ServerCursor(bitmap->Bits(),
bitmapFrame.IntegerWidth() + 1,
bitmapFrame.IntegerHeight() + 1,
bitmap->ColorSpace());
fCursorAndDragBitmap->SetHotSpot(BPoint(-offset.x, -offset.y));
}
} else {
fCursorAndDragBitmap = fCursor;
}
// TODO: handle reference counting stuff
// if (fDragBitmap)
// fDragBitmap->Release();
fDragBitmap = bitmap;
fDragBitmapOffset = offset;
// if (fDragBitmap)
// fDragBitmap->Aquire();
delete fCursorAreaBackup;
fCursorAreaBackup = NULL;
if (!fCursorAndDragBitmap)
return;
if (fCursorAndDragBitmap && !IsDoubleBuffered()) {
BRect cursorBounds = fCursorAndDragBitmap->Bounds();
fCursorAreaBackup = new buffer_clip(cursorBounds.IntegerWidth() + 1,
cursorBounds.IntegerHeight() + 1);
}
_DrawCursor(_CursorFrame());
}
+9
View File
@@ -17,6 +17,7 @@
class RenderingBuffer; class RenderingBuffer;
class RGBColor; class RGBColor;
class ServerBitmap;
class ServerCursor; class ServerCursor;
class UpdateQueue; class UpdateQueue;
class BString; class BString;
@@ -82,6 +83,9 @@ class HWInterface : public MultiLocker {
const float& y); const float& y);
BPoint GetCursorPosition(); BPoint GetCursorPosition();
void SetDragBitmap(const ServerBitmap* bitmap,
const BPoint& offsetFromCursor);
// frame buffer access (you need to ReadLock!) // frame buffer access (you need to ReadLock!)
RenderingBuffer* DrawingBuffer() const; RenderingBuffer* DrawingBuffer() const;
virtual RenderingBuffer* FrontBuffer() const = 0; virtual RenderingBuffer* FrontBuffer() const = 0;
@@ -123,6 +127,8 @@ class HWInterface : public MultiLocker {
BRect _CursorFrame() const; BRect _CursorFrame() const;
void _RestoreCursorArea() const; void _RestoreCursorArea() const;
void _AdoptDragBitmap(const ServerBitmap* bitmap,
const BPoint& offset);
// If we draw the cursor somewhere in the drawing buffer, // If we draw the cursor somewhere in the drawing buffer,
// we need to backup its contents before drawing, so that // we need to backup its contents before drawing, so that
@@ -158,6 +164,9 @@ class HWInterface : public MultiLocker {
buffer_clip* fCursorAreaBackup; buffer_clip* fCursorAreaBackup;
ServerCursor* fCursor; ServerCursor* fCursor;
const ServerBitmap* fDragBitmap;
BPoint fDragBitmapOffset;
ServerCursor* fCursorAndDragBitmap;
bool fCursorVisible; bool fCursorVisible;
BPoint fCursorLocation; BPoint fCursorLocation;
bool fDoubleBuffered; bool fDoubleBuffered;
+11 -7
View File
@@ -380,7 +380,6 @@ Painter::StraightLine(BPoint a, BPoint b, const rgb_color& c) const
} else if (a.y == b.y) { } else if (a.y == b.y) {
// horizontal // horizontal
uint32 bpr = fBuffer->stride();
int32 y = (int32)a.y; int32 y = (int32)a.y;
uint8* dst = fBuffer->row(y); uint8* dst = fBuffer->row(y);
int32 x1 = (int32)min_c(a.x, b.x); int32 x1 = (int32)min_c(a.x, b.x);
@@ -699,7 +698,7 @@ Painter::FillRect(const BRect& r, const rgb_color& c) const
color.data8[0] = c.blue; color.data8[0] = c.blue;
color.data8[1] = c.green; color.data8[1] = c.green;
color.data8[2] = c.red; color.data8[2] = c.red;
color.data8[3] = 255; color.data8[3] = c.alpha;
// fill rects, iterate over clipping boxes // fill rects, iterate over clipping boxes
fBaseRenderer->first_clip_box(); fBaseRenderer->first_clip_box();
do { do {
@@ -1106,25 +1105,30 @@ Painter::_SetRendererColor(const rgb_color& color) const
#if ALIASED_DRAWING #if ALIASED_DRAWING
fOutlineRenderer->line_color(agg::rgba(color.red / 255.0, fOutlineRenderer->line_color(agg::rgba(color.red / 255.0,
color.green / 255.0, color.green / 255.0,
color.blue / 255.0)); color.blue / 255.0,
color.alpha / 255.0));
#else #else
fOutlineRenderer->color(agg::rgba(color.red / 255.0, fOutlineRenderer->color(agg::rgba(color.red / 255.0,
color.green / 255.0, color.green / 255.0,
color.blue / 255.0)); color.blue / 255.0,
color.alpha / 255.0));
#endif // ALIASED_DRAWING #endif // ALIASED_DRAWING
#endif // USE_OUTLINE_RASTERIZER #endif // USE_OUTLINE_RASTERIZER
if (fRenderer) if (fRenderer)
fRenderer->color(agg::rgba(color.red / 255.0, fRenderer->color(agg::rgba(color.red / 255.0,
color.green / 255.0, color.green / 255.0,
color.blue / 255.0)); color.blue / 255.0,
color.alpha / 255.0));
if (fFontRendererSolid) if (fFontRendererSolid)
fFontRendererSolid->color(agg::rgba(color.red / 255.0, fFontRendererSolid->color(agg::rgba(color.red / 255.0,
color.green / 255.0, color.green / 255.0,
color.blue / 255.0)); color.blue / 255.0,
color.alpha / 255.0));
if (fFontRendererBin) if (fFontRendererBin)
fFontRendererBin->color(agg::rgba(color.red / 255.0, fFontRendererBin->color(agg::rgba(color.red / 255.0,
color.green / 255.0, color.green / 255.0,
color.blue / 255.0)); color.blue / 255.0,
color.alpha / 255.0));
} }
@@ -34,6 +34,7 @@ union pixel32 {
d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 8)) >> 8); \ d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 8)) >> 8); \
d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 8)) >> 8); \ d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 8)) >> 8); \
d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 8)) >> 8); \ d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 8)) >> 8); \
d[3] = 255; \
} }
// BLEND_FROM // BLEND_FROM
@@ -48,6 +49,7 @@ union pixel32 {
d[0] = (((((b2) - (b1)) * (a)) + ((b1) << 8)) >> 8); \ d[0] = (((((b2) - (b1)) * (a)) + ((b1) << 8)) >> 8); \
d[1] = (((((g2) - (g1)) * (a)) + ((g1) << 8)) >> 8); \ d[1] = (((((g2) - (g1)) * (a)) + ((g1) << 8)) >> 8); \
d[2] = (((((r2) - (r1)) * (a)) + ((r1) << 8)) >> 8); \ d[2] = (((((r2) - (r1)) * (a)) + ((r1) << 8)) >> 8); \
d[3] = 255; \
} }
// BLEND16 // BLEND16
@@ -63,6 +65,7 @@ union pixel32 {
d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 16)) >> 16); \ d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 16)) >> 16); \
d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 16)) >> 16); \ d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 16)) >> 16); \
d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 16)) >> 16); \ d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 16)) >> 16); \
d[3] = 255; \
} }
@@ -31,6 +31,7 @@
d[0] = min_c(255, _p.data8[0] + (b)); \ d[0] = min_c(255, _p.data8[0] + (b)); \
d[1] = min_c(255, _p.data8[1] + (g)); \ d[1] = min_c(255, _p.data8[1] + (g)); \
d[2] = min_c(255, _p.data8[2] + (r)); \ d[2] = min_c(255, _p.data8[2] + (r)); \
d[3] = 255; \
} }
@@ -23,6 +23,7 @@
d[0] = (r); \ d[0] = (r); \
d[1] = (g); \ d[1] = (g); \
d[2] = (b); \ d[2] = (b); \
d[3] = 255; \
} }
// blend_pixel_alpha_cc // blend_pixel_alpha_cc
@@ -23,6 +23,7 @@
d[0] = (b); \ d[0] = (b); \
d[1] = (g); \ d[1] = (g); \
d[2] = (r); \ d[2] = (r); \
d[3] = 255; \
} }
// blend_pixel_alpha_co // blend_pixel_alpha_co
@@ -23,6 +23,7 @@
d[0] = (b); \ d[0] = (b); \
d[1] = (g); \ d[1] = (g); \
d[2] = (r); \ d[2] = (r); \
d[3] = 255; \
} }
// blend_pixel_alpha_pc // blend_pixel_alpha_pc
@@ -23,6 +23,7 @@
d[0] = (b); \ d[0] = (b); \
d[1] = (g); \ d[1] = (g); \
d[2] = (r); \ d[2] = (r); \
d[3] = 255; \
} }
// blend_pixel_alpha_po // blend_pixel_alpha_po
@@ -30,6 +30,7 @@
d[0] = (_p.data8[0] + (b)) >> 1; \ d[0] = (_p.data8[0] + (b)) >> 1; \
d[1] = (_p.data8[1] + (g)) >> 1; \ d[1] = (_p.data8[1] + (g)) >> 1; \
d[2] = (_p.data8[2] + (r)) >> 1; \ d[2] = (_p.data8[2] + (r)) >> 1; \
d[3] = 255; \
} }
// blend_pixel_blend // blend_pixel_blend
@@ -18,11 +18,12 @@
} }
// ASSIGN_COPY // ASSIGN_COPY
#define ASSIGN_COPY(d, r, g, b) \ #define ASSIGN_COPY(d, r, g, b, a) \
{ \ { \
d[0] = (b); \ d[0] = (b); \
d[1] = (g); \ d[1] = (g); \
d[2] = (r); \ d[2] = (r); \
d[3] = (a); \
} }
@@ -34,7 +35,7 @@ blend_pixel_copy(int x, int y, const color_type& c, uint8 cover,
uint8* p = buffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
rgb_color color = pattern->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (cover == 255) { if (cover == 255) {
ASSIGN_COPY(p, color.red, color.green, color.blue); ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha);
} else { } else {
rgb_color l = pattern->LowColor().GetColor32(); rgb_color l = pattern->LowColor().GetColor32();
BLEND_COPY(p, color.red, color.green, color.blue, cover, BLEND_COPY(p, color.red, color.green, color.blue, cover,
@@ -101,7 +102,7 @@ blend_solid_hspan_copy(int x, int y, unsigned len,
rgb_color color = pattern->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_COPY(p, color.red, color.green, color.blue); ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha);
} else { } else {
BLEND_COPY(p, color.red, color.green, color.blue, *covers, BLEND_COPY(p, color.red, color.green, color.blue, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
@@ -127,7 +128,7 @@ blend_solid_vspan_copy(int x, int y, unsigned len,
rgb_color color = pattern->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_COPY(p, color.red, color.green, color.blue); ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha);
} else { } else {
BLEND_COPY(p, color.red, color.green, color.blue, *covers, BLEND_COPY(p, color.red, color.green, color.blue, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
@@ -153,7 +154,7 @@ blend_color_hspan_copy(int x, int y, unsigned len, const color_type* colors,
do { do {
if(*covers) { if(*covers) {
if(*covers == 255) { if(*covers == 255) {
ASSIGN_COPY(p, colors->r, colors->g, colors->b); ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
} else { } else {
BLEND_COPY(p, colors->r, colors->g, colors->b, *covers, BLEND_COPY(p, colors->r, colors->g, colors->b, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
@@ -167,7 +168,7 @@ blend_color_hspan_copy(int x, int y, unsigned len, const color_type* colors,
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_COPY(p, colors->r, colors->g, colors->b); ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
@@ -18,7 +18,7 @@ blend_pixel_copy_solid(int x, int y, const color_type& c, uint8 cover,
{ {
uint8* p = buffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) { if (cover == 255) {
ASSIGN_COPY(p, c.r, c.g, c.b); ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
} else { } else {
rgb_color l = pattern->LowColor().GetColor32(); rgb_color l = pattern->LowColor().GetColor32();
BLEND_COPY(p, c.r, c.g, c.b, cover, BLEND_COPY(p, c.r, c.g, c.b, cover,
@@ -69,7 +69,7 @@ blend_solid_hspan_copy_solid(int x, int y, unsigned len,
do { do {
if (*covers) { if (*covers) {
if(*covers == 255) { if(*covers == 255) {
ASSIGN_COPY(p, c.r, c.g, c.b); ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
} else { } else {
BLEND_COPY(p, c.r, c.g, c.b, *covers, BLEND_COPY(p, c.r, c.g, c.b, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
@@ -94,7 +94,7 @@ blend_solid_vspan_copy_solid(int x, int y, unsigned len,
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_COPY(p, c.r, c.g, c.b); ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
} else { } else {
BLEND_COPY(p, c.r, c.g, c.b, *covers, BLEND_COPY(p, c.r, c.g, c.b, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
@@ -121,7 +121,7 @@ blend_color_hspan_copy_solid(int x, int y, unsigned len,
do { do {
if(*covers) { if(*covers) {
if(*covers == 255) { if(*covers == 255) {
ASSIGN_COPY(p, colors->r, colors->g, colors->b); ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
} else { } else {
BLEND_COPY(p, colors->r, colors->g, colors->b, *covers, BLEND_COPY(p, colors->r, colors->g, colors->b, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
@@ -135,7 +135,7 @@ blend_color_hspan_copy_solid(int x, int y, unsigned len,
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_COPY(p, colors->r, colors->g, colors->b); ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
@@ -23,6 +23,7 @@
d[0] = (b); \ d[0] = (b); \
d[1] = (g); \ d[1] = (g); \
d[2] = (r); \ d[2] = (r); \
d[3] = 255; \
} }
// blend_pixel_erase // blend_pixel_erase
@@ -27,6 +27,7 @@
d[0] = 255 - _p.data8[0]; \ d[0] = 255 - _p.data8[0]; \
d[1] = 255 - _p.data8[1]; \ d[1] = 255 - _p.data8[1]; \
d[2] = 255 - _p.data8[2]; \ d[2] = 255 - _p.data8[2]; \
d[3] = 255; \
} }
// blend_pixel_invert // blend_pixel_invert
@@ -31,6 +31,7 @@
d[0] = max_c(_p.data8[0], (b)); \ d[0] = max_c(_p.data8[0], (b)); \
d[1] = max_c(_p.data8[1], (g)); \ d[1] = max_c(_p.data8[1], (g)); \
d[2] = max_c(_p.data8[2], (r)); \ d[2] = max_c(_p.data8[2], (r)); \
d[3] = 255; \
} }
@@ -25,6 +25,7 @@
d[0] = min_c(_p.data8[0], (b)); \ d[0] = min_c(_p.data8[0], (b)); \
d[1] = min_c(_p.data8[1], (g)); \ d[1] = min_c(_p.data8[1], (g)); \
d[2] = min_c(_p.data8[2], (r)); \ d[2] = min_c(_p.data8[2], (r)); \
d[3] = 255; \
} }
@@ -23,6 +23,7 @@
d[0] = (b); \ d[0] = (b); \
d[1] = (g); \ d[1] = (g); \
d[2] = (r); \ d[2] = (r); \
d[3] = 255; \
} }
// blend_pixel_over // blend_pixel_over
@@ -23,6 +23,7 @@
d[0] = (b); \ d[0] = (b); \
d[1] = (g); \ d[1] = (g); \
d[2] = (r); \ d[2] = (r); \
d[3] = 255; \
} }
// compare // compare
@@ -33,6 +33,7 @@
d[0] = max_c(0, _p.data8[0] - (b)); \ d[0] = max_c(0, _p.data8[0] - (b)); \
d[1] = max_c(0, _p.data8[1] - (g)); \ d[1] = max_c(0, _p.data8[1] - (g)); \
d[2] = max_c(0, _p.data8[2] - (r)); \ d[2] = max_c(0, _p.data8[2] - (r)); \
d[3] = 255; \
} }