There has been some confusion if fillRect() should accept a buffer or a pixel. This can cause misrendering if your data is not in the native endian order. A buffer makes more sense here though, and is what most of the callers are already assuming, so change the API to follow that.tags/v1.4.90
void Cursor::drawOutline(const Pixel& c) | void Cursor::drawOutline(const Pixel& c) | ||||
{ | { | ||||
Cursor outlined; | Cursor outlined; | ||||
rdr::U8 cbuf[4]; | |||||
// Create a mirror of the existing cursor | // Create a mirror of the existing cursor | ||||
outlined.setPF(getPF()); | outlined.setPF(getPF()); | ||||
outlined.hotspot = hotspot; | outlined.hotspot = hotspot; | ||||
// Clear the mirror's background to the outline colour | // Clear the mirror's background to the outline colour | ||||
outlined.fillRect(getRect(), c); | |||||
outlined.getPF().bufferFromPixel(cbuf, c); | |||||
outlined.fillRect(getRect(), cbuf); | |||||
// Blit the existing cursor, using its mask | // Blit the existing cursor, using its mask | ||||
outlined.maskRect(getRect(), data, mask.buf); | outlined.maskRect(getRect(), data, mask.buf); |
const PixelFormat& pf, const rdr::U8* colour) | const PixelFormat& pf, const rdr::U8* colour) | ||||
{ | { | ||||
ManagedPixelBuffer buffer(pf, width, height); | ManagedPixelBuffer buffer(pf, width, height); | ||||
Pixel pixel; | |||||
Palette palette; | Palette palette; | ||||
rdr::U32 palcol; | rdr::U32 palcol; | ||||
pixel = pf.pixelFromBuffer(colour); | |||||
buffer.fillRect(buffer.getRect(), pixel); | |||||
buffer.fillRect(buffer.getRect(), colour); | |||||
palcol = 0; | palcol = 0; | ||||
memcpy(&palcol, colour, pf.bpp/8); | memcpy(&palcol, colour, pf.bpp/8); |
{ | { | ||||
} | } | ||||
void ModifiablePixelBuffer::fillRect(const Rect& r, Pixel pix) | |||||
void ModifiablePixelBuffer::fillRect(const Rect& r, const void* pix) | |||||
{ | { | ||||
int stride; | int stride; | ||||
U8 *buf; | U8 *buf; | ||||
if (b == 1) { | if (b == 1) { | ||||
while (h--) { | while (h--) { | ||||
memset(buf, pix, w); | |||||
memset(buf, *(const U8*)pix, w); | |||||
buf += stride * b; | buf += stride * b; | ||||
} | } | ||||
} else { | } else { | ||||
U8 pixbuf[4], *start; | |||||
U8 *start; | |||||
int w1; | int w1; | ||||
start = buf; | start = buf; | ||||
format.bufferFromPixel(pixbuf, pix); | |||||
w1 = w; | w1 = w; | ||||
while (w1--) { | while (w1--) { | ||||
memcpy(buf, pixbuf, b); | |||||
memcpy(buf, pix, b); | |||||
buf += b; | buf += b; | ||||
} | } | ||||
buf += (stride - w) * b; | buf += (stride - w) * b; | ||||
} | } | ||||
void ModifiablePixelBuffer::fillRect(const PixelFormat& pf, const Rect &dest, | void ModifiablePixelBuffer::fillRect(const PixelFormat& pf, const Rect &dest, | ||||
Pixel pix) | |||||
const void* pix) | |||||
{ | { | ||||
fillRect(dest, format.pixelFromPixel(pf, pix)); | |||||
rdr::U8 buf[4]; | |||||
format.bufferFromBuffer(buf, pf, (const rdr::U8*)pix, 1); | |||||
fillRect(dest, buf); | |||||
} | } | ||||
void ModifiablePixelBuffer::imageRect(const PixelFormat& pf, const Rect &dest, | void ModifiablePixelBuffer::imageRect(const PixelFormat& pf, const Rect &dest, |
// These operations DO NOT clip to the pixelbuffer area, or trap overruns. | // These operations DO NOT clip to the pixelbuffer area, or trap overruns. | ||||
// Fill a rectangle | // Fill a rectangle | ||||
void fillRect(const Rect &dest, Pixel pix); | |||||
void fillRect(const Rect &dest, const void* pix); | |||||
// Copy pixel data to the buffer | // Copy pixel data to the buffer | ||||
void imageRect(const Rect &dest, const void* pixels, int stride=0); | void imageRect(const Rect &dest, const void* pixels, int stride=0); | ||||
// Render in a specific format | // Render in a specific format | ||||
// Does the exact same thing as the above methods, but the given | // Does the exact same thing as the above methods, but the given | ||||
// pixel values are defined by the given PixelFormat. | // pixel values are defined by the given PixelFormat. | ||||
void fillRect(const PixelFormat& pf, const Rect &dest, Pixel pix); | |||||
void fillRect(const PixelFormat& pf, const Rect &dest, const void* pix); | |||||
void imageRect(const PixelFormat& pf, const Rect &dest, | void imageRect(const PixelFormat& pf, const Rect &dest, | ||||
const void* pixels, int stride=0); | const void* pixels, int stride=0); | ||||
public: | public: | ||||
SStaticDesktop(const Point& size) : server(0), buffer(0) { | SStaticDesktop(const Point& size) : server(0), buffer(0) { | ||||
PixelFormat pf; | PixelFormat pf; | ||||
const rdr::U8 black[4] = { 0, 0, 0, 0 }; | |||||
buffer = new ManagedPixelBuffer(pf, size.x, size.y); | buffer = new ManagedPixelBuffer(pf, size.x, size.y); | ||||
if (buffer) buffer->fillRect(buffer->getRect(), 0); | |||||
if (buffer) | |||||
buffer->fillRect(buffer->getRect(), black); | |||||
} | } | ||||
SStaticDesktop(const Point& size, const PixelFormat& pf) : buffer(0) { | SStaticDesktop(const Point& size, const PixelFormat& pf) : buffer(0) { | ||||
const rdr::U8 black[4] = { 0, 0, 0, 0 }; | |||||
buffer = new ManagedPixelBuffer(pf, size.x, size.y); | buffer = new ManagedPixelBuffer(pf, size.x, size.y); | ||||
if (buffer) buffer->fillRect(buffer->getRect(), 0); | |||||
if (buffer) | |||||
buffer->fillRect(buffer->getRect(), black); | |||||
} | } | ||||
virtual ~SStaticDesktop() { | virtual ~SStaticDesktop() { | ||||
if (buffer) delete buffer; | if (buffer) delete buffer; |
{ | { | ||||
int nSubrects = is->readU32(); | int nSubrects = is->readU32(); | ||||
PIXEL_T bg = is->READ_PIXEL(); | PIXEL_T bg = is->READ_PIXEL(); | ||||
pb->fillRect(pf, r, bg); | |||||
pb->fillRect(pf, r, &bg); | |||||
for (int i = 0; i < nSubrects; i++) { | for (int i = 0; i < nSubrects; i++) { | ||||
PIXEL_T pix = is->READ_PIXEL(); | PIXEL_T pix = is->READ_PIXEL(); | ||||
int y = is->readU16(); | int y = is->readU16(); | ||||
int w = is->readU16(); | int w = is->readU16(); | ||||
int h = is->readU16(); | int h = is->readU16(); | ||||
pb->fillRect(pf, Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), pix); | |||||
pb->fillRect(pf, Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), &pix); | |||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
pix = is->READ_PIXEL(); | pix = is->READ_PIXEL(); | ||||
} | } | ||||
pb->fillRect(serverpf, r, pix); | |||||
pb->fillRect(serverpf, r, &pix); | |||||
return; | return; | ||||
} | } | ||||
if (palSize == 1) { | if (palSize == 1) { | ||||
PIXEL_T pix = palette[0]; | PIXEL_T pix = palette[0]; | ||||
pb->fillRect(pf, t, pix); | |||||
pb->fillRect(pf, t, &pix); | |||||
continue; | continue; | ||||
} | } | ||||
const rdr::U8* data; | const rdr::U8* data; | ||||
int stride; | int stride; | ||||
const rdr::U8 black[4] = { 0, 0, 0, 0 }; | |||||
// FIXME: Resize should probably be a feature of the pixel buffer itself | // FIXME: Resize should probably be a feature of the pixel buffer itself | ||||
if ((w == frameBuffer->width()) && (h == frameBuffer->height())) | if ((w == frameBuffer->width()) && (h == frameBuffer->height())) | ||||
rect.setXYWH(frameBuffer->width(), 0, | rect.setXYWH(frameBuffer->width(), 0, | ||||
newBuffer->width() - frameBuffer->width(), | newBuffer->width() - frameBuffer->width(), | ||||
newBuffer->height()); | newBuffer->height()); | ||||
newBuffer->fillRect(rect, 0); | |||||
newBuffer->fillRect(rect, black); | |||||
} | } | ||||
if (newBuffer->height() > frameBuffer->height()) { | if (newBuffer->height() > frameBuffer->height()) { | ||||
rect.setXYWH(0, frameBuffer->height(), | rect.setXYWH(0, frameBuffer->height(), | ||||
newBuffer->width(), | newBuffer->width(), | ||||
newBuffer->height() - frameBuffer->height()); | newBuffer->height() - frameBuffer->height()); | ||||
newBuffer->fillRect(rect, 0); | |||||
newBuffer->fillRect(rect, black); | |||||
} | } | ||||
delete frameBuffer; | delete frameBuffer; |