examples/activex_cpp/pdf_to_text/pdf_to_text.cpp
98 lines
// ============================================================================
// pdf_to_text -- C++ ActiveX (COM) port, GENERATED by
// tools/gen_activex_cpp_examples.py from examples/cpp/pdf_to_text/pdf_to_text.cpp
//
// DO NOT EDIT BY HAND unless you also fix the generator: the next run
// overwrites this file. If a case cannot be expressed mechanically, teach the
// generator the rule -- that is what keeps the other 87 honest.
//
// This drives the SAME engine as examples/cpp/pdf_to_text/pdf_to_text.cpp, but through the COM
// object wrappers/activex exposes rather than the flat C API, so it exercises
// the marshalling layer no compiled language exercised before.
// ============================================================================
#import "..\\..\\..\\wrappers\\activex\\LumasPdfAX.tlb" no_namespace named_guids
#include <windows.h>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
// Output goes beside the EXECUTABLE, at the same relative path delphi's lands
// at, because tools/compare_lang_outputs.py keys on exactly that.
static std::string exeDir() {
char buf[MAX_PATH];
GetModuleFileNameA(nullptr, buf, MAX_PATH);
std::string s(buf);
size_t p = s.find_last_of("\\/");
return p == std::string::npos ? std::string(".") : s.substr(0, p);
}
// pdf_to_text -- C++ port of examples\Vb6\pdf_to_text\pdf_to_text.bas
// Imports a PDF and extracts each page's text (pdfSplitPageTextA) to out.txt.
#include "repo_root.h"
#include <cstdio>
#include <string>
static const unsigned long emNoFuncNames = 0x10000000; // not in the wrapper enum; from LumasPdf.pas
int main(int argc, char** argv) {
(void)argc; (void)argv;
if (FAILED(CoInitialize(nullptr))) return 1;
int _rc = 0;
try {
ILumasPDFPtr pdf;
if (FAILED(pdf.CreateInstance(L"LumasPdf.PDF")))
_com_issue_error(E_FAIL);
pdf->RaiseExceptions = VARIANT_TRUE;
pdf->SetErrorMode(emNoFuncNames);
std::string cmapDir = exeDir() + "/CMap";
pdf->SetCMapDirA(cmapDir.c_str(), lcmRecursive | lcmDelayed);
if(pdf->CreateNewPDFA("") == 0){ pdf->DeletePDF(); return 1; }
pdf->SetImportFlags(ifContentOnly | ifImportAsPage);
const char* inFile = LUMAS_REPO_ROOT "/sample_multipage.pdf";
if(pdf->OpenImportFileA(inFile, ptOpen, "") < 0){ pdf->FreePDF(); pdf->DeletePDF(); return 1; }
if(pdf->ImportPDFFile(1, 1.0, 1.0) < 0){ pdf->FreePDF(); pdf->DeletePDF(); return 1; }
pdf->CloseImportFile();
std::string outFile = exeDir() + "/out.txt";
FILE* fp = fopen(outFile.c_str(), "w");
if(!fp){ pdf->FreePDF(); pdf->DeletePDF(); return 1; }
long count = pdf->GetPageCount();
for(long i = 1; i <= count; ++i){
fprintf(fp, "----- Page %d -----\n", i);
pdf->EditPage(i);
_bstr_t _bs_txt = pdf->SplitPageText(i);
const char* txt = (const char*)_bs_txt;
fprintf(fp, "%s\n", txt ? txt : "");
pdf->EndPage();
}
fclose(fp);
pdf->FreePDF();
printf("Text written to: %s\n", outFile.c_str());
return 0;
} catch (const _com_error& e) {
const _bstr_t d = e.Description();
if (d.length())
std::fprintf(stderr, "COM error 0x%08lx: %ws\n",
(unsigned long)e.Error(), (const wchar_t*)d);
else
std::fprintf(stderr, "COM error 0x%08lx: %s\n",
(unsigned long)e.Error(), e.ErrorMessage());
_rc = 1;
}
CoUninitialize();
return _rc;
}
This file is in the SDK at examples/activex_cpp/pdf_to_text/pdf_to_text.cpp.
The build fails if this page and that file ever differ.