コード例 #1
0
ファイル: PdfSync.cpp プロジェクト: BianChengNan/sumatrapdf
int Pdfsync::DocToSource(UINT pageNo, PointI pt, ScopedMem<WCHAR>& filename, UINT *line, UINT *col)
{
    if (IsIndexDiscarded())
        if (RebuildIndex() != PDFSYNCERR_SUCCESS)
            return PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED;

    // find the entry in the index corresponding to this page
    if (pageNo <= 0 || pageNo >= sheetIndex.Count() || pageNo > (UINT)engine->PageCount())
        return PDFSYNCERR_INVALID_PAGE_NUMBER;

    // PdfSync coordinates are y-inversed
    RectI mbox = engine->PageMediabox(pageNo).Round();
    pt.y = mbox.dy - pt.y;

    // distance to the closest pdf location (in the range <PDFSYNC_EPSILON_SQUARE)
    UINT closest_xydist = UINT_MAX;
    UINT selected_record = UINT_MAX;
    // If no record is found within a distance^2 of PDFSYNC_EPSILON_SQUARE
    // (selected_record == -1) then we pick up the record that is closest
    // vertically to the hit-point.
    UINT closest_ydist = UINT_MAX; // vertical distance between the hit point and the vertically-closest record
    UINT closest_xdist = UINT_MAX; // horizontal distance between the hit point and the vertically-closest record
    UINT closest_ydist_record = UINT_MAX; // vertically-closest record

    // read all the sections of 'p' declarations for this pdf sheet
    for (size_t i = sheetIndex.At(pageNo); i < points.Count() && points.At(i).page == pageNo; i++) {
        // check whether it is closer than the closest point found so far
        UINT dx = abs(pt.x - (int)SYNC_TO_PDF_COORDINATE(points.At(i).x));
        UINT dy = abs(pt.y - (int)SYNC_TO_PDF_COORDINATE(points.At(i).y));
        UINT dist = dx * dx + dy * dy;
        if (dist < PDFSYNC_EPSILON_SQUARE && dist < closest_xydist) {
            selected_record = points.At(i).record;
            closest_xydist = dist;
        }
        else if ((closest_xydist == UINT_MAX) && dy < PDFSYNC_EPSILON_Y &&
                 (dy < closest_ydist || (dy == closest_ydist && dx < closest_xdist))) {
            closest_ydist_record = points.At(i).record;
            closest_ydist = dy;
            closest_xdist = dx;
        }
    }

    if (selected_record == UINT_MAX)
        selected_record = closest_ydist_record;
    if (selected_record == UINT_MAX)
        return PDFSYNCERR_NO_SYNC_AT_LOCATION; // no record was found close enough to the hit point

    // We have a record number, we need to find its declaration ('l ...') in the syncfile
    PdfsyncLine cmp; cmp.record = selected_record;
    PdfsyncLine *found = (PdfsyncLine *)bsearch(&cmp, lines.LendData(), lines.Count(), sizeof(PdfsyncLine), cmpLineRecords);
    assert(found);
    if (!found)
        return PDFSYNCERR_NO_SYNC_AT_LOCATION;

    filename.Set(str::Dup(srcfiles.At(found->file)));
    *line = found->line;
    *col = found->column;

    return PDFSYNCERR_SUCCESS;
}
コード例 #2
0
static void BenchFile(const WCHAR *filePath, const WCHAR *pagesSpec)
{
    if (!file::Exists(filePath)) {
        return;
    }

    // ad-hoc: if enabled times layout instead of rendering and does layout
    // using all text rendering methods, so that we can compare and find
    // docs that take a long time to load

    if (Doc::IsSupportedFile(filePath) && !gGlobalPrefs->ebookUI.useFixedPageUI) {
        BenchEbookLayout(filePath);
        return;
    }

    if (ChmModel::IsSupportedFile(filePath) && !gGlobalPrefs->chmUI.useFixedPageUI) {
        BenchChmLoadOnly(filePath);
        return;
    }

    Timer total;
    logbench(L"Starting: %s", filePath);

    Timer t;
    BaseEngine *engine = EngineManager::CreateEngine(filePath);
    if (!engine) {
        logbench(L"Error: failed to load %s", filePath);
        return;
    }

    double timeMs = t.Stop();
    logbench(L"load: %.2f ms", timeMs);
    int pages = engine->PageCount();
    logbench(L"page count: %d", pages);

    if (nullptr == pagesSpec) {
        for (int i = 1; i <= pages; i++) {
            BenchLoadRender(engine, i);
        }
    }

    assert(!pagesSpec || IsBenchPagesInfo(pagesSpec));
    Vec<PageRange> ranges;
    if (ParsePageRanges(pagesSpec, ranges)) {
        for (size_t i = 0; i < ranges.Count(); i++) {
            for (int j = ranges.At(i).start; j <= ranges.At(i).end; j++) {
                if (1 <= j && j <= pages)
                    BenchLoadRender(engine, j);
            }
        }
    }

    delete engine;
    total.Stop();

    logbench(L"Finished (in %.2f ms): %s", total.GetTimeInMs(), filePath);
}
コード例 #3
0
ファイル: PdfPreview.cpp プロジェクト: kzmkv/SumatraPDF
    RectD GetPageRect(int pageNo) {
        if (preventRecursion)
            return RectD();

        preventRecursion = true;
        // assume that any engine methods could lead to a seek
        RectD bbox = engine->PageMediabox(pageNo);
        bbox = engine->Transform(bbox, pageNo, 1.0, 0);
        preventRecursion = false;
        return bbox;
    }
