summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--splash/SplashState.h278
-rw-r--r--test/perf-test-preview-dummy.cc44
-rw-r--r--test/perf-test-preview-win.cc544
3 files changed, 433 insertions, 433 deletions
diff --git a/splash/SplashState.h b/splash/SplashState.h
index 13d54788..2c603531 100644
--- a/splash/SplashState.h
+++ b/splash/SplashState.h
@@ -1,139 +1,139 @@
-//========================================================================
-//
-// SplashState.h
-//
-//========================================================================
-
-//========================================================================
-//
-// Modified under the Poppler project - http://poppler.freedesktop.org
-//
-// All changes made under the Poppler project to this file are licensed
-// under GPL version 2 or later
-//
-// Copyright (C) 2011, 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
-//
-// To see a description of the changes please see the Changelog file that
-// came with your tarball or type make ChangeLog if you are building from git
-//
-//========================================================================
-
-#ifndef SPLASHSTATE_H
-#define SPLASHSTATE_H
-
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
-#include "SplashTypes.h"
-
-class SplashPattern;
-class SplashScreen;
-class SplashClip;
-class SplashBitmap;
-
-//------------------------------------------------------------------------
-// line cap values
-//------------------------------------------------------------------------
-
-#define splashLineCapButt 0
-#define splashLineCapRound 1
-#define splashLineCapProjecting 2
-
-//------------------------------------------------------------------------
-// line join values
-//------------------------------------------------------------------------
-
-#define splashLineJoinMiter 0
-#define splashLineJoinRound 1
-#define splashLineJoinBevel 2
-
-//------------------------------------------------------------------------
-// SplashState
-//------------------------------------------------------------------------
-
-class SplashState {
-public:
-
- // Create a new state object, initialized with default settings.
- SplashState(int width, int height, GBool vectorAntialias,
- SplashScreenParams *screenParams);
- SplashState(int width, int height, GBool vectorAntialias,
- SplashScreen *screenA);
-
- // Copy a state object.
- SplashState *copy() { return new SplashState(this); }
-
- ~SplashState();
-
- // Set the stroke pattern. This does not copy <strokePatternA>.
- void setStrokePattern(SplashPattern *strokePatternA);
-
- // Set the fill pattern. This does not copy <fillPatternA>.
- void setFillPattern(SplashPattern *fillPatternA);
-
- // Set the screen. This does not copy <screenA>.
- void setScreen(SplashScreen *screenA);
-
- // Set the line dash pattern. This copies the <lineDashA> array.
- void setLineDash(SplashCoord *lineDashA, int lineDashLengthA,
- SplashCoord lineDashPhaseA);
-
- // Set the soft mask bitmap.
- void setSoftMask(SplashBitmap *softMaskA);
-
- // Set the overprint parametes.
- void setFillOverprint(GBool fillOverprintA) { fillOverprint = fillOverprintA; }
- void setStrokeOverprint(GBool strokeOverprintA) { strokeOverprint = strokeOverprintA; }
- void setOverprintMode(int overprintModeA) { overprintMode = overprintModeA; }
-
- // Set the transfer function.
- void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray);
-
-private:
-
- SplashState(SplashState *state);
-
- SplashCoord matrix[6];
- SplashPattern *strokePattern;
- SplashPattern *fillPattern;
- SplashScreen *screen;
- SplashBlendFunc blendFunc;
- SplashCoord strokeAlpha;
- SplashCoord fillAlpha;
- SplashCoord lineWidth;
- int lineCap;
- int lineJoin;
- SplashCoord miterLimit;
- SplashCoord flatness;
- SplashCoord *lineDash;
- int lineDashLength;
- SplashCoord lineDashPhase;
- GBool strokeAdjust;
- SplashClip *clip;
- SplashBitmap *softMask;
- GBool deleteSoftMask;
- GBool inNonIsolatedGroup;
- GBool fillOverprint;
- GBool strokeOverprint;
- int overprintMode;
- Guchar rgbTransferR[256],
- rgbTransferG[256],
- rgbTransferB[256];
- Guchar grayTransfer[256];
-#if SPLASH_CMYK
- Guchar cmykTransferC[256],
- cmykTransferM[256],
- cmykTransferY[256],
- cmykTransferK[256];
- Guchar deviceNTransfer[SPOT_NCOMPS+4][256];
-#endif
- Guint overprintMask;
- GBool overprintAdditive;
-
- SplashState *next; // used by Splash class
-
- friend class Splash;
-};
-
-#endif
+//========================================================================
+//
+// SplashState.h
+//
+//========================================================================
+
+//========================================================================
+//
+// Modified under the Poppler project - http://poppler.freedesktop.org
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2011, 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
+//
+// To see a description of the changes please see the Changelog file that
+// came with your tarball or type make ChangeLog if you are building from git
+//
+//========================================================================
+
+#ifndef SPLASHSTATE_H
+#define SPLASHSTATE_H
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "SplashTypes.h"
+
+class SplashPattern;
+class SplashScreen;
+class SplashClip;
+class SplashBitmap;
+
+//------------------------------------------------------------------------
+// line cap values
+//------------------------------------------------------------------------
+
+#define splashLineCapButt 0
+#define splashLineCapRound 1
+#define splashLineCapProjecting 2
+
+//------------------------------------------------------------------------
+// line join values
+//------------------------------------------------------------------------
+
+#define splashLineJoinMiter 0
+#define splashLineJoinRound 1
+#define splashLineJoinBevel 2
+
+//------------------------------------------------------------------------
+// SplashState
+//------------------------------------------------------------------------
+
+class SplashState {
+public:
+
+ // Create a new state object, initialized with default settings.
+ SplashState(int width, int height, GBool vectorAntialias,
+ SplashScreenParams *screenParams);
+ SplashState(int width, int height, GBool vectorAntialias,
+ SplashScreen *screenA);
+
+ // Copy a state object.
+ SplashState *copy() { return new SplashState(this); }
+
+ ~SplashState();
+
+ // Set the stroke pattern. This does not copy <strokePatternA>.
+ void setStrokePattern(SplashPattern *strokePatternA);
+
+ // Set the fill pattern. This does not copy <fillPatternA>.
+ void setFillPattern(SplashPattern *fillPatternA);
+
+ // Set the screen. This does not copy <screenA>.
+ void setScreen(SplashScreen *screenA);
+
+ // Set the line dash pattern. This copies the <lineDashA> array.
+ void setLineDash(SplashCoord *lineDashA, int lineDashLengthA,
+ SplashCoord lineDashPhaseA);
+
+ // Set the soft mask bitmap.
+ void setSoftMask(SplashBitmap *softMaskA);
+
+ // Set the overprint parametes.
+ void setFillOverprint(GBool fillOverprintA) { fillOverprint = fillOverprintA; }
+ void setStrokeOverprint(GBool strokeOverprintA) { strokeOverprint = strokeOverprintA; }
+ void setOverprintMode(int overprintModeA) { overprintMode = overprintModeA; }
+
+ // Set the transfer function.
+ void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray);
+
+private:
+
+ SplashState(SplashState *state);
+
+ SplashCoord matrix[6];
+ SplashPattern *strokePattern;
+ SplashPattern *fillPattern;
+ SplashScreen *screen;
+ SplashBlendFunc blendFunc;
+ SplashCoord strokeAlpha;
+ SplashCoord fillAlpha;
+ SplashCoord lineWidth;
+ int lineCap;
+ int lineJoin;
+ SplashCoord miterLimit;
+ SplashCoord flatness;
+ SplashCoord *lineDash;
+ int lineDashLength;
+ SplashCoord lineDashPhase;
+ GBool strokeAdjust;
+ SplashClip *clip;
+ SplashBitmap *softMask;
+ GBool deleteSoftMask;
+ GBool inNonIsolatedGroup;
+ GBool fillOverprint;
+ GBool strokeOverprint;
+ int overprintMode;
+ Guchar rgbTransferR[256],
+ rgbTransferG[256],
+ rgbTransferB[256];
+ Guchar grayTransfer[256];
+#if SPLASH_CMYK
+ Guchar cmykTransferC[256],
+ cmykTransferM[256],
+ cmykTransferY[256],
+ cmykTransferK[256];
+ Guchar deviceNTransfer[SPOT_NCOMPS+4][256];
+#endif
+ Guint overprintMask;
+ GBool overprintAdditive;
+
+ SplashState *next; // used by Splash class
+
+ friend class Splash;
+};
+
+#endif
diff --git a/test/perf-test-preview-dummy.cc b/test/perf-test-preview-dummy.cc
index 09f7d0f8..3522d12f 100644
--- a/test/perf-test-preview-dummy.cc
+++ b/test/perf-test-preview-dummy.cc
@@ -1,22 +1,22 @@
-/* Copyright Krzysztof Kowalczyk 2006-2007
- License: GPLv2 */
-
-/* This is a no-op preview support for perf-test.
-Using this perf-test still works for performance testing, you just don't
-get any visual feedback during testing.
-*/
-
-#include "splash/SplashBitmap.h"
-
-void PreviewBitmapSplash(SplashBitmap *bmpSplash)
-{
-}
-
-void PreviewBitmapDestroy(void)
-{
-}
-
-void PreviewBitmapInit(void)
-{
-}
-
+/* Copyright Krzysztof Kowalczyk 2006-2007
+ License: GPLv2 */
+
+/* This is a no-op preview support for perf-test.
+Using this perf-test still works for performance testing, you just don't
+get any visual feedback during testing.
+*/
+
+#include "splash/SplashBitmap.h"
+
+void PreviewBitmapSplash(SplashBitmap *bmpSplash)
+{
+}
+
+void PreviewBitmapDestroy(void)
+{
+}
+
+void PreviewBitmapInit(void)
+{
+}
+
diff --git a/test/perf-test-preview-win.cc b/test/perf-test-preview-win.cc
index 2d53335e..93c73244 100644
--- a/test/perf-test-preview-win.cc
+++ b/test/perf-test-preview-win.cc
@@ -1,272 +1,272 @@
-/* Copyright Krzysztof Kowalczyk 2006-2007
- License: GPLv2 */
-
-/* This is a preview support for perf-test for Windows */
-
-#include <windows.h>
-#include <assert.h>
-
-#include "SplashBitmap.h"
-
-#define WIN_CLASS_NAME "PDFTEST_PDF_WIN"
-#define COL_WINDOW_BG RGB(0xff, 0xff, 0xff)
-
-static HWND gHwndSplash;
-static HBRUSH gBrushBg;
-
-static SplashBitmap *gBmpSplash;
-
-int rect_dx(RECT *r)
-{
- int dx = r->right - r->left;
- assert(dx >= 0);
- return dx;
-}
-
-int rect_dy(RECT *r)
-{
- int dy = r->bottom - r->top;
- assert(dy >= 0);
- return dy;
-}
-
-static HBITMAP createDIBitmapCommon(SplashBitmap *bmp, HDC hdc)
-{
- int bmpDx = bmp->getWidth();
- int bmpDy = bmp->getHeight();
- int bmpRowSize = bmp->getRowSize();
-
- BITMAPINFOHEADER bmih;
- bmih.biSize = sizeof(bmih);
- bmih.biHeight = -bmpDy;
- bmih.biWidth = bmpDx;
- bmih.biPlanes = 1;
- bmih.biBitCount = 24;
- bmih.biCompression = BI_RGB;
- bmih.biSizeImage = bmpDy * bmpRowSize;;
- bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 0;
- bmih.biClrUsed = bmih.biClrImportant = 0;
-
- unsigned char* bmpData = bmp->getDataPtr();
- HBITMAP hbmp = ::CreateDIBitmap(hdc, &bmih, CBM_INIT, bmpData, (BITMAPINFO *)&bmih , DIB_RGB_COLORS);
- return hbmp;
-}
-
-static void stretchDIBitsCommon(SplashBitmap *bmp, HDC hdc, int leftMargin, int topMargin, int pageDx, int pageDy)
-{
- int bmpDx = bmp->getWidth();
- int bmpDy = bmp->getHeight();
- int bmpRowSize = bmp->getRowSize();
-
- BITMAPINFOHEADER bmih;
- bmih.biSize = sizeof(bmih);
- bmih.biHeight = -bmpDy;
- bmih.biWidth = bmpDx;
- bmih.biPlanes = 1;
- // we could create this dibsection in monochrome
- // if the printer is monochrome, to reduce memory consumption
- // but splash is currently setup to return a full colour bitmap
- bmih.biBitCount = 24;
- bmih.biCompression = BI_RGB;
- bmih.biSizeImage = bmpDy * bmpRowSize;;
- bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 0;
- bmih.biClrUsed = bmih.biClrImportant = 0;
- SplashColorPtr bmpData = bmp->getDataPtr();
-
- ::StretchDIBits(hdc,
- // destination rectangle
- -leftMargin, -topMargin, pageDx, pageDy,
- // source rectangle
- 0, 0, bmpDx, bmpDy,
- bmpData,
- (BITMAPINFO *)&bmih ,
- DIB_RGB_COLORS,
- SRCCOPY);
-}
-
-/* Set the client area size of the window 'hwnd' to 'dx'/'dy'. */
-static void resizeClientArea(HWND hwnd, int x, int dx, int dy, int *dx_out)
-{
- RECT rc;
- GetClientRect(hwnd, &rc);
- if ((rect_dx(&rc) == dx) && (rect_dy(&rc) == dy))
- return;
-
- RECT rw;
- GetWindowRect(hwnd, &rw);
- int win_dx = rect_dx(&rw) + (dx - rect_dx(&rc));
- int win_dy = rect_dy(&rw) + (dy - rect_dy(&rc));
- SetWindowPos(hwnd, NULL, x, 0, win_dx, win_dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER);
- if (dx_out)
- *dx_out = win_dx;
-}
-
-static void resizeClientAreaToRenderedBitmap(HWND hwnd, SplashBitmap *bmp, int x, int *dxOut)
-{
- int dx = bmp->getWidth();
- int dy = bmp->getHeight();
- resizeClientArea(hwnd, x, dx, dy, dxOut);
-}
-
-static void drawBitmap(HWND hwnd, SplashBitmap *bmp)
-{
- PAINTSTRUCT ps;
-
- HDC hdc = BeginPaint(hwnd, &ps);
- SetBkMode(hdc, TRANSPARENT);
- FillRect(hdc, &ps.rcPaint, gBrushBg);
-
- HBITMAP hbmp = createDIBitmapCommon(bmp, hdc);
- if (hbmp) {
- HDC bmpDC = CreateCompatibleDC(hdc);
- if (bmpDC) {
- SelectObject(bmpDC, hbmp);
- int xSrc = 0, ySrc = 0;
- int xDest = 0, yDest = 0;
- int bmpDx = bmp->getWidth();
- int bmpDy = bmp->getHeight();
- BitBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, SRCCOPY);
- DeleteDC(bmpDC);
- bmpDC = NULL;
- }
- DeleteObject(hbmp);
- hbmp = NULL;
- }
- EndPaint(hwnd, &ps);
-}
-
-static void onPaint(HWND hwnd)
-{
- if (hwnd == gHwndSplash) {
- if (gBmpSplash) {
- drawBitmap(hwnd, gBmpSplash);
- }
- }
-}
-
-static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- switch (message)
- {
- case WM_CREATE:
- // do nothing
- break;
-
- case WM_ERASEBKGND:
- return TRUE;
-
- case WM_PAINT:
- /* it might happen that we get WM_PAINT after destroying a window */
- onPaint(hwnd);
- break;
-
- case WM_DESTROY:
- /* WM_DESTROY might be sent as a result of File\Close, in which case CloseWindow() has already been called */
- break;
-
- default:
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- return 0;
-}
-
-static BOOL registerWinClass(void)
-{
- WNDCLASSEX wcex;
- ATOM atom;
-
- wcex.cbSize = sizeof(WNDCLASSEX);
-
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = NULL;
- wcex.hIcon = NULL;
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = NULL;
- wcex.lpszMenuName = NULL;
- wcex.lpszClassName = WIN_CLASS_NAME;
- wcex.hIconSm = NULL;
-
- atom = RegisterClassEx(&wcex);
- if (atom)
- return TRUE;
- return FALSE;
-}
-
-static bool initWinIfNecessary(void)
-{
- if (gHwndSplash)
- return true;
-
- if (!registerWinClass())
- return false;
-
- gBrushBg = CreateSolidBrush(COL_WINDOW_BG);
-
- gHwndSplash = CreateWindow(
- WIN_CLASS_NAME, "Splash",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0,
- CW_USEDEFAULT, 0,
- NULL, NULL,
- NULL, NULL);
-
- if (!gHwndSplash)
- return false;
-
- ShowWindow(gHwndSplash, SW_HIDE);
- return true;
-}
-
-static void pumpMessages(void)
-{
- BOOL isMessage;
- MSG msg;
-
- for (;;) {
- isMessage = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
- if (!isMessage)
- return;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-}
-
-void PreviewBitmapInit(void)
-{
- /* no need to do anything */
-}
-
-void PreviewBitmapDestroy(void)
-{
- PostQuitMessage(0);
- pumpMessages();
- DeleteObject(gBrushBg);
-}
-
-static void UpdateWindows(void)
-{
- if (gBmpSplash) {
- resizeClientAreaToRenderedBitmap(gHwndSplash, gBmpSplash, 0, NULL);
- ShowWindow(gHwndSplash, SW_SHOW);
- InvalidateRect(gHwndSplash, NULL, FALSE);
- UpdateWindow(gHwndSplash);
- } else {
- ShowWindow(gHwndSplash, SW_HIDE);
- }
-
- pumpMessages();
-}
-
-void PreviewBitmapSplash(SplashBitmap *bmpSplash)
-{
- if (!initWinIfNecessary())
- return;
-
- gBmpSplash = bmpSplash;
- UpdateWindows();
-}
-
-
+/* Copyright Krzysztof Kowalczyk 2006-2007
+ License: GPLv2 */
+
+/* This is a preview support for perf-test for Windows */
+
+#include <windows.h>
+#include <assert.h>
+
+#include "SplashBitmap.h"
+
+#define WIN_CLASS_NAME "PDFTEST_PDF_WIN"
+#define COL_WINDOW_BG RGB(0xff, 0xff, 0xff)
+
+static HWND gHwndSplash;
+static HBRUSH gBrushBg;
+
+static SplashBitmap *gBmpSplash;
+
+int rect_dx(RECT *r)
+{
+ int dx = r->right - r->left;
+ assert(dx >= 0);
+ return dx;
+}
+
+int rect_dy(RECT *r)
+{
+ int dy = r->bottom - r->top;
+ assert(dy >= 0);
+ return dy;
+}
+
+static HBITMAP createDIBitmapCommon(SplashBitmap *bmp, HDC hdc)
+{
+ int bmpDx = bmp->getWidth();
+ int bmpDy = bmp->getHeight();
+ int bmpRowSize = bmp->getRowSize();
+
+ BITMAPINFOHEADER bmih;
+ bmih.biSize = sizeof(bmih);
+ bmih.biHeight = -bmpDy;
+ bmih.biWidth = bmpDx;
+ bmih.biPlanes = 1;
+ bmih.biBitCount = 24;
+ bmih.biCompression = BI_RGB;
+ bmih.biSizeImage = bmpDy * bmpRowSize;;
+ bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 0;
+ bmih.biClrUsed = bmih.biClrImportant = 0;
+
+ unsigned char* bmpData = bmp->getDataPtr();
+ HBITMAP hbmp = ::CreateDIBitmap(hdc, &bmih, CBM_INIT, bmpData, (BITMAPINFO *)&bmih , DIB_RGB_COLORS);
+ return hbmp;
+}
+
+static void stretchDIBitsCommon(SplashBitmap *bmp, HDC hdc, int leftMargin, int topMargin, int pageDx, int pageDy)
+{
+ int bmpDx = bmp->getWidth();
+ int bmpDy = bmp->getHeight();
+ int bmpRowSize = bmp->getRowSize();
+
+ BITMAPINFOHEADER bmih;
+ bmih.biSize = sizeof(bmih);
+ bmih.biHeight = -bmpDy;
+ bmih.biWidth = bmpDx;
+ bmih.biPlanes = 1;
+ // we could create this dibsection in monochrome
+ // if the printer is monochrome, to reduce memory consumption
+ // but splash is currently setup to return a full colour bitmap
+ bmih.biBitCount = 24;
+ bmih.biCompression = BI_RGB;
+ bmih.biSizeImage = bmpDy * bmpRowSize;;
+ bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 0;
+ bmih.biClrUsed = bmih.biClrImportant = 0;
+ SplashColorPtr bmpData = bmp->getDataPtr();
+
+ ::StretchDIBits(hdc,
+ // destination rectangle
+ -leftMargin, -topMargin, pageDx, pageDy,
+ // source rectangle
+ 0, 0, bmpDx, bmpDy,
+ bmpData,
+ (BITMAPINFO *)&bmih ,
+ DIB_RGB_COLORS,
+ SRCCOPY);
+}
+
+/* Set the client area size of the window 'hwnd' to 'dx'/'dy'. */
+static void resizeClientArea(HWND hwnd, int x, int dx, int dy, int *dx_out)
+{
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ if ((rect_dx(&rc) == dx) && (rect_dy(&rc) == dy))
+ return;
+
+ RECT rw;
+ GetWindowRect(hwnd, &rw);
+ int win_dx = rect_dx(&rw) + (dx - rect_dx(&rc));
+ int win_dy = rect_dy(&rw) + (dy - rect_dy(&rc));
+ SetWindowPos(hwnd, NULL, x, 0, win_dx, win_dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER);
+ if (dx_out)
+ *dx_out = win_dx;
+}
+
+static void resizeClientAreaToRenderedBitmap(HWND hwnd, SplashBitmap *bmp, int x, int *dxOut)
+{
+ int dx = bmp->getWidth();
+ int dy = bmp->getHeight();
+ resizeClientArea(hwnd, x, dx, dy, dxOut);
+}
+
+static void drawBitmap(HWND hwnd, SplashBitmap *bmp)
+{
+ PAINTSTRUCT ps;
+
+ HDC hdc = BeginPaint(hwnd, &ps);
+ SetBkMode(hdc, TRANSPARENT);
+ FillRect(hdc, &ps.rcPaint, gBrushBg);
+
+ HBITMAP hbmp = createDIBitmapCommon(bmp, hdc);
+ if (hbmp) {
+ HDC bmpDC = CreateCompatibleDC(hdc);
+ if (bmpDC) {
+ SelectObject(bmpDC, hbmp);
+ int xSrc = 0, ySrc = 0;
+ int xDest = 0, yDest = 0;
+ int bmpDx = bmp->getWidth();
+ int bmpDy = bmp->getHeight();
+ BitBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, SRCCOPY);
+ DeleteDC(bmpDC);
+ bmpDC = NULL;
+ }
+ DeleteObject(hbmp);
+ hbmp = NULL;
+ }
+ EndPaint(hwnd, &ps);
+}
+
+static void onPaint(HWND hwnd)
+{
+ if (hwnd == gHwndSplash) {
+ if (gBmpSplash) {
+ drawBitmap(hwnd, gBmpSplash);
+ }
+ }
+}
+
+static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_CREATE:
+ // do nothing
+ break;
+
+ case WM_ERASEBKGND:
+ return TRUE;
+
+ case WM_PAINT:
+ /* it might happen that we get WM_PAINT after destroying a window */
+ onPaint(hwnd);
+ break;
+
+ case WM_DESTROY:
+ /* WM_DESTROY might be sent as a result of File\Close, in which case CloseWindow() has already been called */
+ break;
+
+ default:
+ return DefWindowProc(hwnd, message, wParam, lParam);
+ }
+ return 0;
+}
+
+static BOOL registerWinClass(void)
+{
+ WNDCLASSEX wcex;
+ ATOM atom;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = NULL;
+ wcex.hIcon = NULL;
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = NULL;
+ wcex.lpszMenuName = NULL;
+ wcex.lpszClassName = WIN_CLASS_NAME;
+ wcex.hIconSm = NULL;
+
+ atom = RegisterClassEx(&wcex);
+ if (atom)
+ return TRUE;
+ return FALSE;
+}
+
+static bool initWinIfNecessary(void)
+{
+ if (gHwndSplash)
+ return true;
+
+ if (!registerWinClass())
+ return false;
+
+ gBrushBg = CreateSolidBrush(COL_WINDOW_BG);
+
+ gHwndSplash = CreateWindow(
+ WIN_CLASS_NAME, "Splash",
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0,
+ CW_USEDEFAULT, 0,
+ NULL, NULL,
+ NULL, NULL);
+
+ if (!gHwndSplash)
+ return false;
+
+ ShowWindow(gHwndSplash, SW_HIDE);
+ return true;
+}
+
+static void pumpMessages(void)
+{
+ BOOL isMessage;
+ MSG msg;
+
+ for (;;) {
+ isMessage = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
+ if (!isMessage)
+ return;
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+}
+
+void PreviewBitmapInit(void)
+{
+ /* no need to do anything */
+}
+
+void PreviewBitmapDestroy(void)
+{
+ PostQuitMessage(0);
+ pumpMessages();
+ DeleteObject(gBrushBg);
+}
+
+static void UpdateWindows(void)
+{
+ if (gBmpSplash) {
+ resizeClientAreaToRenderedBitmap(gHwndSplash, gBmpSplash, 0, NULL);
+ ShowWindow(gHwndSplash, SW_SHOW);
+ InvalidateRect(gHwndSplash, NULL, FALSE);
+ UpdateWindow(gHwndSplash);
+ } else {
+ ShowWindow(gHwndSplash, SW_HIDE);
+ }
+
+ pumpMessages();
+}
+
+void PreviewBitmapSplash(SplashBitmap *bmpSplash)
+{
+ if (!initWinIfNecessary())
+ return;
+
+ gBmpSplash = bmpSplash;
+ UpdateWindows();
+}
+
+