summaryrefslogtreecommitdiff
path: root/src/drivers/WinAPI
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-04-03 06:51:09 +0000
committerManolo Gouy <Manolo>2016-04-03 06:51:09 +0000
commitf1ffe2f1fee001ffb3c9327c6c09f5e5d9dc91de (patch)
tree58a67c3e8a8f8d651e358efc70d04747321c251b /src/drivers/WinAPI
parentc88af210e775d90d2537f4277909bb081a9c064a (diff)
Rewrite fl_read_image.cxx under the driver model.
Files fl_read_image_mac.cxx and fl_read_image_win32.cxx are no longer used; their content is now in Fl_XXX_Screen_Driver.cxx git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11516 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers/WinAPI')
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H1
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx100
2 files changed, 101 insertions, 0 deletions
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H
index f874750a7..a8c530fbe 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H
+++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H
@@ -71,6 +71,7 @@ public:
virtual void remove_timeout(Fl_Timeout_Handler cb, void *argp);
virtual int dnd(int unused);
virtual int compose(int &del);
+ virtual uchar *read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha);
};
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
index 7dd7df843..bf49eebd8 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
@@ -553,6 +553,106 @@ void Fl_Screen_Driver::font_name(int num, const char *name) {
s->first = 0;
}
+
+uchar * // O - Pixel buffer or NULL if failed
+Fl_WinAPI_Screen_Driver::read_win_rectangle(uchar *p, // I - Pixel buffer or NULL to allocate
+ int X, // I - Left position
+ int Y, // I - Top position
+ int w, // I - Width of area to read
+ int h, // I - Height of area to read
+ int alpha) // I - Alpha value for image (0 for none)
+{
+ int d; // Depth of image
+
+ // Allocate the image data array as needed...
+ d = alpha ? 4 : 3;
+
+ if (!p) p = new uchar[w * h * d];
+
+ // Initialize the default colors/alpha in the whole image...
+ memset(p, alpha, w * h * d);
+
+ // Grab all of the pixels in the image...
+
+ // Assure that we are not trying to read non-existing data. If it is so, the
+ // function should still work, but the out-of-bounds part of the image is
+ // untouched (initialized with the alpha value or 0 (black), resp.).
+
+ int ww = w; // We need the original width for output data line size
+
+ int shift_x = 0; // X target shift if X modified
+ int shift_y = 0; // Y target shift if X modified
+
+ if (X < 0) {
+ shift_x = -X;
+ w += X;
+ X = 0;
+ }
+ if (Y < 0) {
+ shift_y = -Y;
+ h += Y;
+ Y = 0;
+ }
+
+ if (h < 1 || w < 1) return p; // nothing to copy
+
+ int line_size = ((3*w+3)/4) * 4; // each line is aligned on a DWORD (4 bytes)
+ uchar *dib = new uchar[line_size*h]; // create temporary buffer to read DIB
+
+ // fill in bitmap info for GetDIBits
+
+ BITMAPINFO bi;
+ bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi.bmiHeader.biWidth = w;
+ bi.bmiHeader.biHeight = -h; // negative => top-down DIB
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 24; // 24 bits RGB
+ bi.bmiHeader.biCompression = BI_RGB;
+ bi.bmiHeader.biSizeImage = 0;
+ bi.bmiHeader.biXPelsPerMeter = 0;
+ bi.bmiHeader.biYPelsPerMeter = 0;
+ bi.bmiHeader.biClrUsed = 0;
+ bi.bmiHeader.biClrImportant = 0;
+
+ // copy bitmap from original DC (Window, Fl_Offscreen, ...)
+ HDC gc = (HDC)fl_graphics_driver->gc();
+ HDC hdc = CreateCompatibleDC(gc);
+ HBITMAP hbm = CreateCompatibleBitmap(gc,w,h);
+
+ int save_dc = SaveDC(hdc); // save context for cleanup
+ SelectObject(hdc,hbm); // select bitmap
+ BitBlt(hdc,0,0,w,h,gc,X,Y,SRCCOPY); // copy image section to DDB
+
+ // copy RGB image data to the allocated DIB
+
+ GetDIBits(hdc, hbm, 0, h, dib, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
+
+ // finally copy the image data to the user buffer
+
+ for (int j = 0; j<h; j++) {
+ const uchar *src = dib + j * line_size; // source line
+ uchar *tg = p + (j + shift_y) * d * ww + shift_x * d; // target line
+ for (int i = 0; i<w; i++) {
+ uchar b = *src++;
+ uchar g = *src++;
+ *tg++ = *src++; // R
+ *tg++ = g; // G
+ *tg++ = b; // B
+ if (alpha)
+ *tg++ = alpha; // alpha
+ }
+ }
+
+ // free used GDI and other structures
+
+ RestoreDC(hdc,save_dc); // reset DC
+ DeleteDC(hdc);
+ DeleteObject(hbm);
+ delete[] dib; // delete DIB temporary buffer
+
+ return p;
+}
+
//
// End of "$Id$".
// \ No newline at end of file