summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Wey2012-01-02 16:55:11 +0100
committerMike Wey2012-01-02 16:55:11 +0100
commitc7acbf8a060f91d585c7a48d2562ebf7f9241f48 (patch)
tree48d03ebb194610137e79b694aaebf0458233b85b
parent210970a92f2b01ebc91ccee68493ed0733a2868d (diff)
parentc17126a686f8191b19ab8ed6be1b1f4117df3b30 (diff)
Merge branch 'WindowsDisplay'
-rw-r--r--dmagick/Array.d18
-rw-r--r--dmagick/Image.d14
-rw-r--r--dmagick/internal/Windows.d216
-rw-r--r--examples/draw.d2
-rw-r--r--windows.mak4
5 files changed, 246 insertions, 8 deletions
diff --git a/dmagick/Array.d b/dmagick/Array.d
index 62f17fa..339de5c 100644
--- a/dmagick/Array.d
+++ b/dmagick/Array.d
@@ -31,6 +31,8 @@ import dmagick.c.montage;
import dmagick.c.statistic;
import dmagick.c.quantize;
+version(Windows) import dmagick.internal.Windows;
+
/// See_Also: $(CXREF layer, _ImageLayerMethod)
public alias dmagick.c.layer.ImageLayerMethod ImageLayerMethod;
@@ -165,12 +167,20 @@ void compositeLayers(
*/
void display(Image[] images)
{
- linkImages(images);
- scope(exit) unlinkImages(images);
+ version(Windows)
+ {
+ Window win = new Window(images);
+ win.display();
+ }
+ else
+ {
+ linkImages(images);
+ scope(exit) unlinkImages(images);
- DisplayImages(images[0].options.imageInfo, images[0].imageRef);
+ DisplayImages(images[0].options.imageInfo, images[0].imageRef);
- DMagickException.throwException(&(images[0].imageRef.exception));
+ DMagickException.throwException(&(images[0].imageRef.exception));
+ }
}
/**
diff --git a/dmagick/Image.d b/dmagick/Image.d
index 86c2a5b..b68c220 100644
--- a/dmagick/Image.d
+++ b/dmagick/Image.d
@@ -25,6 +25,8 @@ import dmagick.ImageView;
import dmagick.Options;
import dmagick.Utils;
+version(Windows) import dmagick.internal.Windows;
+
//Import all translated c headers.
import dmagick.c.MagickCore;
@@ -1178,9 +1180,17 @@ class Image
*/
void display()
{
- DisplayImages(options.imageInfo, imageRef);
+ version(Windows)
+ {
+ Window win = new Window(this);
+ win.display();
+ }
+ else
+ {
+ DisplayImages(options.imageInfo, imageRef);
- DMagickException.throwException(&(imageRef.exception));
+ DMagickException.throwException(&(imageRef.exception));
+ }
}
/**
diff --git a/dmagick/internal/Windows.d b/dmagick/internal/Windows.d
new file mode 100644
index 0000000..3d7628e
--- /dev/null
+++ b/dmagick/internal/Windows.d
@@ -0,0 +1,216 @@
+/**
+ * Copyright: Mike Wey 2011
+ * License: zlib (See accompanying LICENSE file)
+ * Authors: Mike Wey
+ */
+
+module dmagick.internal.Windows;
+
+import core.sys.windows.windows;
+
+import dmagick.Image;
+import dmagick.Exception;
+import dmagick.Geometry;
+
+class Window
+{
+ Image image;
+ Image[] imageList;
+ size_t index;
+ size_t height;
+ size_t width;
+
+ WNDCLASS wndclass;
+ HINSTANCE hInstance;
+ BITMAPINFO bmi; // bitmap header
+ HWND hwnd;
+ MSG msg;
+
+ static Window[HWND] windows;
+
+ /**
+ * Create an window foe displaying an image.
+ */
+ this(Image image)
+ {
+ this.image = image;
+
+ height = image.rows;
+ width = image.columns;
+
+ hInstance = cast(HINSTANCE) GetModuleHandleA(null);
+
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = &WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInstance;
+ wndclass.hIcon = LoadIconA(null, IDI_APPLICATION);
+ wndclass.hCursor = LoadCursorA(null, IDC_ARROW);
+ wndclass.hbrBackground = null;
+ wndclass.lpszMenuName = null;
+ wndclass.lpszClassName = "DMagick";
+
+ if (!RegisterClassA(&wndclass))
+ throw new DMagickException("Displaying images requires Windows NT!");
+
+ RECT rect = RECT(0,0, width,height);
+ AdjustWindowRect(&rect, WS_CAPTION | WS_SYSMENU, false);
+
+ hwnd = CreateWindowA("DMagick", "DMagick", WS_CAPTION | WS_SYSMENU,
+ CW_USEDEFAULT, CW_USEDEFAULT, rect.right-rect.left, rect.bottom-rect.top,
+ null, null, hInstance, null);
+
+ // setup bitmap info
+ bmi.bmiHeader.biSize = BITMAPINFOHEADER.sizeof;
+ bmi.bmiHeader.biWidth = width;
+ bmi.bmiHeader.biHeight = -height; // must be inverted so Y axis is at top
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32; // four 8-bit components
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = width * height * 4;
+
+ windows[hwnd] = this;
+ }
+
+ /**
+ * Create an window foe displaying an animation
+ * or a collection of images.
+ */
+ this(Image[] images)
+ {
+ this(images[0]);
+
+ imageList = images;
+ index = 0;
+ }
+
+ /**
+ * Open the window and display the image.
+ */
+ void display()
+ {
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ UpdateWindow(hwnd);
+
+ if ( imageList !is null )
+ {
+ UINT delay = cast(UINT)image.animationDelay.total!"msecs"();
+
+ if ( delay == 0 )
+ delay = 1000;
+
+ SetTimer(hwnd, 0, delay, null);
+ }
+
+ while (GetMessageA(&msg, null, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessageA(&msg);
+ }
+ }
+
+ extern(Windows) static LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+ {
+ switch (message)
+ {
+ case WM_ERASEBKGND: // don't redraw bg
+ return 1;
+
+ case WM_PAINT:
+ windows[hwnd].draw();
+ return 0;
+
+ case WM_TIMER:
+ windows[hwnd].nextFrame();
+ return 0;
+
+ case WM_DESTROY:
+ windows[hwnd] = null;
+ PostQuitMessage(0);
+ return 0;
+
+ default:
+ }
+
+ return DefWindowProcA(hwnd, message, wParam, lParam);
+ }
+
+ /**
+ * Draw the image on the window.
+ */
+ void draw()
+ {
+ HDC hdc; // handle of the DC we will create
+ HDC hdcwnd; // DC for the window
+ HBITMAP hbitmap; // bitmap handle
+ PAINTSTRUCT ps;
+ VOID* pvBits; // pointer to DIB section
+ ULONG ulWindowWidth, ulWindowHeight; // window width/height
+ RECT rt; // used for getting window dimensions
+
+ // get window dimensions
+ GetClientRect(hwnd, &rt);
+
+ // calculate window width/height
+ ulWindowWidth = rt.right - rt.left;
+ ulWindowHeight = rt.bottom - rt.top;
+
+ // make sure we have at least some window size
+ if (ulWindowWidth < 1 || ulWindowHeight < 1)
+ return;
+
+ // Get DC for window
+ hdcwnd = BeginPaint(hwnd, &ps);
+
+ // create a DC for our bitmap -- the source DC for BitBlt
+ hdc = CreateCompatibleDC(hdcwnd);
+
+ // create our DIB section and select the bitmap into the dc
+ hbitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pvBits, null, 0x0);
+ SelectObject(hdc, hbitmap);
+
+ enum channels = "BGRA"; // win32 uses BGR(A)
+ Geometry area = Geometry(width, height);
+ byte[] arr = (cast(byte*)pvBits)[0 .. (area.width * area.height) * channels.length];
+ image.exportPixels(area, arr, channels);
+
+ BitBlt(hdcwnd, 0, 0, width, height, hdc, 0, 0, SRCCOPY);
+
+ DeleteObject(hbitmap);
+ DeleteDC(hdc);
+ EndPaint(hwnd, &ps);
+ }
+
+ /**
+ * Setup the next frame, and invalidate the window so its repainted.
+ */
+ void nextFrame()
+ {
+ if (++index == imageList.length)
+ index = 0;
+
+ image = imageList[index];
+
+ UINT delay = cast(UINT)image.animationDelay.total!"msecs"();
+
+ if ( delay == 0 )
+ delay = 1000;
+
+ SetTimer(hwnd, 0, delay, null);
+ InvalidateRect(hwnd,null,false);
+ }
+}
+
+pragma(lib, "gdi32.lib");
+
+const AC_SRC_OVER = 0x00;
+const AC_SRC_ALPHA = 0x01;
+
+enum DWORD BI_RGB = 0;
+enum UINT DIB_RGB_COLORS = 0;
+
+extern(Windows) BOOL BitBlt(HDC, int, int, int, int, HDC, int, int, DWORD);
+extern(Windows) HBITMAP CreateCompatibleBitmap(HDC, int, int);
+extern(Windows) HBITMAP CreateDIBSection(HDC, const(BITMAPINFO)*, UINT, void**, HANDLE, DWORD);
+extern(Windows) UINT_PTR SetTimer(HWND, UINT_PTR, UINT, TIMERPROC); \ No newline at end of file
diff --git a/examples/draw.d b/examples/draw.d
index deed525..6839dba 100644
--- a/examples/draw.d
+++ b/examples/draw.d
@@ -64,7 +64,7 @@ void main()
dc.fill(cylinderTop);
dc.roundRectangle(progressXmax - (2 * wc), progressYmin, progressXmax, progressYmax, wc, hc);
- dc.font("Helvetica");
+ dc.fontFamily("Sans");
dc.fontSize(fontsize);
dc.stroke(textShadow);
dc.fill(textColor);
diff --git a/windows.mak b/windows.mak
index ebf57c1..5b0edeb 100644
--- a/windows.mak
+++ b/windows.mak
@@ -108,7 +108,9 @@ SOURCE= \
dmagick\c\type.d \
dmagick\c\utility.d \
dmagick\c\xmlTree.d \
- dmagick\c\xwindow.d
+ dmagick\c\xwindow.d \
+ \
+ dmagick\internal\Windows.d \
################## DOCS ####################################