void CPageViewer_Draw(CPageViewer_t *viewer, int x, int y, int w, int h) { int i; document_rendered_link_t *link; int line; char buf[512]; int sx, sy, sw, sh; // change x, y, w, h x = x + (w - 8*(w/8)) /2; w = w/8; y = y + (h - 8*(h/8)) /2; h = h/8; if (w < 20 || h < 10) return; if (viewer->page == NULL) return; sx = x; sy = y; sw = w; sh = h; if (viewer->page->width != w) viewer->page->should_render = true; if (viewer->page->should_render) RenderDocument(viewer, w); // current link, if in navigation mode link = viewer->navigation_mode ? viewer->current_links[viewer->current_link_index] : NULL; // draw title bar /* if (viewer->page->rendered.title && viewer->show_title) { for (line = 0; line < viewer->page->rendered.title_lines; line++) { MakeString(buf, viewer->page->rendered.title + line*viewer->page->width, viewer->page->width); UI_Print(x, y + line*8, buf, false); } UI_MakeLine(buf, viewer->page->width/2); UI_Print_Center(x, y + line*8, viewer->page->width*8, buf, false); sh -= line + 1; sy += (line + 1) * 8; } */ // calculate scrollable area yet if (viewer->show_status) sh -= 2; if (viewer->page->rendered.text_lines - viewer->page->current_line < sh) viewer->page->current_line -= sh - (viewer->page->rendered.text_lines - viewer->page->current_line); if (viewer->page->current_line < 0) viewer->page->current_line = 0; // draw status bar if (viewer->show_status) { if (viewer->navigation_mode) { if (strlen (link->tag->href) > w) { strlcpy (buf, link->tag->href, min (sizeof (buf), w-3)); strlcat (buf, "...", sizeof (buf)); } else { int offset = (w - strlen(link->tag->href)) / 2; memset(buf, ' ', offset); strlcpy (buf + offset, link->tag->href, sizeof (buf) - offset); } UI_Print(x, y + (h-1)*8, buf, false); } else { snprintf(buf, sizeof (buf), "%d lines ", viewer->page->rendered.text_lines); if (sh >= viewer->page->rendered.text_lines) strlcat(buf, "[full]", sizeof (buf)); else if (viewer->page->current_line == 0) strlcat(buf, "[top]", sizeof (buf)); else if (viewer->page->current_line + sh == viewer->page->rendered.text_lines) strlcat(buf, "[bottom]", sizeof (buf)); else { int percent = (100*(viewer->page->current_line + sh)) / viewer->page->rendered.text_lines; strlcat(buf, va("[%d%%]", percent), sizeof (buf)); } UI_Print(x+8*(w-strlen(buf)-1), y + (h-1)*8, buf, false); if (viewer->page->doc && viewer->page->doc->title) { int l = w - strlen(buf) - 3; if (strlen(viewer->page->doc->title) <= l) { UI_Print(x+8, y + (h-1)*8, viewer->page->doc->title, false); } else { strlcpy(buf, viewer->page->doc->title, min (sizeof (buf), l-3)); strlcat(buf, "...", sizeof (buf)); UI_Print(x+8, y + (h-1)*8, buf, false); } } } UI_MakeLine(buf, w); UI_Print_Center(x, y + (h-2)*8, w*8, buf, false); } // process with scrollable area for (line = 0; line < min(sh, viewer->page->rendered.text_lines - viewer->page->current_line); line++) { int start, end; MakeString(buf, (byte *) viewer->page->rendered.text + (line+viewer->page->current_line)*viewer->page->width, viewer->page->width); if (link) { start = max(link->start, (viewer->page->current_line + line) * viewer->page->width); end = min(link->end, (viewer->page->current_line + line + 1) * viewer->page->width); if (end > start) { start -= (viewer->page->current_line + line) * viewer->page->width; end -= (viewer->page->current_line + line) * viewer->page->width; for (i=start; i < end; i++) buf[i] ^= 128; } } UI_Print(sx, sy + line*8, buf, false); } viewer->page->last_height = sh; }
int main(int argc, char **argv) { setlocale(LC_ALL, "C"); DisableDataExecution(); WStrVec argList; ParseCmdLine(GetCommandLine(), argList); if (argList.Count() < 2) { Usage: ErrOut("%s <filename> [-pwd <password>][-full][-alt][-render <path-%%d.tga>]\n", path::GetBaseName(argList.At(0))); return 0; } ScopedMem<WCHAR> filePath; WIN32_FIND_DATA fdata; HANDLE hfind = FindFirstFile(argList.At(1), &fdata); if (INVALID_HANDLE_VALUE != hfind) { ScopedMem<WCHAR> dir(path::GetDir(argList.At(1))); filePath.Set(path::Join(dir, fdata.cFileName)); FindClose(hfind); } else { // embedded documents are referred to by an invalid path // containing more information after a colon (e.g. "C:\file.pdf:3:0") filePath.Set(str::Dup(argList.At(1))); } bool fullDump = false; WCHAR *password = NULL; WCHAR *renderPath = NULL; bool useAlternateHandlers = false; bool loadOnly = false; int breakAlloc = 0; for (size_t i = 2; i < argList.Count(); i++) { if (str::Eq(argList.At(i), L"-full")) fullDump = true; else if (str::Eq(argList.At(i), L"-pwd") && i + 1 < argList.Count()) password = argList.At(++i); else if (str::Eq(argList.At(i), L"-render") && i + 1 < argList.Count()) renderPath = argList.At(++i); else if (str::Eq(argList.At(i), L"-alt")) useAlternateHandlers = true; else if (str::Eq(argList.At(i), L"-loadonly")) loadOnly = true; #ifdef DEBUG else if (str::Eq(argList.At(i), L"-breakalloc") && i + 1 < argList.Count()) breakAlloc = _wtoi(argList.At(++i)); #endif else goto Usage; } #ifdef DEBUG if (breakAlloc) { _CrtSetBreakAlloc(breakAlloc); if (!IsDebuggerPresent()) MessageBox(NULL, L"Keep your debugger ready for the allocation breakpoint...", L"EngineDump", MB_ICONINFORMATION); } #endif // optionally use GDI+ rendering for PDF/XPS and the original ChmEngine for CHM DebugGdiPlusDevice(useAlternateHandlers); DebugAlternateChmEngine(!useAlternateHandlers); ScopedGdiPlus gdiPlus; DocType engineType; PasswordHolder pwdUI(password); BaseEngine *engine = EngineManager::CreateEngine(true, filePath, &pwdUI, &engineType); if (!engine) { ErrOut("Error: Couldn't create an engine for %s!\n", path::GetBaseName(filePath)); return 1; } if (!loadOnly) DumpData(engine, fullDump); if (renderPath) RenderDocument(engine, renderPath); delete engine; #ifdef DEBUG // report memory leaks on stderr for engines that shouldn't leak if (engineType != Engine_DjVu) { _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); } #endif return 0; }
int main(int argc, char **argv) { setlocale(LC_ALL, "C"); DisableDataExecution(); WStrVec argList; ParseCmdLine(GetCommandLine(), argList); if (argList.Count() < 2) { Usage: ErrOut("%s [-pwd <password>][-quick][-render <path-%%d.tga>] <filename>", path::GetBaseName(argList.At(0))); return 2; } ScopedMem<WCHAR> filePath; WCHAR *password = NULL; bool fullDump = true; WCHAR *renderPath = NULL; float renderZoom = 1.f; bool useAlternateHandlers = false; bool loadOnly = false, silent = false; #ifdef DEBUG int breakAlloc = 0; #endif for (size_t i = 1; i < argList.Count(); i++) { if (str::Eq(argList.At(i), L"-pwd") && i + 1 < argList.Count() && !password) password = argList.At(++i); else if (str::Eq(argList.At(i), L"-quick")) fullDump = false; else if (str::Eq(argList.At(i), L"-render") && i + 1 < argList.Count() && !renderPath) { // optional zoom argument (e.g. -render 50% file.pdf) float zoom; if (i + 2 < argList.Count() && str::Parse(argList.At(i + 1), L"%f%%%$", &zoom) && zoom > 0.f) { renderZoom = zoom / 100.f; i++; } renderPath = argList.At(++i); } // -alt is for debugging alternate rendering methods else if (str::Eq(argList.At(i), L"-alt")) useAlternateHandlers = true; // -loadonly and -silent are only meant for profiling else if (str::Eq(argList.At(i), L"-loadonly")) loadOnly = true; else if (str::Eq(argList.At(i), L"-silent")) silent = true; // -full is for backward compatibility else if (str::Eq(argList.At(i), L"-full")) fullDump = true; #ifdef DEBUG else if (str::Eq(argList.At(i), L"-breakalloc") && i + 1 < argList.Count()) breakAlloc = _wtoi(argList.At(++i)); #endif else if (!filePath) filePath.Set(str::Dup(argList.At(i))); else goto Usage; } if (!filePath) goto Usage; #ifdef DEBUG if (breakAlloc) { _CrtSetBreakAlloc(breakAlloc); if (!IsDebuggerPresent()) MessageBox(NULL, L"Keep your debugger ready for the allocation breakpoint...", L"EngineDump", MB_ICONINFORMATION); } #endif if (silent) { FILE *nul; freopen_s(&nul, "NUL", "w", stdout); freopen_s(&nul, "NUL", "w", stderr); } // optionally use GDI+ rendering for PDF/XPS DebugGdiPlusDevice(useAlternateHandlers); ScopedGdiPlus gdiPlus; ScopedMiniMui miniMui; WIN32_FIND_DATA fdata; HANDLE hfind = FindFirstFile(filePath, &fdata); // embedded documents are referred to by an invalid path // containing more information after a colon (e.g. "C:\file.pdf:3:0") if (INVALID_HANDLE_VALUE != hfind) { ScopedMem<WCHAR> dir(path::GetDir(filePath)); filePath.Set(path::Join(dir, fdata.cFileName)); FindClose(hfind); } EngineType engineType; PasswordHolder pwdUI(password); BaseEngine *engine = EngineManager::CreateEngine(filePath, &pwdUI, &engineType); if (!engine) { ErrOut("Error: Couldn't create an engine for %s!", path::GetBaseName(filePath)); return 1; } Vec<PageAnnotation> *userAnnots = LoadFileModifications(engine->FileName()); engine->UpdateUserAnnotations(userAnnots); delete userAnnots; if (!loadOnly) DumpData(engine, fullDump); if (renderPath) RenderDocument(engine, renderPath, renderZoom, silent); delete engine; #ifdef DEBUG // report memory leaks on stderr for engines that shouldn't leak if (engineType != Engine_DjVu) { _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); } #endif return 0; }