コード例 #4
0
// returns a list of permissions denied by this document
// Caller needs to free the result
static WCHAR *FormatPermissions(Controller *ctrl)
{
    if (!ctrl->AsFixed())
        return nullptr;

    WStrVec denials;

    BaseEngine *engine = ctrl->AsFixed()->GetEngine();
    if (!engine->AllowsPrinting())
        denials.Push(str::Dup(_TR("printing document")));
    if (!engine->AllowsCopyingText())
        denials.Push(str::Dup(_TR("copying text")));

    return denials.Join(L", ");
}
コード例 #5
0
ファイル: PdfSync.cpp プロジェクト: sambhare/sumatrapdf
int Pdfsync::SourceToDoc(const WCHAR* srcfilename, UINT line, UINT col, UINT* page, Vec<RectI>& rects) {
    if (IsIndexDiscarded())
        if (RebuildIndex() != PDFSYNCERR_SUCCESS)
            return PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED;

    Vec<size_t> found_records;
    UINT ret = SourceToRecord(srcfilename, line, col, found_records);
    if (ret != PDFSYNCERR_SUCCESS || found_records.size() == 0)
        return ret;

    rects.Reset();

    // records have been found for the desired source position:
    // we now find the page and positions in the PDF corresponding to these found records
    UINT firstPage = UINT_MAX;
    for (size_t i = 0; i < points.size(); i++) {
        if (!found_records.Contains(points.at(i).record))
            continue;
        if (firstPage != UINT_MAX && firstPage != points.at(i).page)
            continue;
        firstPage = *page = points.at(i).page;
        RectD rc(SYNC_TO_PDF_COORDINATE(points.at(i).x), SYNC_TO_PDF_COORDINATE(points.at(i).y), MARK_SIZE, MARK_SIZE);
        // PdfSync coordinates are y-inversed
        RectD mbox = engine->PageMediabox(firstPage);
        rc.y = mbox.dy - (rc.y + rc.dy);
        rects.Push(rc.Round());
    }

    if (rects.size() > 0)
        return PDFSYNCERR_SUCCESS;
    // the record does not correspond to any point in the PDF: this is possible...
    return PDFSYNCERR_NOSYNCPOINT_FOR_LINERECORD;
}
コード例 #6
0
ファイル: PdfPreview.cpp プロジェクト: kzmkv/SumatraPDF
IFACEMETHODIMP PreviewBase::GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha)
{
    BaseEngine *engine = GetEngine();
    if (!engine)
        return E_FAIL;

    RectD page = engine->Transform(engine->PageMediabox(1), 1, 1.0, 0);
    float zoom = min(cx / (float)page.dx, cx / (float)page.dy) - 0.001f;
    RectI thumb = RectD(0, 0, page.dx * zoom, page.dy * zoom).Round();

    BITMAPINFO bmi = { 0 };
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
    bmi.bmiHeader.biHeight = thumb.dy;
    bmi.bmiHeader.biWidth = thumb.dx;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;

    unsigned char *bmpData = NULL;
    HBITMAP hthumb = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&bmpData, NULL, 0);
    if (!hthumb)
        return E_OUTOFMEMORY;

    page = engine->Transform(thumb.Convert<double>(), 1, zoom, 0, true);
    RenderedBitmap *bmp = engine->RenderBitmap(1, zoom, 0, &page);

    HDC hdc = GetDC(NULL);
    if (bmp && GetDIBits(hdc, bmp->GetBitmap(), 0, thumb.dy, bmpData, &bmi, DIB_RGB_COLORS)) {
        // cf. http://msdn.microsoft.com/en-us/library/bb774612(v=VS.85).aspx
        for (int i = 0; i < thumb.dx * thumb.dy; i++)
            bmpData[4 * i + 3] = 0xFF;

        *phbmp = hthumb;
        if (pdwAlpha)
            *pdwAlpha = WTSAT_RGB;
    }
    else {
        DeleteObject(hthumb);
        hthumb = NULL;
    }

    ReleaseDC(NULL, hdc);
    delete bmp;

    return hthumb ? S_OK : E_NOTIMPL;
}
コード例 #7
0
static void BenchFile(TCHAR *filePath, const TCHAR *pagesSpec)
{
    if (!file::Exists(filePath)) {
        return;
    }

    Timer total(true);
    logbench("Starting: %s", filePath);

    Timer t(true);
    BaseEngine *engine = EngineManager(!gUseEbookUI).CreateEngine(filePath);
    t.Stop();

    if (!engine) {
        logbench("Error: failed to load %s", filePath);
        return;
    }

    double timems = t.GetTimeInMs();
    logbench("load: %.2f ms", timems);
    int pages = engine->PageCount();
    logbench("page count: %d", pages);

    if (NULL == pagesSpec) {
        for (int i = 1; i <= pages; i++) {
            BenchLoadRender(engine, i);
        }
    }

    assert(!pagesSpec || IsBenchPagesInfo(pagesSpec));
    Vec<PageRange> ranges;
    if (ParsePageRanges(pagesSpec, ranges)) {
        for (size_t i = 0; i < ranges.Count(); i++) {
            for (int j = ranges.At(i).start; j <= ranges.At(i).end; j++) {
                if (1 <= j && j <= pages)
                    BenchLoadRender(engine, j);
            }
        }
    }

    delete engine;
    total.Stop();

    logbench("Finished (in %.2f ms): %s", total.GetTimeInMs(), filePath);
}
コード例 #8
0
ファイル: PdfPreview.cpp プロジェクト: kzmkv/SumatraPDF
IFACEMETHODIMP PreviewBase::DoPreview()
{
    WNDCLASSEX wcex = { 0 };
    wcex.cbSize = sizeof(wcex);
    wcex.lpfnWndProc = PreviewWndProc;
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.lpszClassName = _T("SumatraPDF_PreviewPane");
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClassEx(&wcex);

    m_hwnd = CreateWindow(wcex.lpszClassName, NULL, WS_CHILD | WS_VSCROLL | WS_VISIBLE,
                          m_rcParent.x, m_rcParent.x, m_rcParent.dx, m_rcParent.dy,
                          m_hwndParent, NULL, NULL, NULL);
    if (!m_hwnd)
        return HRESULT_FROM_WIN32(GetLastError());

    this->renderer = NULL;
    SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)this);

    BaseEngine *engine = GetEngine();
    int pageCount = 1;
    if (engine) {
        pageCount = engine->PageCount();
        this->renderer = new PageRenderer(engine, m_hwnd);
        // don't use the engine afterwards directly (cf. PageRenderer::preventRecursion)
        engine = NULL;
    }

    SCROLLINFO si = { 0 };
    si.cbSize = sizeof(si);
    si.fMask = SIF_ALL;
    si.nPos = 1;
    si.nMin = 1;
    si.nMax = pageCount;
    si.nPage = si.nMax > 1 ? 1 : 2;
    SetScrollInfo(m_hwnd, SB_VERT, &si, TRUE);

    ShowWindow(m_hwnd, SW_SHOW);
    return S_OK;
}
コード例 #9
0
ファイル: HepRndmGenerators.cpp プロジェクト: l1calo/gaudi
 /// Initialize the generator
 virtual StatusCode initialize(const IRndmGen::Param& par)   {
   StatusCode status = RndmGen::initialize(par);
   if ( status.isSuccess() )   {
     try   {
       Rndm::DefinedPdf* specs = dynamic_cast<Rndm::DefinedPdf*>(m_params);
       if ( 0 != specs )  {
         m_generator = new RandGeneral( &specs->pdf()[0],
                                        specs->pdf().size(),
                                        specs->interpolation());
         BaseEngine* engine = dynamic_cast<BaseEngine*>(m_engine);
         if ( 0 != engine )    {
           m_hepEngine = engine->hepEngine();
           if ( 0 != m_hepEngine )   {
             return StatusCode::SUCCESS;
           }
         }
       }
     }
     catch (...)   {
     }
   }
   return StatusCode::FAILURE;
 }
