diff --git a/rosapps/smartpdf/baseutils/test_win.bat b/rosapps/smartpdf/baseutils/test_win.bat deleted file mode 100644 index 1950253e6c2..00000000000 --- a/rosapps/smartpdf/baseutils/test_win.bat +++ /dev/null @@ -1,23 +0,0 @@ -@echo off -pushd . -@call "C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat" -IF ERRORLEVEL 1 goto VC_SETUP_FAILED - -nmake -f Makefile.vc8 -IF ERRORLEVEL 1 goto COMPILATION_FAILED - -del *.obj *.ilk -test_file_util_d.exe -goto END - -:VC_SETUP_FAILED -echo Failed to setup vc8 -goto END - -:COMPILATION_FAILED -echo Compilation failed! -goto END - -:END -popd - diff --git a/rosapps/smartpdf/baseutils/win-build.bat b/rosapps/smartpdf/baseutils/win-build.bat deleted file mode 100644 index babce10aaf6..00000000000 --- a/rosapps/smartpdf/baseutils/win-build.bat +++ /dev/null @@ -1,5 +0,0 @@ -nmake -f makefile.msvc TARGET=rel -nmake -f makefile.msvc TARGET=dbg -nmake -f makefile.msvc TARGET=rel-unicode -nmake -f makefile.msvc TARGET=dbg-unicode - diff --git a/rosapps/smartpdf/baseutils/win-rebuild.bat b/rosapps/smartpdf/baseutils/win-rebuild.bat deleted file mode 100644 index 21ca9d65f1d..00000000000 --- a/rosapps/smartpdf/baseutils/win-rebuild.bat +++ /dev/null @@ -1,9 +0,0 @@ -nmake -f makefile.msvc TARGET=rel clean -nmake -f makefile.msvc TARGET=dbg clean -nmake -f makefile.msvc TARGET=rel-unicode clean -nmake -f makefile.msvc TARGET=dbg-unicode clean - -nmake -f makefile.msvc TARGET=rel -nmake -f makefile.msvc TARGET=dbg -nmake -f makefile.msvc TARGET=rel-unicode -nmake -f makefile.msvc TARGET=dbg-unicode diff --git a/rosapps/smartpdf/fitz/build-debug.bat b/rosapps/smartpdf/fitz/build-debug.bat deleted file mode 100644 index f5d2999d79f..00000000000 --- a/rosapps/smartpdf/fitz/build-debug.bat +++ /dev/null @@ -1 +0,0 @@ -nmake -f Makefile.vc DEBUG=1 diff --git a/rosapps/smartpdf/fitz/build.bat b/rosapps/smartpdf/fitz/build.bat deleted file mode 100644 index 8f330af4638..00000000000 --- a/rosapps/smartpdf/fitz/build.bat +++ /dev/null @@ -1 +0,0 @@ -nmake -f Makefile.vc diff --git a/rosapps/smartpdf/fitz/clean.bat b/rosapps/smartpdf/fitz/clean.bat deleted file mode 100644 index 09a2fa18ea6..00000000000 --- a/rosapps/smartpdf/fitz/clean.bat +++ /dev/null @@ -1 +0,0 @@ -nmake -f Makefile.vc clean \ No newline at end of file diff --git a/rosapps/smartpdf/src/Kopie von SumatraPDF.cpp b/rosapps/smartpdf/src/Kopie von SumatraPDF.cpp deleted file mode 100644 index 67e1f2d9764..00000000000 --- a/rosapps/smartpdf/src/Kopie von SumatraPDF.cpp +++ /dev/null @@ -1,5103 +0,0 @@ -/* Copyright Krzysztof Kowalczyk 2006-2007 - License: GPLv2 */ - -// have to undef _WIN32_IE here to use TB_* constants -// (_WIN32_IE was defined in *.cbp - codeblocks project file) -// ==> we have to use a stable API instead of MinGW 5.1.3 :-\ - -#ifdef __GNUC__ -#undef _WIN32_IE -#endif - -#include "SumatraPDF.h" - -#include "str_util.h" -#include "file_util.h" -#include "geom_util.h" -#include "win_util.h" -#include "translations.h" - -#include "SumatraDialogs.h" -#include "FileHistory.h" -#include "AppPrefs.h" -#include "DisplayModelSplash.h" - -/* TODO: this and StandardSecurityHandler::getAuthData() and new GlobalParams - should be moved to another file (PopplerInit(), PopplerDeinit() */ -#include "PDFDoc.h" -#include "SecurityHandler.h" -#include "GlobalParams.h" - -#include -#include -#include -#include -#include /* for _mkdir() */ - -#include -#include - -#include "str_strsafe.h" - -#include - -// some stupid things are in headers of MinGW 5.1.3 :-\ -// why we have to define these constants & prototypes again (?!) -#ifdef __GNUC__ -#ifndef VK_OEM_PLUS -#define VK_OEM_PLUS 0xBB -#endif -#ifndef VK_OEM_MINUS -#define VK_OEM_MINUS 0xBD -#endif - -extern "C" { -extern BOOL WINAPI GetDefaultPrinterA(LPSTR,LPDWORD); -extern BOOL WINAPI GetDefaultPrinterW(LPWSTR,LPDWORD); -} -#endif - -// this sucks but I don't know any other way -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") - -//#define FANCY_UI 1 - -/* Define if you want to conserve memory by always freeing cached bitmaps - for pages not visible. Only enable for stress-testing the logic. On - desktop machine we usually have plenty memory */ -//#define CONSERVE_MEMORY 1 - -/* Next action for the benchmark mode */ -#define MSG_BENCH_NEXT_ACTION WM_USER + 1 - -#define ZOOM_IN_FACTOR 1.2 -#define ZOOM_OUT_FACTOR 1.0 / ZOOM_IN_FACTOR - -/* if TRUE, we're in debug mode where we show links as blue rectangle on - the screen. Makes debugging code related to links easier. - TODO: make a menu item in DEBUG build to turn it on/off. */ -#ifdef DEBUG -static BOOL gDebugShowLinks = TRUE; -#else -static BOOL gDebugShowLinks = FALSE; -#endif - -/* default UI settings */ -#define DEFAULT_DISPLAY_MODE DM_CONTINUOUS - -//#define DEFAULT_ZOOM ZOOM_FIT_WIDTH -#define DEFAULT_ZOOM ZOOM_FIT_PAGE -#define DEFAULT_ROTATION 0 - -//#define START_WITH_ABOUT 1 - -/* define if want to use double-buffering for rendering the PDF. Takes more memory!. */ -#define DOUBLE_BUFFER 1 - -#define DRAGQUERY_NUMFILES 0xFFFFFFFF - -#define MAX_LOADSTRING 100 - -#define WM_CREATE_FAILED -1 -#define WM_CREATE_OK 0 -#define WM_NCPAINT_HANDLED 0 -#define WM_VSCROLL_HANDLED 0 -#define WM_HSCROLL_HANDLED 0 - -#define ABOUT_WIN_DX 440 -#define ABOUT_WIN_DY 300 - -#define WM_APP_REPAINT_DELAYED (WM_APP + 10) -#define WM_APP_REPAINT_NOW (WM_APP + 11) - -/* A caption is 4 white/blue 2 pixel line and a 3 pixel white line */ -#define CAPTION_DY 2*(2*4)+3 - -#define COL_CAPTION_BLUE RGB(0,0x50,0xa0) -#define COL_WHITE RGB(0xff,0xff,0xff) -#define COL_BLACK RGB(0,0,0) -#define COL_WINDOW_BG RGB(0xcc, 0xcc, 0xcc) -#define COL_WINDOW_SHADOW RGB(0x40, 0x40, 0x40) - -#define FRAME_CLASS_NAME _T("SUMATRA_PDF_FRAME") -#define CANVAS_CLASS_NAME _T("SUMATRA_PDF_CANVAS") -#define ABOUT_CLASS_NAME _T("SUMATRA_PDF_ABOUT") -#define APP_NAME _T("SumatraPDF") -#define PDF_DOC_NAME _T("Adobe PDF Document") -#define ABOUT_WIN_TITLE _TR("About SumatraPDF") -#define PREFS_FILE_NAME _T("sumatrapdfprefs.txt") -#define APP_SUB_DIR _T("SumatraPDF") - -#define BENCH_ARG_TXT "-bench" -#define PRINT_TO_ARG_TXT "-print-to" -#define NO_REGISTER_EXT_ARG_TXT "-no-register-ext" -#define PRINT_TO_DEFAULT_ARG_TXT "-print-to-default" -#define EXIT_ON_PRINT_ARG_TXT "-exit-on-print" -#define ENUM_PRINTERS_ARG_TXT "-enum-printers" - -/* Default size for the window, happens to be american A4 size (I think) */ -#define DEF_WIN_DX 612 -#define DEF_WIN_DY 792 - -#define REPAINT_TIMER_ID 1 -#define REPAINT_DELAY_IN_MS 400 - -/* A special "pointer" vlaue indicating that we tried to render this bitmap - but couldn't (e.g. due to lack of memory) */ -#define BITMAP_CANNOT_RENDER (RenderedBitmap*)NULL - -#define WS_REBAR (WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | RBS_VARHEIGHT | \ - RBS_BANDBORDERS | CCS_NODIVIDER | CCS_NOPARENTALIGN) - -#define MAX_RECENT_FILES_IN_MENU 15 - -typedef struct StrList { - struct StrList * next; - char * str; -} StrList; - -static FileHistoryList * gFileHistoryRoot = NULL; - -static HINSTANCE ghinst = NULL; -TCHAR windowTitle[MAX_LOADSTRING]; - -static WindowInfo* gWindowList; - -static HCURSOR gCursorArrow; -static HCURSOR gCursorHand; -static HCURSOR gCursorDrag; -static HBRUSH gBrushBg; -static HBRUSH gBrushWhite; -static HBRUSH gBrushShadow; -static HBRUSH gBrushLinkDebug; - -static HPEN ghpenWhite; -static HPEN ghpenBlue; - -#ifdef _WINDLL -static bool gRunningDLL = true; -#else -static bool gRunningDLL = false; -#endif -//static AppVisualStyle gVisualStyle = VS_WINDOWS; - -static char * gBenchFileName; -static int gBenchPageNum = INVALID_PAGE_NO; -BOOL gShowToolbar = TRUE; -BOOL gUseFitz = TRUE; -/* If false, we won't ask the user if he wants Sumatra to handle PDF files */ -BOOL gPdfAssociateDontAskAgain = FALSE; -/* If gPdfAssociateDontAskAgain is TRUE, says whether we should silently associate - or not */ -BOOL gPdfAssociateShouldAssociate = TRUE; -#ifdef DOUBLE_BUFFER -static bool gUseDoubleBuffer = true; -#else -static bool gUseDoubleBuffer = false; -#endif - -#define MAX_PAGE_REQUESTS 8 -static PageRenderRequest gPageRenderRequests[MAX_PAGE_REQUESTS]; -static int gPageRenderRequestsCount = 0; - -static HANDLE gPageRenderThreadHandle; -static HANDLE gPageRenderSem; -static PageRenderRequest * gCurPageRenderReq; - -static int gReBarDy; -static int gReBarDyFrame; -static HWND gHwndAbout; - -typedef struct ToolbarButtonInfo { - /* information provided at compile time */ - int bitmapResourceId; - int cmdId; - TCHAR * toolTip; - - /* information calculated at runtime */ - int index; -} ToolbarButtonInfo; - -#define IDB_SEPARATOR -1 - -ToolbarButtonInfo gToolbarButtons[] = { - { IDB_SILK_OPEN, IDM_OPEN, _TRN(TEXT("Open")), 0 }, - { IDB_SEPARATOR, IDB_SEPARATOR, 0, 0 }, - { IDB_SILK_PREV, IDM_GOTO_PREV_PAGE, _TRN(TEXT("Previous Page")), 0 }, - { IDB_SILK_NEXT, IDM_GOTO_NEXT_PAGE, _TRN(TEXT("Next Page")), 0 }, - { IDB_SEPARATOR, IDB_SEPARATOR, 0, 0 }, - { IDB_SILK_ZOOM_IN, IDT_VIEW_ZOOMIN, _TRN(TEXT("Zoom In")), 0 }, - { IDB_SILK_ZOOM_OUT, IDT_VIEW_ZOOMOUT, _TRN(TEXT("Zoom Out")), 0 } -}; /* @author: Klemens Friedl; TEXT() casts */ - -#define DEFAULT_LANGUAGE "en" - -#define TOOLBAR_BUTTONS_COUNT dimof(gToolbarButtons) - -static const char *g_currLangName; - -struct LangDef { - const char* _langName; - int _langId; -} g_langs[] = { - {"en", IDM_LANG_EN}, - {"pl", IDM_LANG_PL}, - {"fr", IDM_LANG_FR}, - {"de", IDM_LANG_DE}, -}; - -#define LANGS_COUNT dimof(g_langs) - -static void WindowInfo_ResizeToPage(WindowInfo *win, int pageNo); -static void CreateToolbar(WindowInfo *win, HINSTANCE hInst); -static void RebuildProgramMenus(void); - -const char* CurrLangNameGet() { - if (!g_currLangName) - return DEFAULT_LANGUAGE; - return g_currLangName; -} - -bool CurrLangNameSet(const char* langName) { - bool validLang = false; - for (int i=0; i < LANGS_COUNT; i++) { - if (str_eq(langName, g_langs[i]._langName)) { - validLang = true; - break; - } - } - assert(validLang); - if (!validLang) return false; - free((void*)g_currLangName); - g_currLangName = str_dup(langName); - - bool ok = Translations_SetCurrentLanguage(langName); - assert(ok); - - return true; -} - -void CurrLangNameFree() { - free((void*)g_currLangName); - g_currLangName = NULL; -} - -void LaunchBrowser(const TCHAR *url) -{ - launch_url(url); -} - -static BOOL pageRenderAbortCb(void *data) -{ - PageRenderRequest *req = (PageRenderRequest*)data; - if (req->abort) { - DBG_OUT("Rendering of page %d aborted\n", req->pageNo); - return TRUE; - } - else - return FALSE; -} - -void RenderQueue_RemoveForDisplayModel(DisplayModel *dm) { - LockCache(); - int reqCount = gPageRenderRequestsCount; - int curPos = 0; - for(int i = 0; i < reqCount; i++) { - PageRenderRequest *req = &(gPageRenderRequests[i]); - bool shouldRemove = (req->dm == dm); - if (i != curPos) - gPageRenderRequests[curPos] = gPageRenderRequests[i]; - if (shouldRemove) - --gPageRenderRequestsCount; - else - ++curPos; - } - UnlockCache(); -} - -/* Wait until rendering of a page beloging to has finished. */ -/* TODO: this might take some time, would be good to show a dialog to let the - user know he has to wait until we finish */ -void cancelRenderingForDisplayModel(DisplayModel *dm) { - - DBG_OUT("cancelRenderingForDisplayModel()\n"); - bool renderingFinished = false;; - for (;;) { - LockCache(); - if (!gCurPageRenderReq || (gCurPageRenderReq->dm != dm)) - renderingFinished = true; - else - gCurPageRenderReq->abort = TRUE; - UnlockCache(); - if (renderingFinished) - break; - /* TODO: busy loop is not good, but I don't have a better idea */ - sleep_milliseconds(500); - } -} - -/* Render a bitmap for page in . */ -void RenderQueue_Add(DisplayModel *dm, int pageNo) { - DBG_OUT("RenderQueue_Add(pageNo=%d)\n", pageNo); - assert(dm); - if (!dm) return; //goto Exit; /* @author: Klemens Friedl; because of crosses initialization of [...] */ - - LockCache(); - PdfPageInfo *pageInfo = dm->getPageInfo(pageNo); - int rotation = dm->rotation(); - normalizeRotation(&rotation); - double zoomLevel = dm->zoomReal(); - - if (BitmapCache_Exists(dm, pageNo, zoomLevel, rotation)) { - goto LeaveCsAndExit; - } - - if (gCurPageRenderReq && - (gCurPageRenderReq->pageNo == pageNo) && (gCurPageRenderReq->dm == dm)) { - if ((gCurPageRenderReq->zoomLevel != zoomLevel) || (gCurPageRenderReq->rotation != rotation)) { - /* Currently rendered page is for the same page but with different zoom - or rotation, so abort it */ - DBG_OUT(" aborting rendering\n"); - gCurPageRenderReq->abort = TRUE; - } else { - /* we're already rendering exactly the same page */ - DBG_OUT(" already rendering this page\n"); - goto LeaveCsAndExit; - } - } - - for (int i=0; i < gPageRenderRequestsCount; i++) { - PageRenderRequest* req = &(gPageRenderRequests[i]); - if ((req->pageNo == pageNo) && (req->dm == dm)) { - if ((req->zoomLevel == zoomLevel) && (req->rotation == rotation)) { - /* Request with exactly the same parameters already queued for - rendering. Move it to the top of the queue so that it'll - be rendered faster. */ - PageRenderRequest tmp; - tmp = gPageRenderRequests[gPageRenderRequestsCount-1]; - gPageRenderRequests[gPageRenderRequestsCount-1] = *req; - *req = tmp; - DBG_OUT(" already queued\n"); - goto LeaveCsAndExit; - } else { - /* There was a request queued for the same page but with different - zoom or rotation, so only replace this request */ - DBG_OUT("Replacing request for page %d with new request\n", req->pageNo); - req->zoomLevel = zoomLevel; - req->rotation = rotation; - goto LeaveCsAndExit; - - } - } - } - - PageRenderRequest* newRequest; - /* add request to the queue */ - if (gPageRenderRequestsCount == MAX_PAGE_REQUESTS) { - /* queue is full -> remove the oldest items on the queue */ - memmove(&(gPageRenderRequests[0]), &(gPageRenderRequests[1]), sizeof(PageRenderRequest)*(MAX_PAGE_REQUESTS-1)); - newRequest = &(gPageRenderRequests[MAX_PAGE_REQUESTS-1]); - } else { - newRequest = &(gPageRenderRequests[gPageRenderRequestsCount]); - gPageRenderRequestsCount++; - } - assert(gPageRenderRequestsCount <= MAX_PAGE_REQUESTS); - newRequest->dm = dm; - newRequest->pageNo = pageNo; - newRequest->zoomLevel = zoomLevel; - newRequest->rotation = rotation; - newRequest->abort = FALSE; - - UnlockCache(); - /* tell rendering thread there's a new request to render */ - LONG prevCount; - ReleaseSemaphore(gPageRenderSem, 1, &prevCount); -Exit: - return; -LeaveCsAndExit: - UnlockCache(); - return; -} - -void RenderQueue_Pop(PageRenderRequest *req) -{ - LockCache(); - assert(gPageRenderRequestsCount > 0); - assert(gPageRenderRequestsCount <= MAX_PAGE_REQUESTS); - --gPageRenderRequestsCount; - *req = gPageRenderRequests[gPageRenderRequestsCount]; - assert(gPageRenderRequestsCount >= 0); - UnlockCache(); -} - -static HMENU FindMenuItem(WindowInfo *win, UINT id) -{ - HMENU menuMain = GetMenu(win->hwndFrame); - - /* TODO: to be fully valid, it would have to be recursive */ - for (int i = 0; i < GetMenuItemCount(menuMain); i++) { - UINT thisId = GetMenuItemID(menuMain, i); - HMENU subMenu = GetSubMenu(menuMain, i); - if (id == thisId) - return subMenu; - for (int j = 0; j < GetMenuItemCount(subMenu); j++) { - thisId = GetMenuItemID(menuMain, j); - if (id == thisId) - return GetSubMenu(subMenu, j); - } - } - return NULL; -} - -static HMENU GetFileMenu(HWND hwnd) -{ - return GetSubMenu(GetMenu(hwnd), 0); -} - -static void SwitchToDisplayMode(WindowInfo *win, DisplayMode displayMode) -{ - HMENU menuMain; - UINT id; - - menuMain = GetMenu(win->hwndFrame); - CheckMenuItem(menuMain, IDM_VIEW_SINGLE_PAGE, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VIEW_CONTINUOUS, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VIEW_FACING, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VIEW_CONTINUOUS_FACING, MF_BYCOMMAND | MF_UNCHECKED); - - win->dm->changeDisplayMode(displayMode); - if (DM_SINGLE_PAGE == displayMode) { - id = IDM_VIEW_SINGLE_PAGE; - } else if (DM_FACING == displayMode) { - id = IDM_VIEW_FACING; - } else if (DM_CONTINUOUS == displayMode) { - id = IDM_VIEW_CONTINUOUS; - } else if (DM_CONTINUOUS_FACING == displayMode) { - id = IDM_VIEW_CONTINUOUS_FACING; - } else - assert(0); - - CheckMenuItem(menuMain, id, MF_BYCOMMAND | MF_CHECKED); -} - -static UINT AllocNewMenuId(void) -{ - static UINT firstId = 1000; - ++firstId; - return firstId; -} - -#define SEP_ITEM "-----" - -typedef struct MenuDef { - const char *m_title; - int m_id; -} MenuDef; - -MenuDef menuDefFile[] = { - { _TRN("&Open\tCtrl-O"), IDM_OPEN }, - { _TRN("&Close\tCtrl-W"), IDM_CLOSE }, - { _TRN("&Save as"), IDM_SAVEAS }, - { _TRN("&Print"), IDM_PRINT }, - { SEP_ITEM, 0 }, - { _TRN("Make SumatraPDF a default PDF reader"), IDM_MAKE_DEFAULT_READER }, - { SEP_ITEM , 0 }, - { _TRN("E&xit\tCtrl-Q"), IDM_EXIT } -}; - -MenuDef menuDefView[] = { - { _TRN("Single page"), IDM_VIEW_SINGLE_PAGE }, - { _TRN("Facing"), IDM_VIEW_FACING }, - { _TRN("Continuous"), IDM_VIEW_CONTINUOUS }, - { _TRN("Continuous facing"), IDM_VIEW_CONTINUOUS_FACING }, - { SEP_ITEM, 0 }, - { _TRN("Rotate left"), IDM_VIEW_ROTATE_LEFT }, - { _TRN("Rotate right"), IDM_VIEW_ROTATE_RIGHT }, - { SEP_ITEM, 0 }, - { _TRN("Show toolbar"), IDM_VIEW_SHOW_HIDE_TOOLBAR }, - { SEP_ITEM, 0 }, - { _TRN("Use MuPDF rendering engine"), IDM_VIEW_USE_FITZ }, -}; - -MenuDef menuDefGoTo[] = { - { _TRN("Next Page"), IDM_GOTO_NEXT_PAGE }, - { _TRN("Previous Page"), IDM_GOTO_PREV_PAGE }, - { _TRN("First Page\tHome"), IDM_GOTO_FIRST_PAGE }, - { _TRN("Last Page\tEnd"), IDM_GOTO_LAST_PAGE }, - { _TRN("Page...\tCtrl-G"), IDM_GOTO_PAGE }, -}; - -MenuDef menuDefZoom[] = { - { _TRN("Fit &Page\tCtrl-0"), IDM_ZOOM_FIT_PAGE }, - { _TRN("Act&ual Size\tCtrl-1"), IDM_ZOOM_ACTUAL_SIZE }, - { _TRN("Fit Widt&h\tCtrl-2"), IDM_ZOOM_FIT_WIDTH }, - { SEP_ITEM }, - { _TRN("6400%"), IDM_ZOOM_6400 }, - { _TRN("3200%"), IDM_ZOOM_3200 }, - { _TRN("1600%"), IDM_ZOOM_1600 }, - { _TRN("800%"), IDM_ZOOM_800 }, - { _TRN("400%"), IDM_ZOOM_400 }, - { _TRN("200%"), IDM_ZOOM_200 }, - { _TRN("150%"), IDM_ZOOM_150 }, - { _TRN("125%"), IDM_ZOOM_125 }, - { _TRN("100%"), IDM_ZOOM_100 }, - { _TRN("50%"), IDM_ZOOM_50 }, - { _TRN("25%"), IDM_ZOOM_25 }, - { _TRN("12.5%"), IDM_ZOOM_12_5 }, - { _TRN("8.33%"), IDM_ZOOM_8_33 }, -}; - -MenuDef menuDefLang[] = { - { _TRN("&English"), IDM_LANG_EN }, - { _TRN("&French"), IDM_LANG_FR }, - { _TRN("&German"), IDM_LANG_DE }, - { _TRN("&Polish"), IDM_LANG_PL }, -}; - -MenuDef menuDefHelp[] = { - { _TRN("&Visit website"), IDM_VISIT_WEBSITE }, - { _TRN("&About"), IDM_ABOUT } -}; - -static void AddFileMenuItem(HMENU menuFile, FileHistoryList *node) -{ - assert(node); - if (!node) return; - assert(menuFile); - if (!menuFile) return; - - UINT newId = node->menuId; - if (INVALID_MENU_ID == node->menuId) - newId = AllocNewMenuId(); - const char* txt = FilePath_GetBaseName(node->state.filePath); - AppendMenu(menuFile, MF_ENABLED | MF_STRING, newId, (TCHAR*)txt); /* @author: Klemens Friedl; TCHAR* cast */ - node->menuId = newId; -} - -static HMENU BuildMenuFromMenuDef(MenuDef menuDefs[], int menuItems) -{ - HMENU m = CreateMenu(); - if (NULL == m) return NULL; - for (int i=0; i < menuItems; i++) { - MenuDef md = menuDefs[i]; - const char *title = md.m_title; - int id = md.m_id; - if (str_eq(title, SEP_ITEM)) - AppendMenu(m, MF_SEPARATOR, 0, NULL); - else { - const WCHAR* wtitle = Translatations_GetTranslationW(title); - if (wtitle) - AppendMenuW(m, MF_STRING, (UINT_PTR)id, wtitle); - } - } - return m; -} - -static HMENU g_currMenu = NULL; - -static void DestroyCurrentMenu() -{ - DestroyMenu(g_currMenu); - g_currMenu = NULL; -} - -static void AddRecentFilesToMenu(HMENU m) -{ - if (!gFileHistoryRoot) return; - - AppendMenu(m, MF_SEPARATOR, 0, NULL); - - int itemsAdded = 0; - FileHistoryList *curr = gFileHistoryRoot; - while (curr) { - assert(curr->state.filePath); - if (curr->state.filePath) { - AddFileMenuItem(m, curr); - assert(curr->menuId != INVALID_MENU_ID); - ++itemsAdded; - if (itemsAdded >= MAX_RECENT_FILES_IN_MENU) { - DBG_OUT(" not adding, reached max %d items\n", MAX_RECENT_FILES_IN_MENU); - return; - } - } - curr = curr->next; - } -} - -static HMENU ForceRebuildMenu() -{ - HMENU tmp; - DestroyCurrentMenu(); - g_currMenu = CreateMenu(); - tmp = BuildMenuFromMenuDef(menuDefFile, dimof(menuDefFile)); - AddRecentFilesToMenu(tmp); - AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&File")); - tmp = BuildMenuFromMenuDef(menuDefView, dimof(menuDefView)); - AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&View")); - tmp = BuildMenuFromMenuDef(menuDefGoTo, dimof(menuDefGoTo)); - AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Go To")); - tmp = BuildMenuFromMenuDef(menuDefZoom, dimof(menuDefZoom)); - AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Zoom")); - tmp = BuildMenuFromMenuDef(menuDefLang, dimof(menuDefLang)); - AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Language")); - tmp = BuildMenuFromMenuDef(menuDefHelp, dimof(menuDefHelp)); - AppendMenuW(g_currMenu, MF_POPUP | MF_STRING, (UINT_PTR)tmp, _TRW("&Help")); - return g_currMenu; -} - -static HMENU GetProgramMenu() -{ - if (NULL == g_currMenu) - ForceRebuildMenu(); - assert(g_currMenu); - return g_currMenu; -} - -/* Return the full exe path of my own executable. - Caller needs to free() the result. */ -static char *ExePathGet(void) -{ - char *cmdline = GetCommandLineA(); - return str_parse_possibly_quoted(&cmdline); -} - -/* Set the client area size of the window 'hwnd' to 'dx'/'dy'. */ -static void WinResizeClientArea(HWND hwnd, int dx, int dy) -{ - 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, 0, 0, win_dx, win_dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOMOVE| SWP_NOZORDER); -} - -static void SetCanvasSizeToDxDy(WindowInfo *win, int w, int h) -{ - RECT canvasRect; - GetWindowRect(win->hwndCanvas, &canvasRect); - RECT frameRect; - GetWindowRect(win->hwndFrame, &frameRect); - int dx = rect_dx(&frameRect) - rect_dx(&canvasRect); - assert(dx >= 0); - int dy = rect_dy(&frameRect) - rect_dy(&canvasRect); - assert(dy >= 0); - SetWindowPos(win->hwndFrame, NULL, 0, 0, w+dx, h+dy, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOMOVE| SWP_NOZORDER); - //SetWindowPos(win->hwndCanvas, NULL, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOMOVE| SWP_NOZORDER); -} - -static void CaptionPens_Create(void) -{ - LOGPEN pen; - - assert(!ghpenWhite); - pen.lopnStyle = PS_SOLID; - pen.lopnWidth.x = 1; - pen.lopnWidth.y = 1; - pen.lopnColor = COL_WHITE; - ghpenWhite = CreatePenIndirect(&pen); - pen.lopnColor = COL_CAPTION_BLUE; - ghpenBlue = CreatePenIndirect(&pen); -} - -static void CaptionPens_Destroy(void) -{ - if (ghpenWhite) { - DeleteObject(ghpenWhite); - ghpenWhite = NULL; - } - - if (ghpenBlue) { - DeleteObject(ghpenBlue); - ghpenBlue = NULL; - } -} - -static void AddFileToHistory(const char *filePath) -{ - FileHistoryList * node; - uint32_t oldMenuId = INVALID_MENU_ID; - - assert(filePath); - if (!filePath) return; - - /* if a history entry with the same name already exists, then delete it. - That way we don't have duplicates and the file moves to the front of the list */ - node = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, filePath); - if (node) { - oldMenuId = node->menuId; - FileHistoryList_Node_RemoveAndFree(&gFileHistoryRoot, node); - } - node = FileHistoryList_Node_CreateFromFilePath(filePath); - if (!node) - return; - node->menuId = oldMenuId; - FileHistoryList_Node_InsertHead(&gFileHistoryRoot, node); -} - -extern "C" char *GetPasswordForFile(WindowInfo *win, const char *fileName); - -/* Get password for a given 'fileName', can be NULL if user cancelled the - dialog box. - Caller needs to free() the result. */ -char *GetPasswordForFile(WindowInfo *win, const char *fileName) -{ - fileName = FilePath_GetBaseName(fileName); - return Dialog_GetPassword(win, fileName); -} - -void *StandardSecurityHandler::getAuthData() -{ - WindowInfo * win; - const char * pwd; - StandardAuthData * authData; - - win = (WindowInfo*)doc->getGUIData(); - assert(win); - if (!win) - return NULL; - - pwd = GetPasswordForFile(win, doc->getFileName()->getCString()); - if (!pwd) - return NULL; - - authData = new StandardAuthData(new GooString(pwd), new GooString(pwd)); - free((void*)pwd); - return (void*)authData; -} - -/* Return true if this program has been started from "Program Files" directory - (which is an indicator that it has been installed */ -static bool runningFromProgramFiles(void) -{ - char programFilesDir[MAX_PATH]; - BOOL fOk = SHGetSpecialFolderPath(NULL, (TCHAR*)programFilesDir, CSIDL_PROGRAM_FILES, FALSE); /* @author: Klemens Friedl; TCHAR* cast */ - char *exePath = ExePathGet(); - if (!exePath) return true; // again, assume it is - bool fromProgramFiles = false; - if (fOk) { - if (str_startswithi(exePath, programFilesDir)) - fromProgramFiles = true; - } else { - // SHGetSpecialFolderPath() might fail on win95/98 so need a different check - if (strstr(exePath, "Program Files")) - fromProgramFiles = true; - } - free(exePath); - return fromProgramFiles; -} - -static bool IsRunningInPortableMode(void) -{ - return !runningFromProgramFiles(); -} - -static void AppGetAppDir(DString* pDs) -{ - char dir[MAX_PATH]; - - SHGetSpecialFolderPath(NULL, (TCHAR*)dir, CSIDL_APPDATA, TRUE); /* @author: Klemens Friedl; TCHAR* cast */ - DStringSprintf(pDs, "%s/%s", dir, APP_SUB_DIR); - _mkdir(pDs->pString); -} - -/* Generate the full path for a filename used by the app in the userdata path. */ -static void AppGenDataFilename(char* pFilename, DString* pDs) -{ - assert(0 == pDs->length); - assert(pFilename); - if (!pFilename) return; - assert(pDs); - if (!pDs) return; - - bool portable = IsRunningInPortableMode(); - if (portable) { - /* Use the same path as the binary */ - char *exePath = ExePathGet(); - if (!exePath) return; - char *dir = FilePath_GetDir(exePath); - if (dir) - DStringSprintf(pDs, "%s", dir); - free((void*)exePath); - free((void*)dir); - } else { - AppGetAppDir(pDs); - } - if (!str_endswithi(pDs->pString, DIR_SEP_STR) && !(DIR_SEP_CHAR == pFilename[0])) { - DStringAppend(pDs, DIR_SEP_STR, -1); - } - DStringAppend(pDs, pFilename, -1); -} - -static void Prefs_GetFileName(DString* pDs) -{ - assert(0 == pDs->length); - AppGenDataFilename((char*)PREFS_FILE_NAME, pDs); /* @author: Klemens Friedl; char* cast */ -} - -/* Load preferences from the preferences file. */ -static void Prefs_Load(void) -{ - DString path; - static bool loaded = false; - char * prefsTxt = NULL; - - assert(!loaded); - loaded = true; - - DBG_OUT("Prefs_Load()\n"); - - DStringInit(&path); - Prefs_GetFileName(&path); - - size_t prefsFileLen; - prefsTxt = file_read_all(path.pString, &prefsFileLen); - if (str_empty(prefsTxt)) { - DBG_OUT(" no prefs file or is empty\n"); - return; - } - DBG_OUT("Prefs file %s:\n%s\n", path.pString, prefsTxt); - - bool fOk = Prefs_Deserialize(prefsTxt, &gFileHistoryRoot); - assert(fOk); - - DStringFree(&path); - free((void*)prefsTxt); -} - -static struct idToZoomMap { - UINT id; - double zoom; -} gZoomMenuItemsId[] = { - { IDM_ZOOM_6400, 6400.0 }, - { IDM_ZOOM_3200, 3200.0 }, - { IDM_ZOOM_1600, 1600.0 }, - { IDM_ZOOM_800, 800.0 }, - { IDM_ZOOM_400, 400.0 }, - { IDM_ZOOM_200, 200.0 }, - { IDM_ZOOM_150, 150.0 }, - { IDM_ZOOM_125, 125.0 }, - { IDM_ZOOM_100, 100.0 }, - { IDM_ZOOM_50, 50.0 }, - { IDM_ZOOM_25, 25.0 }, - { IDM_ZOOM_12_5, 12.5 }, - { IDM_ZOOM_8_33, 8.33 }, - { IDM_ZOOM_FIT_PAGE, ZOOM_FIT_PAGE }, - { IDM_ZOOM_FIT_WIDTH, ZOOM_FIT_WIDTH }, - { IDM_ZOOM_ACTUAL_SIZE, 100.0 } -}; - -static UINT MenuIdFromVirtualZoom(double virtualZoom) -{ - for (int i=0; i < dimof(gZoomMenuItemsId); i++) { - if (virtualZoom == gZoomMenuItemsId[i].zoom) - return gZoomMenuItemsId[i].id; - } - return IDM_ZOOM_ACTUAL_SIZE; -} - -static void ZoomMenuItemCheck(HMENU hmenu, UINT menuItemId) -{ - BOOL found = FALSE; - - for (int i=0; ihwndCanvas, &posX, &posY); - - ds->windowX = posX; - ds->windowY = posY; -} - -static void UpdateCurrentFileDisplayStateForWin(WindowInfo *win) -{ - DisplayState ds; - const char * fileName = NULL; - FileHistoryList*node = NULL; - - if (!win) - return; - if (WS_SHOWING_PDF != win->state) - return; - if (!win->dm) - return; - - fileName = win->dm->fileName(); - assert(fileName); - if (!fileName) - return; - - if (!gRunningDLL) - { - node = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, fileName); - assert(node); - if (!node) - return; - } - - DisplayState_Init(&ds); - if (!displayStateFromDisplayModel(&ds, win->dm)) - return; - - UpdateDisplayStateWindowPos(win, &ds); - DisplayState_Free(&(node->state)); - node->state = ds; - node->state.visible = TRUE; -} - -static void UpdateCurrentFileDisplayState(void) -{ - WindowInfo * currWin; - FileHistoryList * currFile; - - currFile = gFileHistoryRoot; - while (currFile) { - currFile->state.visible = FALSE; - currFile = currFile->next; - } - - currWin = gWindowList; - while (currWin) { - UpdateCurrentFileDisplayStateForWin(currWin); - currWin = currWin->next; - } -} - -static void Prefs_Save(void) -{ - DString path; - DString prefsStr; - -#if 0 - if (gPrefsSaved) - return; - gPrefsSaved = TRUE; -#endif - - DStringInit(&prefsStr); - - /* mark currently shown files as visible */ - UpdateCurrentFileDisplayState(); - - bool fOk = Prefs_Serialize(&gFileHistoryRoot, &prefsStr); - if (!fOk) - goto Exit; - - DStringInit(&path); - Prefs_GetFileName(&path); - DBG_OUT("prefs file=%s\nprefs:\n%s\n", path.pString, prefsStr.pString); - /* TODO: consider 2-step process: - * write to a temp file - * rename temp file to final file */ - write_to_file((TCHAR*)path.pString, (void*)prefsStr.pString, prefsStr.length); /* @author: Klemens Friedl; TCHAR* cast */ - -Exit: - DStringFree(&prefsStr); - DStringFree(&path); -} - -static bool WindowInfo_Dib_Init(WindowInfo *win) { - assert(NULL == win->dibInfo); - win->dibInfo = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + 12); - if (!win->dibInfo) - return false; - win->dibInfo->bmiHeader.biSize = sizeof(win->dibInfo->bmiHeader); - win->dibInfo->bmiHeader.biPlanes = 1; - win->dibInfo->bmiHeader.biBitCount = 24; - win->dibInfo->bmiHeader.biCompression = BI_RGB; - win->dibInfo->bmiHeader.biXPelsPerMeter = 2834; - win->dibInfo->bmiHeader.biYPelsPerMeter = 2834; - win->dibInfo->bmiHeader.biClrUsed = 0; - win->dibInfo->bmiHeader.biClrImportant = 0; - return true; -} - -static void WindowInfo_Dib_Deinit(WindowInfo *win) { - free((void*)win->dibInfo); - win->dibInfo = NULL; -} - -static void WindowInfo_DoubleBuffer_Delete(WindowInfo *win) { - if (win->bmpDoubleBuffer) { - DeleteObject(win->bmpDoubleBuffer); - win->bmpDoubleBuffer = NULL; - } - - if (win->hdcDoubleBuffer) { - DeleteDC(win->hdcDoubleBuffer); - win->hdcDoubleBuffer = NULL; - } - win->hdcToDraw = NULL; -} - -static bool WindowInfo_DoubleBuffer_New(WindowInfo *win) -{ - WindowInfo_DoubleBuffer_Delete(win); - - win->hdc = GetDC(win->hwndCanvas); - win->hdcToDraw = win->hdc; - win->GetCanvasSize(); - if (!gUseDoubleBuffer || (0 == win->winDx()) || (0 == win->winDy())) - return true; - - win->hdcDoubleBuffer = CreateCompatibleDC(win->hdc); - if (!win->hdcDoubleBuffer) - return false; - - win->bmpDoubleBuffer = CreateCompatibleBitmap(win->hdc, win->winDx(), win->winDy()); - if (!win->bmpDoubleBuffer) { - WindowInfo_DoubleBuffer_Delete(win); - return false; - } - /* TODO: do I need this ? */ - SelectObject(win->hdcDoubleBuffer, win->bmpDoubleBuffer); - /* fill out everything with background color */ - RECT r = {0}; - r.bottom = win->winDy(); - r.right = win->winDx(); - FillRect(win->hdcDoubleBuffer, &r, gBrushBg); - win->hdcToDraw = win->hdcDoubleBuffer; - return TRUE; -} - -static void WindowInfo_DoubleBuffer_Show(WindowInfo *win, HDC hdc) -{ - if (win->hdc != win->hdcToDraw) { - assert(win->hdcToDraw == win->hdcDoubleBuffer); - BitBlt(hdc, 0, 0, win->winDx(), win->winDy(), win->hdcDoubleBuffer, 0, 0, SRCCOPY); - } -} - -static void WindowInfo_Delete(WindowInfo *win) -{ - if (win->dm) { - RenderQueue_RemoveForDisplayModel(win->dm); - cancelRenderingForDisplayModel(win->dm); - } - delete win->dm; - win->dm = NULL; - WindowInfo_Dib_Deinit(win); - WindowInfo_DoubleBuffer_Delete(win); - delete win; -} - -static WindowInfo* WindowInfo_FindByHwnd(HWND hwnd) -{ - WindowInfo *win = gWindowList; - while (win) { - if (hwnd == win->hwndFrame) - return win; - if (hwnd == win->hwndCanvas) - return win; - if (hwnd == win->hwndReBar) - return win; - win = win->next; - } - return NULL; -} - -static WindowInfo *WindowInfo_New(HWND hwndFrame) { - WindowInfo * win = WindowInfo_FindByHwnd(hwndFrame); - assert(!win); - - win = new WindowInfo();; - if (!win) - return NULL; - - if (!WindowInfo_Dib_Init(win)) - goto Error; - - win->state = WS_ABOUT; - win->hwndFrame = hwndFrame; - win->mouseAction = MA_IDLE; - return win; -Error: - WindowInfo_Delete(win); - return NULL; -} - -static void WindowInfoList_Add(WindowInfo *win) { - win->next = gWindowList; - gWindowList = win; -} - -static bool WindowInfoList_ExistsWithError(void) { - WindowInfo *cur = gWindowList; - while (cur) { - if (WS_ERROR_LOADING_PDF == cur->state) - return true; - cur = cur->next; - } - return false; -} - -static void WindowInfoList_Remove(WindowInfo *to_remove) { - assert(to_remove); - if (!to_remove) - return; - if (gWindowList == to_remove) { - gWindowList = to_remove->next; - return; - } - WindowInfo* curr = gWindowList; - while (curr) { - if (to_remove == curr->next) { - curr->next = to_remove->next; - return; - } - curr = curr->next; - } -} - -static void WindowInfoList_DeleteAll(void) { - WindowInfo* curr = gWindowList; - while (curr) { - WindowInfo* next = curr->next; - WindowInfo_Delete(curr); - curr = next; - } - gWindowList = NULL; -} - -static int WindowInfoList_Len(void) { - int len = 0; - WindowInfo* curr = gWindowList; - while (curr) { - ++len; - curr = curr->next; - } - return len; -} - -static void WindowInfo_RedrawAll(WindowInfo *win, bool update=false) { - InvalidateRect(win->hwndCanvas, NULL, false); - if (update) - UpdateWindow(win->hwndCanvas); -} - -static bool FileCloseMenuEnabled(void) { - WindowInfo* win = gWindowList; - while (win) { - if (win->state == WS_SHOWING_PDF) - return true; - win = win->next; - } - return false; -} - -static void ToolbarUpdateStateForWindow(WindowInfo *win) { - LPARAM enable = (LPARAM)MAKELONG(1,0); - LPARAM disable = (LPARAM)MAKELONG(0,0); - - for (int i=0; i < TOOLBAR_BUTTONS_COUNT; i++) { - int cmdId = gToolbarButtons[i].cmdId; - if (IDB_SEPARATOR == cmdId) - continue; - LPARAM buttonState = enable; - if (IDM_OPEN != cmdId) { - if (WS_SHOWING_PDF != win->state) - buttonState = disable; - } - SendMessage(win->hwndToolbar, TB_ENABLEBUTTON, cmdId, buttonState); - } -} - -static void MenuUpdateShowToolbarStateForWindow(WindowInfo *win) { - HMENU hmenu = GetMenu(win->hwndFrame); - if (gShowToolbar) - CheckMenuItem(hmenu, IDM_VIEW_SHOW_HIDE_TOOLBAR, MF_BYCOMMAND | MF_CHECKED); - else - CheckMenuItem(hmenu, IDM_VIEW_SHOW_HIDE_TOOLBAR, MF_BYCOMMAND | MF_UNCHECKED); -} - -static void MenuUpdateUseFitzStateForWindow(WindowInfo *win) { - HMENU hmenu = GetMenu(win->hwndFrame); - if (gUseFitz) - CheckMenuItem(hmenu, IDM_VIEW_USE_FITZ, MF_BYCOMMAND | MF_CHECKED); - else - CheckMenuItem(hmenu, IDM_VIEW_USE_FITZ, MF_BYCOMMAND | MF_UNCHECKED); -} - -// show which language is being used via check in Language/* menu -static void MenuUpdateLanguage(WindowInfo *win) { - HMENU hmenu = GetMenu(win->hwndFrame); - for (int i = 0; i < LANGS_COUNT; i++) { - const char *langName = g_langs[i]._langName; - int langMenuId = g_langs[i]._langId; - if (str_eq(CurrLangNameGet(), langName)) - CheckMenuItem(hmenu, langMenuId, MF_BYCOMMAND | MF_CHECKED); - else - CheckMenuItem(hmenu, langMenuId, MF_BYCOMMAND | MF_UNCHECKED); - } -} - -static void MenuUpdateStateForWindow(WindowInfo *win) { - static UINT menusToDisableIfNoPdf[] = { - IDM_VIEW_SINGLE_PAGE, IDM_VIEW_FACING, IDM_VIEW_CONTINUOUS, IDM_VIEW_CONTINUOUS_FACING, - IDM_VIEW_ROTATE_LEFT, IDM_VIEW_ROTATE_RIGHT, IDM_GOTO_NEXT_PAGE, IDM_GOTO_PREV_PAGE, - IDM_GOTO_FIRST_PAGE, IDM_GOTO_LAST_PAGE, IDM_GOTO_PAGE, IDM_ZOOM_FIT_PAGE, - IDM_ZOOM_ACTUAL_SIZE, IDM_ZOOM_FIT_WIDTH, IDM_ZOOM_6400, IDM_ZOOM_3200, - IDM_ZOOM_1600, IDM_ZOOM_800, IDM_ZOOM_400, IDM_ZOOM_200, IDM_ZOOM_150, - IDM_ZOOM_125, IDM_ZOOM_100, IDM_ZOOM_50, IDM_ZOOM_25, IDM_ZOOM_12_5, - IDM_ZOOM_8_33, IDM_SAVEAS }; - - bool fileCloseEnabled = FileCloseMenuEnabled(); - HMENU hmenu = GetMenu(win->hwndFrame); - if (fileCloseEnabled) - EnableMenuItem(hmenu, IDM_CLOSE, MF_BYCOMMAND | MF_ENABLED); - else - EnableMenuItem(hmenu, IDM_CLOSE, MF_BYCOMMAND | MF_GRAYED); - - bool filePrintEnabled = false; - if (win->dm && win->dm->pdfEngine() && win->dm->pdfEngine()->printingAllowed()) - filePrintEnabled = true; - if (filePrintEnabled) - EnableMenuItem(hmenu, IDM_PRINT, MF_BYCOMMAND | MF_ENABLED); - else - EnableMenuItem(hmenu, IDM_PRINT, MF_BYCOMMAND | MF_GRAYED); - - MenuUpdateShowToolbarStateForWindow(win); - MenuUpdateUseFitzStateForWindow(win); - MenuUpdateLanguage(win); - - for (int i = 0; i < dimof(menusToDisableIfNoPdf); i++) { - UINT menuId = menusToDisableIfNoPdf[i]; - if (WS_SHOWING_PDF == win->state) - EnableMenuItem(hmenu, menuId, MF_BYCOMMAND | MF_ENABLED); - else - EnableMenuItem(hmenu, menuId, MF_BYCOMMAND | MF_GRAYED); - } - /* Hide scrollbars if not showing a PDF */ - /* TODO: doesn't really fit the name of the function */ - if (WS_SHOWING_PDF == win->state) - ShowScrollBar(win->hwndCanvas, SB_BOTH, TRUE); - else { - ShowScrollBar(win->hwndCanvas, SB_BOTH, FALSE); - win_set_text(win->hwndFrame, APP_NAME); - } -} - -/* Disable/enable menu items and toolbar buttons depending on wheter a - given window shows a PDF file or not. */ -static void MenuToolbarUpdateStateForAllWindows(void) { - WindowInfo* win = gWindowList; - while (win) { - MenuUpdateStateForWindow(win); - ToolbarUpdateStateForWindow(win); - win = win->next; - } -} - -static WindowInfo* WindowInfo_CreateEmpty(void) { - HWND hwndFrame, hwndCanvas; - WindowInfo* win; - -#if FANCY_UI - hwndFrame = CreateWindowEx( -// WS_EX_TOOLWINDOW, - 0, -// WS_OVERLAPPEDWINDOW, -// WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, - //WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_HSCROLL | WS_VSCROLL, - FRAME_CLASS_NAME, windowTitle, - WS_POPUP, - CW_USEDEFAULT, CW_USEDEFAULT, - DEF_WIN_DX, DEF_WIN_DY, - NULL, NULL, - ghinst, NULL); -#else - hwndFrame = CreateWindow( - FRAME_CLASS_NAME, windowTitle, - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, - DEF_WIN_DX, DEF_WIN_DY, - NULL, NULL, - ghinst, NULL); - HMENU m = GetProgramMenu(); - SetMenu(hwndFrame, m); -#endif - - if (!hwndFrame) - return NULL; - - win = WindowInfo_New(hwndFrame); - hwndCanvas = CreateWindow( - CANVAS_CLASS_NAME, NULL, - WS_CHILD | WS_HSCROLL | WS_VSCROLL, - CW_USEDEFAULT, CW_USEDEFAULT, - DEF_WIN_DX, DEF_WIN_DY, - hwndFrame, NULL, - ghinst, NULL); - if (!hwndCanvas) - return NULL; - win->hwndCanvas = hwndCanvas; - CreateToolbar(win, ghinst); - return win; -} - -BOOL GetDesktopWindowClientRect(RECT *r) -{ - HWND hwnd = GetDesktopWindow(); - if (!hwnd) return FALSE; - return GetClientRect(hwnd, r); -} - -void GetCanvasDxDyDiff(WindowInfo *win, int *dxOut, int *dyOut) -{ - RECT canvasRect; - GetWindowRect(win->hwndCanvas, &canvasRect); - RECT totalRect; - GetWindowRect(win->hwndFrame, &totalRect); - *dxOut = rect_dx(&totalRect) - rect_dx(&canvasRect); - // TODO: should figure out why it fires in DLL - assert(gRunningDLL || *dxOut >= 0); - *dyOut = rect_dy(&totalRect) - rect_dy(&canvasRect); - // TODO: should figure out why it fires in DLL - assert(gRunningDLL || *dyOut >= 0); -} - -SizeI GetMaxCanvasSize(WindowInfo *win) -{ - AppBarData abd; - RECT r; - GetDesktopWindowClientRect(&r); - // substract the area of the window not used for canvas - int dx, dy; - GetCanvasDxDyDiff(win, &dx, &dy); // TODO: lame name - int maxCanvasDx = rect_dx(&r) - dx; - int maxCanvasDy = rect_dy(&r) - dy; - if (abd.isHorizontal()) { - assert(maxCanvasDx >= abd.dx()); - maxCanvasDx -= abd.dx(); - } else { - assert(abd.isVertical()); - assert(maxCanvasDy >= abd.dy()); - maxCanvasDy -= abd.dy(); - } - return SizeI(maxCanvasDx, maxCanvasDy); -} - - -static void RecalcSelectionPosition (WindowInfo *win) { - SelectionOnPage * selOnPage = win->selectionOnPage; - RectD selD; - PdfPageInfo* pageInfo; - - while (selOnPage != NULL) { - pageInfo = win->dm->getPageInfo(selOnPage->pageNo); - /* if page is not visible, we hide seletion by simply moving it off - * the canvas */ - if (!pageInfo->visible) { - selOnPage->selectionCanvas.x = -100; - selOnPage->selectionCanvas.y = -100; - selOnPage->selectionCanvas.dx = 0; - selOnPage->selectionCanvas.dy = 0; - } else {//page is visible - RectD_Copy (&selD, &selOnPage->selectionPage); - win->dm->rectCvtUserToScreen (selOnPage->pageNo, &selD); - RectI_FromRectD (&selOnPage->selectionCanvas, &selD); - } - selOnPage = selOnPage->next; - } -} - -static WindowInfo* LoadPdf(const char *fileName, bool ignoreHistorySizePos = true, bool ignoreHistory = false) -{ - assert(fileName); - if (!fileName) return NULL; - - FileHistoryList * fileFromHistory = NULL; - if (!ignoreHistory) - fileFromHistory = FileHistoryList_Node_FindByFilePath(&gFileHistoryRoot, fileName); - - WindowInfo * win; - bool reuseExistingWindow = false; - if ((1 == WindowInfoList_Len()) && (WS_SHOWING_PDF != gWindowList->state)) { - win = gWindowList; - reuseExistingWindow = true; - } else { - win = WindowInfo_CreateEmpty(); - if (!win) - return NULL; - } - - win->GetCanvasSize(); - SizeI maxCanvasSize = GetMaxCanvasSize(win); - SizeD totalDrawAreaSize(win->winSize()); - if (fileFromHistory && !ignoreHistorySizePos) { - WinResizeClientArea(win->hwndCanvas, fileFromHistory->state.windowDx, fileFromHistory->state.windowDy); - totalDrawAreaSize = SizeD(fileFromHistory->state.windowDx, fileFromHistory->state.windowDy); - Win32_Win_SetPos(win->hwndFrame, fileFromHistory->state.windowX, fileFromHistory->state.windowY); - } -#if 0 // not ready yet - else { - IntelligentWindowResize(win); - } -#endif - - /* TODO: make sure it doesn't have a stupid position like - outside of the screen etc. */ -#if 0 - if (totalDrawAreaSize.dxI() > maxCanvasSize.dx) - totalDrawAreaSize.setDx(maxCanvasSize.dx); - if (totalDrawAreaSize.dyI() > maxCanvasSize.dy) - totalDrawAreaSize.setDy(maxCanvasSize.dy); - - WinResizeClientArea(win->hwndCanvas, totalDrawAreaSize.dxI(), totalDrawAreaSize.dyI()); -#endif - - /* In theory I should get scrollbars sizes using Win32_GetScrollbarSize(&scrollbarYDx, &scrollbarXDy); - but scrollbars are not part of the client area on windows so it's better - not to have them taken into account by DisplayModelSplash code. - TODO: I think it's broken anyway and DisplayModelSplash needs to know if - scrollbars are part of client area in order to accomodate windows - UI properly */ - DisplayMode displayMode = DEFAULT_DISPLAY_MODE; - int offsetX = 0; - int offsetY = 0; - int startPage = 1; - int scrollbarYDx = 0; - int scrollbarXDy = 0; - if (fileFromHistory) { - startPage = fileFromHistory->state.pageNo; - displayMode = fileFromHistory->state.displayMode; - offsetX = fileFromHistory->state.scrollX; - offsetY = fileFromHistory->state.scrollY; - } - - if (gUseFitz) { - win->dm = DisplayModelFitz_CreateFromFileName(fileName, - totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, win); - } else { - win->dm = DisplayModelSplash_CreateFromFileName(fileName, - totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, win); - } - - double zoomVirtual = DEFAULT_ZOOM; - int rotation = DEFAULT_ROTATION; - if (!win->dm) { - if (!reuseExistingWindow && WindowInfoList_ExistsWithError()) { - /* don't create more than one window with errors */ - WindowInfo_Delete(win); - return NULL; - } - win->state = WS_ERROR_LOADING_PDF; - DBG_OUT("failed to load file %s\n", fileName); - //goto Exit; /* @author: Klemens Friedl; because of "crosses initialization of [...]" */ - if (!reuseExistingWindow) - WindowInfoList_Add(win); - MenuToolbarUpdateStateForAllWindows(); - assert(win); - DragAcceptFiles(win->hwndFrame, TRUE); - DragAcceptFiles(win->hwndCanvas, TRUE); - ShowWindow(win->hwndFrame, SW_SHOW); - ShowWindow(win->hwndCanvas, SW_SHOW); - UpdateWindow(win->hwndFrame); - UpdateWindow(win->hwndCanvas); - return win; - } - - win->dm->setAppData((void*)win); - - if (!fileFromHistory) { - AddFileToHistory(fileName); - RebuildProgramMenus(); - } - - /* TODO: if fileFromHistory, set the state based on gFileHistoryList node for - this entry */ - win->state = WS_SHOWING_PDF; - if (fileFromHistory) { - zoomVirtual = fileFromHistory->state.zoomVirtual; - rotation = fileFromHistory->state.rotation; - } - - UINT menuId = MenuIdFromVirtualZoom(zoomVirtual); - ZoomMenuItemCheck(GetMenu(win->hwndFrame), menuId); - - win->dm->relayout(zoomVirtual, rotation); - if (!win->dm->validPageNo(startPage)) - startPage = 1; - /* TODO: need to calculate proper offsetY, currently giving large offsetY - remembered for continuous mode breaks things (makes all pages invisible) */ - offsetY = 0; - /* TODO: make sure offsetX isn't bogus */ - win->dm->goToPage(startPage, offsetY, offsetX); - - /* only resize the window if it's a newly opened window */ - if (!reuseExistingWindow && !fileFromHistory) - WindowInfo_ResizeToPage(win, startPage); - - if (reuseExistingWindow) - WindowInfo_RedrawAll(win); - -Exit: - if (!reuseExistingWindow) - WindowInfoList_Add(win); - MenuToolbarUpdateStateForAllWindows(); - assert(win); - DragAcceptFiles(win->hwndFrame, TRUE); - DragAcceptFiles(win->hwndCanvas, TRUE); - ShowWindow(win->hwndFrame, SW_SHOW); - ShowWindow(win->hwndCanvas, SW_SHOW); - UpdateWindow(win->hwndFrame); - UpdateWindow(win->hwndCanvas); - return win; -} - -static HFONT Win32_Font_GetSimple(HDC hdc, char *fontName, int fontSize) -{ - HFONT font_dc; - HFONT font; - LOGFONT lf = {0}; - - font_dc = (HFONT)GetStockObject(SYSTEM_FONT); - if (!GetObject(font_dc, sizeof(LOGFONT), &lf)) - return NULL; - - lf.lfHeight = (LONG)-fontSize; - lf.lfWidth = 0; - //lf.lfHeight = -MulDiv(fontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72); - lf.lfItalic = FALSE; - lf.lfUnderline = FALSE; - lf.lfStrikeOut = FALSE; - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfOutPrecision = OUT_TT_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; - //lf.lfQuality = CLEARTYPE_QUALITY; - lf.lfPitchAndFamily = DEFAULT_PITCH; - strcpy_s((char*)lf.lfFaceName, LF_FACESIZE, fontName); /* @author: Klemens Friedl; char* cast */ - lf.lfWeight = FW_DONTCARE; - font = CreateFontIndirect(&lf); - return font; -} - -static void Win32_Font_Delete(HFONT font) -{ - DeleteObject(font); -} - -void DisplayModel::pageChanged(void) -{ - WindowInfo *win = (WindowInfo*)appData(); - assert(win); - if (!win) return; - -#if 0 - if (!win->dmSplash->pdfDoc) - return; -#endif - - int currPageNo = currentPageNo(); - int pageCount = win->dm->pageCount(); - const char *baseName = FilePath_GetBaseName(win->dm->fileName()); - if (pageCount <= 0) - win_set_text(win->hwndFrame, (TCHAR*)baseName); /* @author: Klemens Friedl; TCHAR* cast */ - else { - char titleBuf[256]; - HRESULT hr = StringCchPrintfA(titleBuf, dimof(titleBuf), "%s page %d of %d", baseName, currPageNo, pageCount); - win_set_text(win->hwndFrame, (TCHAR*)titleBuf); /* @author: Klemens Friedl; TCHAR* cast */ - /* @author: Klemens Friedl; FIXME: hr is unused ATM */ - } -} - -/* Call from non-UI thread to cause repainting of the display */ -static void triggerRepaintDisplayPotentiallyDelayed(WindowInfo *win, bool delayed) -{ - assert(win); - if (!win) return; - if (delayed) - PostMessage(win->hwndCanvas, WM_APP_REPAINT_DELAYED, 0, 0); - else - PostMessage(win->hwndCanvas, WM_APP_REPAINT_NOW, 0, 0); -} - -static void triggerRepaintDisplayNow(WindowInfo* win) -{ - triggerRepaintDisplayPotentiallyDelayed(win, false); -} - -void DisplayModel::repaintDisplay(bool delayed) -{ - WindowInfo* win = (WindowInfo*)appData(); - triggerRepaintDisplayPotentiallyDelayed(win, delayed); -} - -void DisplayModel::setScrollbarsState(void) -{ - WindowInfo *win = (WindowInfo*)this->appData(); - assert(win); - if (!win) return; - - SCROLLINFO si = {0}; - si.cbSize = sizeof(si); - si.fMask = SIF_ALL; - - int canvasDx = _canvasSize.dxI(); - int canvasDy = _canvasSize.dyI(); - int drawAreaDx = drawAreaSize.dxI(); - int drawAreaDy = drawAreaSize.dyI(); - - if (drawAreaDx >= canvasDx) { - si.nPos = 0; - si.nMin = 0; - si.nMax = 99; - si.nPage = 100; - } else { - si.nPos = (int)areaOffset.x; - si.nMin = 0; - si.nMax = canvasDx-1; - si.nPage = drawAreaDx; - } - SetScrollInfo(win->hwndCanvas, SB_HORZ, &si, TRUE); - - if (drawAreaDy >= canvasDy) { - si.nPos = 0; - si.nMin = 0; - si.nMax = 99; - si.nPage = 100; - } else { - si.nPos = (int)areaOffset.y; - si.nMin = 0; - si.nMax = canvasDy-1; - si.nPage = drawAreaDy; - } - SetScrollInfo(win->hwndCanvas, SB_VERT, &si, TRUE); -} - -static void WindowInfo_ResizeToWindow(WindowInfo *win) -{ - assert(win); - if (!win) return; - assert(win->dm); - if (!win->dm) return; - - win->dm->changeTotalDrawAreaSize(win->winSize()); -} - -void WindowInfo_ResizeToPage(WindowInfo *win, int pageNo) -{ - bool fullScreen = false; - - assert(win); - if (!win) return; - assert(win->dm); - if (!win->dm) - return; - - /* TODO: should take current monitor into account? */ - HDC hdc = GetDC(win->hwndCanvas); - int displayDx = GetDeviceCaps(hdc, HORZRES); - int displayDy = GetDeviceCaps(hdc, VERTRES); - - int dx, dy; - if (fullScreen) { - /* TODO: fullscreen not yet supported */ - assert(0); - dx = displayDx; - dy = displayDy; - } else { - assert(win->dm->validPageNo(pageNo)); - if (!win->dm->validPageNo(pageNo)) - return; - PdfPageInfo *pageInfo = win->dm->getPageInfo(pageNo); - assert(pageInfo); - if (!pageInfo) - return; - DisplaySettings *displaySettings = globalDisplaySettings(); - dx = pageInfo->currDx + displaySettings->paddingPageBorderLeft + displaySettings->paddingPageBorderRight; - dy = pageInfo->currDy + displaySettings->paddingPageBorderTop + displaySettings->paddingPageBorderBottom; - if (dx > displayDx - 10) - dx = displayDx - 10; - if (dy > displayDy - 10) - dy = displayDy - 10; - } - - WinResizeClientArea(win->hwndCanvas, dx, dy); -} - -static void WindowInfo_ToggleZoom(WindowInfo *win) -{ - DisplayModel * dm; - - assert(win); - if (!win) return; - - dm = win->dm; - assert(dm); - if (!dm) return; - - if (ZOOM_FIT_PAGE == dm->zoomVirtual()) - dm->setZoomVirtual(ZOOM_FIT_WIDTH); - else if (ZOOM_FIT_WIDTH == dm->zoomVirtual()) - dm->setZoomVirtual(ZOOM_FIT_PAGE); -} - -static BOOL WindowInfo_PdfLoaded(WindowInfo *win) -{ - assert(win); - if (!win) return FALSE; - if (!win->dm) return FALSE; -#if 0 - assert(win->dmSplash->pdfDoc); - assert(win->dmSplash->pdfDoc->isOk()); -#endif - return TRUE; -} - -int WindowsVerMajor() -{ - DWORD version = GetVersion(); - return (int)(version & 0xFF); -} - -int WindowsVerMinor() -{ - DWORD version = GetVersion(); - return (int)((version & 0xFF00) >> 8); -} - -bool WindowsVer2000OrGreater() -{ - if (WindowsVerMajor() >= 5) - return true; - return false; -} - -static bool AlreadyRegisteredForPdfExtentions(void) -{ - bool registered = false; - HKEY key = NULL; - char nameBuf[sizeof(APP_NAME)+8]; - DWORD cbNameBuf = sizeof(nameBuf); - DWORD keyType; - - /* HKEY_CLASSES_ROOT\.pdf */ - if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT(".pdf"), 0, KEY_QUERY_VALUE, &key)) /* @author: Klemens Friedl; TEXT() cast */ - return false; - - if (ERROR_SUCCESS != RegQueryValueEx(key, NULL, NULL, &keyType, (LPBYTE)nameBuf, &cbNameBuf)) - goto Exit; - - if (REG_SZ != keyType) - goto Exit; - - if (cbNameBuf != sizeof(APP_NAME)) - goto Exit; - - if (0 == memcmp(APP_NAME, nameBuf, sizeof(APP_NAME))) - registered = true; - -Exit: - RegCloseKey(key); - return registered; -} - -static void AssociateExeWithPdfExtensions() -{ - char tmp[256]; - HKEY key = NULL, kicon = NULL, kshell = NULL, kopen = NULL, kcmd = NULL; - DWORD disp; - HRESULT hr; - - char * exePath = ExePathGet(); - assert(exePath); - if (!exePath) return; - - HKEY hkeyToUse = HKEY_CURRENT_USER; - if (WindowsVer2000OrGreater()) - hkeyToUse = HKEY_LOCAL_MACHINE; - - /* key\.pdf */ /* @author: Klemens Friedl; TEXT() && TCHAR* casts */ - if (RegCreateKeyEx(hkeyToUse, - TEXT(".pdf"), 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_WRITE, NULL, &key, &disp)) - goto Exit; - - if (RegSetValueEx(key, TEXT(""), 0, REG_SZ, (const BYTE*)APP_NAME, sizeof(APP_NAME))) - goto Exit; - - RegCloseKey(key); - key = NULL; - - /* key\APP_NAME */ - if (RegCreateKeyEx(hkeyToUse, - APP_NAME, 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_WRITE, NULL, &key, &disp)) - goto Exit; - - if (RegSetValueEx(key, TEXT(""), 0, REG_SZ, (const BYTE*)PDF_DOC_NAME, sizeof(PDF_DOC_NAME))) - goto Exit; - - /* key\APP_NAME\DefaultIcon */ - if (RegCreateKeyEx(key, - TEXT("DefaultIcon"), 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_WRITE, NULL, &kicon, &disp)) - goto Exit; - - /* Note: I don't understand why icon index has to be 0, but it just has to */ - hr = StringCchPrintfA(tmp, dimof(tmp), "%s,0", exePath); - if (RegSetValueEx(kicon, TEXT(""), 0, REG_SZ, (const BYTE*)tmp, strlen(tmp)+1)) - goto Exit; - - RegCloseKey(kicon); - kicon = NULL; - - /* HKEY_CLASSES_ROOT\APP_NAME\Shell\Open\Command */ - if (RegCreateKeyEx(key, - TEXT("shell"), 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_WRITE, NULL, &kshell, &disp)) - goto Exit; - - if (RegCreateKeyEx(kshell, - TEXT("open"), 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_WRITE, NULL, &kopen, &disp)) - goto Exit; - - if (RegCreateKeyEx(kopen, - TEXT("command"), 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_WRITE, NULL, &kcmd, &disp)) - goto Exit; - - hr = StringCchPrintfA(tmp, dimof(tmp), "\"%s\" \"%%1\"", exePath); - if (RegSetValueEx(kcmd, TEXT(""), 0, REG_SZ, (const BYTE*)tmp, strlen(tmp)+1)) - goto Exit; - - SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, 0, 0); - -Exit: - if (kcmd) - RegCloseKey(kcmd); - if (kopen) - RegCloseKey(kopen); - if (kshell) - RegCloseKey(kshell); - if (key) - RegCloseKey(key); - free(exePath); -} - -static void RegisterForPdfExtentions(HWND hwnd) -{ - if (AlreadyRegisteredForPdfExtentions()) - return; - - if (IsRunningInPortableMode()) - return; - - /* Ask user for permission, unless he previously said he doesn't want to - see this dialog */ - if (!gPdfAssociateDontAskAgain) { - int result = Dialog_PdfAssociate(hwnd, &gPdfAssociateDontAskAgain); - if (DIALOG_NO_PRESSED == result) { - gPdfAssociateShouldAssociate = FALSE; - } else { - assert(DIALOG_OK_PRESSED == result); - gPdfAssociateShouldAssociate = TRUE; - } - } - - if (gPdfAssociateShouldAssociate) - AssociateExeWithPdfExtensions(); -} - -static void OnDropFiles(WindowInfo *win, HDROP hDrop) -{ - int i; - char filename[MAX_PATH]; - const int files_count = DragQueryFile(hDrop, DRAGQUERY_NUMFILES, 0, 0); - - for (i = 0; i < files_count; i++) - { - DragQueryFile(hDrop, i, (TCHAR*)filename, MAX_PATH); /* @author: Klemens Friedl; TCHAR* cast */ - LoadPdf(filename); - } - DragFinish(hDrop); - - if (files_count > 0) - WindowInfo_RedrawAll(win); -} - -static void DrawLineSimple(HDC hdc, int sx, int sy, int ex, int ey) -{ - MoveToEx(hdc, sx, sy, NULL); - LineTo(hdc, ex, ey); -} - -#if 0 -/* Draw caption area for a given window 'win' in the classic AmigaOS style */ -static void AmigaCaptionDraw(WindowInfo *win) -{ - HGDIOBJ prevPen; - HDC hdc = win->hdc; - - assert(VS_AMIGA == gVisualStyle); - - prevPen = SelectObject(hdc, ghpenWhite); - - /* white */ - DrawLineSimple(hdc, 0, 0, win->winDx, 0); - DrawLineSimple(hdc, 0, 1, win->winDx, 1); - - /* white */ - DrawLineSimple(hdc, 0, 4, win->winDx, 4); - DrawLineSimple(hdc, 0, 5, win->winDx, 5); - - /* white */ - DrawLineSimple(hdc, 0, 8, win->winDx, 8); - DrawLineSimple(hdc, 0, 9, win->winDx, 9); - - /* white */ - DrawLineSimple(hdc, 0, 12, win->winDx, 12); - DrawLineSimple(hdc, 0, 13, win->winDx, 13); - - /* white */ - DrawLineSimple(hdc, 0, 16, win->winDx, 16); - DrawLineSimple(hdc, 0, 17, win->winDx, 17); - DrawLineSimple(hdc, 0, 18, win->winDx, 18); - - SelectObject(hdc, ghpenBlue); - - /* blue */ - DrawLineSimple(hdc, 0, 2, win->winDx, 2); - DrawLineSimple(hdc, 0, 3, win->winDx, 3); - - /* blue */ - DrawLineSimple(hdc, 0, 6, win->winDx, 6); - DrawLineSimple(hdc, 0, 7, win->winDx, 7); - - /* blue */ - DrawLineSimple(hdc, 0, 10, win->winDx, 10); - DrawLineSimple(hdc, 0, 11, win->winDx, 11); - - /* blue */ - DrawLineSimple(hdc, 0, 14, win->winDx, 14); - DrawLineSimple(hdc, 0, 15, win->winDx, 15); - - SelectObject(hdc, prevPen); -} -#endif - -static void WinResizeIfNeeded(WindowInfo *win, bool resizeWindow=true) -{ - RECT rc; - GetClientRect(win->hwndCanvas, &rc); - int win_dx = rect_dx(&rc); - int win_dy = rect_dy(&rc); - - if (win->hdcToDraw && - (win_dx == win->winDx()) && - (win_dy == win->winDy())) - { - return; - } - - WindowInfo_DoubleBuffer_New(win); - if (resizeWindow) - WindowInfo_ResizeToWindow(win); -} - -static void PostBenchNextAction(HWND hwnd) -{ - PostMessage(hwnd, MSG_BENCH_NEXT_ACTION, 0, 0); -} - -static void OnBenchNextAction(WindowInfo *win) -{ - if (!win->dm) - return; - - if (win->dm->goToNextPage(0)) - PostBenchNextAction(win->hwndFrame); -} - -static void DrawCenteredText(HDC hdc, RECT *r, char *txt) -{ - SetBkMode(hdc, TRANSPARENT); - DrawText(hdc, (TCHAR*)txt, strlen(txt), r, DT_CENTER | DT_VCENTER | DT_SINGLELINE); /* @author: Klemens Friedl; TCHAR* cast */ -} - -static void SeeLastError(void) { - char *msgBuf = NULL; - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR) &msgBuf, 0, NULL); - if (!msgBuf) return; - printf("SeeLastError(): %s\n", msgBuf); - OutputDebugStringA(msgBuf); - LocalFree(msgBuf); -} - -static void PaintTransparentRectangle(WindowInfo *win, HDC hdc, RectI *rect) { - HBITMAP hbitmap; // bitmap handle - BITMAPINFO bmi; // bitmap header - VOID *pvBits; // pointer to DIB section - BLENDFUNCTION bf; // structure for alpha blending - HDC rectDC = CreateCompatibleDC(hdc); - const DWORD selectionColorYellow = 0xfff5fc0c; - const DWORD selectionColorBlack = 0xff000000; - const int margin = 1; - - ZeroMemory(&bmi, sizeof(BITMAPINFO)); - - bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = rect->dx; - bmi.bmiHeader.biHeight = rect->dy; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = rect->dx * rect->dy * 4; - - hbitmap = CreateDIBSection (rectDC, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0); - SelectObject(rectDC, hbitmap); - - for (int y = 0; y < rect->dy; y++) { - for (int x = 0; x < rect->dx; x++) { - if (x < margin || x > rect->dx - margin - 1 - || y < margin || y > rect->dy - margin - 1) - ((UINT32 *)pvBits)[x + y * rect->dx] = selectionColorBlack; - else - ((UINT32 *)pvBits)[x + y * rect->dx] = selectionColorYellow; - } - } - bf.BlendOp = AC_SRC_OVER; - bf.BlendFlags = 0; - bf.SourceConstantAlpha = 0x5f; - bf.AlphaFormat = AC_SRC_ALPHA; - - /*if (!AlphaBlend(hdc, rect->x, rect->y, rect->dx, rect->dy, - rectDC, 0, 0, rect->dx, rect->dy, bf)) - DBG_OUT("AlphaBlending error\n");*/ - /* @author: Klemens Friedl; error: 'AlphaBlend' was not declared in this scope; even with WINVER: 0x0500 set in rbuild file, weird; @FIXME */ - DeleteObject (hbitmap); - DeleteDC (rectDC); -} - -static void PaintSelection (WindowInfo *win, HDC hdc) { - if (win->mouseAction == MA_SELECTING) { - // during selecting - RectI selRect; - - selRect.x = min (win->selectionRect.x, - win->selectionRect.x + win->selectionRect.dx); - selRect.y = min (win->selectionRect.y, - win->selectionRect.y + win->selectionRect.dy); - selRect.dx = abs (win->selectionRect.dx); - selRect.dy = abs (win->selectionRect.dy); - - if (selRect.dx != 0 && selRect.dy != 0) - PaintTransparentRectangle (win, hdc, &selRect); - } else { - // after selection is done - SelectionOnPage *selOnPage = win->selectionOnPage; - // TODO: Move recalcing to better place - RecalcSelectionPosition(win); - while (selOnPage != NULL) { - if (selOnPage->selectionCanvas.dx != 0 && selOnPage->selectionCanvas.dy != 0) - PaintTransparentRectangle(win, hdc, &selOnPage->selectionCanvas); - selOnPage = selOnPage->next; - } - } -} - -static void WindowInfo_Paint(WindowInfo *win, HDC hdc, PAINTSTRUCT *ps) -{ - RECT bounds; - RenderedBitmap * renderedBmp = NULL; - - assert(win); - if (!win) return; - DisplayModel* dm = win->dm; - assert(dm); - if (!dm) return; -#if 0 // TODO: write the equivalent dm->isOk() ? - assert(dm->pdfDoc); - if (!dm->pdfDoc) return; -#endif - - assert(win->hdcToDraw); - hdc = win->hdcToDraw; - - FillRect(hdc, &(ps->rcPaint), gBrushBg); - - DBG_OUT("WindowInfo_Paint() "); - for (int pageNo = 1; pageNo <= dm->pageCount(); ++pageNo) { - PdfPageInfo *pageInfo = dm->getPageInfo(pageNo); - if (!pageInfo->visible) - continue; - assert(pageInfo->shown); - if (!pageInfo->shown) - continue; - - //BitmapCacheEntry *entry = BitmapCache_Find(dm, pageNo, dm->zoomReal(), dm->rotation()); - BitmapCacheEntry *entry = BitmapCache_Find(dm, pageNo); - if (entry) { - if ((dm->rotation() != entry->rotation) || (dm->zoomReal() != entry->zoomLevel)) - entry = NULL; - else - renderedBmp = entry->bitmap; - } - - if (!renderedBmp) - DBG_OUT(" missing bitmap on visible page %d\n", pageNo); - - int xSrc = (int)pageInfo->bitmapX; - int ySrc = (int)pageInfo->bitmapY; - int bmpDx = (int)pageInfo->bitmapDx; - int bmpDy = (int)pageInfo->bitmapDy; - int xDest = (int)pageInfo->screenX; - int yDest = (int)pageInfo->screenY; - - if (!entry) { - /* TODO: assert is queued for rendering ? */ - HFONT fontRightTxt = Win32_Font_GetSimple(hdc, "Tahoma", 14); - HFONT origFont = (HFONT)SelectObject(hdc, fontRightTxt); /* Just to remember the orig font */ - bounds.left = xDest; - bounds.top = yDest; - bounds.right = xDest + bmpDx; - bounds.bottom = yDest + bmpDy; - FillRect(hdc, &bounds, gBrushWhite); - DrawCenteredText(hdc, &bounds, "Please wait - rendering..."); - DBG_OUT("drawing empty %d ", pageNo); - if (origFont) - SelectObject(hdc, origFont); - Win32_Font_Delete(fontRightTxt); - continue; - } - - if (BITMAP_CANNOT_RENDER == renderedBmp) { - bounds.left = xDest; - bounds.top = yDest; - bounds.right = xDest + bmpDx; - bounds.bottom = yDest + bmpDy; - FillRect(hdc, &bounds, gBrushWhite); - DrawCenteredText(hdc, &bounds, "Couldn't render the page"); - continue; - } - - DBG_OUT("page %d ", pageNo); - - int renderedBmpDx = renderedBmp->dx(); - int renderedBmpDy = renderedBmp->dy(); - int currPageDx = pageInfo->currDx; - int currPageDy = pageInfo->currDy; - HBITMAP hbmp = renderedBmp->createDIBitmap(hdc); - if (!hbmp) - continue; - - HDC bmpDC = CreateCompatibleDC(hdc); - if (bmpDC) { - SelectObject(bmpDC, hbmp); -#if 0 - if ((currPageDx != renderedBmpDx) || (currPageDy != renderedBmpDy)) - StretchBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, renderedBmpDx, renderedBmpDy, SRCCOPY); - else -#endif - BitBlt(hdc, xDest, yDest, bmpDx, bmpDy, bmpDC, xSrc, ySrc, SRCCOPY); - DeleteDC(bmpDC); - } - DeleteObject(hbmp); - } - - if (win->showSelection) - PaintSelection(win, hdc); - - DBG_OUT("\n"); - if (!gDebugShowLinks) - return; - - RectI drawAreaRect; - /* debug code to visualize links */ - drawAreaRect.x = (int)dm->areaOffset.x; - drawAreaRect.y = (int)dm->areaOffset.y; - drawAreaRect.dx = dm->drawAreaSize.dxI(); - drawAreaRect.dy = dm->drawAreaSize.dyI(); - - for (int linkNo = 0; linkNo < dm->linkCount(); ++linkNo) { - PdfLink *pdfLink = dm->link(linkNo); - - RectI rectLink, intersect; - rectLink.x = pdfLink->rectCanvas.x; - rectLink.y = pdfLink->rectCanvas.y; - rectLink.dx = pdfLink->rectCanvas.dx; - rectLink.dy = pdfLink->rectCanvas.dy; - - if (RectI_Intersect(&rectLink, &drawAreaRect, &intersect)) { - RECT rectScreen; - rectScreen.left = (LONG) ((double)intersect.x - dm->areaOffset.x); - rectScreen.top = (LONG) ((double)intersect.y - dm->areaOffset.y); - rectScreen.right = rectScreen.left + rectLink.dx; - rectScreen.bottom = rectScreen.top + rectLink.dy; - FillRect(hdc, &rectScreen, gBrushLinkDebug); - DBG_OUT(" link on screen rotate=%d, (x=%d, y=%d, dx=%d, dy=%d)\n", - dm->rotation() + dm->pagesInfo[pdfLink->pageNo-1].rotation, - rectScreen.left, rectScreen.top, rect_dx(&rectScreen), rect_dy(&rectScreen)); - } - } -} - -/* TODO: change the name to DrawAbout. - Draws the about screen a remember some state for hyperlinking. - It transcribes the design I did in graphics software - hopeless - to understand without seeing the design. */ -#define ABOUT_RECT_PADDING 8 -#define ABOUT_RECT_BORDER_DX_DY 4 -#define ABOUT_LINE_OUTER_SIZE 2 -#define ABOUT_LINE_RECT_SIZE 5 -#define ABOUT_LINE_SEP_SIZE 1 -#define ABOUT_LEFT_RIGHT_SPACE_DX 8 -#define ABOUT_MARGIN_DX 10 -#define ABOUT_BOX_MARGIN_DY 6 - -#define ABOUT_BORDER_COL COL_BLACK - -#define SUMATRA_TXT "Sumatra PDF" -#define SUMATRA_TXT_FONT "Arial Black" -#define SUMATRA_TXT_FONT_SIZE 24 -#define BETA_TXT "Beta v0.7" -#define BETA_TXT_FONT "Arial Black" -#define BETA_TXT_FONT_SIZE 12 -#define LEFT_TXT_FONT "Arial" -#define LEFT_TXT_FONT_SIZE 12 -#define RIGHT_TXT_FONT "Arial Black" -#define RIGHT_TXT_FONT_SIZE 12 - -#define ABOUT_BG_COLOR RGB(255,242,0) -#define ABOUT_RECT_BG_COLOR RGB(247,148,29) - -#define ABOUT_TXT_DY 6 - -typedef struct AboutLayoutInfoEl { - /* static data, must be provided */ - const char * leftTxt; - const char * rightTxt; - const char * url; - - /* data calculated by the layout */ - int leftTxtPosX; - int leftTxtPosY; - int leftTxtDx; - int leftTxtDy; - - int rightTxtPosX; - int rightTxtPosY; - int rightTxtDx; - int rightTxtDy; -} AboutLayoutInfoEl; - -AboutLayoutInfoEl gAboutLayoutInfo[] = { - { "design", "Krzysztof Kowalczyk", "http://blog.kowalczyk.info", - 0, 0, 0, 0, 0, 0, 0, 0 }, - - { "programming", "Krzysztof Kowalczyk", "http://blog.kowalczyk.info", - 0, 0, 0, 0, 0, 0, 0, 0 }, - - { "pdf rendering 1", "poppler + xpdf", "http://poppler.freedesktop.org/", - 0, 0, 0, 0, 0, 0, 0, 0 }, - - { "pdf rendering 2", "MuPDF", "http://ccxvii.net/apparition/", - 0, 0, 0, 0, 0, 0, 0, 0 }, - - { "license", "GPL v2", "http://www.gnu.org/copyleft/gpl.html", - 0, 0, 0, 0, 0, 0, 0, 0 }, - - { "website", "http://blog.kowalczyk.info/software/sumatra", "http://blog.kowalczyk.info/software/sumatrapdf", - 0, 0, 0, 0, 0, 0, 0, 0 }, - - { "forums", "http://blog.kowalczyk.info/forum_sumatra", "http://blog.kowalczyk.info/forum_sumatra", - 0, 0, 0, 0, 0, 0, 0, 0 }, - - { "program icon", "Goce Mitevski", "http://monsteer.deviantart.com", - 0, 0, 0, 0, 0, 0, 0, 0 }, - - { "toolbar icons", "Mark James", "http://www.famfamfam.com/lab/icons/silk/", - 0, 0, 0, 0, 0, 0, 0, 0 }, - - { NULL, NULL, NULL, - 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -static const char *AboutGetLink(WindowInfo *win, int x, int y) -{ - for (int i = 0; gAboutLayoutInfo[i].leftTxt; i++) { - if ((x < gAboutLayoutInfo[i].rightTxtPosX) || - (x > gAboutLayoutInfo[i].rightTxtPosX + gAboutLayoutInfo[i].rightTxtDx)) - continue; - if ((y < gAboutLayoutInfo[i].rightTxtPosY) || - (y > gAboutLayoutInfo[i].rightTxtPosY + gAboutLayoutInfo[i].rightTxtDy)) - continue; - return gAboutLayoutInfo[i].url; - } - return NULL; -} - -static void DrawAbout(HWND hwnd, HDC hdc, PAINTSTRUCT *ps) -{ - RECT rcTmp; - SIZE txtSize; - int totalDx, totalDy; - int leftDy, rightDy; - int leftLargestDx, rightLargestDx; - int sumatraPdfTxtDx, sumatraPdfTxtDy; - int betaTxtDx, betaTxtDy; - int linePosX, linePosY, lineDy; - int currY; - int fontDyDiff; - int offX, offY; - int x, y; - int boxDy; - - DString str; - DStringInit(&str); - - HBRUSH brushBg = CreateSolidBrush(ABOUT_BG_COLOR); - HBRUSH brushRectBg = CreateSolidBrush(ABOUT_RECT_BG_COLOR); - - HPEN penRectBorder = CreatePen(PS_SOLID, ABOUT_RECT_BORDER_DX_DY, COL_BLACK); - HPEN penBorder = CreatePen(PS_SOLID, ABOUT_LINE_OUTER_SIZE, COL_BLACK); - HPEN penDivideLine = CreatePen(PS_SOLID, ABOUT_LINE_SEP_SIZE, COL_BLACK); - - RECT rc; - GetClientRect(hwnd, &rc); - - int areaDx = rect_dx(&rc); - int areaDy = rect_dy(&rc); - - HFONT fontSumatraTxt = Win32_Font_GetSimple(hdc, SUMATRA_TXT_FONT, SUMATRA_TXT_FONT_SIZE); - HFONT fontBetaTxt = Win32_Font_GetSimple(hdc, BETA_TXT_FONT, BETA_TXT_FONT_SIZE); - HFONT fontLeftTxt = Win32_Font_GetSimple(hdc, LEFT_TXT_FONT, LEFT_TXT_FONT_SIZE); - HFONT fontRightTxt = Win32_Font_GetSimple(hdc, RIGHT_TXT_FONT, RIGHT_TXT_FONT_SIZE); - - HFONT origFont = (HFONT)SelectObject(hdc, fontSumatraTxt); /* Just to remember the orig font */ - - SetBkMode(hdc, TRANSPARENT); - - /* Layout stuff */ - const char *txt = SUMATRA_TXT; - GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @author: Klemens Friedl; TCHAR* cast */ - sumatraPdfTxtDx = txtSize.cx; - sumatraPdfTxtDy = txtSize.cy; - - boxDy = sumatraPdfTxtDy + ABOUT_BOX_MARGIN_DY * 2; - txt = BETA_TXT; - GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @author: Klemens Friedl; TCHAR* cast */ - betaTxtDx = txtSize.cx; - betaTxtDy = txtSize.cy; - - (HFONT)SelectObject(hdc, fontLeftTxt); - leftLargestDx = 0; - leftDy = 0; - for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { - txt = gAboutLayoutInfo[i].leftTxt; - GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @author: Klemens Friedl; TCHAR* cast */ - gAboutLayoutInfo[i].leftTxtDx = (int)txtSize.cx; - gAboutLayoutInfo[i].leftTxtDy = (int)txtSize.cy; - if (0 == i) - leftDy = gAboutLayoutInfo[i].leftTxtDy; - else - assert(leftDy == gAboutLayoutInfo[i].leftTxtDy); - if (leftLargestDx < gAboutLayoutInfo[i].leftTxtDx) - leftLargestDx = gAboutLayoutInfo[i].leftTxtDx; - } - - (HFONT)SelectObject(hdc, fontRightTxt); - rightLargestDx = 0; - rightDy = 0; - for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { - txt = gAboutLayoutInfo[i].rightTxt; - GetTextExtentPoint32(hdc, (TCHAR*)txt, strlen(txt), &txtSize); /* @author: Klemens Friedl; TCHAR* cast */ - gAboutLayoutInfo[i].rightTxtDx = (int)txtSize.cx; - gAboutLayoutInfo[i].rightTxtDy = (int)txtSize.cy; - if (0 == i) - rightDy = gAboutLayoutInfo[i].rightTxtDy; - else - assert(rightDy == gAboutLayoutInfo[i].rightTxtDy); - if (rightLargestDx < gAboutLayoutInfo[i].rightTxtDx) - rightLargestDx = gAboutLayoutInfo[i].rightTxtDx; - } - - fontDyDiff = (rightDy - leftDy) / 2; - - /* in the x order */ - totalDx = ABOUT_LINE_OUTER_SIZE + ABOUT_MARGIN_DX + leftLargestDx; - totalDx += ABOUT_LEFT_RIGHT_SPACE_DX + ABOUT_LINE_SEP_SIZE + ABOUT_LEFT_RIGHT_SPACE_DX; - totalDx += rightLargestDx + ABOUT_MARGIN_DX + ABOUT_LINE_OUTER_SIZE; - - totalDy = 0; - totalDy += boxDy; - totalDy += ABOUT_LINE_OUTER_SIZE; - totalDy += (dimof(gAboutLayoutInfo)-1) * (rightDy + ABOUT_TXT_DY); - totalDy += ABOUT_LINE_OUTER_SIZE + 4; - - offX = (areaDx - totalDx) / 2; - offY = (areaDy - totalDy) / 2; - - rcTmp.left = offX; - rcTmp.top = offY; - rcTmp.right = totalDx + offX; - rcTmp.bottom = totalDy + offY; - - FillRect(hdc, &rc, brushBg); - - SelectObject(hdc, brushBg); - SelectObject(hdc, penBorder); - - Rectangle(hdc, offX, offY + ABOUT_LINE_OUTER_SIZE, offX + totalDx, offY + boxDy + ABOUT_LINE_OUTER_SIZE); - - SetTextColor(hdc, ABOUT_BORDER_COL); - (HFONT)SelectObject(hdc, fontSumatraTxt); - x = offX + (totalDx - sumatraPdfTxtDx) / 2; - y = offY + (boxDy - sumatraPdfTxtDy) / 2; - txt = SUMATRA_TXT; - TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @author: Klemens Friedl; TCHAR* cast */ - - //SetTextColor(hdc, ABOUT_RECT_BG_COLOR); - (HFONT)SelectObject(hdc, fontBetaTxt); - //SelectObject(hdc, brushRectBg); - x = offX + (totalDx - sumatraPdfTxtDx) / 2 + sumatraPdfTxtDx + 6; - y = offY + (boxDy - sumatraPdfTxtDy) / 2; - txt = BETA_TXT; - TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @author: Klemens Friedl; TCHAR* cast */ - SetTextColor(hdc, ABOUT_BORDER_COL); - - offY += boxDy; - Rectangle(hdc, offX, offY, offX + totalDx, offY + totalDy - boxDy); - - linePosX = ABOUT_LINE_OUTER_SIZE + ABOUT_MARGIN_DX + leftLargestDx + ABOUT_LEFT_RIGHT_SPACE_DX; - linePosY = 4; - lineDy = (dimof(gAboutLayoutInfo)-1) * (rightDy + ABOUT_TXT_DY); - - /* render text on the left*/ - currY = linePosY; - (HFONT)SelectObject(hdc, fontLeftTxt); - for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { - txt = gAboutLayoutInfo[i].leftTxt; - x = linePosX + offX - ABOUT_LEFT_RIGHT_SPACE_DX - gAboutLayoutInfo[i].leftTxtDx; - y = currY + fontDyDiff + offY; - gAboutLayoutInfo[i].leftTxtPosX = x; - gAboutLayoutInfo[i].leftTxtPosY = y; - TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @author: Klemens Friedl; TCHAR* cast */ - currY += rightDy + ABOUT_TXT_DY; - } - - /* render text on the rigth */ - currY = linePosY; - (HFONT)SelectObject(hdc, fontRightTxt); - for (int i = 0; gAboutLayoutInfo[i].leftTxt != NULL; i++) { - txt = gAboutLayoutInfo[i].rightTxt; - x = linePosX + offX + ABOUT_LEFT_RIGHT_SPACE_DX; - y = currY + offY; - gAboutLayoutInfo[i].rightTxtPosX = x; - gAboutLayoutInfo[i].rightTxtPosY = y; - TextOut(hdc, x, y, (TCHAR*)txt, strlen(txt)); /* @author: Klemens Friedl; TCHAR* cast */ - currY += rightDy + ABOUT_TXT_DY; - } - - SelectObject(hdc, penDivideLine); - MoveToEx(hdc, linePosX + offX, linePosY + offY, NULL); - LineTo(hdc, linePosX + offX, linePosY + lineDy + offY); - - if (origFont) - SelectObject(hdc, origFont); - - Win32_Font_Delete(fontSumatraTxt); - Win32_Font_Delete(fontBetaTxt); - Win32_Font_Delete(fontLeftTxt); - Win32_Font_Delete(fontRightTxt); - - DeleteObject(brushBg); - DeleteObject(brushRectBg); - DeleteObject(penBorder); - DeleteObject(penDivideLine); - DeleteObject(penRectBorder); -} - -static void WinMoveDocBy(WindowInfo *win, int dx, int dy) -{ - assert(win); - if (!win) return; - assert (WS_SHOWING_PDF == win->state); - if (WS_SHOWING_PDF != win->state) return; - assert(win->dm); - if (!win->dm) return; - assert(!win->linkOnLastButtonDown); - if (win->linkOnLastButtonDown) return; - if (0 != dx) - win->dm->scrollXBy(dx); - if (0 != dy) - win->dm->scrollYBy(dy, FALSE); -} - -static void CopySelectionTextToClipboard(WindowInfo *win) -{ - SelectionOnPage * selOnPage; - - assert(win); - if (!win) return; - - if (!win->selectionOnPage) return; - - HGLOBAL handle; - unsigned short *ucsbuf; - int ucsbuflen = 4096; - - if (!OpenClipboard(NULL)) return; - - EmptyClipboard(); - - handle = GlobalAlloc(GMEM_MOVEABLE, ucsbuflen * sizeof(unsigned short)); - if (!handle) { - CloseClipboard(); - return; - } - ucsbuf = (unsigned short *) GlobalLock(handle); - - selOnPage = win->selectionOnPage; - - int copied = 0; - while (selOnPage != NULL) { - int charCopied = win->dm->getTextInRegion(selOnPage->pageNo, - &selOnPage->selectionPage, ucsbuf + copied, ucsbuflen - copied - 1); - copied += charCopied; - if (ucsbuflen - copied == 1) - break; - selOnPage = selOnPage->next; - } - ucsbuf[copied] = 0; - - GlobalUnlock(handle); - - SetClipboardData(CF_UNICODETEXT, handle); - CloseClipboard(); -} - -static void DeleteOldSelectionInfo (WindowInfo *win) { - SelectionOnPage *selOnPage = win->selectionOnPage; - while (selOnPage != NULL) { - SelectionOnPage *tmp = selOnPage->next; - free(selOnPage); - selOnPage = tmp; - } - win->selectionOnPage = NULL; -} - -static void ConvertSelectionRectToSelectionOnPage (WindowInfo *win) { - RectI pageOnScreen, intersect; - - for (int pageNo = win->dm->pageCount(); pageNo >= 1; --pageNo) { - PdfPageInfo *pageInfo = win->dm->getPageInfo(pageNo); - if (!pageInfo->visible) - continue; - assert(pageInfo->shown); - if (!pageInfo->shown) - continue; - - pageOnScreen.x = pageInfo->screenX; - pageOnScreen.y = pageInfo->screenY; - pageOnScreen.dx = pageInfo->bitmapDx; - pageOnScreen.dy = pageInfo->bitmapDy; - - if (!RectI_Intersect(&win->selectionRect, &pageOnScreen, &intersect)) - continue; - - /* selection intersects with a page on the screen */ - SelectionOnPage *selOnPage = (SelectionOnPage*)malloc(sizeof(SelectionOnPage)); - RectD_FromRectI(&selOnPage->selectionPage, &intersect); - - win->dm->rectCvtScreenToUser (&selOnPage->pageNo, &selOnPage->selectionPage); - - assert (pageNo == selOnPage->pageNo); - - selOnPage->next = win->selectionOnPage; - win->selectionOnPage = selOnPage; - } -} - -static void OnMouseLeftButtonDown(WindowInfo *win, int x, int y) -{ - assert(win); - if (!win) return; - if (WS_SHOWING_PDF == win->state && win->mouseAction == MA_IDLE) { - assert(win->dm); - if (!win->dm) return; - win->linkOnLastButtonDown = win->dm->linkAtPosition(x, y); - /* dragging mode only starts when we're not on a link */ - if (!win->linkOnLastButtonDown) { - SetCapture(win->hwndCanvas); - win->mouseAction = MA_DRAGGING; - win->dragPrevPosX = x; - win->dragPrevPosY = y; - SetCursor(gCursorDrag); - DBG_OUT(" dragging start, x=%d, y=%d\n", x, y); - } - } else if (WS_ABOUT == win->state) { - win->url = AboutGetLink(win, x, y); - } -} - -static void OnMouseLeftButtonUp(WindowInfo *win, int x, int y) -{ - PdfLink * link; - const char * url; - int dragDx, dragDy; - - assert(win); - if (!win) return; - - if (WS_ABOUT == win->state) { - url = AboutGetLink(win, x, y); - if (url == win->url) - LaunchBrowser(url); - win->url = NULL; - return; - } - - if (WS_SHOWING_PDF != win->state) - return; - - assert(win->dm); - if (!win->dm) return; - - if (win->mouseAction == MA_DRAGGING && (GetCapture() == win->hwndCanvas)) { - dragDx = 0; dragDy = 0; - dragDx = x - win->dragPrevPosX; - dragDy = y - win->dragPrevPosY; - DBG_OUT(" dragging ends, x=%d, y=%d, dx=%d, dy=%d\n", x, y, dragDx, dragDy); - assert(!win->linkOnLastButtonDown); - WinMoveDocBy(win, dragDx, -dragDy*2); - win->dragPrevPosX = x; - win->dragPrevPosY = y; - win->mouseAction = MA_IDLE; - SetCursor(gCursorArrow); - ReleaseCapture(); - return; - } - - if (!win->linkOnLastButtonDown) - return; - - link = win->dm->linkAtPosition(x, y); - if (link && (link == win->linkOnLastButtonDown)) - win->dm->handleLink(link); - win->linkOnLastButtonDown = NULL; -} - -static void OnMouseMove(WindowInfo *win, int x, int y, WPARAM flags) -{ - PdfLink * link; - const char * url; - int dragDx, dragDy; - - assert(win); - if (!win) return; - - if (WS_SHOWING_PDF == win->state) { - assert(win->dm); - if (!win->dm) return; - if (win->mouseAction == MA_SELECTING) { - SetCursor(gCursorArrow); - win->selectionRect.dx = x - win->selectionRect.x; - win->selectionRect.dy = y - win->selectionRect.y; - triggerRepaintDisplayNow(win); - } else { - if (win->mouseAction == MA_DRAGGING) { - dragDx = 0; dragDy = 0; - dragDx = -(x - win->dragPrevPosX); - dragDy = -(y - win->dragPrevPosY); - DBG_OUT(" drag move, x=%d, y=%d, dx=%d, dy=%d\n", x, y, dragDx, dragDy); - WinMoveDocBy(win, dragDx, dragDy*2); - win->dragPrevPosX = x; - win->dragPrevPosY = y; - return; - } - link = win->dm->linkAtPosition(x, y); - if (link) - SetCursor(gCursorHand); - else - SetCursor(gCursorArrow); - } - } else if (WS_ABOUT == win->state) { - url = AboutGetLink(win, x, y); - if (url) { - SetCursor(gCursorHand); - } else { - SetCursor(gCursorArrow); - } - } else { - // TODO: be more efficient, this only needs to be set once (I think) - SetCursor(gCursorArrow); - } -} - -static void OnMouseRightButtonDown(WindowInfo *win, int x, int y) -{ - //DBG_OUT("Right button clicked on %d %d\n", x, y); - assert (win); - if (!win) return; - - if (WS_SHOWING_PDF == win->state && win->mouseAction == MA_IDLE) { - win->documentBlocked = true; - DeleteOldSelectionInfo (win); - - win->selectionRect.x = x; - win->selectionRect.y = y; - win->selectionRect.dx = 0; - win->selectionRect.dy = 0; - win->showSelection = true; - win->mouseAction = MA_SELECTING; - - triggerRepaintDisplayNow(win); - } -} - -static void OnMouseRightButtonUp(WindowInfo *win, int x, int y) -{ - assert (win); - if (!win) return; - - if (WS_SHOWING_PDF == win->state && win->mouseAction == MA_SELECTING) { - assert (win->dm); - if (!win->dm) return; - win->documentBlocked = false; - - win->selectionRect.dx = abs (x - win->selectionRect.x); - win->selectionRect.dy = abs (y - win->selectionRect.y); - win->selectionRect.x = min (win->selectionRect.x, x); - win->selectionRect.y = min (win->selectionRect.y, y); - - win->mouseAction = MA_IDLE; - if (win->selectionRect.dx == 0 || win->selectionRect.dy == 0) { - win->showSelection = false; - } else { - ConvertSelectionRectToSelectionOnPage (win); - CopySelectionTextToClipboard (win); - } - triggerRepaintDisplayNow(win); - } -} - -#define ABOUT_ANIM_TIMER_ID 15 - -static void AnimState_AnimStop(AnimState *state) -{ - KillTimer(state->hwnd, ABOUT_ANIM_TIMER_ID); -} - -static void AnimState_NextFrame(AnimState *state) -{ - state->frame += 1; - InvalidateRect(state->hwnd, NULL, FALSE); - UpdateWindow(state->hwnd); -} - -static void AnimState_AnimStart(AnimState *state, HWND hwnd, UINT freqInMs) -{ - assert(IsWindow(hwnd)); - AnimState_AnimStop(state); - state->frame = 0; - state->hwnd = hwnd; - SetTimer(state->hwnd, ABOUT_ANIM_TIMER_ID, freqInMs, NULL); - AnimState_NextFrame(state); -} - -#define ANIM_FONT_NAME "Georgia" -#define ANIM_FONT_SIZE_START 20 -#define SCROLL_SPEED 3 - -static void DrawAnim2(WindowInfo *win, HDC hdc, PAINTSTRUCT *ps) -{ - AnimState * state = &(win->animState); - DString txt; - RECT rc; - HFONT fontArial24 = NULL; - HFONT origFont = NULL; - int curFontSize; - static int curTxtPosX = -1; - static int curTxtPosY = -1; - static int curDir = SCROLL_SPEED; - - GetClientRect(win->hwndCanvas, &rc); - - DStringInit(&txt); - - if (-1 == curTxtPosX) - curTxtPosX = 40; - if (-1 == curTxtPosY) - curTxtPosY = 25; - - int areaDx = rect_dx(&rc); - int areaDy = rect_dy(&rc); - -#if 0 - if (state->frame % 24 <= 12) { - curFontSize = ANIM_FONT_SIZE_START + (state->frame % 24); - } else { - curFontSize = ANIM_FONT_SIZE_START + 12 - (24 - (state->frame % 24)); - } -#else - curFontSize = ANIM_FONT_SIZE_START; -#endif - - curTxtPosY += curDir; - if (curTxtPosY < 20) - curDir = SCROLL_SPEED; - else if (curTxtPosY > areaDy - 40) - curDir = -SCROLL_SPEED; - - fontArial24 = Win32_Font_GetSimple(hdc, ANIM_FONT_NAME, curFontSize); - assert(fontArial24); - - origFont = (HFONT)SelectObject(hdc, fontArial24); - - SetBkMode(hdc, TRANSPARENT); - FillRect(hdc, &rc, gBrushBg); - //DStringSprintf(&txt, "Welcome to animation %d", state->frame); - DStringSprintf(&txt, "Welcome to animation"); - //DrawText (hdc, txt.pString, -1, &rc, DT_SINGLELINE); - TextOut(hdc, curTxtPosX, curTxtPosY, (TCHAR*)txt.pString, txt.length); /* @author: Klemens Friedl; TCHAR* cast */ - WindowInfo_DoubleBuffer_Show(win, hdc); - if (state->frame > 99) - state->frame = 0; - - if (origFont) - SelectObject(hdc, origFont); - Win32_Font_Delete(fontArial24); -} - -static void WindowInfo_DoubleBuffer_Resize_IfNeeded(WindowInfo *win) -{ - WinResizeIfNeeded(win, false); -} - -static void OnPaintAbout(HWND hwnd) -{ - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hwnd, &ps); - SetBkMode(hdc, TRANSPARENT); - DrawAbout(hwnd, hdc, &ps); - EndPaint(hwnd, &ps); -} - -static void OnPaint(WindowInfo *win) -{ - PAINTSTRUCT ps; - HDC hdc = BeginPaint(win->hwndCanvas, &ps); - - SetBkMode(hdc, TRANSPARENT); - RECT rc; - GetClientRect(win->hwndCanvas, &rc); - - if (WS_ABOUT == win->state) { - WindowInfo_DoubleBuffer_Resize_IfNeeded(win); - DrawAbout(win->hwndCanvas, win->hdcToDraw, &ps); - WindowInfo_DoubleBuffer_Show(win, hdc); - } else if (WS_ERROR_LOADING_PDF == win->state) { - HFONT fontRightTxt = Win32_Font_GetSimple(hdc, "Tahoma", 14); - HFONT origFont = (HFONT)SelectObject(hdc, fontRightTxt); /* Just to remember the orig font */ - FillRect(hdc, &ps.rcPaint, gBrushBg); - /* @author: Klemens Friedl; translation function and it's related macros need some care */ - //DrawText(hdc, _TR("Error loading PDF file."), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; - DrawText(hdc, TEXT("Error loading PDF file."), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; - if (origFont) - SelectObject(hdc, origFont); - Win32_Font_Delete(fontRightTxt); - } else if (WS_SHOWING_PDF == win->state) { - //TODO: it might cause infinite loop due to showing/hiding scrollbars - WinResizeIfNeeded(win); - WindowInfo_Paint(win, hdc, &ps); -#if 0 - if (VS_AMIGA == gVisualStyle) - AmigaCaptionDraw(win); -#endif - WindowInfo_DoubleBuffer_Show(win, hdc); - } else - assert(0); - - EndPaint(win->hwndCanvas, &ps); -} - -static void OnMenuExit(void) -{ - Prefs_Save(); - PostQuitMessage(0); -} - -/* Close the document associated with window 'hwnd'. - Closes the window unless this is the last window in which - case it switches to empty window and disables the "File\Close" - menu item. */ -static void CloseWindow(WindowInfo *win, bool quitIfLast) -{ - assert(win); - if (!win) return; - - bool lastWindow = false; - if (gRunningDLL) { - lastWindow = true; - } else { - if (1 == WindowInfoList_Len()) - lastWindow = true; - - if (lastWindow) - Prefs_Save(); - else - UpdateCurrentFileDisplayStateForWin(win); - } - - win->state = WS_ABOUT; - - if (lastWindow && !quitIfLast) { - /* last window - don't delete it */ - delete win->dm; - win->dm = NULL; - WindowInfo_RedrawAll(win); - } else { - HWND hwndToDestroy = win->hwndFrame; - WindowInfoList_Remove(win); - WindowInfo_Delete(win); - DragAcceptFiles(hwndToDestroy, FALSE); - DestroyWindow(hwndToDestroy); - } - - if (lastWindow && quitIfLast) { - assert(0 == WindowInfoList_Len()); - PostQuitMessage(0); - } else { - if (!gRunningDLL) - MenuToolbarUpdateStateForAllWindows(); - } -} - -/* Zoom document in window 'hwnd' to zoom level 'zoom'. - 'zoom' is given as a floating-point number, 1.0 is 100%, 2.0 is 200% etc. -*/ -static void OnMenuZoom(WindowInfo *win, UINT menuId) -{ - if (!win->dm) - return; - - double zoom = ZoomMenuItemToZoom(menuId); - win->dm->zoomTo(zoom); - ZoomMenuItemCheck(GetMenu(win->hwndFrame), menuId); -} - -static bool CheckPrinterStretchDibSupport(HWND hwndForMsgBox, HDC hdc) -{ - // most printers can support stretchdibits, - // whereas a lot of printers do not support bitblt - // quit if printer doesn't support StretchDIBits - int rasterCaps = GetDeviceCaps(hdc, RASTERCAPS); - int supportsStretchDib = rasterCaps & RC_STRETCHDIB; - if (supportsStretchDib) - return true; - - MessageBox(hwndForMsgBox, TEXT("This printer doesn't support StretchDIBits function"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); - return false; -} - -// TODO: make it run in a background thread by constructing new PdfEngine() -// from a file name - this should be thread safe -static void PrintToDevice(DisplayModel *dm, HDC hdc, LPDEVMODE devMode, int fromPage, int toPage) { - - assert(toPage >= fromPage); - assert(dm); - if (!dm) return; - - PdfEngine *pdfEngine = dm->pdfEngine(); - DOCINFO di = {0}; - di.cbSize = sizeof (DOCINFO); - di.lpszDocName = (LPCTSTR)pdfEngine->fileName(); - - if (StartDoc(hdc, &di) <= 0) - return; - - // rendering for the same DisplayModel is not thread-safe - // TODO: in fitz, propably rendering anything might not be thread-safe - RenderQueue_RemoveForDisplayModel(dm); - cancelRenderingForDisplayModel(dm); - - // print all the pages the user requested unless - // bContinue flags there is a problem. - for (int pageNo = fromPage; pageNo <= toPage; pageNo++) { - int rotation = pdfEngine->pageRotation(pageNo); - - DBG_OUT(" printing: drawing bitmap for page %d\n", pageNo); - - // render at a big zoom, 250% should be good enough. It's a compromise - // between quality and memory usage. TODO: ideally we would use zoom - // that matches the size of the page in the printer - // TODO: consider using a greater zoom level e.g. 750.0 - RenderedBitmap *bmp = pdfEngine->renderBitmap(pageNo, 250.0, rotation, NULL, NULL); - if (!bmp) - goto Error; /* most likely ran out of memory */ - - StartPage(hdc); - // MM_TEXT: Each logical unit is mapped to one device pixel. - // Positive x is to the right; positive y is down. - SetMapMode(hdc, MM_TEXT); - - int pageHeight = GetDeviceCaps(hdc, PHYSICALHEIGHT); - int pageWidth = GetDeviceCaps(hdc, PHYSICALWIDTH); - - int topMargin = GetDeviceCaps(hdc, PHYSICALOFFSETY); - int leftMargin = GetDeviceCaps(hdc, PHYSICALOFFSETX); - if (DMORIENT_LANDSCAPE == devMode->dmOrientation) - swap_int(&topMargin, &leftMargin); - - bmp->stretchDIBits(hdc, -leftMargin, -topMargin, pageWidth, pageHeight); - delete bmp; - if (EndPage(hdc) <= 0) { - AbortDoc(hdc); - return; - } - } - -Error: - EndDoc(hdc); -} - -/* Show Print Dialog box to allow user to select the printer -and the pages to print. - -Creates a new dummy page for each page with a large zoom factor, -and then uses StretchDIBits to copy this to the printer's dc. - -So far have tested printing from XP to - - Acrobat Professional 6 (note that acrobat is usually set to - downgrade the resolution of its bitmaps to 150dpi) - - HP Laserjet 2300d - - HP Deskjet D4160 - - Lexmark Z515 inkjet, which should cover most bases. -*/ -static void OnMenuPrint(WindowInfo *win) -{ - PRINTDLG pd; - - assert(win); - if (!win) return; - - DisplayModel *dm = win->dm; - assert(dm); - if (!dm) return; - - /* printing uses the WindowInfo win that is created for the - screen, it may be possible to create a new WindowInfo - for printing to so we don't mess with the screen one, - but the user is not inconvenienced too much, and this - way we only need to concern ourselves with one dm. - TODO: don't re-use WindowInfo, use a different, synchronious - way of creating a bitmap */ - ZeroMemory(&pd, sizeof(pd)); - pd.lStructSize = sizeof(pd); - pd.hwndOwner = win->hwndFrame; - pd.hDevMode = NULL; - pd.hDevNames = NULL; - pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; - pd.nCopies = 1; - /* by default print all pages */ - pd.nFromPage = 1; - pd.nToPage = dm->pageCount(); - pd.nMinPage = 1; - pd.nMaxPage = dm->pageCount(); - - BOOL pressedOk = PrintDlg(&pd); - if (!pressedOk) { - if (CommDlgExtendedError()) { - /* if PrintDlg was cancelled then - CommDlgExtendedError is zero, otherwise it returns the - error code, which we could look at here if we wanted. - for now just warn the user that printing has stopped - becasue of an error */ - MessageBox(win->hwndFrame, TEXT("Cannot initialise printer"), TEXT("Printing problem."), MB_ICONEXCLAMATION | MB_OK); - } /* @author: Klemens Friedl; TEXT() casts */ - return; - } - - if (CheckPrinterStretchDibSupport(win->hwndFrame, pd.hDC)) - PrintToDevice(dm, pd.hDC, (LPDEVMODE)pd.hDevMode, pd.nFromPage, pd.nToPage); - - DeleteDC(pd.hDC); - if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames); - if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode); -} - -static void OnMenuSaveAs(WindowInfo *win) -{ - OPENFILENAME ofn = {0}; - char dstFileName[MAX_PATH] = {0}; - const char* srcFileName = NULL; - - assert(win); - if (!win) return; - assert(win->dm); - if (!win->dm) return; - - srcFileName = win->dm->fileName(); - assert(srcFileName); - if (!srcFileName) return; - - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = win->hwndFrame; - ofn.lpstrFile = (TCHAR*)dstFileName; - - // Set lpstrFile[0] to '\0' so that GetOpenFileName does not - // use the contents of szFile to initialize itself. - ofn.lpstrFile[0] = '\0'; - ofn.nMaxFile = dimof(dstFileName); - ofn.lpstrFilter = TEXT("PDF\0*.pdf\0All\0*.*\0"); /* @author: Klemens Friedl; TEXT() casts */ - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT; - - if (FALSE == GetSaveFileName(&ofn)) - return; - - char* realDstFileName = dstFileName; - if (!str_endswithi(dstFileName, ".pdf")) { - realDstFileName = str_cat(dstFileName, ".pdf"); - } - BOOL cancelled = FALSE; - BOOL ok = CopyFileEx((TCHAR*)srcFileName, (TCHAR*)realDstFileName, NULL, NULL, &cancelled, COPY_FILE_FAIL_IF_EXISTS); /* @author: Klemens Friedl; TCHAR* cast */ - if (!ok) { - SeeLastError(); - /* @author: Klemens Friedl; translation needs some care */ - //MessageBox(win->hwndFrame, _TR("Failed to save a file"), TEXT("Information"), MB_OK); - MessageBox(win->hwndFrame, TEXT("Failed to save a file"), TEXT("Information"), MB_OK); - } - if (realDstFileName != dstFileName) - free(realDstFileName); -} - -static void OnMenuOpen(WindowInfo *win) -{ - OPENFILENAME ofn = {0}; - char fileName[PATH_MAX]; - - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = win->hwndFrame; - ofn.lpstrFile = (TCHAR*)fileName; /* @author: Klemens Friedl; TCHAR* cast */ - - // Set lpstrFile[0] to '\0' so that GetOpenFileName does not - // use the contents of szFile to initialize itself. - ofn.lpstrFile[0] = '\0'; - ofn.nMaxFile = sizeof(fileName); - ofn.lpstrFilter = TEXT("PDF\0*.pdf\0All\0*.*\0"); - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - - if (FALSE == GetOpenFileName(&ofn)) - return; - - win = LoadPdf(fileName); - if (!win) - return; -} - -static void RotateLeft(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - win->dm->rotateBy(-90); -} - -static void RotateRight(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - win->dm->rotateBy(90); -} - -static void OnVScroll(WindowInfo *win, WPARAM wParam) -{ - if (win->documentBlocked) return; - SCROLLINFO si = {0}; - int iVertPos; - - si.cbSize = sizeof (si); - si.fMask = SIF_ALL; - GetScrollInfo(win->hwndCanvas, SB_VERT, &si); - - iVertPos = si.nPos; - - switch (LOWORD(wParam)) - { - case SB_TOP: - si.nPos = si.nMin; - break; - - case SB_BOTTOM: - si.nPos = si.nMax; - break; - - case SB_LINEUP: - si.nPos -= 16; - break; - - case SB_LINEDOWN: - si.nPos += 16; - break; - - case SB_PAGEUP: - si.nPos -= si.nPage; - break; - - case SB_PAGEDOWN: - si.nPos += si.nPage; - break; - - case SB_THUMBTRACK: - si.nPos = si.nTrackPos; - break; - - default: - break; - } - - // Set the position and then retrieve it. Due to adjustments - // by Windows it may not be the same as the value set. - si.fMask = SIF_POS; - SetScrollInfo(win->hwndCanvas, SB_VERT, &si, TRUE); - GetScrollInfo(win->hwndCanvas, SB_VERT, &si); - - // If the position has changed, scroll the window and update it - if (win->dm && (si.nPos != iVertPos)) - win->dm->scrollYTo(si.nPos); -} - -static void OnHScroll(WindowInfo *win, WPARAM wParam) -{ - if (win->documentBlocked) return; - SCROLLINFO si = {0}; - int iVertPos; - - si.cbSize = sizeof (si); - si.fMask = SIF_ALL; - GetScrollInfo(win->hwndCanvas, SB_HORZ, &si); - - iVertPos = si.nPos; - - switch (LOWORD(wParam)) - { - case SB_TOP: - si.nPos = si.nMin; - break; - - case SB_BOTTOM: - si.nPos = si.nMax; - break; - - case SB_LINEUP: - si.nPos -= 16; - break; - - case SB_LINEDOWN: - si.nPos += 16; - break; - - case SB_PAGEUP: - si.nPos -= si.nPage; - break; - - case SB_PAGEDOWN: - si.nPos += si.nPage; - break; - - case SB_THUMBTRACK: - si.nPos = si.nTrackPos; - break; - - default: - break; - } - - // Set the position and then retrieve it. Due to adjustments - // by Windows it may not be the same as the value set. - si.fMask = SIF_POS; - SetScrollInfo(win->hwndCanvas, SB_HORZ, &si, TRUE); - GetScrollInfo(win->hwndCanvas, SB_HORZ, &si); - - // If the position has changed, scroll the window and update it - if (win->dm && (si.nPos != iVertPos)) - win->dm->scrollXTo(si.nPos); -} - -static void ViewWithAcrobat(WindowInfo *win) -{ - // TODO: write me -} - -static void OnMenuViewSinglePage(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - SwitchToDisplayMode(win, DM_SINGLE_PAGE); -} - -static void OnMenuViewFacing(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - SwitchToDisplayMode(win, DM_FACING); -} - -static void OneMenuMakeDefaultReader(void) -{ - AssociateExeWithPdfExtensions(); - /* @author: Klemens Friedl; translation need some care */ - //MessageBox(NULL, _TR("SumatraPDF is now a default reader for PDF files."), "Information", MB_OK); - MessageBox(NULL, TEXT("SumatraPDF is now a default reader for PDF files."), TEXT("Information"), MB_OK); -} - -static void OnSize(WindowInfo *win, int dx, int dy) -{ - int rebBarDy = 0; - if (gShowToolbar) { - SetWindowPos(win->hwndReBar, NULL, 0, 0, dx, rebBarDy, SWP_NOZORDER); - rebBarDy = gReBarDy + gReBarDyFrame; - } - SetWindowPos(win->hwndCanvas, NULL, 0, rebBarDy, dx, dy-rebBarDy, SWP_NOZORDER); -} - -static void ReloadPdfDocument(WindowInfo *win) -{ - if (WS_SHOWING_PDF != win->state) - return; - const char *fileName = NULL; - if (win->dm) - fileName = (const char*)str_dup(win->dm->fileName()); - CloseWindow(win, false); - if (fileName) { - LoadPdf(fileName); - free((void*)fileName); - } -} - -static void RebuildProgramMenus(void) -{ - HMENU m = ForceRebuildMenu(); - WindowInfo *win = gWindowList; - while (win) { - SetMenu(win->hwndFrame, m); - MenuUpdateStateForWindow(win); - win = win->next; - } -} - -static void LanguageChanged(const char *langName) -{ - assert(!str_eq(langName, CurrLangNameGet())); - - CurrLangNameSet(langName); - - RebuildProgramMenus(); - // TODO: recreate tooltips -} - -static void OnMenuLanguage(int langId) -{ - const char *langName = NULL; - for (int i=0; i < LANGS_COUNT; i++) { - if (g_langs[i]._langId == langId) { - langName = g_langs[i]._langName; - break; - } - } - - assert(langName); - if (!langName) return; - if (str_eq(langName, CurrLangNameGet())) - return; - LanguageChanged(langName); -} - -static void OnMenuViewUseFitz(WindowInfo *win) -{ - assert(win); - DBG_OUT("OnMenuViewUseFitz()\n"); - if (gUseFitz) - gUseFitz = FALSE; - else - gUseFitz = TRUE; - - ReloadPdfDocument(win); - win = gWindowList; - while (win) { - MenuUpdateUseFitzStateForWindow(win); - win = win->next; - } -} - -static void OnMenuViewShowHideToolbar() -{ - if (gShowToolbar) - gShowToolbar = FALSE; - else - gShowToolbar = TRUE; - - WindowInfo* win = gWindowList; - while (win) { - if (gShowToolbar) - ShowWindow(win->hwndReBar, SW_SHOW); - else - ShowWindow(win->hwndReBar, SW_HIDE); - int dx, dy, x, y; - Win32_Win_GetPos(win->hwndFrame, &x, &y); - Win32_Win_GetSize(win->hwndFrame, &dx, &dy); - // TODO: a hack. I add 1 to dy to cause sending WM_SIZE msg to hwndFrame - // but I shouldn't really change the size. But I don't know how to - // cause sending WM_SIZE otherwise. I tried calling OnSize() directly, - // but it left scrollbar partially hidden - MoveWindow(win->hwndFrame, x, y, dx, dy+1, TRUE); - MenuUpdateShowToolbarStateForWindow(win); - win = win->next; - } -} - -static void OnMenuViewContinuous(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - SwitchToDisplayMode(win, DM_CONTINUOUS); -} - -static void OnMenuViewContinuousFacing(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - SwitchToDisplayMode(win, DM_CONTINUOUS_FACING); -} - -static void OnMenuGoToNextPage(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - win->dm->goToNextPage(0); -} - -static void OnMenuGoToPrevPage(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - win->dm->goToPrevPage(0); -} - -static void OnMenuGoToLastPage(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - win->dm->goToLastPage(); -} - -static void OnMenuGoToFirstPage(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - win->dm->goToFirstPage(); -} - -static void OnMenuGoToPage(WindowInfo *win) -{ - assert(win); - if (!win) return; - if (!WindowInfo_PdfLoaded(win)) - return; - - int newPageNo = Dialog_GoToPage(win); - if (win->dm->validPageNo(newPageNo)) - win->dm->goToPage(newPageNo, 0); -} - -static void OnMenuViewRotateLeft(WindowInfo *win) -{ - RotateLeft(win); -} - -static void OnMenuViewRotateRight(WindowInfo *win) -{ - RotateRight(win); -} - -#define KEY_PRESSED_MASK 0x8000 -static bool WasKeyDown(int virtKey) -{ - SHORT state = GetKeyState(virtKey); - if (KEY_PRESSED_MASK & state) - return true; - return false; -} - -static bool WasShiftPressed() -{ - return WasKeyDown(VK_LSHIFT) || WasKeyDown(VK_RSHIFT); -} - -static bool WasCtrlPressed() -{ - return WasKeyDown(VK_LCONTROL) || WasKeyDown(VK_RCONTROL); -} - -static void OnKeydown(WindowInfo *win, int key, LPARAM lparam) -{ - if (!win->dm) - return; - if (win->documentBlocked) - return; - - bool shiftPressed = WasShiftPressed(); - bool ctrlPressed = WasCtrlPressed(); - //DBG_OUT("key=%d,%c,shift=%d,ctrl=%d\n", key, (char)key, (int)shiftPressed, (int)ctrlPressed); - - if (VK_PRIOR == key) { - /* TODO: more intelligence (see VK_NEXT comment). Also, probably - it's exactly the same as 'n' so the code should be factored out */ - win->dm->goToPrevPage(0); - /* SendMessage (win->hwnd, WM_VSCROLL, SB_PAGEUP, 0); */ - } else if (VK_NEXT == key) { - /* TODO: this probably should be more intelligent (scroll if not yet at the bottom, - go to next page if at the bottom, and something entirely different in continuous mode */ - win->dm->goToNextPage(0); - /* SendMessage (win->hwnd, WM_VSCROLL, SB_PAGEDOWN, 0); */ - } else if (VK_UP == key) { - SendMessage (win->hwndCanvas, WM_VSCROLL, SB_LINEUP, 0); - } else if (VK_DOWN == key) { - SendMessage (win->hwndCanvas, WM_VSCROLL, SB_LINEDOWN, 0); - } else if (VK_LEFT == key) { - SendMessage (win->hwndCanvas, WM_HSCROLL, SB_PAGEUP, 0); - } else if (VK_RIGHT == key) { - SendMessage (win->hwndCanvas, WM_HSCROLL, SB_PAGEDOWN, 0); - } else if (VK_HOME == key) { - win->dm->goToFirstPage(); - } else if (VK_END == key) { - win->dm->goToLastPage(); -#if 0 // we do it via accelerators - } else if ('G' == key) { - if (ctrlPressed) - OnMenuGoToPage(win); -#endif - } else if (VK_OEM_PLUS == key) { - // Emulate acrobat: "Shift Ctrl +" is rotate clockwise - if (shiftPressed & ctrlPressed) - RotateRight(win); - } else if (VK_OEM_MINUS == key) { - // Emulate acrobat: "Shift Ctrl -" is rotate counter-clockwise - if (shiftPressed & ctrlPressed) - RotateLeft(win); - } -} - -static void OnChar(WindowInfo *win, int key) -{ - if (!win->dm) - return; - if (win->documentBlocked) - return; - -// DBG_OUT("char=%d,%c\n", key, (char)key); - - if (VK_SPACE == key) { - win->dm->scrollYByAreaDy(true, true); - } else if (VK_BACK == key) { - win->dm->scrollYByAreaDy(false, true); - } else if ('g' == key) { - OnMenuGoToPage(win); - } else if ('k' == key) { - SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEDOWN, 0); - } else if ('j' == key) { - SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEUP, 0); - } else if ('n' == key) { - win->dm->goToNextPage(0); - } else if ('c' == key) { - // TODO: probably should preserve facing vs. non-facing - win->dm->changeDisplayMode(DM_CONTINUOUS); - } else if ('p' == key) { - win->dm->goToPrevPage(0); - } else if ('z' == key) { - WindowInfo_ToggleZoom(win); - } else if ('q' == key) { - DestroyWindow(win->hwndFrame); - } else if ('+' == key) { - win->dm->zoomBy(ZOOM_IN_FACTOR); - } else if ('-' == key) { - win->dm->zoomBy(ZOOM_OUT_FACTOR); - } else if ('r' == key) { - ReloadPdfDocument(win); - } -} - -static inline bool IsEnumPrintersArg(const char *txt) -{ - if (str_ieq(txt, ENUM_PRINTERS_ARG_TXT)) - return true; - return false; -} - -static inline bool IsDontRegisterExtArg(const char *txt) -{ - if (str_ieq(txt, NO_REGISTER_EXT_ARG_TXT)) - return true; - return false; -} - -static inline bool IsPrintToArg(const char *txt) -{ - if (str_ieq(txt, PRINT_TO_ARG_TXT)) - return true; - return false; -} - -static inline bool IsPrintToDefaultArg(const char *txt) -{ - if (str_ieq(txt, PRINT_TO_ARG_TXT)) - return true; - return false; -} - -static inline bool IsExitOnPrintArg(const char *txt) -{ - if (str_ieq(txt, EXIT_ON_PRINT_ARG_TXT)) - return true; - return false; -} - -static inline bool IsBenchArg(const char *txt) -{ - if (str_ieq(txt, BENCH_ARG_TXT)) - return true; - return false; -} - -static bool IsBenchMode(void) -{ - if (NULL != gBenchFileName) - return true; - return false; -} - -/* Find a file in a file history list that has a given 'menuId'. - Return a copy of filename or NULL if couldn't be found. - It's used to figure out if a menu item selected by the user - is one of the "recent files" menu items in File menu. - Caller needs to free() the memory. - */ -static const char *RecentFileNameFromMenuItemId(UINT menuId) { - FileHistoryList* curr = gFileHistoryRoot; - while (curr) { - if (curr->menuId == menuId) - return str_dup(curr->state.filePath); - curr = curr->next; - } - return NULL; -} - -#define FRAMES_PER_SECS 60 -#define ANIM_FREQ_IN_MS 1000 / FRAMES_PER_SECS - -static void OnMenuAbout() { - if (gHwndAbout) { - SetActiveWindow(gHwndAbout); - return; - } - gHwndAbout = CreateWindow( - ABOUT_CLASS_NAME, (TCHAR*)ABOUT_WIN_TITLE, - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, - ABOUT_WIN_DX, ABOUT_WIN_DY, - NULL, NULL, - ghinst, NULL); /* @author: Klemens Friedl; TCHAR* cast */ - if (!gHwndAbout) - return; - ShowWindow(gHwndAbout, SW_SHOW); -} - -BOOL PrivateIsAppThemed() { - BOOL isThemed = FALSE; - HMODULE hDll = LoadLibrary(TEXT("uxtheme.dll")); /* @author: Klemens Friedl; TEXT() cast */ - if (!hDll) return FALSE; - - FARPROC fp = GetProcAddress(hDll, TEXT("IsAppThemed")); /* @author: Klemens Friedl; TEXT() cast */ - if (fp) - isThemed = fp(); - - FreeLibrary(hDll); - return isThemed; -} - -static TBBUTTON TbButtonFromButtonInfo(int i) { - TBBUTTON tbButton = {0}; - if (IDB_SEPARATOR == gToolbarButtons[i].cmdId) { - tbButton.fsStyle = TBSTYLE_SEP; - } else { - tbButton.iBitmap = gToolbarButtons[i].index; - tbButton.idCommand = gToolbarButtons[i].cmdId; - tbButton.fsState = TBSTATE_ENABLED; - tbButton.fsStyle = TBSTYLE_BUTTON; - tbButton.iString = (INT_PTR)gToolbarButtons[i].toolTip; - } - return tbButton; -} - -#define WS_TOOLBAR (WS_CHILD | WS_CLIPSIBLINGS | \ - TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | \ - TBSTYLE_LIST | CCS_NODIVIDER | CCS_NOPARENTALIGN ) - -static void CreateToolbar(WindowInfo *win, HINSTANCE hInst) { - BOOL bIsAppThemed = PrivateIsAppThemed(); - - HWND hwndOwner = win->hwndFrame; - HWND hwndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_TOOLBAR, - 0,0,0,0, hwndOwner,(HMENU)IDC_TOOLBAR, hInst,NULL); - win->hwndToolbar = hwndToolbar; - LRESULT lres = SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); - - ShowWindow(hwndToolbar, SW_SHOW); - HIMAGELIST himl = 0; - TBBUTTON tbButtons[TOOLBAR_BUTTONS_COUNT]; - for (int i=0; i < TOOLBAR_BUTTONS_COUNT; i++) { - if (IDB_SEPARATOR != gToolbarButtons[i].bitmapResourceId) { - HBITMAP hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(gToolbarButtons[i].bitmapResourceId)); - if (!himl) { - BITMAP bmp; - GetObject(hbmp, sizeof(BITMAP), &bmp); - int dx = bmp.bmWidth; - int dy = bmp.bmHeight; - himl = ImageList_Create(dx, dy, ILC_COLORDDB | ILC_MASK, 0, 0); - } - int index = ImageList_AddMasked(himl, hbmp, RGB(255,0,255)); - DeleteObject(hbmp); - gToolbarButtons[i].index = index; - } - tbButtons[i] = TbButtonFromButtonInfo(i); - } - lres = SendMessage(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl); - - // TODO: construct disabled image list as well? - //SendMessage(hwndToolbar, TB_SETDISABLEDIMAGELIST, 0, (LPARAM)himl); - - LRESULT exstyle = SendMessage(hwndToolbar, TB_GETEXTENDEDSTYLE, 0, 0); - exstyle |= TBSTYLE_EX_MIXEDBUTTONS; - lres = SendMessage(hwndToolbar, TB_SETEXTENDEDSTYLE, 0, exstyle); - - lres = SendMessage(hwndToolbar, TB_ADDBUTTONS, TOOLBAR_BUTTONS_COUNT, (LPARAM)tbButtons); - RECT rc; - lres = SendMessage(hwndToolbar, TB_GETITEMRECT, 0, (LPARAM)&rc); - - DWORD reBarStyle = WS_REBAR | WS_VISIBLE; - win->hwndReBar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, reBarStyle, - 0,0,0,0, hwndOwner, (HMENU)IDC_REBAR, hInst, NULL); - if (!win->hwndReBar) - SeeLastError(); - - REBARINFO rbi; - rbi.cbSize = sizeof(REBARINFO); - rbi.fMask = 0; - rbi.himl = (HIMAGELIST)NULL; - lres = SendMessage(win->hwndReBar, RB_SETBARINFO, 0, (LPARAM)&rbi); - - REBARBANDINFO rbBand; - rbBand.cbSize = sizeof(REBARBANDINFO); - rbBand.fMask = /*RBBIM_COLORS | RBBIM_TEXT | RBBIM_BACKGROUND | */ - RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE /*| RBBIM_SIZE*/; - rbBand.fStyle = /*RBBS_CHILDEDGE |*//* RBBS_BREAK |*/ RBBS_FIXEDSIZE /*| RBBS_GRIPPERALWAYS*/; - if (bIsAppThemed) - rbBand.fStyle |= RBBS_CHILDEDGE; - rbBand.hbmBack = NULL; - rbBand.lpText = "Toolbar"; - rbBand.hwndChild = hwndToolbar; - rbBand.cxMinChild = (rc.right - rc.left) * TOOLBAR_BUTTONS_COUNT; - rbBand.cyMinChild = (rc.bottom - rc.top) + 2 * rc.top; - rbBand.cx = 0; - lres = SendMessage(win->hwndReBar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); - - SetWindowPos(win->hwndReBar, NULL, 0, 0, 0, 0, SWP_NOZORDER); - GetWindowRect(win->hwndReBar, &rc); - gReBarDy = rc.bottom - rc.top; - //TODO: this was inherited but doesn't seem to be right (makes toolbar - // partially unpainted if using classic scheme on xp or vista - //gReBarDyFrame = bIsAppThemed ? 0 : 2; - gReBarDyFrame = 0; -} - -static LRESULT CALLBACK WndProcAbout(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_CREATE: - assert(!gHwndAbout); - break; - - case WM_ERASEBKGND: - // do nothing, helps to avoid flicker - return TRUE; - - case WM_PAINT: - OnPaintAbout(hwnd); - break; - - case WM_DESTROY: - assert(gHwndAbout); - gHwndAbout = NULL; - break; - - default: - return DefWindowProc(hwnd, message, wParam, lParam); - } - return 0; -} - -/* TODO: gAccumDelta must be per WindowInfo */ -static int gDeltaPerLine, gAccumDelta; // for mouse wheel logic - -static LRESULT CALLBACK WndProcCanvas(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - WindowInfo * win; - win = WindowInfo_FindByHwnd(hwnd); - switch (message) - { - case WM_APP_REPAINT_DELAYED: - if (win) - SetTimer(win->hwndCanvas, REPAINT_TIMER_ID, REPAINT_DELAY_IN_MS, NULL); - break; - - case WM_APP_REPAINT_NOW: - if (win) - WindowInfo_RedrawAll(win); - break; - - case WM_VSCROLL: - OnVScroll(win, wParam); - return WM_VSCROLL_HANDLED; - - case WM_HSCROLL: - OnHScroll(win, wParam); - return WM_HSCROLL_HANDLED; - - case WM_MOUSEMOVE: - if (win) - OnMouseMove(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), wParam); - break; - - case WM_LBUTTONDOWN: - if (win) - OnMouseLeftButtonDown(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - break; - - case WM_LBUTTONUP: - if (win) - OnMouseLeftButtonUp(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - break; - - case WM_RBUTTONDOWN: - if (win) - OnMouseRightButtonDown(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - break; - - case WM_RBUTTONUP: - if (win) - OnMouseRightButtonUp(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - break; - - case WM_SETCURSOR: - if (win && win->mouseAction == MA_DRAGGING) { - SetCursor(gCursorDrag); - return TRUE; - } - break; - - case WM_TIMER: - assert(win); - if (win) { - if (REPAINT_TIMER_ID == wParam) - WindowInfo_RedrawAll(win); - else - AnimState_NextFrame(&win->animState); - } - break; - - case WM_DROPFILES: - if (win) - OnDropFiles(win, (HDROP)wParam); - break; - - case WM_ERASEBKGND: - // do nothing, helps to avoid flicker - return TRUE; - - case WM_PAINT: - /* it might happen that we get WM_PAINT after destroying a window */ - if (win) { - /* blindly kill the timer, just in case it's there */ - KillTimer(win->hwndCanvas, REPAINT_TIMER_ID); - OnPaint(win); - } - break; - - default: - return DefWindowProc(hwnd, message, wParam, lParam); - } - return 0; -} - -static LRESULT CALLBACK WndProcFrame(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - int wmId, wmEvent; - WindowInfo * win; - ULONG ulScrollLines; // for mouse wheel logic - const char * fileName; - - win = WindowInfo_FindByHwnd(hwnd); - - switch (message) - { - case WM_CREATE: - // do nothing - goto InitMouseWheelInfo; - - case WM_SIZE: - if (win) { - int dx = LOWORD(lParam); - int dy = HIWORD(lParam); - OnSize(win, dx, dy); - } - break; - - case WM_COMMAND: - wmId = LOWORD(wParam); - wmEvent = HIWORD(wParam); - - fileName = RecentFileNameFromMenuItemId(wmId); - if (fileName) { - LoadPdf(fileName); - free((void*)fileName); - break; - } - - switch (wmId) - { - case IDM_OPEN: - case IDT_FILE_OPEN: - OnMenuOpen(win); - break; - case IDM_SAVEAS: - OnMenuSaveAs(win); - break; - - case IDT_FILE_PRINT: - case IDM_PRINT: - OnMenuPrint(win); - break; - - case IDM_MAKE_DEFAULT_READER: - OneMenuMakeDefaultReader(); - break; - - case IDT_FILE_EXIT: - case IDM_CLOSE: - CloseWindow(win, FALSE); - break; - - case IDM_EXIT: - OnMenuExit(); - break; - - case IDT_VIEW_ZOOMIN: - if (win->dm) - win->dm->zoomBy(ZOOM_IN_FACTOR); - break; - - case IDT_VIEW_ZOOMOUT: - if (win->dm) - win->dm->zoomBy(ZOOM_OUT_FACTOR); - break; - - case IDM_ZOOM_6400: - case IDM_ZOOM_3200: - case IDM_ZOOM_1600: - case IDM_ZOOM_800: - case IDM_ZOOM_400: - case IDM_ZOOM_200: - case IDM_ZOOM_150: - case IDM_ZOOM_125: - case IDM_ZOOM_100: - case IDM_ZOOM_50: - case IDM_ZOOM_25: - case IDM_ZOOM_12_5: - case IDM_ZOOM_8_33: - case IDM_ZOOM_FIT_PAGE: - case IDM_ZOOM_FIT_WIDTH: - case IDM_ZOOM_ACTUAL_SIZE: - OnMenuZoom(win, (UINT)wmId); - break; - - case IDM_ZOOM_FIT_VISIBLE: - /* TODO: implement me */ - break; - - case IDM_VIEW_SINGLE_PAGE: - OnMenuViewSinglePage(win); - break; - - case IDM_VIEW_FACING: - OnMenuViewFacing(win); - break; - - case IDM_VIEW_CONTINUOUS: - OnMenuViewContinuous(win); - break; - - case IDM_VIEW_SHOW_HIDE_TOOLBAR: - OnMenuViewShowHideToolbar(); - break; - - case IDM_VIEW_USE_FITZ: - OnMenuViewUseFitz(win); - break; - - case IDM_GOTO_NEXT_PAGE: - OnMenuGoToNextPage(win); - break; - - case IDM_GOTO_PREV_PAGE: - OnMenuGoToPrevPage(win); - break; - - case IDM_GOTO_FIRST_PAGE: - OnMenuGoToFirstPage(win); - break; - - case IDM_GOTO_LAST_PAGE: - OnMenuGoToLastPage(win); - break; - - case IDM_GOTO_PAGE: - OnMenuGoToPage(win); - break; - - case IDM_VIEW_CONTINUOUS_FACING: - OnMenuViewContinuousFacing(win); - break; - - case IDM_VIEW_ROTATE_LEFT: - OnMenuViewRotateLeft(win); - break; - - case IDM_VIEW_ROTATE_RIGHT: - OnMenuViewRotateRight(win); - break; - - case IDM_VISIT_WEBSITE: - LaunchBrowser(_T("http://blog.kowalczyk.info/software/sumatrapdf/")); - break; - - case IDM_LANG_EN: - case IDM_LANG_PL: - case IDM_LANG_FR: - case IDM_LANG_DE: - OnMenuLanguage((int)wmId); - break; - - case IDM_ABOUT: - OnMenuAbout(); - break; - default: - return DefWindowProc(hwnd, message, wParam, lParam); - } - break; - - case WM_CHAR: - if (win) - OnChar(win, wParam); - break; - - case WM_KEYDOWN: - if (win) - OnKeydown(win, wParam, lParam); - break; - - case WM_SETTINGCHANGE: -InitMouseWheelInfo: - SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &ulScrollLines, 0); - // ulScrollLines usually equals 3 or 0 (for no scrolling) - // WHEEL_DELTA equals 120, so iDeltaPerLine will be 40 - if (ulScrollLines) - gDeltaPerLine = WHEEL_DELTA / ulScrollLines; - else - gDeltaPerLine = 0; - return 0; - - // TODO: I don't understand why WndProcCanvas() doesn't receive this message - case WM_MOUSEWHEEL: - if (!win || !win->dm) /* TODO: check for pdfDoc as well ? */ - break; - - if (gDeltaPerLine == 0) - break; - - gAccumDelta += (short) HIWORD (wParam); // 120 or -120 - - while (gAccumDelta >= gDeltaPerLine) - { - SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEUP, 0); - gAccumDelta -= gDeltaPerLine; - } - - while (gAccumDelta <= -gDeltaPerLine) - { - SendMessage(win->hwndCanvas, WM_VSCROLL, SB_LINEDOWN, 0); - gAccumDelta += gDeltaPerLine; - } - return 0; - - case WM_DROPFILES: - if (win) - OnDropFiles(win, (HDROP)wParam); - break; - - case WM_DESTROY: - /* WM_DESTROY might be sent as a result of File\Close, in which case CloseWindow() has already been called */ - if (win) - CloseWindow(win, TRUE); - break; - - case IDM_VIEW_WITH_ACROBAT: - if (win) - ViewWithAcrobat(win); - break; - - case MSG_BENCH_NEXT_ACTION: - if (win) - OnBenchNextAction(win); - break; - - default: - return DefWindowProc(hwnd, message, wParam, lParam); - } - return 0; -} - -static BOOL RegisterWinClass(HINSTANCE hInstance) -{ - WNDCLASSEX wcex; - ATOM atom; - - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = WndProcFrame; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SUMATRAPDF)); - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = NULL; - wcex.lpszMenuName = NULL; - wcex.lpszClassName = FRAME_CLASS_NAME; - wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); - atom = RegisterClassEx(&wcex); - if (!atom) - return FALSE; - - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = WndProcCanvas; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hIcon = 0; - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = NULL; - wcex.lpszMenuName = NULL; - wcex.lpszClassName = CANVAS_CLASS_NAME; - wcex.hIconSm = 0; - atom = RegisterClassEx(&wcex); - if (!atom) - return FALSE; - - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = WndProcAbout; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hIcon = 0; - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = NULL; - wcex.lpszMenuName = NULL; - wcex.lpszClassName = ABOUT_CLASS_NAME; - wcex.hIconSm = 0; - atom = RegisterClassEx(&wcex); - if (!atom) - return FALSE; - - return TRUE; -} - -#define IDC_HAND MAKEINTRESOURCE(32649) -static BOOL InstanceInit(HINSTANCE hInstance, int nCmdShow) -{ - ghinst = hInstance; - - globalParams = new GlobalParams(""); - if (!globalParams) - return FALSE; - - SplashColorsInit(); - gCursorArrow = LoadCursor(NULL, IDC_ARROW); - gCursorHand = LoadCursor(NULL, IDC_HAND); // apparently only available if WINVER >= 0x0500 - if (!gCursorHand) - gCursorHand = LoadCursor(ghinst, MAKEINTRESOURCE(IDC_CURSORDRAG)); - gCursorDrag = LoadCursor(ghinst, MAKEINTRESOURCE(IDC_CURSORDRAG)); - gBrushBg = CreateSolidBrush(COL_WINDOW_BG); - gBrushWhite = CreateSolidBrush(COL_WHITE); - gBrushShadow = CreateSolidBrush(COL_WINDOW_SHADOW); - gBrushLinkDebug = CreateSolidBrush(RGB(0x00,0x00,0xff)); - return TRUE; -} - -static void StrList_Reverse(StrList **strListRoot) -{ - StrList *newRoot = NULL; - StrList *cur, *next; - if (!strListRoot) - return; - cur = *strListRoot; - while (cur) { - next = cur->next; - cur->next = newRoot; - newRoot = cur; - cur = next; - } - *strListRoot = newRoot; -} - -static BOOL StrList_InsertAndOwn(StrList **root, char *txt) -{ - StrList * el; - assert(root && txt); - if (!root || !txt) - return FALSE; - - el = (StrList*)malloc(sizeof(StrList)); - if (!el) - return FALSE; - el->str = txt; - el->next = *root; - *root = el; - return TRUE; -} - -static void StrList_Destroy(StrList **root) -{ - StrList * cur; - StrList * next; - - if (!root) - return; - cur = *root; - while (cur) { - next = cur->next; - free((void*)cur->str); - free((void*)cur); - cur = next; - } - *root = NULL; -} - -static StrList *StrList_FromCmdLine(char *cmdLine) -{ - char * exePath; - StrList * strList = NULL; - char * txt; - - assert(cmdLine); - - if (!cmdLine) - return NULL; - - exePath = ExePathGet(); - if (!exePath) - return NULL; - if (!StrList_InsertAndOwn(&strList, exePath)) { - free((void*)exePath); - return NULL; - } - - for (;;) { - txt = str_parse_possibly_quoted(&cmdLine); - if (!txt) - break; - if (!StrList_InsertAndOwn(&strList, txt)) { - free((void*)txt); - break; - } - } - StrList_Reverse(&strList); - return strList; -} - -static void u_DoAllTests(void) -{ -#ifdef DEBUG - printf("Running tests\n"); - u_RectI_Intersect(); -#else - printf("Not running tests\n"); -#endif -} - -#define CONSERVE_MEMORY 1 - -static DWORD WINAPI PageRenderThread(PVOID data) -{ - PageRenderRequest req; - RenderedBitmap * bmp; - - DBG_OUT("PageRenderThread() started\n"); - while (1) { - //DBG_OUT("Worker: wait\n"); - LockCache(); - gCurPageRenderReq = NULL; - int count = gPageRenderRequestsCount; - UnlockCache(); - if (0 == count) { - DWORD waitResult = WaitForSingleObject(gPageRenderSem, INFINITE); - if (WAIT_OBJECT_0 != waitResult) { - DBG_OUT(" WaitForSingleObject() failed\n"); - continue; - } - } - if (0 == gPageRenderRequestsCount) { - continue; - } - LockCache(); - RenderQueue_Pop(&req); - gCurPageRenderReq = &req; - UnlockCache(); - DBG_OUT("PageRenderThread(): dequeued %d\n", req.pageNo); - if (!req.dm->pageVisibleNearby(req.pageNo)) { - DBG_OUT("PageRenderThread(): not rendering because not visible\n"); - continue; - } - assert(!req.abort); - MsTimer renderTimer; - bmp = req.dm->renderBitmap(req.pageNo, req.zoomLevel, req.rotation, pageRenderAbortCb, (void*)&req); - renderTimer.stop(); - LockCache(); - gCurPageRenderReq = NULL; - UnlockCache(); - if (req.abort) { - delete bmp; - continue; - } - if (bmp) - DBG_OUT("PageRenderThread(): finished rendering %d\n", req.pageNo); - else - DBG_OUT("PageRenderThread(): failed to render a bitmap of page %d\n", req.pageNo); - double renderTime = renderTimer.timeInMs(); - BitmapCache_Add(req.dm, req.pageNo, req.zoomLevel, req.rotation, bmp, renderTime); -#ifdef CONSERVE_MEMORY - BitmapCache_FreeNotVisible(); -#endif - WindowInfo* win = (WindowInfo*)req.dm->appData(); - triggerRepaintDisplayNow(win); - } - DBG_OUT("PageRenderThread() finished\n"); - return 0; -} - -static void CreatePageRenderThread(void) -{ - LONG semMaxCount = 1000; /* don't really know what the limit should be */ - DWORD dwThread1ID = 0; - assert(NULL == gPageRenderThreadHandle); - - gPageRenderSem = CreateSemaphore(NULL, 0, semMaxCount, NULL); - gPageRenderThreadHandle = CreateThread(NULL, 0, PageRenderThread, (void*)NULL, 0, &dwThread1ID); - assert(NULL != gPageRenderThreadHandle); -} - -static void PrintFile(WindowInfo *win, const char *fileName, const char *printerName) -{ - char devstring[256]; // array for WIN.INI data - HANDLE printer; - LPDEVMODE devMode = NULL; - DWORD structSize, returnCode; - - if (!win->dm->pdfEngine()->printingAllowed()) { - MessageBox(win->hwndFrame, "Cannot print this file", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); - return; - } - - // Retrieve the printer, printer driver, and - // output-port names from WIN.INI. - GetProfileString("Devices", printerName, "", devstring, sizeof(devstring)); - - // Parse the string of names, setting ptrs as required - // If the string contains the required names, use them to - // create a device context. - char *driver = strtok (devstring, (const char *) ","); - char *port = strtok((char *) NULL, (const char *) ","); - - if (!driver || !port) { - MessageBox(win->hwndFrame, "Printer with given name doesn't exist", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); - return; - } - - BOOL fOk = OpenPrinter((LPSTR)printerName, &printer, NULL); - if (!fOk) { - MessageBox(win->hwndFrame, _TR("Could not open Printer"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK); - return; - } - - HDC hdcPrint = NULL; - structSize = DocumentProperties(NULL, - printer, /* Handle to our printer. */ - (LPSTR) printerName, /* Name of the printer. */ - NULL, /* Asking for size, so */ - NULL, /* these are not used. */ - 0); /* Zero returns buffer size. */ - devMode = (LPDEVMODE)malloc(structSize); - if (!devMode) goto Exit; - - // Get the default DevMode for the printer and modify it for your needs. - returnCode = DocumentProperties(NULL, - printer, - (LPSTR) printerName, - devMode, /* The address of the buffer to fill. */ - NULL, /* Not using the input buffer. */ - DM_OUT_BUFFER); /* Have the output buffer filled. */ - - if (IDOK != returnCode) { - // If failure, inform the user, cleanup and return failure. - MessageBox(win->hwndFrame, "Could not obtain Printer properties", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); - goto Exit; - } - - PdfPageInfo * pageInfo = pageInfo = win->dm->getPageInfo(1); - - if (pageInfo->bitmapDx > pageInfo->bitmapDy) { - devMode->dmOrientation = DMORIENT_LANDSCAPE; - } else { - devMode->dmOrientation = DMORIENT_PORTRAIT; - } - - /* - * Merge the new settings with the old. - * This gives the driver an opportunity to update any private - * portions of the DevMode structure. - */ - DocumentProperties(NULL, - printer, - (LPSTR) printerName, - devMode, /* Reuse our buffer for output. */ - devMode, /* Pass the driver our changes. */ - DM_IN_BUFFER | /* Commands to Merge our changes and */ - DM_OUT_BUFFER); /* write the result. */ - - ClosePrinter(printer); - - hdcPrint = CreateDC(driver, printerName, port, devMode); - if (!hdcPrint) { - MessageBox(win->hwndFrame, "Couldn't initialize printer", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); - goto Exit; - } - - if (CheckPrinterStretchDibSupport(win->hwndFrame, hdcPrint)) - PrintToDevice(win->dm, hdcPrint, devMode, 1, win->dm->pageCount()); -Exit: - free(devMode); - DeleteDC(hdcPrint); -} - -static void EnumeratePrinters() -{ - PRINTER_INFO_5 *info5Arr = NULL; - DWORD bufSize = 0, printersCount; - BOOL fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, - 5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount); - if (!fOk) { - info5Arr = (PRINTER_INFO_5*)malloc(bufSize); - fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, - 5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount); - } - if (!info5Arr) - return; - assert(fOk); - if (!fOk) return; - printf("Printers: %d\n", printersCount); - for (DWORD i=0; i < printersCount; i++) { - const char *printerName = info5Arr[i].pPrinterName; - const char *printerPort = info5Arr[i].pPortName; - bool fDefault = false; - if (info5Arr[i].Attributes & PRINTER_ATTRIBUTE_DEFAULT) - fDefault = true; - printf("Name: %s, port: %s, default: %d\n", printerName, printerPort, (int)fDefault); - } - TCHAR buf[512]; - bufSize = sizeof(buf); - fOk = GetDefaultPrinter(buf, &bufSize); - if (!fOk) { - if (ERROR_FILE_NOT_FOUND == GetLastError()) - printf("No default printer\n"); - } - free(info5Arr); -} - -/* Get the name of default printer or NULL if not exists. - The caller needs to free() the result */ -char *GetDefaultPrinterName() -{ - char buf[512]; - DWORD bufSize = sizeof(buf); - if (GetDefaultPrinterA(buf, &bufSize)) - return str_dup(buf); - return NULL; -} - -int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) -{ - StrList * argListRoot; - StrList * currArg; - char * benchPageNumStr = NULL; - MSG msg = {0}; - HACCEL hAccelTable; - WindowInfo* win; - int pdfOpened = 0; - bool exitOnPrint = false; - bool printToDefaultPrinter = false; - - UNREFERENCED_PARAMETER(hPrevInstance); - - u_DoAllTests(); - - INITCOMMONCONTROLSEX cex; - cex.dwSize = sizeof(INITCOMMONCONTROLSEX); - cex.dwICC = ICC_WIN95_CLASSES | ICC_DATE_CLASSES | ICC_USEREX_CLASSES | ICC_COOL_CLASSES; - InitCommonControlsEx(&cex); - - argListRoot = StrList_FromCmdLine(lpCmdLine); - assert(argListRoot); - if (!argListRoot) - return 0; - - Prefs_Load(); - /* parse argument list. If BENCH_ARG_TXT was given, then we're in benchmarking mode. Otherwise - we assume that all arguments are PDF file names. - BENCH_ARG_TXT can be followed by file or directory name. If file, it can additionally be followed by - a number which we interpret as page number */ - bool registerForPdfExtentions = true; - currArg = argListRoot->next; - char *printerName = NULL; - while (currArg) { - if (IsEnumPrintersArg(currArg->str)) { - EnumeratePrinters(); - /* this is for testing only, exit immediately */ - goto Exit; - } - - if (IsDontRegisterExtArg(currArg->str)) { - registerForPdfExtentions = false; - currArg = currArg->next; - continue; - } - - if (IsBenchArg(currArg->str)) { - currArg = currArg->next; - if (currArg) { - gBenchFileName = currArg->str; - if (currArg->next) - benchPageNumStr = currArg->next->str; - } - break; - } - - if (IsExitOnPrintArg(currArg->str)) { - currArg = currArg->next; - exitOnPrint = true; - continue; - } - - if (IsPrintToDefaultArg(currArg->str)) { - printToDefaultPrinter = true; - continue; - } - - if (IsPrintToArg(currArg->str)) { - currArg = currArg->next; - if (currArg) { - printerName = currArg->str; - currArg = currArg->next; - } - continue; - } - - // we assume that switches come first and file names to open later - // TODO: it would probably be better to collect all non-switches - // in a separate list so that file names can be interspersed with - // switches - break; - } - - if (benchPageNumStr) { - gBenchPageNum = atoi(benchPageNumStr); - if (gBenchPageNum < 1) - gBenchPageNum = INVALID_PAGE_NO; - } - - LoadString(hInstance, IDS_APP_TITLE, windowTitle, MAX_LOADSTRING); - if (!RegisterWinClass(hInstance)) - goto Exit; - - CaptionPens_Create(); - if (!InstanceInit(hInstance, nCmdShow)) - goto Exit; - - hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SUMATRAPDF)); - - CreatePageRenderThread(); - /* remaining arguments are names of PDF files */ - if (NULL != gBenchFileName) { - win = LoadPdf(gBenchFileName); - if (win) - ++pdfOpened; - } else { - while (currArg) { - win = LoadPdf(currArg->str); - if (!win) - goto Exit; - - if (exitOnPrint) - ShowWindow(win->hwndFrame, SW_HIDE); - - if (printToDefaultPrinter) { - printerName = GetDefaultPrinterName(); - if (printerName) - PrintFile(win, currArg->str, printerName); - free(printerName); - } else if (printerName) { - // note: this prints all of PDF files. Another option would be to - // print only the first one - PrintFile(win, currArg->str, printerName); - } - ++pdfOpened; - currArg = currArg->next; - } - } - - if (printerName && exitOnPrint) - goto Exit; - - if (0 == pdfOpened) { - /* disable benchmark mode if we couldn't open file to benchmark */ - gBenchFileName = 0; -#ifdef REOPEN_FILES_AT_STARTUP - FileHistoryList * currFile = gFileHistoryRoot; - while (currFile) { - if (currFile->state.visible) { - win = LoadPdf(currFile->state.filePath, false); - if (win) - ++pdfOpened; - } - currFile = currFile->next; - } -#endif - if (0 == pdfOpened) { - win = WindowInfo_CreateEmpty(); - if (!win) - goto Exit; - WindowInfoList_Add(win); - - /* TODO: should this be part of WindowInfo_CreateEmpty() ? */ - DragAcceptFiles(win->hwndFrame, TRUE); - ShowWindow(win->hwndCanvas, SW_SHOW); - UpdateWindow(win->hwndCanvas); - ShowWindow(win->hwndFrame, SW_SHOW); - UpdateWindow(win->hwndFrame); - } - } - - if (IsBenchMode()) { - assert(win); - assert(pdfOpened > 0); - if (win) - PostBenchNextAction(win->hwndFrame); - } - - if (0 == pdfOpened) - MenuToolbarUpdateStateForAllWindows(); - - if (registerForPdfExtentions) - RegisterForPdfExtentions(win ? win->hwndFrame : NULL); - - while (GetMessage(&msg, NULL, 0, 0)) { - if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - -Exit: - WindowInfoList_DeleteAll(); - FileHistoryList_Free(&gFileHistoryRoot); - CaptionPens_Destroy(); - DeleteObject(gBrushBg); - DeleteObject(gBrushWhite); - DeleteObject(gBrushShadow); - DeleteObject(gBrushLinkDebug); - - delete globalParams; - StrList_Destroy(&argListRoot); - Translations_FreeData(); - CurrLangNameFree(); - //histDump(); - return (int) msg.wParam; -} - -// Code for DLL interace -static WindowInfo* CreateEmpty(HWND parentHandle) { - WindowInfo* pdfWin; - HWND hwndCanvas; - pdfWin = WindowInfo_New(parentHandle); - hwndCanvas = CreateWindow( - CANVAS_CLASS_NAME, NULL, - WS_CHILD | WS_HSCROLL | WS_VSCROLL, - CW_USEDEFAULT, CW_USEDEFAULT, - DEF_WIN_DX, DEF_WIN_DY, - parentHandle, NULL, - ghinst, NULL); - if (hwndCanvas) - pdfWin->hwndCanvas = hwndCanvas; - return pdfWin; -} - -static void OpenPdf(WindowInfo* pdfWin,const char *fileName, HWND parentHandle) -{ - assert(fileName); - if (!fileName) return; - assert(pdfWin); - if (!pdfWin) return; - - pdfWin->GetCanvasSize(); - SizeI maxCanvasSize = GetMaxCanvasSize(pdfWin); - SizeD totalDrawAreaSize(pdfWin->winSize()); - DisplayMode displayMode = DEFAULT_DISPLAY_MODE; - int offsetX = 0; - int offsetY = 0; - int startPage = 1; - int scrollbarYDx = 0; - int scrollbarXDy = 0; - - if (gUseFitz) { - pdfWin->dm = DisplayModelFitz_CreateFromFileName(fileName, - totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, pdfWin); - } - else { - pdfWin->dm = DisplayModelSplash_CreateFromFileName(fileName, - totalDrawAreaSize, scrollbarYDx, scrollbarXDy, displayMode, startPage, pdfWin); - } - - pdfWin->dm->setAppData((void*)pdfWin); - pdfWin->state = WS_SHOWING_PDF; - double zoomVirtual = DEFAULT_ZOOM; - int rotation = DEFAULT_ROTATION; - - UINT menuId = MenuIdFromVirtualZoom(zoomVirtual); - ZoomMenuItemCheck(GetMenu(pdfWin->hwndFrame), menuId); - - pdfWin->dm->relayout(zoomVirtual, rotation); - if (!pdfWin->dm->validPageNo(startPage)) - startPage = 1; - offsetY = 0; - pdfWin->dm->goToPage(startPage, offsetY, offsetX); - WindowInfo_ResizeToPage(pdfWin, startPage); - WindowInfoList_Add(pdfWin); - - RECT rect; - if (GetWindowRect(pdfWin->hwndFrame , &rect) != 0) - { - int nWidth = rect_dx(&rect); - int nHeight = rect_dy(&rect); - WinResizeClientArea(pdfWin->hwndCanvas, nWidth, nHeight); - } - - ShowWindow(pdfWin->hwndFrame, SW_SHOW); - ShowWindow(pdfWin->hwndCanvas, SW_SHOW); - UpdateWindow(pdfWin->hwndFrame); - UpdateWindow(pdfWin->hwndCanvas); -} - -void Sumatra_LoadPDF(WindowInfo* pdfWin, const char *pdfFile) -{ - int pdfOpened = 0; - OpenPdf(pdfWin, pdfFile, pdfWin->hwndFrame); - ++pdfOpened; - if (pdfWin) - ShowWindow(pdfWin->hwndFrame, SW_SHOWNORMAL); -} - -void Sumatra_PrintPDF(WindowInfo* pdfWin, const char *pdfFile, long showOptionWindow) -{ -} - -void Sumatra_Print(WindowInfo* pdfWin) -{ - if (WindowInfo_PdfLoaded(pdfWin)) - OnMenuPrint(pdfWin); -} - -void Sumatra_ShowPrintDialog(WindowInfo* pdfWin) -{ - if (WindowInfo_PdfLoaded(pdfWin)) - OnMenuPrint(pdfWin); -} - -void Sumatra_SetDisplayMode(WindowInfo* pdfWin,long displayMode) -{ - if (WindowInfo_PdfLoaded(pdfWin)) - SwitchToDisplayMode(pdfWin, (DisplayMode)displayMode); -} - -long Sumatra_GoToNextPage(WindowInfo* pdfWin) -{ - if (!WindowInfo_PdfLoaded(pdfWin)) - return 0; - pdfWin->dm->goToNextPage(0); - return pdfWin->dm->currentPageNo(); -} - -long Sumatra_GoToPreviousPage(WindowInfo* pdfWin) -{ - if (!WindowInfo_PdfLoaded(pdfWin)) - return 0; - pdfWin->dm->goToPrevPage(0); - return pdfWin->dm->currentPageNo(); -} - -long Sumatra_GoToFirstPage(WindowInfo* pdfWin) -{ - if (!WindowInfo_PdfLoaded(pdfWin)) - return 0; - pdfWin->dm->goToFirstPage(); - return pdfWin->dm->currentPageNo(); -} - -long Sumatra_GoToLastPage(WindowInfo* pdfWin) -{ - if (!WindowInfo_PdfLoaded(pdfWin)) - return 0; - pdfWin->dm->goToLastPage(); - return pdfWin->dm->currentPageNo(); -} - -long Sumatra_GetNumberOfPages(WindowInfo* pdfWin) -{ - if (!WindowInfo_PdfLoaded(pdfWin)) - return 0; - return pdfWin->dm->pageCount(); -} - -long Sumatra_GetCurrentPage(WindowInfo* pdfWin) -{ - if (!WindowInfo_PdfLoaded(pdfWin)) - return 0; - return pdfWin->dm->currentPageNo(); -} - -long Sumatra_GoToThisPage(WindowInfo* pdfWin,long pageNumber) -{ - if (!WindowInfo_PdfLoaded(pdfWin)) - return 0; - if (pdfWin->dm->validPageNo(pageNumber)) - pdfWin->dm->goToPage(pageNumber, 0); - return pdfWin->dm->currentPageNo(); -} - -long Sumatra_ZoomIn(WindowInfo* pdfWin) -{ - if (WindowInfo_PdfLoaded(pdfWin)) - { - long currentZoom = Sumatra_GetCurrentZoom(pdfWin); - if (currentZoom < 500) - Sumatra_SetZoom(pdfWin,currentZoom+10); - } - return Sumatra_GetCurrentZoom(pdfWin); -} - -long Sumatra_ZoomOut(WindowInfo* pdfWin) -{ - if (WindowInfo_PdfLoaded(pdfWin)) - { - long currentZoom = Sumatra_GetCurrentZoom(pdfWin); - if (currentZoom > 10) - Sumatra_SetZoom(pdfWin,currentZoom-10); - } - return Sumatra_GetCurrentZoom(pdfWin); -} - -long Sumatra_SetZoom(WindowInfo* pdfWin,long zoomValue) -{ - if (WindowInfo_PdfLoaded(pdfWin)) - pdfWin->dm->zoomTo((double)zoomValue); - return Sumatra_GetCurrentZoom(pdfWin); -} - -long Sumatra_GetCurrentZoom(WindowInfo* pdfWin) -{ - double zoomLevel = 0; - if (WindowInfo_PdfLoaded(pdfWin)) - zoomLevel = pdfWin->dm->zoomReal(); - return (long)zoomLevel; -} - -void Sumatra_Resize(WindowInfo* pdfWin) -{ - RECT rect; - if (GetWindowRect(pdfWin->hwndFrame , &rect) != 0) - { - int nWidth = rect_dx(&rect); - int nHeight = rect_dy(&rect); - WinResizeClientArea(pdfWin->hwndCanvas, nWidth, nHeight); - } -} - -void Sumatra_ClosePdf(WindowInfo* pdfWin) -{ - if (WindowInfo_PdfLoaded(pdfWin)) - CloseWindow(pdfWin, FALSE); -} - -WindowInfo* Sumatra_Init(HWND pHandle) -{ - WindowInfo* pdfWin; - gRunningDLL = true; - HINSTANCE hInstance = NULL; - HINSTANCE hPrevInstance = NULL; - int nCmdShow = 0; - - StrList * argListRoot = NULL; - StrList * currArg = NULL; - MSG msg = {0}; - bool exitOnPrint = false; - bool printToDefaultPrinter = false; - gUseFitz = TRUE; - - UNREFERENCED_PARAMETER(hPrevInstance); - - u_DoAllTests(); - - INITCOMMONCONTROLSEX cex; - cex.dwSize = sizeof(INITCOMMONCONTROLSEX); - cex.dwICC = ICC_WIN95_CLASSES | ICC_DATE_CLASSES | ICC_USEREX_CLASSES | ICC_COOL_CLASSES; - InitCommonControlsEx(&cex); - argListRoot = NULL; - - LoadString(hInstance, IDS_APP_TITLE, windowTitle, MAX_LOADSTRING); - - if (!RegisterWinClass(hInstance)) - Sumatra_Exit(); - - CaptionPens_Create(); - - if (!InstanceInit(hInstance, nCmdShow)) - Sumatra_Exit(); - - CreatePageRenderThread(); - - bool reuseExistingWindow = false; - - if (pHandle == 0 ) - pHandle = NULL; - - pdfWin = CreateEmpty(pHandle); - - return pdfWin; -} - -void Sumatra_Exit() -{ - CaptionPens_Destroy(); - DeleteObject(gBrushBg); - DeleteObject(gBrushWhite); - DeleteObject(gBrushShadow); - DeleteObject(gBrushLinkDebug); - delete globalParams; -} diff --git a/rosapps/smartpdf/src/build-release.bat b/rosapps/smartpdf/src/build-release.bat deleted file mode 100644 index fccacf17e33..00000000000 --- a/rosapps/smartpdf/src/build-release.bat +++ /dev/null @@ -1,52 +0,0 @@ -@set PATH=%PATH%;%ProgramFiles%\Microsoft Visual Studio 8\Common7\IDE -@set NSIS_EXE=%ProgramFiles%\NSIS\makensis.exe -@set PATH=%PATH%;%ProgramFiles%\NSIS -@set FASTDL_PATH=C:\kjk\src\web\fastdl\www - -@pushd . -@set VERSION=%1 -@IF NOT DEFINED VERSION GOTO VERSION_NEEDED - -@rem TODO: check if %NSIS_EXE% file exists, GOTO NSIS_NEEDED if not -@rem @IF NOT EXISTS %NSIS_EXE% GOTO NSIS_NEEDED -devenv ..\sumatrapdf.sln /Rebuild "Release|Win32" -@IF ERRORLEVEL 1 goto BUILD_FAILED -echo Compilation ok! -copy ..\Release\SumatraPDF.exe ..\Release\SumatraPDF-uncomp.exe -upx --best ..\Release\SumatraPDF.exe -@IF ERRORLEVEL 1 goto PACK_FAILED - -@makensis installer -@IF ERRORLEVEL 1 goto INSTALLER_FAILED - -move SumatraPDF-install.exe ..\Release\SumatraPDF-%VERSION%-install.exe -copy ..\Release\SumatraPDF-%VERSION%-install.exe %FASTDL_PATH%\SumatraPDF-%VERSION%-install.exe - -@cd ..\Release -@rem don't bother compressing since our *.exe has already been packed -zip -0 SumatraPDF-%VERSION%.zip SumatraPDF.exe -copy SumatraPDF-%VERSION%.zip %FASTDL_PATH%\SumatraPDF-%VERSION%.zip -@goto END - -:INSTALLER_FAILED -echo Installer script failed -@goto END - -:PACK_FAILED -echo Failed to pack executable with upx. Do you have upx installed? -@goto END - -:BUILD_FAILED -echo Build failed! -@goto END - -:VERSION_NEEDED -echo Need to provide version number e.g. build-release.bat 1.0 -@goto END - -:NSIS_NEEDED -echo NSIS doesn't seem to be installed. Get it from http://nsis.sourceforge.net/Download -@goto END - -:END -@popd diff --git a/rosapps/smartpdf/src/icons-silk/Thumbs.db b/rosapps/smartpdf/src/icons-silk/Thumbs.db deleted file mode 100644 index 5548668a6b6..00000000000 Binary files a/rosapps/smartpdf/src/icons-silk/Thumbs.db and /dev/null differ