/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// /************************************************************************/ /* This console application imports aPDF file to a DWG file */ /* to the console. */ /************************************************************************/ #include "OdaCommon.h" #define ODPDFIMPORTEX_S "OdPdfImportEx" static const char cUsage[] = { ODPDFIMPORTEX_S " sample program. Copyright (C) " TD_COPYRIGHT_START_YEAR_S TD_COPYRIGHT_END_S "\n" "Usage: " ODPDFIMPORTEX_S " PDF_filename output_DWG_filename [Embed Fonts Dir]\n" " Embed Fonts Dir - directory for saving extracted embedded fonts. If the value is not set, the embedded fonts won't be used.\n" "\nPress ENTER to continue...\n" }; #include "OdHeap.h" #include "DbDatabase.h" #include "RxDynamicModule.h" #include "ExSystemServices.h" #include "ExHostAppServices.h" #include "PdfImport.h" #include "PdfImportEx.h" #include "RxVariantValue.h" #define STL_USING_IOSTREAM #include "OdaSTL.h" #define STD(a) std:: a #ifdef OD_HAVE_CONSOLE_H_FILE #include #endif #include "diagnostics.h" /************************************************************************/ /* Define a Custom Services class. */ /* */ /* Combines the platform dependent functionality of */ /* ExSystemServices and ExHostAppServices */ /************************************************************************/ class MyServices : public ExSystemServices, public ExHostAppServices { protected: ODRX_USING_HEAP_OPERATORS(ExSystemServices); private: }; /************************************************************************/ /* Define a module map for statically linked modules: */ /************************************************************************/ #ifndef _TOOLKIT_IN_DLL_ ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(ModelerModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdRecomputeDimBlockModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(ExFieldEvaluatorModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(TD_3DSolidHistoryModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(TD_DynBlocksModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(DbCryptModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdTfModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(PdfImportModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(ExRasterModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdRasterProcessingServicesImpl); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdSpatialReferenceModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdGeoDataModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(GeolocationObjModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdDbGeoMapPEModule); ODRX_BEGIN_STATIC_MODULE_MAP() ODRX_DEFINE_STATIC_APPLICATION(OdModelerGeometryModuleName, ModelerModule) ODRX_DEFINE_STATIC_APPLICATION(OdRecomputeDimBlockModuleName, OdRecomputeDimBlockModule) ODRX_DEFINE_STATIC_APPMODULE(OdExFieldEvaluatorModuleName, ExFieldEvaluatorModule) ODRX_DEFINE_STATIC_APPMODULE(Od3DSolidHistoryTxModuleName, TD_3DSolidHistoryModule) ODRX_DEFINE_STATIC_APPMODULE(OdDynBlocksModuleName, TD_DynBlocksModule) ODRX_DEFINE_STATIC_APPMODULE(DbCryptModuleName, DbCryptModule) ODRX_DEFINE_STATIC_APPMODULE(TfModuleName, OdTfModule) ODRX_DEFINE_STATIC_APPMODULE(OdPdfImportModuleName, PdfImportModule) ODRX_DEFINE_STATIC_APPMODULE(RX_RASTER_SERVICES_APPNAME, ExRasterModule) ODRX_DEFINE_STATIC_APPMODULE(OdRasterProcessorModuleName, OdRasterProcessingServicesImpl) ODRX_DEFINE_STATIC_APPMODULE(OdSpatialReferenceModuleName, OdSpatialReferenceModule) ODRX_DEFINE_STATIC_APPMODULE(OdGeoDataModuleName, OdGeoDataModule) ODRX_DEFINE_STATIC_APPLICATION(OdGeolocationObjModuleName, GeolocationObjModule) ODRX_DEFINE_STATIC_APPLICATION(OdGeoMapPEModuleName, OdDbGeoMapPEModule) ODRX_END_STATIC_MODULE_MAP() #endif /********************************************************************************/ /* Define Assert function to not crash Debug application if assertion is fired. */ /********************************************************************************/ static void MyAssert(const char* expression, const char* fileName, int nLineNo) { OdString message; message.format(L"/!\\ Assertion failed: \"%ls\" in file: \"%ls\", line: %d\n", OdString(expression).c_str(), OdString(fileName).c_str(), nLineNo); odPrintConsoleString(message); } /********************************************************************************/ /* Define Trace function to dump trace messages in Debug configuration. */ /********************************************************************************/ void MyTraceFn(const OdChar* debugString) { odPrintConsoleString(L"Trace: %ls\n", debugString); } /************************************************************************/ /* Main */ /************************************************************************/ #if defined(OD_USE_WMAIN) int wmain(int argc, wchar_t* argv[]) #else int main(int argc, char* argv[]) #endif { #ifdef OD_HAVE_CCOMMAND_FUNC argc = ccommand(&argv); #endif /**********************************************************************/ /* Verify the argument count and display an error message as required */ /**********************************************************************/ if (argc < 3) { STD(cout) << cUsage; STD(cin).get(); return 1; } else { #ifndef _TOOLKIT_IN_DLL_ ODRX_INIT_STATIC_MODULE_MAP(); #endif /********************************************************************/ /* Create a custom Services instance. */ /********************************************************************/ OdStaticRxObject svcs; /**********************************************************************/ /* Set customized assert function */ /**********************************************************************/ odSetAssertFunc(MyAssert); /********************************************************************/ /* Initialize the Drawings SDK. */ /********************************************************************/ odInitialize(&svcs); #ifndef _MSC_VER /********************************************************************/ /* Find the data file and and initialize the character mapper */ /********************************************************************/ odPrintConsoleString(L"Initializing OdCharMapper: "); OdString iniFile = svcs.findFile(OD_T("adinit.dat")); if (!iniFile.isEmpty()) { OdCharMapper::initialize(iniFile); odPrintConsoleString(L"ok\n"); } else odPrintConsoleString(L"\"adinit.dat\" is not found. String CP conversion is not supported in this run.\n"); #endif /********************************************************************/ /* Display the Product and Version that created the executable */ /********************************************************************/ odPrintConsoleString(L"\n" ODPDFIMPORTEX_S L" developed using %ls ver %ls\n", svcs.product().c_str(), svcs.versionString().c_str()); bool bSuccess = true; try { ::odrxDynamicLinker()->loadModule(OdExFieldEvaluatorModuleName); ::odrxDynamicLinker()->loadModule(Od3DSolidHistoryTxModuleName); ::odrxDynamicLinker()->loadModule(OdDynBlocksModuleName); OdString PDF_filename(argv[1]); OdString output_DWG_filename(argv[2]); OdString ebedded_fonts_path; if (argc > 3) { ebedded_fonts_path = argv[3]; } /******************************************************************/ /* Load the PDF import module. */ /******************************************************************/ OdRxModulePtr pModule = ::odrxDynamicLinker()->loadModule(OdPdfImportModuleName, false); /*****************************************************************************************/ /* Create the PDF importer objectand check whether it was successfully created. */ /****************************************************************************************/ PdfImporterExPtr pdfImporter = ((OdPdfImportModule*)pModule.get())->create();; if (pdfImporter.isNull()) odPrintConsoleString(L"Pdf Importer object creation failed!\n"); /******************************************************************/ /* Create empty database to import the pdf file into it. */ /******************************************************************/ OdDbDatabasePtr pDb = svcs.createDatabase(); /*********************************************************************************/ /* Set import parameters using the properties() method of the importer object */ /* To see the full list of import parameters */ /* https://docs.opendesign.com/td/td_pdf_import_parameters.html */ /*********************************************************************************/ pdfImporter->properties()->putAt(OD_T("Database"), pDb); OdString path = svcs.findFile(PDF_filename); pdfImporter->properties()->putAt(OD_T("PdfPath"), OdRxVariantValue(path)); pdfImporter->properties()->putAt(L"UseClipping", OdRxVariantValue(true)); pdfImporter->properties()->putAt(L"UsePageBorderClipping", OdRxVariantValue(true)); pdfImporter->properties()->putAt(L"UseImageClipping", OdRxVariantValue(true)); pdfImporter->properties()->putAt(L"ImportShadingAsGradientHatch", OdRxVariantValue(true)); /*********************************************************************************/ /* Import embedded fonts processing */ /*********************************************************************************/ /*********************************************************************************/ /* Class for setting extracted embedded fonts for use in an application. */ /*********************************************************************************/ class EmbeddedFontHandler { public: EmbeddedFontHandler() {}; ~EmbeddedFontHandler() { #if defined(OD_WINDOWS_DESKTOP) for (auto& elem : m_FontsList) { /*************************************************************************************************************/ /* IMPORTANT!!! The font will be removed from Windows resources when the application has completed. */ /*************************************************************************************************************/ RemoveFontResourceW(elem.c_str()); } #endif } bool AddFontList(OdStringArray& font_files_name, OdDbHostAppServices* pHostApp) { bool ret = true; for (auto& file_name : font_files_name) { #if defined(OD_WINDOWS_DESKTOP) if (0 == AddFontResourceW(file_name.c_str())) ret = false; (void)pHostApp; #else OdTtfDescriptor descr; if (!pHostApp->ttfFileNameByDescriptor(descr, file_name)) ret = false; #endif m_FontsList.push_back(file_name); } return ret; } OdStringArray m_FontsList; }; EmbeddedFontHandler embedded_font_handler; if (!ebedded_fonts_path.isEmpty()) { /*********************************************************************************/ /* Sets import embedded fonts parameters */ /*********************************************************************************/ pdfImporter->properties()->putAt(OD_T("ExtractEmbeddedFonts"), OdRxVariantValue(true)); pdfImporter->properties()->putAt(OD_T("EbeddedFontsPath"), OdRxVariantValue(ebedded_fonts_path)); /*********************************************************************************/ /* Extracting embedded fonts */ /*********************************************************************************/ pdfImporter->loadDocument(); pdfImporter->loadPage(); OdStringArray font_files_name; pdfImporter->extractEmbededFonts(font_files_name); /*********************************************************************************/ /* Install extracted embedded fonts for use in the application */ /*********************************************************************************/ embedded_font_handler.AddFontList(font_files_name, pDb->appServices()); } /******************************************************************/ /* Run the PdfImport process. */ /******************************************************************/ OdPdfImport::ImportResult importResult = pdfImporter->import(); if (importResult != OdPdfImport::success) odPrintConsoleString(L"PdfImportResult = %d\n", (int)importResult); /******************************************************************/ /* Write the resulting DWG file. */ /******************************************************************/ pDb->writeFile(output_DWG_filename, OdDb::kDwg, OdDb::kDHL_CURRENT); /****************************************************************/ /* Display the File Name and Version */ /****************************************************************/ odPrintConsoleString(L"\nFile Name: \"%ls\"", pDb->getFilename().c_str()); odPrintConsoleString(L"\nFile Version: %d\n", pDb->originalFileVersion()); } /********************************************************************/ /* Display the error */ /********************************************************************/ catch (OdError& e) { odPrintConsoleString(L"\nODA Error: %ls\n", e.description().c_str()); bSuccess = false; } catch (...) { odPrintConsoleString(L"\nUnknown Error.\nPress ENTER to continue...\n"); STD(cin).get(); return 0; } /********************************************************************/ /* Uninitialize the Drawings SDK */ /********************************************************************/ try { odUninitialize(); odPrintConsoleString(L"ODA uninitialized\n"); if (bSuccess) odPrintConsoleString(ODPDFIMPORTEX_S L" Finished Successfully\n"); } catch(OdError& e) { odPrintConsoleString(L"odUninitialize() failed\n"); odPrintConsoleString(L"OdError description:\n%ls\n", e.description().c_str()); } catch(...) { odPrintConsoleString(L"odUninitialize() failed\n"); } return 0; } }