コード例 #10
0
    virtual void Visit(const WCHAR *name, const WCHAR *url, int level) {
        PageDestination *dest;
        if (!url)
            dest = NULL;
        else if (IsExternalUrl(url))
            dest = new SimpleDest2(0, RectD(), str::Dup(url));
        else if (str::FindChar(url, '%')) {
            ScopedMem<WCHAR> decodedUrl(str::Dup(url));
            str::UrlDecodeInPlace(decodedUrl);
            dest = engine->GetNamedDest(decodedUrl);
        }
        else
            dest = engine->GetNamedDest(url);

        EbookTocItem *item = new EbookTocItem(str::Dup(name), dest);
        item->id = ++idCounter;
        item->open = level <= 2;
        if (isIndex) {
            item->pageNo = 0;
            item->open = level != 1;
            level++;
        }
        AppendTocItem(root, item, level);
    }
コード例 #11
0
    PrintData(BaseEngine *engine, PRINTER_INFO_2 *printerInfo, DEVMODE *devMode,
              Vec<PRINTPAGERANGE> &ranges, Print_Advanced_Data &advData, int rotation = 0,
              Vec<SelectionOnPage> *sel = nullptr)
        : engine(nullptr), advData(advData), rotation(rotation) {
        if (engine)
            this->engine = engine->Clone();

        if (printerInfo) {
            printerName.Set(str::Dup(printerInfo->pPrinterName));
        }
        if (devMode)
            this->devMode.Set((LPDEVMODE)memdup(devMode, devMode->dmSize + devMode->dmDriverExtra));

        if (!sel)
            this->ranges = ranges;
        else
            this->sel = *sel;
    }
