pdfsync.h.svn-base

来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· SVN-BASE 代码 · 共 325 行

SVN-BASE
325
字号
// Copyright William Blum 2008 http://william.famille-blum.org/// PDF-source synchronizer based on .pdfsync file// License: GPLv2#ifndef _PDF_SYNC_H__#define _PDF_SYNC_H__#include <windows.h>#include <assert.h>#include "base_util.h"#include "str_util.h"#include "tstr_util.h"#include "file_util.h"#ifdef SYNCTEX_FEATURE#include "synctex_parser.h"#endif#ifdef USE_STL#include <vector>#include <stack>using namespace std;#else#define ALLOC_INCREMENT  10template <class _Ty>class vector {public:    _Ty &operator[](size_t i) const    {        assert(i<m_size);        return m_data[i];    }    void clear()    {        m_size = 0;    }    void push_back(_Ty v)    {        if (m_size>=m_allocsize) {            m_allocsize += ALLOC_INCREMENT;            m_data = (_Ty *)realloc(m_data, sizeof(_Ty) * m_allocsize);         }        m_data[m_size] = v;        m_size++;    }    void resize(size_t s)    {        if (s>m_allocsize) {            m_allocsize = s+ALLOC_INCREMENT-s%ALLOC_INCREMENT;            m_data = (_Ty *)realloc(m_data, sizeof(_Ty) * m_allocsize);         }        m_size = s;    }    size_t size()    {        return m_size;    }    vector()    {        m_allocsize = ALLOC_INCREMENT;        m_size = 0;        m_data = (_Ty *)malloc(sizeof(_Ty) * m_allocsize);     }    ~vector()    {        for(size_t i=0; i<m_size; i++)            m_data[i].~_Ty();        free(m_data);    }private:    _Ty *m_data;    size_t m_allocsize, m_size;};template <class _Ty>class stack : public vector<_Ty> {public:    void push(_Ty v) {        push_back(v);    }    void pop() {        assert(this->size()>0);        resize(this->size()-1);    }    _Ty &top() {        assert(this->size()>0);        return (*this)[this->size()-1];    }};#endif// size of the mark highlighting the location calculated by forward-search#define MARK_SIZE                            10 // maximum error in the source file line number when doing forward-search#define EPSILON_LINE                         5  // Minimal error distance^2 between a point clicked by the user and a PDF mark#define PDFSYNC_EPSILON_SQUARE               800// Minimal vertical distance#define PDFSYNC_EPSILON_Y                    20//////// Error codes returned by the synchronization functionsenum {  PDFSYNCERR_SUCCESS,                   // the synchronization succeeded        PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED, // the sync file cannot be opened        PDFSYNCERR_INVALID_PAGE_NUMBER,       // the given page number does not exist in the sync file        PDFSYNCERR_NO_SYNC_AT_LOCATION,       // no synchronization found at this location        PDFSYNCERR_UNKNOWN_SOURCEFILE,        // the source file is not present in the sync file        PDFSYNCERR_NORECORD_IN_SOURCEFILE,    // there is not any record declaration for that particular source file        PDFSYNCERR_NORECORD_FOR_THATLINE,     // no record found for the requested line        PDFSYNCERR_NOSYNCPOINT_FOR_LINERECORD,// a record is found for the given source line but there is not point in the PDF that corresponds to it};typedef struct {    TCHAR filename[_MAX_PATH]; // source file name#ifndef NDEBUG    fpos_t openline_pos;    // start of the scope in the sync file    fpos_t closeline_pos;   // end of the scope#endif    size_t first_recordsection; // index of the first record section of that file    size_t last_recordsection;  // index of the last record section of that file} src_file;// a plines_section is a section of consecutive lines of the form "p ..."typedef struct {    fpos_t startpos; // position of the first "p ..." line#ifndef NDEBUG    fpos_t endpos;#endif} plines_section;// a section of consecutive records declarations in the syncfile ('l' lines)typedef struct {    size_t srcfile;           // index of the `scoping' source file     fpos_t startpos;       // start position in the sync file    UINT firstrecord;      // number of the first record in the section#ifndef NDEBUG    fpos_t endpos;         // end position in the sync file    int highestrecord;      // highest record ##endif} record_section;#define PDF_EXTENSION     ".PDF"#define PDFSYNC_EXTENSION ".PDFSYNC"// System of point coordinatestypedef enum { TopLeft,    // origin at the top-left corner       BottomLeft, // origin at the bottom-left corner} CoordSystem;class Synchronizer{public:    Synchronizer(LPCTSTR _syncfilename) {        this->index_discarded = true;        this->coordsys = BottomLeft; // by default set the internal coordinate system to bottom-left        this->dir = FilePath_GetDir(_syncfilename);    }    ~Synchronizer() {        if (dir)            free(dir);    }    // conversion from one coordinate system to another    void convert_coord_to_internal(UINT *x, UINT *y, UINT pageHeight, CoordSystem src)    {        if (src==this->coordsys)            return;            *y = pageHeight - *y;    }    void convert_coord_from_internal(UINT *x, UINT *y, UINT pageHeight, CoordSystem dst)    {        if (dst==this->coordsys)            return;            *y = pageHeight - *y;    }        // Inverse-search:    //  - sheet: page number in the PDF (starting from 1)    //  - x,y: user-specified PDF-coordinates. They must be given in the system used internally by the synchronizer.    //  - maxy: contains the height of the page. this is necessary to convert into the coordinate-system used internally by the syncrhonizer.    //    For an A4 paper it is approximately equal to maxy=842.    //  - cchFilename: size of the buffer 'filename'    // The result is returned in filename, line, col    //  - filename: receives the name of the source file    //  - line: receives the line number    //  - col: receives the column number    virtual UINT pdf_to_source(UINT sheet, UINT x, UINT y, PTSTR filename, UINT cchFilename, UINT *line, UINT *col) = 0;        // Forward-search:    // The result is returned in (page,x,y). The coordinates x,y are specified in the internal     // coordinate system.    virtual UINT source_to_pdf(LPCTSTR srcfilename, UINT line, UINT col, UINT *page, UINT *x, UINT *y) = 0;    void discard_index() { this->index_discarded = true; }    bool is_index_discarded() { return this->index_discarded; }    int rebuild_index() { this->index_discarded = false; return 0; }    UINT prepare_commandline(LPCTSTR pattern, LPCTSTR filename, UINT line, UINT col, PTSTR cmdline, UINT cchCmdline);private:    bool index_discarded; // true if the index needs to be recomputed (needs to be set to true when a change to the pdfsync file is detected)protected:    CoordSystem coordsys; // system used internally by the syncfile for the PDF coordinates    PTSTR dir;            // directory where the syncfile lies};#ifdef SYNCTEX_FEATURE#define SYNCTEX_EXTENSION ".synctex"#define SYNCTEXGZ_EXTENSION ".synctex.gz"// Synchronizer based on .synctex file generated with SyncTexclass SyncTex : public Synchronizer{public:    SyncTex(LPCTSTR _syncfilename) : Synchronizer(_syncfilename)    {        size_t n = _tcslen(_syncfilename);        size_t u1 = dimof(SYNCTEX_EXTENSION)-1,               u2 = dimof(SYNCTEXGZ_EXTENSION)-1;        assert((n>u1 && _tcsicmp(_syncfilename+(n-u1),SYNCTEX_EXTENSION)==0)               ||(n>u2 && _tcsicmp(_syncfilename+(n-u2),SYNCTEXGZ_EXTENSION)==0));        tstr_copy(this->syncfilename, dimof(this->syncfilename), _syncfilename);                this->scanner = NULL;        this->coordsys = TopLeft;    }    ~SyncTex()    {        if (scanner)          synctex_scanner_free(scanner);    }    void discard_index() { Synchronizer::discard_index();}    bool is_index_discarded() { return Synchronizer::is_index_discarded(); }    UINT pdf_to_source(UINT sheet, UINT x, UINT y, PTSTR srcfilepath, UINT cchFilepath, UINT *line, UINT *col);    UINT source_to_pdf(LPCTSTR srcfilename, UINT line, UINT col, UINT *page, UINT *x, UINT *y);    int rebuild_index();private:    TCHAR syncfilename[_MAX_PATH];    synctex_scanner_t scanner;};#endif// Synchronizer based on .sync file generated with the pdfsync tex packageclass Pdfsync : public Synchronizer{public:    Pdfsync(LPCTSTR _syncfilename) : Synchronizer(_syncfilename)    {        size_t n = _tcslen(_syncfilename);        size_t u = dimof(PDFSYNC_EXTENSION)-1;        assert(n>u && _tcsicmp(_syncfilename+(n-u),PDFSYNC_EXTENSION) == 0 );        tstr_copy(this->syncfilename, dimof(this->syncfilename), _syncfilename);        this->coordsys = BottomLeft;    }    int rebuild_index();    UINT pdf_to_source(UINT sheet, UINT x, UINT y, PTSTR srcfilepath, UINT cchFilepath, UINT *line, UINT *col);
    UINT source_to_pdf(LPCTSTR srcfilename, UINT line, UINT col, UINT *page, UINT *x, UINT *y);private:    int get_record_section(int record_index);    int scan_and_build_index(FILE *fp);    UINT source_to_record(FILE *fp, LPCTSTR srcfilename, UINT line, UINT col, vector<size_t> &records);    FILE *opensyncfile();private:    vector<size_t> pdfsheet_index; // pdfsheet_index[i] contains the index in pline_sections of the first pline section for that sheet    vector<plines_section> pline_sections;    vector<record_section> record_sections;    vector<src_file> srcfiles;    TCHAR syncfilename[_MAX_PATH];};// create a synchronizer for the given PDF fileSynchronizer *CreateSynchronizer(LPCTSTR pdffilename);#define PDFSYNC_DDE_SERVICE_A         "SUMATRA"#define PDFSYNC_DDE_SERVICE_W         L"SUMATRA"#define PDFSYNC_DDE_TOPIC_A           "control"#define PDFSYNC_DDE_TOPIC_W           L"control"// forward-search command//  format: [ForwardSearch("<pdffilepath>","<sourcefilepath>",<line>,<column>[,<newwindow>, <setfocus>])]//    if newwindow = 1 then a new window is created even if the file is already open//    if focus = 1 then the focus is set to the window//  eg: [ForwardSearch("c:\file.pdf","c:\folder\source.tex",298,0)]#define DDECOMMAND_SYNC_A         "ForwardSearch"#define DDECOMMAND_SYNC_W         L DDECOMMAND_SYNC_A// open file command//  format: [Open("<pdffilepath>"[,<newwindow>,<setfocus>,<forcerefresh>])]//    if newwindow = 1 then a new window is created even if the file is already open//    if focus = 1 then the focus is set to the window//  eg: [Open("c:\file.pdf", 1, 1)]#define DDECOMMAND_OPEN_A         "Open"#define DDECOMMAND_OPEN_W         L DDECOMMAND_OPEN_A// jump to named destination command//  format: [GoToNamedDest("<pdffilepath>","<destination name>")]//  eg: [GoToNamedDest("c:\file.pdf", "chapter.1")]. pdf file must be already opened#define DDECOMMAND_GOTO_A         "GotoNamedDest"#define DDECOMMAND_GOTO_W         L DDECOMMAND_GOTO_ALRESULT OnDDEInitiate(HWND hwnd, WPARAM wparam, LPARAM lparam);LRESULT OnDDExecute(HWND hwnd, WPARAM wparam, LPARAM lparam);LRESULT OnDDETerminate(HWND hwnd, WPARAM wparam, LPARAM lparam);#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?