#if wxUSE_NANOX
#undef wxHAVE_LIB_XPM
#define wxHAVE_LIB_XPM 0
+
+// Copy from the drawable to the wxImage
+bool wxGetImageFromDrawable(GR_DRAW_ID drawable, int srcX, int srcY, int width, int height, wxImage& image);
#endif
#if wxUSE_XPM
M_BMPDATA->m_height = height;
#if wxUSE_NANOX
- M_BMPDATA->m_bitmap = (WXPixmap) GrNewPixmap(width, height, NULL);
+ M_BMPDATA->m_pixmap = (WXPixmap) GrNewPixmap(width, height, NULL);
M_BMPDATA->m_bpp = bpp;
- wxASSERT_MSG( M_BMPDATA->m_bitmap, wxT("Bitmap creation failed") );
+ wxASSERT_MSG( M_BMPDATA->m_pixmap, wxT("Bitmap creation failed") );
#else
if (depth == 1)
{
if (!Create(w, h, depth))
return FALSE;
- wxMemoryDC memDC;
- memDC.SelectObject(*this);
+ // Unfortunately the mask has to be screen-depth since
+ // 1-bpp bitmaps don't seem to be supported
+ // TODO: implement transparent drawing, presumably
+ // by doing several blits as per the Windows
+ // implementation because Nano-X doesn't support
+ // XSetClipMask.
+ // TODO: could perhaps speed this function up
+ // by making a buffer of pixel values,
+ // and then calling GrArea to write that to the
+ // pixmap. See demos/nxroach.c.
+
+ bool hasMask = image.HasMask();
+
+ GC pixmapGC = GrNewGC();
+ Pixmap pixmap = (Pixmap) GetPixmap();
+
+ GC maskGC = 0;
+ Pixmap maskPixmap = 0;
- // Warning: this is very inefficient.
- wxPen pen;
- pen.SetStyle(wxSOLID);
- pen.SetWidth(1);
+ unsigned char maskR = 0;
+ unsigned char maskG = 0;
+ unsigned char maskB = 0;
+
+ if (hasMask)
+ {
+ maskR = image.GetMaskRed();
+ maskG = image.GetMaskGreen();
+ maskB = image.GetMaskBlue();
+
+ maskGC = GrNewGC();
+ maskPixmap = GrNewPixmap(w, h, 0);
+ if (!maskPixmap)
+ hasMask = FALSE;
+ else
+ {
+ wxMask* mask = new wxMask;
+ mask->SetBitmap((WXPixmap) maskPixmap);
+ SetMask(mask);
+ }
+ }
+
+ GR_COLOR lastPixmapColour = 0;
+ GR_COLOR lastMaskColour = 0;
int i, j;
for (i = 0; i < w; i++)
unsigned char red = image.GetRed(i, j);
unsigned char green = image.GetGreen(i, j);
unsigned char blue = image.GetBlue(i, j);
- wxColour colour(red, green, blue);
- pen.SetColour(colour);
- memDC.SetPen(pen);
- memDC.DrawPoint(i, j);
+ GR_COLOR colour = GR_RGB(red, green, blue);
+
+ // Efficiency measure
+ if (colour != lastPixmapColour || (i == 0 && j == 0))
+ {
+ GrSetGCForeground(pixmapGC, colour);
+ lastPixmapColour = colour;
+ }
+
+ GrPoint(pixmap, pixmapGC, i, j);
-#if 0
if (hasMask)
{
// scan the bitmap for the transparent colour and set the corresponding
// pixels in the mask to BLACK and the rest to WHITE
if (maskR == red && maskG == green && maskB == blue)
- ::SetPixel(hMaskDC, i, j, PALETTERGB(0, 0, 0));
+ {
+ colour = GR_RGB(0, 0, 0);
+ }
else
- ::SetPixel(hMaskDC, i, j, PALETTERGB(255, 255, 255));
+ {
+ colour = GR_RGB(255, 255, 255);
+ }
+ if (colour != lastMaskColour || (i == 0 && j == 0))
+ {
+ GrSetGCForeground(maskGC, colour);
+ lastMaskColour = colour;
+ }
+ GrPoint(maskPixmap, maskGC, i, j);
}
-#endif
}
}
- memDC.SelectObject(wxNullBitmap);
+
+ GrDestroyGC(pixmapGC);
+ if (hasMask)
+ GrDestroyGC(maskGC);
return TRUE;
#else
if (image.HasMask())
{
GC gc = XCreateGC( xdisplay, (Pixmap) GetMask()->GetBitmap(), 0, NULL );
- XPutImage( xdisplay, (Pixmap) GetMask()->GetBitmap(), gc, data_image, 0, 0, 0, 0, width, height );
+ XPutImage( xdisplay, (Pixmap) GetMask()->GetBitmap(), gc, mask_image, 0, 0, 0, 0, width, height );
XDestroyImage( mask_image );
XFreeGC( xdisplay, gc );
int bpp = DefaultDepth( xdisplay, xscreen );
#if wxUSE_NANOX
- int w = image.GetWidth();
- int h = image.GetHeight();
-
- wxMemoryDC memDC;
- memDC.SelectObject(*this);
-
- wxColour pixelCol;
-
- // Warning: this is very inefficient.
- int i, j;
- for (i = 0; i < w; i++)
- {
- for (j = 0; j < h; j++)
- {
- memDC.GetPixel(i, j, & pixelCol);
-
- // TODO: make wxColour accessors more efficient
- // by inlining, if possible
- image.SetRGB(i, j,
- pixelCol.Red(), pixelCol.Green(),
- pixelCol.Blue());
- }
- }
- memDC.SelectObject(wxNullBitmap);
-
+ wxGetImageFromDrawable((Pixmap) GetPixmap(), 0, 0, GetWidth(), GetHeight(), image);
return image;
-
#else
// !wxUSE_NANOX
XImage *x_image = NULL;
return M_BMPDATA->m_display;
}
+#if wxUSE_NANOX
+// Copy from the drawable to the wxImage
+bool wxGetImageFromDrawable(GR_DRAW_ID drawable, int srcX, int srcY, int width, int height, wxImage& image)
+{
+ GR_SCREEN_INFO sinfo;
+ int x, y;
+ GR_PIXELVAL *pixels;
+ GR_PALETTE* palette = NULL;
+ unsigned char rgb[3], *pp;
+
+ GrGetScreenInfo(&sinfo);
+
+ if (sinfo.pixtype == MWPF_PALETTE) {
+ if(!(palette = (GR_PALETTE*) malloc(sizeof(GR_PALETTE)))) {
+ return FALSE;
+ }
+ GrGetSystemPalette(palette);
+ }
+
+ if(!(pixels = (GR_PIXELVAL*) malloc(sizeof(GR_PIXELVAL) * width * height)))
+ {
+ return FALSE;
+ }
+
+ image.Create(width, height);
+
+ GrReadArea(drawable, srcX, srcY, width, height,
+ pixels);
+
+
+ for(x = 0; x < sinfo.cols; x++) {
+
+ pp = (unsigned char *)pixels +
+ ((x + (y * sinfo.cols)) *
+ sizeof(GR_PIXELVAL));
+
+ switch(sinfo.pixtype) {
+ /* FIXME: These may need modifying on big endian. */
+ case MWPF_TRUECOLOR0888:
+ case MWPF_TRUECOLOR888:
+ rgb[0] = pp[2];
+ rgb[1] = pp[1];
+ rgb[2] = pp[0];
+ break;
+ case MWPF_PALETTE:
+ rgb[0] = palette->palette[pp[0]].r;
+ rgb[1] = palette->palette[pp[0]].g;
+ rgb[2] = palette->palette[pp[0]].b;
+ break;
+ case MWPF_TRUECOLOR565:
+ rgb[0] = pp[1] & 0xf8;
+ rgb[1] = ((pp[1] & 0x07) << 5) |
+ ((pp[0] & 0xe0) >> 3);
+ rgb[2] = (pp[0] & 0x1f) << 3;
+ break;
+ case MWPF_TRUECOLOR555:
+ rgb[0] = (pp[1] & 0x7c) << 1;
+ rgb[1] = ((pp[1] & 0x03) << 6) |
+ ((pp[0] & 0xe0) >> 2);
+ rgb[2] = (pp[0] & 0x1f) << 3;
+ break;
+ case MWPF_TRUECOLOR332:
+ rgb[0] = pp[0] & 0xe0;
+ rgb[1] = (pp[0] & 0x1c) << 3;
+ rgb[2] = (pp[0] & 0x03) << 6;
+ break;
+ default:
+ fprintf(stderr, "Unsupported pixel "
+ "format\n");
+ return 1;
+ }
+
+ image.SetRGB(x, y, rgb[0], rgb[1], rgb[2]);
+
+ }
+
+ free(pixels);
+ if(palette) free(palette);
+
+ return TRUE;
+}
+
+#if 0
+int GrGetPixelColor(GR_SCREEN_INFO* sinfo, GR_PALETTE* palette, GR_PIXELVAL pixel,
+ unsigned char* red, unsigned char* green, unsigned char* blue)
+{
+ unsigned char rgb[3], *pp;
+
+ pp = (unsigned char*) & pixel ;
+
+ switch (sinfo.pixtype)
+ {
+ /* FIXME: These may need modifying on big endian. */
+ case MWPF_TRUECOLOR0888:
+ case MWPF_TRUECOLOR888:
+ rgb[0] = pp[2];
+ rgb[1] = pp[1];
+ rgb[2] = pp[0];
+ break;
+ case MWPF_PALETTE:
+ rgb[0] = palette->palette[pp[0]].r;
+ rgb[1] = palette->palette[pp[0]].g;
+ rgb[2] = palette->palette[pp[0]].b;
+ break;
+ case MWPF_TRUECOLOR565:
+ rgb[0] = pp[1] & 0xf8;
+ rgb[1] = ((pp[1] & 0x07) << 5) |
+ ((pp[0] & 0xe0) >> 3);
+ rgb[2] = (pp[0] & 0x1f) << 3;
+ break;
+ case MWPF_TRUECOLOR555:
+ rgb[0] = (pp[1] & 0x7c) << 1;
+ rgb[1] = ((pp[1] & 0x03) << 6) |
+ ((pp[0] & 0xe0) >> 2);
+ rgb[2] = (pp[0] & 0x1f) << 3;
+ break;
+ case MWPF_TRUECOLOR332:
+ rgb[0] = pp[0] & 0xe0;
+ rgb[1] = (pp[0] & 0x1c) << 3;
+ rgb[2] = (pp[0] & 0x03) << 6;
+ break;
+ default:
+ fprintf(stderr, "Unsupported pixel format\n");
+ return 0;
+ }
+
+
+ *(red) = rgb[0];
+ *(green) = rgb[1];
+ *(blue) = rgb[2];
+ return 1;
+}
+#endif
+
+#endif
+ // wxUSE_NANOX
+