diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index f2a53ee6b4..02aa9c61f3 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -1335,6 +1335,12 @@ BView::DragMessage(BMessage *message, BBitmap *image, fOwner->fLink->Attach(offset); fOwner->fLink->Attach(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 { diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index 8d6466ed3d..aad03bab6b 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -612,6 +612,8 @@ printf(" sending message to previous mouse target\n"); fDragMessage.MakeEmpty(); fDragMessage.what = 0; fDraggingMessage = false; + + fHWInterface->SetDragBitmap(NULL, B_ORIGIN); } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 8c096f68a9..3d7536087d 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -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; } diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index 685ee8e38c..96eac1e63f 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -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()); +} + + diff --git a/src/servers/app/drawing/HWInterface.h b/src/servers/app/drawing/HWInterface.h index 8c7deb980f..c69dbf3dbf 100644 --- a/src/servers/app/drawing/HWInterface.h +++ b/src/servers/app/drawing/HWInterface.h @@ -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; diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index d2367fa9d1..c86b6d6365 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -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)); } diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h index bb0c6f33a1..c1b10e62c9 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h @@ -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; \ } diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAdd.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAdd.h index 8de6b09993..aa0e4b412c 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAdd.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAdd.h @@ -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; \ } diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCC.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCC.h index 5bda866f0f..b8f09915c9 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCC.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCC.h @@ -23,6 +23,7 @@ d[0] = (r); \ d[1] = (g); \ d[2] = (b); \ + d[3] = 255; \ } // blend_pixel_alpha_cc diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCO.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCO.h index 24a861f07b..a2e1a33757 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCO.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCO.h @@ -23,6 +23,7 @@ d[0] = (b); \ d[1] = (g); \ d[2] = (r); \ + d[3] = 255; \ } // blend_pixel_alpha_co diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h index 9ca4cfc818..2c64894782 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h @@ -23,6 +23,7 @@ d[0] = (b); \ d[1] = (g); \ d[2] = (r); \ + d[3] = 255; \ } // blend_pixel_alpha_pc diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h index 95f4922a04..9fd0b46c6d 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h @@ -23,6 +23,7 @@ d[0] = (b); \ d[1] = (g); \ d[2] = (r); \ + d[3] = 255; \ } // blend_pixel_alpha_po diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlend.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlend.h index b5ce08b1b6..55000b3268 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlend.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlend.h @@ -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 diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopy.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopy.h index 2ae43269c3..6eed677903 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopy.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopy.h @@ -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); diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h index 0a1bc2a0ff..b1a4170526 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h @@ -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); diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h index 4f58b64238..3ede73a681 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h @@ -23,6 +23,7 @@ d[0] = (b); \ d[1] = (g); \ d[2] = (r); \ + d[3] = 255; \ } // blend_pixel_erase diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h index 23c153a3f8..cfa8418212 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h @@ -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 diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMax.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMax.h index 118d38d356..983040ed80 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMax.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMax.h @@ -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; \ } diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMin.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMin.h index f6e4e67e41..d143b48cee 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMin.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMin.h @@ -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; \ } diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h index ab0d4cd2f5..7e595911ee 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h @@ -23,6 +23,7 @@ d[0] = (b); \ d[1] = (g); \ d[2] = (r); \ + d[3] = 255; \ } // blend_pixel_over diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelect.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelect.h index 7a434fc322..662bff7b7c 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelect.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelect.h @@ -23,6 +23,7 @@ d[0] = (b); \ d[1] = (g); \ d[2] = (r); \ + d[3] = 255; \ } // compare diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtract.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtract.h index a7347a1ce5..6683c8ad88 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtract.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtract.h @@ -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; \ }