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:
@@ -1335,6 +1335,12 @@ BView::DragMessage(BMessage *message, BBitmap *image,
|
||||
fOwner->fLink->Attach<BPoint>(offset);
|
||||
fOwner->fLink->Attach<int32>(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;
|
||||
} else {
|
||||
|
||||
@@ -612,6 +612,8 @@ printf(" sending message to previous mouse target\n");
|
||||
fDragMessage.MakeEmpty();
|
||||
fDragMessage.what = 0;
|
||||
fDraggingMessage = false;
|
||||
|
||||
fHWInterface->SetDragBitmap(NULL, B_ORIGIN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1710,9 +1710,15 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
&& dragMessage.Unflatten(buffer) == B_OK) {
|
||||
// ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken);
|
||||
fDesktop->EventDispatcher().SetDragMessage(dragMessage/*, bitmap*/);
|
||||
if (ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken)) {
|
||||
fDesktop->HWInterface()->SetDragBitmap(bitmap, offset);
|
||||
}
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
// sync the client (it can now delete the bitmap)
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Flush();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ HWInterface::HWInterface(bool doubleBuffered)
|
||||
: MultiLocker("hw interface lock"),
|
||||
fCursorAreaBackup(NULL),
|
||||
fCursor(NULL),
|
||||
fDragBitmap(NULL),
|
||||
fDragBitmapOffset(0, 0),
|
||||
fCursorAndDragBitmap(NULL),
|
||||
fCursorVisible(false),
|
||||
fCursorLocation(0, 0),
|
||||
fDoubleBuffered(doubleBuffered),
|
||||
@@ -28,6 +31,7 @@ HWInterface::~HWInterface()
|
||||
{
|
||||
delete fCursorAreaBackup;
|
||||
delete fCursor;
|
||||
delete fCursorAndDragBitmap;
|
||||
delete fUpdateExecutor;
|
||||
}
|
||||
|
||||
@@ -58,20 +62,25 @@ void
|
||||
HWInterface::SetCursor(ServerCursor* cursor)
|
||||
{
|
||||
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) {
|
||||
BRect oldFrame = _CursorFrame();
|
||||
delete fCursor;
|
||||
delete fCursorAreaBackup;
|
||||
fCursor = cursor;
|
||||
Invalidate(oldFrame);
|
||||
BRect r = _CursorFrame();
|
||||
if (fCursor && !IsDoubleBuffered()) {
|
||||
BRect cursorBounds = fCursor->Bounds();
|
||||
fCursorAreaBackup = new buffer_clip(cursorBounds.IntegerWidth() + 1,
|
||||
cursorBounds.IntegerHeight() + 1);
|
||||
_DrawCursor(r);
|
||||
} else
|
||||
fCursorAreaBackup = NULL;
|
||||
_AdoptDragBitmap(fDragBitmap, fDragBitmapOffset);
|
||||
Invalidate(r);
|
||||
}
|
||||
WriteUnlock();
|
||||
@@ -142,6 +151,17 @@ HWInterface::GetCursorPosition()
|
||||
return location;
|
||||
}
|
||||
|
||||
// SetDragBitmap
|
||||
void
|
||||
HWInterface::SetDragBitmap(const ServerBitmap* bitmap,
|
||||
const BPoint& offsetFromCursor)
|
||||
{
|
||||
if (WriteLock()) {
|
||||
_AdoptDragBitmap(bitmap, offsetFromCursor);
|
||||
WriteUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
// DrawingBuffer
|
||||
RenderingBuffer*
|
||||
HWInterface::DrawingBuffer() const
|
||||
@@ -294,8 +314,8 @@ HWInterface::_DrawCursor(BRect area) const
|
||||
src += top * srcBPR + left * 4;
|
||||
|
||||
// offset into cursor bitmap
|
||||
uint8* crs = (uint8*)fCursor->Bits();
|
||||
uint32 crsBPR = fCursor->BytesPerRow();
|
||||
uint8* crs = (uint8*)fCursorAndDragBitmap->Bits();
|
||||
uint32 crsBPR = fCursorAndDragBitmap->BytesPerRow();
|
||||
// since area is clipped to cf,
|
||||
// the diff between top and cf.top is always positive,
|
||||
// same for diff between left and cf.left
|
||||
@@ -320,13 +340,15 @@ HWInterface::_DrawCursor(BRect area) const
|
||||
uint8* c = crs;
|
||||
uint8* d = dst;
|
||||
uint8* b = bup;
|
||||
|
||||
for (int32 x = left; x <= right; x++) {
|
||||
*(uint32*)b = *(uint32*)s;
|
||||
// assumes backbuffer alpha = 255
|
||||
uint8 a = c[3];
|
||||
d[0] = (((c[0] - b[0]) * a) + (b[0] << 8)) >> 8;
|
||||
d[1] = (((c[1] - b[1]) * a) + (b[1] << 8)) >> 8;
|
||||
d[2] = (((c[2] - b[2]) * a) + (b[2] << 8)) >> 8;
|
||||
// assuming pre-multiplied cursor bitmap
|
||||
uint8 a = 255 - c[3];
|
||||
d[0] = ((b[0] * a) >> 8) + c[0];
|
||||
d[1] = ((b[1] * a) >> 8) + c[1];
|
||||
d[2] = ((b[2] * a) >> 8) + c[2];
|
||||
s += 4;
|
||||
c += 4;
|
||||
d += 4;
|
||||
@@ -345,10 +367,11 @@ HWInterface::_DrawCursor(BRect area) const
|
||||
uint8* d = dst;
|
||||
for (int32 x = left; x <= right; x++) {
|
||||
// assumes backbuffer alpha = 255
|
||||
uint8 a = c[3];
|
||||
d[0] = (((c[0] - s[0]) * a) + (s[0] << 8)) >> 8;
|
||||
d[1] = (((c[1] - s[1]) * a) + (s[1] << 8)) >> 8;
|
||||
d[2] = (((c[2] - s[2]) * a) + (s[2] << 8)) >> 8;
|
||||
// assuming pre-multiplied cursor bitmap
|
||||
uint8 a = 255 - c[3];
|
||||
d[0] = ((s[0] * a) >> 8) + c[0];
|
||||
d[1] = ((s[1] * a) >> 8) + c[1];
|
||||
d[2] = ((s[2] * a) >> 8) + c[2];
|
||||
s += 4;
|
||||
c += 4;
|
||||
d += 4;
|
||||
@@ -358,7 +381,6 @@ HWInterface::_DrawCursor(BRect area) const
|
||||
dst += width * 4;
|
||||
}
|
||||
}
|
||||
|
||||
// copy result to front buffer
|
||||
_CopyToFront(buffer, width * 4, left, top, right, bottom);
|
||||
|
||||
@@ -601,9 +623,9 @@ BRect
|
||||
HWInterface::_CursorFrame() const
|
||||
{
|
||||
BRect frame(0.0, 0.0, -1.0, -1.0);
|
||||
if (fCursor && fCursorVisible) {
|
||||
frame = fCursor->Bounds();
|
||||
frame.OffsetTo(fCursorLocation - fCursor->GetHotSpot());
|
||||
if (fCursorAndDragBitmap && fCursorVisible) {
|
||||
frame = fCursorAndDragBitmap->Bounds();
|
||||
frame.OffsetTo(fCursorLocation - fCursorAndDragBitmap->GetHotSpot());
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
class RenderingBuffer;
|
||||
class RGBColor;
|
||||
class ServerBitmap;
|
||||
class ServerCursor;
|
||||
class UpdateQueue;
|
||||
class BString;
|
||||
@@ -82,6 +83,9 @@ class HWInterface : public MultiLocker {
|
||||
const float& y);
|
||||
BPoint GetCursorPosition();
|
||||
|
||||
void SetDragBitmap(const ServerBitmap* bitmap,
|
||||
const BPoint& offsetFromCursor);
|
||||
|
||||
// frame buffer access (you need to ReadLock!)
|
||||
RenderingBuffer* DrawingBuffer() const;
|
||||
virtual RenderingBuffer* FrontBuffer() const = 0;
|
||||
@@ -123,6 +127,8 @@ class HWInterface : public MultiLocker {
|
||||
|
||||
BRect _CursorFrame() const;
|
||||
void _RestoreCursorArea() const;
|
||||
void _AdoptDragBitmap(const ServerBitmap* bitmap,
|
||||
const BPoint& offset);
|
||||
|
||||
// If we draw the cursor somewhere in the drawing buffer,
|
||||
// we need to backup its contents before drawing, so that
|
||||
@@ -158,6 +164,9 @@ class HWInterface : public MultiLocker {
|
||||
buffer_clip* fCursorAreaBackup;
|
||||
|
||||
ServerCursor* fCursor;
|
||||
const ServerBitmap* fDragBitmap;
|
||||
BPoint fDragBitmapOffset;
|
||||
ServerCursor* fCursorAndDragBitmap;
|
||||
bool fCursorVisible;
|
||||
BPoint fCursorLocation;
|
||||
bool fDoubleBuffered;
|
||||
|
||||
@@ -380,7 +380,6 @@ Painter::StraightLine(BPoint a, BPoint b, const rgb_color& c) const
|
||||
|
||||
} else if (a.y == b.y) {
|
||||
// horizontal
|
||||
uint32 bpr = fBuffer->stride();
|
||||
int32 y = (int32)a.y;
|
||||
uint8* dst = fBuffer->row(y);
|
||||
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[1] = c.green;
|
||||
color.data8[2] = c.red;
|
||||
color.data8[3] = 255;
|
||||
color.data8[3] = c.alpha;
|
||||
// fill rects, iterate over clipping boxes
|
||||
fBaseRenderer->first_clip_box();
|
||||
do {
|
||||
@@ -1106,25 +1105,30 @@ Painter::_SetRendererColor(const rgb_color& color) const
|
||||
#if ALIASED_DRAWING
|
||||
fOutlineRenderer->line_color(agg::rgba(color.red / 255.0,
|
||||
color.green / 255.0,
|
||||
color.blue / 255.0));
|
||||
color.blue / 255.0,
|
||||
color.alpha / 255.0));
|
||||
#else
|
||||
fOutlineRenderer->color(agg::rgba(color.red / 255.0,
|
||||
color.green / 255.0,
|
||||
color.blue / 255.0));
|
||||
color.blue / 255.0,
|
||||
color.alpha / 255.0));
|
||||
#endif // ALIASED_DRAWING
|
||||
#endif // USE_OUTLINE_RASTERIZER
|
||||
if (fRenderer)
|
||||
fRenderer->color(agg::rgba(color.red / 255.0,
|
||||
color.green / 255.0,
|
||||
color.blue / 255.0));
|
||||
color.blue / 255.0,
|
||||
color.alpha / 255.0));
|
||||
if (fFontRendererSolid)
|
||||
fFontRendererSolid->color(agg::rgba(color.red / 255.0,
|
||||
color.green / 255.0,
|
||||
color.blue / 255.0));
|
||||
color.blue / 255.0,
|
||||
color.alpha / 255.0));
|
||||
if (fFontRendererBin)
|
||||
fFontRendererBin->color(agg::rgba(color.red / 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[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 8)) >> 8); \
|
||||
d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 8)) >> 8); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// BLEND_FROM
|
||||
@@ -48,6 +49,7 @@ union pixel32 {
|
||||
d[0] = (((((b2) - (b1)) * (a)) + ((b1) << 8)) >> 8); \
|
||||
d[1] = (((((g2) - (g1)) * (a)) + ((g1) << 8)) >> 8); \
|
||||
d[2] = (((((r2) - (r1)) * (a)) + ((r1) << 8)) >> 8); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// BLEND16
|
||||
@@ -63,6 +65,7 @@ union pixel32 {
|
||||
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[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[1] = min_c(255, _p.data8[1] + (g)); \
|
||||
d[2] = min_c(255, _p.data8[2] + (r)); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
d[0] = (r); \
|
||||
d[1] = (g); \
|
||||
d[2] = (b); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// blend_pixel_alpha_cc
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
d[0] = (b); \
|
||||
d[1] = (g); \
|
||||
d[2] = (r); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// blend_pixel_alpha_co
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
d[0] = (b); \
|
||||
d[1] = (g); \
|
||||
d[2] = (r); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// blend_pixel_alpha_pc
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
d[0] = (b); \
|
||||
d[1] = (g); \
|
||||
d[2] = (r); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// blend_pixel_alpha_po
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
d[0] = (_p.data8[0] + (b)) >> 1; \
|
||||
d[1] = (_p.data8[1] + (g)) >> 1; \
|
||||
d[2] = (_p.data8[2] + (r)) >> 1; \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// blend_pixel_blend
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
}
|
||||
|
||||
// ASSIGN_COPY
|
||||
#define ASSIGN_COPY(d, r, g, b) \
|
||||
#define ASSIGN_COPY(d, r, g, b, a) \
|
||||
{ \
|
||||
d[0] = (b); \
|
||||
d[1] = (g); \
|
||||
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);
|
||||
rgb_color color = pattern->R5ColorAt(x, y);
|
||||
if (cover == 255) {
|
||||
ASSIGN_COPY(p, color.red, color.green, color.blue);
|
||||
ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha);
|
||||
} else {
|
||||
rgb_color l = pattern->LowColor().GetColor32();
|
||||
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);
|
||||
if (*covers) {
|
||||
if (*covers == 255) {
|
||||
ASSIGN_COPY(p, color.red, color.green, color.blue);
|
||||
ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha);
|
||||
} else {
|
||||
BLEND_COPY(p, color.red, color.green, color.blue, *covers,
|
||||
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);
|
||||
if (*covers) {
|
||||
if (*covers == 255) {
|
||||
ASSIGN_COPY(p, color.red, color.green, color.blue);
|
||||
ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha);
|
||||
} else {
|
||||
BLEND_COPY(p, color.red, color.green, color.blue, *covers,
|
||||
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 {
|
||||
if(*covers) {
|
||||
if(*covers == 255) {
|
||||
ASSIGN_COPY(p, colors->r, colors->g, colors->b);
|
||||
ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
|
||||
} else {
|
||||
BLEND_COPY(p, colors->r, colors->g, colors->b, *covers,
|
||||
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
|
||||
if (cover == 255) {
|
||||
do {
|
||||
ASSIGN_COPY(p, colors->r, colors->g, colors->b);
|
||||
ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
|
||||
p += 4;
|
||||
++colors;
|
||||
} 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);
|
||||
if (cover == 255) {
|
||||
ASSIGN_COPY(p, c.r, c.g, c.b);
|
||||
ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
|
||||
} else {
|
||||
rgb_color l = pattern->LowColor().GetColor32();
|
||||
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 {
|
||||
if (*covers) {
|
||||
if(*covers == 255) {
|
||||
ASSIGN_COPY(p, c.r, c.g, c.b);
|
||||
ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
|
||||
} else {
|
||||
BLEND_COPY(p, c.r, c.g, c.b, *covers,
|
||||
l.red, l.green, l.blue);
|
||||
@@ -94,7 +94,7 @@ blend_solid_vspan_copy_solid(int x, int y, unsigned len,
|
||||
do {
|
||||
if (*covers) {
|
||||
if (*covers == 255) {
|
||||
ASSIGN_COPY(p, c.r, c.g, c.b);
|
||||
ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
|
||||
} else {
|
||||
BLEND_COPY(p, c.r, c.g, c.b, *covers,
|
||||
l.red, l.green, l.blue);
|
||||
@@ -121,7 +121,7 @@ blend_color_hspan_copy_solid(int x, int y, unsigned len,
|
||||
do {
|
||||
if(*covers) {
|
||||
if(*covers == 255) {
|
||||
ASSIGN_COPY(p, colors->r, colors->g, colors->b);
|
||||
ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
|
||||
} else {
|
||||
BLEND_COPY(p, colors->r, colors->g, colors->b, *covers,
|
||||
l.red, l.green, l.blue);
|
||||
@@ -135,7 +135,7 @@ blend_color_hspan_copy_solid(int x, int y, unsigned len,
|
||||
// solid full opcacity
|
||||
if (cover == 255) {
|
||||
do {
|
||||
ASSIGN_COPY(p, colors->r, colors->g, colors->b);
|
||||
ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
|
||||
p += 4;
|
||||
++colors;
|
||||
} while(--len);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
d[0] = (b); \
|
||||
d[1] = (g); \
|
||||
d[2] = (r); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// blend_pixel_erase
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
d[0] = 255 - _p.data8[0]; \
|
||||
d[1] = 255 - _p.data8[1]; \
|
||||
d[2] = 255 - _p.data8[2]; \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// blend_pixel_invert
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
d[0] = max_c(_p.data8[0], (b)); \
|
||||
d[1] = max_c(_p.data8[1], (g)); \
|
||||
d[2] = max_c(_p.data8[2], (r)); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
d[0] = min_c(_p.data8[0], (b)); \
|
||||
d[1] = min_c(_p.data8[1], (g)); \
|
||||
d[2] = min_c(_p.data8[2], (r)); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
d[0] = (b); \
|
||||
d[1] = (g); \
|
||||
d[2] = (r); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// blend_pixel_over
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
d[0] = (b); \
|
||||
d[1] = (g); \
|
||||
d[2] = (r); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
// compare
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
d[0] = max_c(0, _p.data8[0] - (b)); \
|
||||
d[1] = max_c(0, _p.data8[1] - (g)); \
|
||||
d[2] = max_c(0, _p.data8[2] - (r)); \
|
||||
d[3] = 255; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user