コード例 #12
0
void*
BaseEngine::_DrawingThread(void* arg)
{
    BaseEngine*  engine =(BaseEngine*)arg;
    int& pages = engine->fPages;
    std::vector< std::pair<BBitmap*, bool> >& bitmap = engine->fBitmap;
    std::vector< pthread_mutex_t >& mutex = engine->fMutex;

    int upperbound = -1;
    int lowerbound = -1;
    int pageFuture = -1;
    int pagePast   = -1;
    int currentPage = -1;
    int deleteIndex = 0;
    bool forwardPriority = true;
	
	while(true) {
		pthread_mutex_lock(&gEngineStopMutex);
		if (engine->fStopThread) {
			engine->fStopThread = false;
			pthread_mutex_unlock(&gEngineStopMutex);
			return nullptr;			
		}
		pthread_mutex_unlock(&gEngineStopMutex);
		
        if (currentPage != engine->fCurrentPageNo) {
            if (engine->fCurrentPageNo < currentPage)
                forwardPriority = false;
            else
                forwardPriority = true;

            deleteIndex = 0;
            currentPage = engine->fCurrentPageNo;
            pageFuture = pagePast = currentPage;
            lowerbound =  currentPage - engine->fBackwardCache;
            upperbound =  currentPage + engine->fForwardCache;

            if (lowerbound < 0)         lowerbound = 0;
            if (upperbound >= pages)    upperbound = pages - 1;
        } else {
            for (; deleteIndex < pages; ++deleteIndex) {
                pthread_mutex_lock(&mutex[deleteIndex]);
                if (bitmap[deleteIndex].first != nullptr
                    && (deleteIndex < lowerbound || deleteIndex > upperbound)) {
                    delete bitmap[deleteIndex].first;
                    bitmap[deleteIndex].first = nullptr;
                    pthread_mutex_unlock(&mutex[deleteIndex]);
                    break;
                }
                pthread_mutex_unlock(&mutex[deleteIndex]);
            }

            if (forwardPriority) {
                if (pageFuture < upperbound) {
                    ++pageFuture;
                    pthread_mutex_lock(&mutex[pageFuture]);
                    if (bitmap[pageFuture].first == nullptr) {
                        bitmap[pageFuture] = engine->_RenderBitmap(pageFuture);
                    } else if (bitmap[pageFuture].second == true) {
                        delete bitmap[pageFuture].first;
                        bitmap[pageFuture] = engine->_RenderBitmap(pageFuture);
                    }
                    pthread_mutex_unlock(&mutex[pageFuture]);
                } else if (pagePast > lowerbound) {
                    --pagePast;
                    pthread_mutex_lock(&mutex[pagePast]);
                    if (bitmap[pagePast].first == nullptr) {
                        bitmap[pagePast] = engine->_RenderBitmap(pagePast);
                    } else if (bitmap[pageFuture].second == true) {
                        delete bitmap[pageFuture].first;
                        bitmap[pageFuture] = engine->_RenderBitmap(pageFuture);
                    }
                    pthread_mutex_unlock(&mutex[pagePast]);
                } else {
                    usleep(1000);
                }
            } else {
                if (pagePast > lowerbound) {
                    --pagePast;
                    pthread_mutex_lock(&mutex[pagePast]);
                    if (bitmap[pagePast].first == nullptr)
                        bitmap[pagePast] = engine->_RenderBitmap(pagePast);

                    pthread_mutex_unlock(&mutex[pagePast]);
                } else if (pageFuture < upperbound) {
                    ++pageFuture;
                    pthread_mutex_lock(&mutex[pageFuture]);
                    if (bitmap[pageFuture].first == nullptr)
                        bitmap[pageFuture] = engine->_RenderBitmap(pageFuture);

                    pthread_mutex_unlock(&mutex[pageFuture]);
                } else {
                    usleep(1000);
                }
            }
        }
    }
	return nullptr;
}
コード例 #13
0
ファイル: Print.cpp プロジェクト: iamplaced/sumatrapdf
bool PrintFile(const WCHAR *fileName, const WCHAR *printerName, bool displayErrors, const WCHAR *settings)
{
    if (!HasPermission(Perm_PrinterAccess))
        return false;

    ScopedMem<WCHAR> fileName2(path::Normalize(fileName));
    BaseEngine *engine = EngineManager::CreateEngine(!gUseEbookUI, fileName2);
    if (!engine || !engine->AllowsPrinting()) {
        if (displayErrors)
            MessageBox(NULL, _TR("Cannot print this file"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        return false;
    }

    HANDLE printer;
    bool ok = OpenPrinter((WCHAR *)printerName, &printer, NULL);
    if (!ok) {
        if (displayErrors)
            MessageBox(NULL, _TR("Printer with given name doesn't exist"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        return false;
    }

    // get printer driver information
    DWORD needed = 0;
    GetPrinter(printer, 2, NULL, 0, &needed);
    ScopedMem<PRINTER_INFO_2> infoData((PRINTER_INFO_2 *)AllocArray<BYTE>(needed));
    if (infoData)
        ok = GetPrinter(printer, 2, (LPBYTE)infoData.Get(), needed, &needed);
    if (!ok || !infoData || needed <= sizeof(PRINTER_INFO_2)) goto Exit;

    LONG structSize = DocumentProperties(NULL,
        printer,                /* Handle to our printer. */
        (WCHAR *)printerName,   /* Name of the printer. */ 
        NULL,                   /* Asking for size, so */
        NULL,                   /* these are not used. */
        0);                     /* Zero returns buffer size. */
    if (structSize < sizeof(DEVMODE)) {
        // If failure, inform the user, cleanup and return failure.
        if (displayErrors)
            MessageBox(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        goto Exit;
    }
    LPDEVMODE devMode = (LPDEVMODE)malloc(structSize);
    if (!devMode) goto Exit;

    // Get the default DevMode for the printer and modify it for your needs.
    LONG returnCode = DocumentProperties(NULL,
        printer,
        (WCHAR *)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.
        if (displayErrors)
            MessageBox(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        goto Exit;
    }

    ClosePrinter(printer);
    printer = NULL;

    {
        Print_Advanced_Data advanced;
        Vec<PRINTPAGERANGE> ranges;
        ApplyPrintSettings(settings, engine->PageCount(), ranges, advanced);

        PrintData pd(engine, infoData, devMode, ranges, advanced);
        ok = PrintToDevice(pd);
        if (!ok && displayErrors)
            MessageBox(NULL, _TR("Couldn't initialize printer"), _TR("Printing problem."),
                MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
    }

Exit:
    free(devMode);
    if (printer)
        ClosePrinter(printer);
    delete engine;
    return ok;
}
コード例 #14
0
ファイル: PdfSync.cpp プロジェクト: BianChengNan/sumatrapdf
int SyncTex::SourceToDoc(const WCHAR* srcfilename, UINT line, UINT col, UINT *page, Vec<RectI> &rects)
{
    if (IsIndexDiscarded())
        if (RebuildIndex() != PDFSYNCERR_SUCCESS)
            return PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED;
    assert(this->scanner);

    ScopedMem<WCHAR> srcfilepath;
    // convert the source file to an absolute path
    if (PathIsRelative(srcfilename))
        srcfilepath.Set(PrependDir(srcfilename));
    else
        srcfilepath.Set(str::Dup(srcfilename));
    if (!srcfilepath)
        return PDFSYNCERR_OUTOFMEMORY;

    bool isUtf8 = true;
    char *mb_srcfilepath = str::conv::ToUtf8(srcfilepath);
TryAgainAnsi:
    if (!mb_srcfilepath)
        return PDFSYNCERR_OUTOFMEMORY;
    int ret = synctex_display_query(this->scanner, mb_srcfilepath, line, col);
    free(mb_srcfilepath);
    // recent SyncTeX versions encode in UTF-8 instead of ANSI
    if (isUtf8 && -1 == ret) {
        isUtf8 = false;
        mb_srcfilepath = str::conv::ToAnsi(srcfilepath);
        goto TryAgainAnsi;
    }

    if (-1 == ret)
        return PDFSYNCERR_UNKNOWN_SOURCEFILE;
    if (0 == ret)
        return PDFSYNCERR_NOSYNCPOINT_FOR_LINERECORD;

    synctex_node_t node;
    int firstpage = -1;
    rects.Reset();

    while ((node = synctex_next_result(this->scanner)) != NULL) {
        if (firstpage == -1) {
            firstpage = synctex_node_page(node);
            if (firstpage <= 0 || firstpage > engine->PageCount())
                continue;
            *page = (UINT)firstpage;
        }
        if (synctex_node_page(node) != firstpage)
            continue;

        RectD rc;
        rc.x  = synctex_node_box_visible_h(node);
        rc.y  = synctex_node_box_visible_v(node) - synctex_node_box_visible_height(node);
        rc.dx = synctex_node_box_visible_width(node),
        rc.dy = synctex_node_box_visible_height(node) + synctex_node_box_visible_depth(node);
        rects.Push(rc.Round());
    }

    if (firstpage <= 0)
        return PDFSYNCERR_NOSYNCPOINT_FOR_LINERECORD;
    return PDFSYNCERR_SUCCESS;
}
コード例 #15
0
ファイル: Print.cpp プロジェクト: codepongo/sumatrapdf
bool PrintFile(const WCHAR *fileName, WCHAR *printerName, bool displayErrors, const WCHAR *settings)
{
    bool ok = false;
    if (!HasPermission(Perm_PrinterAccess))
        return false;

    ScopedMem<WCHAR> fileName2(path::Normalize(fileName));
    BaseEngine *engine = EngineManager::CreateEngine(fileName2, true /* prefer Chm2Engine */);
#ifndef DISABLE_DOCUMENT_RESTRICTIONS
    if (engine && !engine->AllowsPrinting()) {
        delete engine;
        engine = NULL;
    }
#endif
    if (!engine) {
        if (displayErrors)
            MessageBoxWarning(NULL, _TR("Cannot print this file"), _TR("Printing problem."));
        return false;
    }

    HANDLE printer;
    BOOL res = OpenPrinter(printerName, &printer, NULL);
    if (0 == res) {
        if (displayErrors)
            MessageBoxWarning(NULL, _TR("Printer with given name doesn't exist"), _TR("Printing problem."));
        return false;
    }

    LPDEVMODE devMode = NULL;
    // get printer driver information
    DWORD needed = 0;
    GetPrinter(printer, 2, NULL, 0, &needed);
    ScopedMem<PRINTER_INFO_2> infoData((PRINTER_INFO_2 *)AllocArray<BYTE>(needed));
    if (infoData)
        res = GetPrinter(printer, 2, (LPBYTE)infoData.Get(), needed, &needed);
    if ((0 == res) || !infoData || needed <= sizeof(PRINTER_INFO_2))
        goto Exit;

    LONG structSize = DocumentProperties(NULL,
        printer,
        printerName,
        NULL,                   /* Asking for size, so */
        NULL,                   /* not used. */
        0);                     /* Zero returns buffer size. */
    if (structSize < sizeof(DEVMODE)) {
        // If failure, inform the user, cleanup and return failure.
        if (displayErrors)
            MessageBoxWarning(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."));
        goto Exit;
    }
    devMode = (LPDEVMODE)malloc(structSize);
    if (!devMode)
        goto Exit;

    // Get the default DevMode for the printer and modify it for your needs.
    LONG returnCode = DocumentProperties(NULL,
        printer,
        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.
        if (displayErrors)
            MessageBoxWarning(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."));
        goto Exit;
    }

    ClosePrinter(printer);
    printer = NULL;

    {
        Print_Advanced_Data advanced;
        Vec<PRINTPAGERANGE> ranges;
        ApplyPrintSettings(settings, engine->PageCount(), ranges, advanced, devMode);

        PrintData pd(engine, infoData, devMode, ranges, advanced);
        ok = PrintToDevice(pd);
        if (!ok && displayErrors)
            MessageBoxWarning(NULL, _TR("Couldn't initialize printer"), _TR("Printing problem."));
    }

Exit:
    free(devMode);
    if (printer)
        ClosePrinter(printer);
    delete engine;
    return ok;
}
コード例 #16
0
ファイル: EngineDump.cpp プロジェクト: lintmars/sumatrapdf
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][-render <path-%%d.tga>]\n",
            path::GetBaseName(argList.At(0)));
        return 2;
    }

    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;
    float renderZoom = 1.f;
    bool useAlternateHandlers = false;
    bool loadOnly = false, silent = 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()) {
            // 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;
#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
    if (silent) {
        FILE *nul;
        freopen_s(&nul, "NUL", "w", stdout);
        freopen_s(&nul, "NUL", "w", stderr);
    }

    // optionally use GDI+ rendering for PDF/XPS and the original ChmEngine for CHM
    DebugGdiPlusDevice(useAlternateHandlers);
    bool useChm2Engine = !useAlternateHandlers;

    ScopedGdiPlus gdiPlus;
    DocType engineType;
    PasswordHolder pwdUI(password);
    BaseEngine *engine = EngineManager::CreateEngine(filePath, &pwdUI, &engineType, useChm2Engine);
    if (!engine) {
        ErrOut("Error: Couldn't create an engine for %s!\n", 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;
}
コード例 #17
0
ファイル: PdfSync.cpp プロジェクト: BianChengNan/sumatrapdf
// see http://itexmac.sourceforge.net/pdfsync.html for the specification
int Pdfsync::RebuildIndex()
{
    size_t len;
    ScopedMem<char> data(file::ReadAll(syncfilepath, &len));
    if (!data)
        return PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED;
    // convert the file data into a list of zero-terminated strings
    str::TransChars(data, "\r\n", "\0\0");

    // parse preamble (jobname and version marker)
    char *line = data;
    char *dataEnd = data + len;

    // replace star by spaces (TeX uses stars instead of spaces in filenames)
    str::TransChars(line, "*/", " \\");
    ScopedMem<WCHAR> jobName(str::conv::FromAnsi(line));
    jobName.Set(str::Join(jobName, L".tex"));
    jobName.Set(PrependDir(jobName));

    line = Advance0Line(line, dataEnd);
    UINT versionNumber = 0;
    if (!line || !str::Parse(line, "version %u", &versionNumber) || versionNumber != 1)
        return PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED;

    // reset synchronizer database
    srcfiles.Reset();
    lines.Reset();
    points.Reset();
    fileIndex.Reset();
    sheetIndex.Reset();

    Vec<size_t> filestack;
    UINT page = 1;
    sheetIndex.Append(0);

    // add the initial tex file to the source file stack
    filestack.Push(srcfiles.Count());
    srcfiles.Append(jobName.StealData());
    PdfsyncFileIndex findex = { 0 };
    fileIndex.Append(findex);

    PdfsyncLine psline;
    PdfsyncPoint pspoint;

    // parse data
    UINT maxPageNo = engine->PageCount();
    while ((line = Advance0Line(line, dataEnd)) != NULL) {
        if (!line)
            break;
        switch (*line) {
        case 'l':
            psline.file = filestack.Last();
            if (str::Parse(line, "l %u %u %u", &psline.record, &psline.line, &psline.column))
                lines.Append(psline);
            else if (str::Parse(line, "l %u %u", &psline.record, &psline.line)) {
                psline.column = 0;
                lines.Append(psline);
            }
            // else dbg("Bad 'l' line in the pdfsync file");
            break;

        case 's':
            if (str::Parse(line, "s %u", &page))
                sheetIndex.Append(points.Count());
            // else dbg("Bad 's' line in the pdfsync file");
            // if (0 == page || page > maxPageNo)
            //     dbg("'s' line with invalid page number in the pdfsync file");
            break;

        case 'p':
            pspoint.page = page;
            if (0 == page || page > maxPageNo)
                /* ignore point for invalid page number */;
            else if (str::Parse(line, "p %u %u %u", &pspoint.record, &pspoint.x, &pspoint.y))
                points.Append(pspoint);
            else if (str::Parse(line, "p* %u %u %u", &pspoint.record, &pspoint.x, &pspoint.y))
                points.Append(pspoint);
            // else dbg("Bad 'p' line in the pdfsync file");
            break;

        case '(':
            {
                ScopedMem<WCHAR> filename(str::conv::FromAnsi(line + 1));
                // if the filename contains quotes then remove them
                // TODO: this should never happen!?
                if (filename[0] == '"' && filename[str::Len(filename) - 1] == '"')
                    filename.Set(str::DupN(filename + 1, str::Len(filename) - 2));
                // undecorate the filepath: replace * by space and / by \ 
                str::TransChars(filename, L"*/", L" \\");
                // if the file name extension is not specified then add the suffix '.tex'
                if (str::IsEmpty(path::GetExt(filename)))
                    filename.Set(str::Join(filename, L".tex"));
                // ensure that the path is absolute
                if (PathIsRelative(filename))
                    filename.Set(PrependDir(filename));

                filestack.Push(srcfiles.Count());
                srcfiles.Append(filename.StealData());
                findex.start = findex.end = lines.Count();
                fileIndex.Append(findex);
            }
            break;

        case ')':
            if (filestack.Count() > 1)
                fileIndex.At(filestack.Pop()).end = lines.Count();
            // else dbg("Unbalanced ')' line in the pdfsync file");
            break;

        default:
            // dbg("Ignoring invalid pdfsync line starting with '%c'", *line);
            break;
        }
    }

    fileIndex.At(0).end = lines.Count();
    assert(filestack.Count() == 1);

    return Synchronizer::RebuildIndex();
}