/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// #include "OdaCommon.h" #include "RxDispatchImpl.h" #include "RxVariantValue.h" #include "DbDictionary.h" #include "RxDynamicModule.h" #include "Ed/EdCommandStack.h" #include "Ed/EdCommandContext.h" #include "Ed/EdUserIO.h" #include "DbCommandContext.h" #include "StaticRxObject.h" #include "PdfProperties.h" #include "PdfImportImpl.h" #include "DbDatabase.h" #include "DbHostAppServices.h" #include "DbBlockTableRecord.h" #include "DbUnderlayReference.h" #include "DbUnderlayDefinition.h" #include "Ge/GeScale3d.h" #include "OdPath.h" #include "PdfImportCmd.h" #include "OdUtilAds.h" #include "DbViewportTable.h" #include "DbDictionaryVar.h" #include "DbGeoData.h" #include "DbGeoMap.h" #include "DbPdfImportObjectGrabber.h" #include "DbProgressMeterGrabber.h" #include #include #include "OdPlatform.h" #include OdRxDictionaryPtr PdfProperties::createObject() { return OdRxObjectImpl::createObject(); } ODRX_DECLARE_PROPERTY2(PdfPath, PdfImportProperties) ODRX_DECLARE_PROPERTY2(Password, PdfImportProperties) ODRX_DECLARE_PROPERTY2(Database, PdfImportProperties) ODRX_DECLARE_PROPERTY2(PageNumber, PdfImportProperties) ODRX_DECLARE_PROPERTY2(LayersUseType, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportVectorGeometry, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportSolidFills, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportTrueTypeText, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportRasterImages, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportAsBlock, PdfImportProperties) ODRX_DECLARE_PROPERTY2(JoinLineAndArcSegments, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ConvertSolidsToHatches, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ApplyLineweight, PdfImportProperties) ODRX_DECLARE_PROPERTY2(InsertionPointX, PdfImportProperties) ODRX_DECLARE_PROPERTY2(InsertionPointY, PdfImportProperties) ODRX_DECLARE_PROPERTY2(Scaling, PdfImportProperties) ODRX_DECLARE_PROPERTY2(Rotation, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportTrueTypeTextAsGeometry, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportGradientFills, PdfImportProperties) ODRX_DECLARE_PROPERTY2(UseProgressMeter, PdfImportProperties) ODRX_DECLARE_PROPERTY2(UseGeometryOptimization, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImagePath, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportType3AsTrueTypeText, PdfImportProperties) ODRX_DECLARE_PROPERTY2(UseRgbColor, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportInvalidTTTextAsGeometry, PdfImportProperties) ODRX_DECLARE_PROPERTY2(UseClipping, PdfImportProperties) ODRX_DECLARE_PROPERTY2(UsePageBorderClipping, PdfImportProperties) ODRX_DECLARE_PROPERTY2(TakeAddMeasurementFactors, PdfImportProperties) ODRX_DECLARE_PROPERTY2(CombineTextObjects, PdfImportProperties) ODRX_DECLARE_PROPERTY2(CharSpaceFactor, PdfImportProperties) ODRX_DECLARE_PROPERTY2(SpaceFactor, PdfImportProperties) ODRX_DECLARE_PROPERTY2(UsePdfTransparency, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportHyperlinkMethod, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportWidgets, PdfImportProperties) ODRX_DECLARE_PROPERTY2(UseImageClipping, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ConsiderINSUNITS, PdfImportProperties) ODRX_DECLARE_PROPERTY2(Type3TextDefaultFont, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ExtractEmbeddedFonts, PdfImportProperties) ODRX_DECLARE_PROPERTY2(EbeddedFontsPath, PdfImportProperties) ODRX_DECLARE_PROPERTY2(TryFixUnicodeTable, PdfImportProperties) ODRX_DECLARE_PROPERTY2(DPIForImagePattern, PdfImportProperties) ODRX_DECLARE_PROPERTY2(UseDownScaleForImagePattern, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportPatternAndClipTextAsText, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportShadingAsGradientHatch, PdfImportProperties) ODRX_DECLARE_PROPERTY2(LineTypeFromCollinearDashes, PdfImportProperties) ODRX_DECLARE_PROPERTY2(TakeAddGeoMeasurementFactors, PdfImportProperties) ODRX_DECLARE_PROPERTY2(ImportInvisibleText, PdfImportProperties) ODRX_DEFINE_PROPERTY2(PdfPath, PdfImportProperties, PdfProperties, getString) ODRX_DEFINE_PROPERTY2(Password, PdfImportProperties, PdfProperties, getString) ODRX_DEFINE_PROPERTY2(PageNumber, PdfImportProperties, PdfProperties, getInt32) ODRX_DEFINE_PROPERTY_OBJECT2(Database, PdfImportProperties, PdfProperties, get_Database, put_Database, OdDbDatabase) ODRX_DEFINE_PROPERTY2(LayersUseType, PdfImportProperties, PdfProperties, getUInt8) ODRX_DEFINE_PROPERTY2(ImportVectorGeometry, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportSolidFills, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportTrueTypeText, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportRasterImages, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportAsBlock, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(JoinLineAndArcSegments, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ConvertSolidsToHatches, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ApplyLineweight, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(InsertionPointX, PdfImportProperties, PdfProperties, getDouble) ODRX_DEFINE_PROPERTY2(InsertionPointY, PdfImportProperties, PdfProperties, getDouble) ODRX_DEFINE_PROPERTY2(Scaling, PdfImportProperties, PdfProperties, getDouble) ODRX_DEFINE_PROPERTY2(Rotation, PdfImportProperties, PdfProperties, getDouble) ODRX_DEFINE_PROPERTY2(ImportTrueTypeTextAsGeometry, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportGradientFills, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(UseProgressMeter, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(UseGeometryOptimization, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImagePath, PdfImportProperties, PdfProperties, getString) ODRX_DEFINE_PROPERTY2(ImportType3AsTrueTypeText, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(UseRgbColor, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportInvalidTTTextAsGeometry, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(UseClipping, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(UsePageBorderClipping, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(TakeAddMeasurementFactors, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(CombineTextObjects, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(CharSpaceFactor, PdfImportProperties, PdfProperties, getDouble) ODRX_DEFINE_PROPERTY2(SpaceFactor, PdfImportProperties, PdfProperties, getDouble) ODRX_DEFINE_PROPERTY2(UsePdfTransparency, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportHyperlinkMethod, PdfImportProperties, PdfProperties, getUInt8) ODRX_DEFINE_PROPERTY2(ImportWidgets, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(UseImageClipping, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ConsiderINSUNITS, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(Type3TextDefaultFont, PdfImportProperties, PdfProperties, getString) ODRX_DEFINE_PROPERTY2(ExtractEmbeddedFonts, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(EbeddedFontsPath, PdfImportProperties, PdfProperties, getString) ODRX_DEFINE_PROPERTY2(TryFixUnicodeTable, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(DPIForImagePattern, PdfImportProperties, PdfProperties, getDouble) ODRX_DEFINE_PROPERTY2(UseDownScaleForImagePattern, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportPatternAndClipTextAsText, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportShadingAsGradientHatch, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(LineTypeFromCollinearDashes, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(TakeAddGeoMeasurementFactors, PdfImportProperties, PdfProperties, getBool) ODRX_DEFINE_PROPERTY2(ImportInvisibleText, PdfImportProperties, PdfProperties, getBool) ODRX_BEGIN_DYNAMIC_PROPERTY_MAP( PdfProperties ); ODRX_GENERATE_PROPERTY2( PdfPath, PdfImportProperties) ODRX_GENERATE_PROPERTY2( Password, PdfImportProperties) ODRX_GENERATE_PROPERTY2( Database, PdfImportProperties) ODRX_GENERATE_PROPERTY2(PageNumber, PdfImportProperties) ODRX_GENERATE_PROPERTY2(LayersUseType, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportVectorGeometry, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportSolidFills, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportTrueTypeText, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportRasterImages, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportAsBlock, PdfImportProperties) ODRX_GENERATE_PROPERTY2(JoinLineAndArcSegments, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ConvertSolidsToHatches, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ApplyLineweight, PdfImportProperties) ODRX_GENERATE_PROPERTY2(InsertionPointX, PdfImportProperties) ODRX_GENERATE_PROPERTY2(InsertionPointY, PdfImportProperties) ODRX_GENERATE_PROPERTY2(Scaling, PdfImportProperties) ODRX_GENERATE_PROPERTY2(Rotation, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportTrueTypeTextAsGeometry, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportGradientFills, PdfImportProperties) ODRX_GENERATE_PROPERTY2(UseProgressMeter, PdfImportProperties) ODRX_GENERATE_PROPERTY2(UseGeometryOptimization, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImagePath, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportType3AsTrueTypeText, PdfImportProperties) ODRX_GENERATE_PROPERTY2(UseRgbColor, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportInvalidTTTextAsGeometry, PdfImportProperties) ODRX_GENERATE_PROPERTY2(UseClipping, PdfImportProperties) ODRX_GENERATE_PROPERTY2(UsePageBorderClipping, PdfImportProperties) ODRX_GENERATE_PROPERTY2(TakeAddMeasurementFactors, PdfImportProperties) ODRX_GENERATE_PROPERTY2(CombineTextObjects, PdfImportProperties) ODRX_GENERATE_PROPERTY2(CharSpaceFactor, PdfImportProperties) ODRX_GENERATE_PROPERTY2(SpaceFactor, PdfImportProperties) ODRX_GENERATE_PROPERTY2(UsePdfTransparency, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportHyperlinkMethod, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportWidgets, PdfImportProperties) ODRX_GENERATE_PROPERTY2(UseImageClipping, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ConsiderINSUNITS, PdfImportProperties) ODRX_GENERATE_PROPERTY2(Type3TextDefaultFont, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ExtractEmbeddedFonts, PdfImportProperties) ODRX_GENERATE_PROPERTY2(EbeddedFontsPath, PdfImportProperties) ODRX_GENERATE_PROPERTY2(TryFixUnicodeTable, PdfImportProperties) ODRX_GENERATE_PROPERTY2(DPIForImagePattern, PdfImportProperties) ODRX_GENERATE_PROPERTY2(UseDownScaleForImagePattern, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportPatternAndClipTextAsText, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportShadingAsGradientHatch, PdfImportProperties) ODRX_GENERATE_PROPERTY2(LineTypeFromCollinearDashes, PdfImportProperties) ODRX_GENERATE_PROPERTY2(TakeAddGeoMeasurementFactors, PdfImportProperties) ODRX_GENERATE_PROPERTY2(ImportInvisibleText, PdfImportProperties) ODRX_END_DYNAMIC_PROPERTY_MAP( PdfProperties ); PdfImporter::PdfImporter() : m_pProperties( PdfProperties::createObject() ) , m_pDocument(nullptr) , m_Page(nullptr) , m_PageNum(-1) , m_isClipBoundaryInverted(false) , m_PreferableFontCallback(nullptr) { } PdfImporter::~PdfImporter() { closeDocument(); } OdRxDictionaryPtr PdfImporter::properties() { return m_pProperties; } #define TOCHAR(a) ((char *)OdAnsiString(OdString(a)).c_str()) double PdfImporter::getPageWidth() const { return FPDF_GetPageWidth(m_Page); } void PdfImporter::setClipBoundary(const OdGePoint2dArray& clipBoundary, const bool is_clip_boundary_inverted) { m_ClipBoundary = clipBoundary; m_isClipBoundaryInverted = is_clip_boundary_inverted; } void PdfImporter::setLayersInfo(std::map& layers_info) { m_LayersInfo = layers_info; } void PdfImporter::clearUnderlayInfo() { m_ClipBoundary.clear(); m_LayersInfo.clear(); m_isClipBoundaryInverted = false; } void PdfImporter::getImportedObjectsInfo(size_t& object_count, size_t& error_count) { if (m_Import_info) { object_count = m_Import_info->m_ObjectCounter; error_count = m_Import_info->m_ErrorCounter; } else { object_count = 0; error_count = 0; } } class BaseFontEnumPdfImportObjectGrabber : public OdPdfImportBaseObjectGrabber { public: BaseFontEnumPdfImportObjectGrabber() { } bool needToAddGraphics(bool* ret) override { return false; } bool needToAddImage(bool* ret) override { return false; } bool needToAddShading(bool* ret) override { return false; } bool needToAddText(bool* ret) override { return true; } float getWidth() override { return 100; } float getHeight() override { return 100; } }; class FontEnumPdfImportObjectGrabber : public BaseFontEnumPdfImportObjectGrabber { public: explicit FontEnumPdfImportObjectGrabber(std::map& font_map) : m_FontMap(font_map) { } virtual bool getPreferableFont(const char* font_name, const char* font_family, const bool is_found, const ImportPreferableFontType font_type, char* preferable_font_name, unsigned int& font_name_size) { m_FontMap[font_name] = font_family; return false; }; std::map& m_FontMap; }; class EmbeddedFontEnumPdfImportObjectGrabber : public BaseFontEnumPdfImportObjectGrabber { public: explicit EmbeddedFontEnumPdfImportObjectGrabber(const OdString& save_path, const OdString& pdf_file_name, std::set& font_list, bool& is_ok) :m_FileSet(font_list) ,m_EbeddedFontsPath(save_path) ,m_PdfFileName(pdf_file_name) ,m_IsOk(is_ok) { m_IsOk = true; } virtual void addText(const wchar_t* text, const PdfImportFontParams* const font_params, const OdPdfImportColor* color, const OdPdfImportMatrix* object_matrix, const bool is_object_visible, const wchar_t* layer_name, const char* hyperlink = nullptr) { if (nullptr != font_params->embedded_font_data) { OdString font_file_name = m_EbeddedFontsPath + m_PdfFileName + L"_" + font_params->font_file_name + ".ttf"; if (m_FileSet.end() == m_FileSet.find(font_file_name)) { try { OdStreamBufPtr font_file = odSystemServices()->createFile( font_file_name, Oda::kFileWrite, Oda::kShareDenyNo, Oda::kCreateAlways); font_file->putBytes(font_params->embedded_font_data, font_params->embedded_font_data_size); if (font_file.isNull()) m_IsOk = false; } catch (...) { m_IsOk = false; } m_FileSet.insert(font_file_name); } } } virtual bool extractEmbeddedFonts() const { return true; } std::set& m_FileSet; OdString m_EbeddedFontsPath; OdString m_PdfFileName; bool& m_IsOk; }; OdPdfImport::ImportResult PdfImporter::fillFontsInfo(std::map& font_map) { if(!isDocumentLoaded() || !isPageLoaded()) return OdPdfImport::fail; auto pGraber = std::make_shared(font_map); long options(0); SETBIT(options, kImportTTFontAsGeometry, m_pProperties->get_ImportTrueTypeTextAsGeometry()); SETBIT(options, kImportType3FontAsTT, m_pProperties->get_ImportType3AsTrueTypeText()); SETBIT(options, kImportInvalidFontAsGeometry, m_pProperties->get_ImportInvalidTTTextAsGeometry()); SETBIT(options, kImportWidgets, m_pProperties->get_ImportWidgets()); SETBIT(options, kFixUnicodeTable, m_pProperties->get_TryFixUnicodeTable()); SETBIT(options, kImportPatternAndClipTextAsText, m_pProperties->get_ImportPatternAndClipTextAsText()); SETBIT(options, kImportInvisibleText, m_pProperties->get_ImportInvisibleText()); FPDF_ImportPage(m_Page, pGraber.get(), options); return OdPdfImport::success; } void PdfImporter::setPreferableFontCallback(PreferableFontCallback callback) { m_PreferableFontCallback = callback; } OdPdfImport::ImportResult PdfImporter::extractEmbededFonts(OdStringArray& font_list) const { if (!isDocumentLoaded() || !isPageLoaded()) return OdPdfImport::fail; setFontPath(); OdString ebedded_fonts_path = m_pProperties->get_EbeddedFontsPath(); if (ebedded_fonts_path.isEmpty()) { OdDbDatabasePtr pDb = OdDbDatabasePtr(m_pProperties->get_Database()); ebedded_fonts_path = pDb->appServices()->getTempPath(); } if (0 != ebedded_fonts_path.getLength() && ebedded_fonts_path[ebedded_fonts_path.getLength() - 1] != pathChar) ebedded_fonts_path += pathChar; std::set file_list; bool is_ok; auto pGraber = std::make_shared(ebedded_fonts_path, OdDbPdfImportObjectGrabber::extractFileName(m_pProperties->get_PdfPath()), file_list, is_ok); long options(0); SETBIT(options, kImportTTFontAsGeometry, m_pProperties->get_ImportTrueTypeTextAsGeometry()); SETBIT(options, kImportType3FontAsTT, m_pProperties->get_ImportType3AsTrueTypeText()); SETBIT(options, kImportInvalidFontAsGeometry, m_pProperties->get_ImportInvalidTTTextAsGeometry()); SETBIT(options, kImportWidgets, m_pProperties->get_ImportWidgets()); SETBIT(options, kFixUnicodeTable, m_pProperties->get_TryFixUnicodeTable()); SETBIT(options, kImportPatternAndClipTextAsText, m_pProperties->get_ImportPatternAndClipTextAsText()); SETBIT(options, kImportInvisibleText, m_pProperties->get_ImportInvisibleText()); FPDF_ImportPage(m_Page, pGraber.get(), options); std::copy(file_list.begin(), file_list.end(), std::back_inserter(font_list)); if (is_ok) return OdPdfImport::success; else return OdPdfImport::font_file_error; } void PdfImporter::setFontPath() const { OdDbDatabasePtr pDb = OdDbDatabasePtr(m_pProperties->get_Database()); auto pHostApp = pDb->appServices(); if (pHostApp) { OdStringArray font_folders; pHostApp->getSystemFontFolders(font_folders); for (auto& elem : font_folders) { FPDF_AddFontPath(elem); } OdString ebedded_fonts_path = m_pProperties->get_EbeddedFontsPath(); if (ebedded_fonts_path.isEmpty()) { OdDbDatabasePtr pDb = OdDbDatabasePtr(m_pProperties->get_Database()); ebedded_fonts_path = pDb->appServices()->getTempPath(); } if (0 != ebedded_fonts_path.getLength() && ebedded_fonts_path[ebedded_fonts_path.getLength() - 1] != pathChar) ebedded_fonts_path += pathChar; FPDF_AddFontPath(ebedded_fonts_path); } } double PdfImporter::getPageHeight() const { return FPDF_GetPageHeight(m_Page); } double PdfImporter::getMeasureDictInfo() { // CORE-16156 : Behavior is identical to A... 2021: // * If a pdf document contains one viewport, the biggest measuring coefficient from the page measuring coefficientand the measuring coefficient of the viewport is taken. // * If a pdf document contains more than one viewport, the page measuring coefficient is taken. std::vector measure_info; FPDF_GetMeasureDictInfo(m_pDocument, m_PageNum, measure_info); if (0 == measure_info.size()) return 1.; if (m_pProperties->get_TakeAddMeasurementFactors() && 2 == measure_info.size()) { return odmax(measure_info[0].measure_factor, measure_info[1].measure_factor)*72.0; } return measure_info[0].measure_factor*72.0; } OdPdfImport::ImportResult PdfImporter::fillLayersInfo(std::map& layers_info) { FPDF_ARRAY pONLayers = 0, pOFFLayers = 0, pLayers = 0; if (!FPDF_LoadLayers(m_pDocument, pLayers, pONLayers, pOFFLayers)) return OdPdfImport::fail; if (!FPDF_GetPageLayers(m_pDocument, m_Page, m_pProperties->get_PageNumber() - 1, m_PageInfo)) return OdPdfImport::fail; for (size_t i = 0; i < m_PageInfo.names.size(); ++i) { layers_info.emplace(m_PageInfo.names[i], FPDF_IsLayerEnabled(m_PageInfo.pli_numbers.size() > i ? m_PageInfo.pli_numbers[i] : -1, pOFFLayers, m_PageInfo.names[i].c_str())); } return OdPdfImport::success; } OdPdfImport::ImportResult PdfImporter::import() { OdPdfImport::ImportResult result(OdPdfImport::success); try { if (!m_DocPath.isEmpty() && 0 != m_DocPath.compare(m_pProperties->get_PdfPath())) { closeDocument(); } result = loadDocument(); if (OdPdfImport::success != result) return result; result = loadPage(); if (OdPdfImport::success != result) return result; m_Import_info = std::make_shared(result); OdRxDictionaryIteratorPtr pIt = m_pProperties->newIterator(); while (!pIt->done()) { m_Import_info->m_pProperties->putAt(pIt->getKey(), pIt->object()); pIt->next(); } OdDbDatabasePtr pDb = OdDbDatabasePtr(m_Import_info->m_pProperties->get_Database()); if (pDb.isNull()) return OdPdfImport::fail; setFontPath(); OdString image_path = m_Import_info->m_pProperties->get_ImagePath(); if (image_path.isEmpty()) image_path = pDb->appServices()->getPDFIMPORTIMAGEPATH(); if(image_path.isEmpty()) image_path = pDb->appServices()->getTempPath(); if (0 != image_path.getLength() && image_path[image_path.getLength() - 1] != pathChar) image_path += pathChar; if (m_pProperties->get_TakeAddGeoMeasurementFactors()) { odrxDynamicLinker()->loadModule(OdGeoDataModuleName, false); odrxDynamicLinker()->loadModule(OdGeoMapPEModuleName, false); FPDF_GetGeoMeasureDictInfo(m_pDocument, m_PageNum, m_Import_info->m_GeoMeasureInfo); } double insunits_scale(1.0); if (m_pProperties->get_ConsiderINSUNITS()) { OdDb::UnitsValue base_unit = pDb->getINSUNITS(); if (base_unit > OdDb::kUnitsUndefined && base_unit <= OdDb::kUnitsMax) { insunits_scale = oddbGetUnitsConversion(OdDb::kUnitsInches, base_unit); } } const double measure = getMeasureDictInfo(); m_Import_info->m_pProperties->put_Scaling(m_pProperties->get_Scaling() * measure * insunits_scale); m_Import_info->m_Width = static_cast(getPageWidth()); m_Import_info->m_Height = -static_cast(getPageHeight()); std::map layers_info(m_LayersInfo); result = fillLayersInfo(layers_info); if (OdPdfImport::success != result) return result; OdGePoint2dArray clip_boundary(m_ClipBoundary); for(auto& elem : clip_boundary) elem /= measure; long options(0); SETBIT(options, kImportTTFontAsGeometry, m_Import_info->m_pProperties->get_ImportTrueTypeTextAsGeometry()); SETBIT(options, kImportType3FontAsTT, m_Import_info->m_pProperties->get_ImportType3AsTrueTypeText()); SETBIT(options, kImportInvalidFontAsGeometry, m_Import_info->m_pProperties->get_ImportInvalidTTTextAsGeometry()); SETBIT(options, kImportWidgets, m_Import_info->m_pProperties->get_ImportWidgets()); SETBIT(options, kFixUnicodeTable, m_Import_info->m_pProperties->get_TryFixUnicodeTable()); SETBIT(options, kImportPatternAndClipTextAsText, m_Import_info->m_pProperties->get_ImportPatternAndClipTextAsText()); SETBIT(options, kImportInvisibleText, m_Import_info->m_pProperties->get_ImportInvisibleText()); if(m_Import_info->m_pProperties->get_UseProgressMeter()) { auto pGraber = std::make_shared(m_Import_info); FPDF_ImportPage(m_Page, pGraber.get(), options); if (0 == m_Import_info->m_ObjectCounter) return OdPdfImport::no_objects_imported; m_Import_info->InitProgressMeter(); m_Import_info->ProgressMeterSetLimit(); OdString cmd_line(OD_T("Importing pdf file...")); m_Import_info->StartProgressMeter(cmd_line); } auto pGraber = std::make_shared(m_Import_info, layers_info, clip_boundary, m_isClipBoundaryInverted, image_path, m_PreferableFontCallback); FPDF_ImportPage(m_Page, pGraber.get(), options); if (m_Import_info->m_pProperties->get_UseProgressMeter()) { m_Import_info->StopProgressMeter(); } result = m_Import_info->m_ImageError; if (0 == m_Import_info->m_ObjectCounter || m_Import_info->m_ObjectCounter == m_Import_info->m_ErrorCounter) result = OdPdfImport::no_objects_imported; } catch (...) { return OdPdfImport::fail; } return result; } OdPdfImport::ImportResult PdfImporter::loadDocument() { if (isDocumentLoaded()) return OdPdfImport::success; OdString path(m_pProperties->get_PdfPath()); OdString password = m_pProperties->get_Password(); OdAnsiCharArray out_file_name; OdCharMapper::unicodeToUtf8(path.c_str(), path.getLength(), out_file_name); m_pDocument = FPDF_LoadDocument(out_file_name.getPtr(), TOCHAR(password.c_str())); if (nullptr == m_pDocument) { unsigned long error = FPDF_GetLastError(); if (FPDF_ERR_PASSWORD == error) return OdPdfImport::bad_password; return OdPdfImport::fail; } m_DocPath = path; return OdPdfImport::success; } bool PdfImporter::isDocumentLoaded() const { return (nullptr != m_pDocument); } void PdfImporter::closeDocument() { if (isPageLoaded()) { FPDF_ClosePage(m_Page); m_Page = nullptr; } if (isDocumentLoaded()) { FPDF_CloseDocument(m_pDocument); m_pDocument = nullptr; } } OdPdfImport::ImportResult PdfImporter::loadPage() { if (isPageLoaded()) return OdPdfImport::success; if (!isDocumentLoaded()) return OdPdfImport::fail; m_PageNum = m_pProperties->get_PageNumber() - 1; if (m_PageNum >= getPageCount()) return OdPdfImport::invalid_page_number; m_Page = FPDF_LoadPage(m_pDocument, m_PageNum); if (nullptr == m_Page) return OdPdfImport::fail; return OdPdfImport::success; } bool PdfImporter::isPageLoaded() const { return (nullptr != m_Page); } OdUInt32 PdfImporter::getPageCount() const { if (!isDocumentLoaded()) return 0; return FPDF_GetPageCount(m_pDocument); } class PdfImportModule : public OdPdfImportModule { OdStaticRxObject m_Command; public: virtual void initApp() { FPDF_InitLibrary(); odedRegCmds()->addCommand(&m_Command); } virtual void uninitApp() { FPDF_DestroyLibrary(); odedRegCmds()->removeCmd(m_Command.groupName(), m_Command.globalName()); } virtual OdPdfImportPtr create() { return OdRxObjectImpl::createObject(); } }; ODRX_DEFINE_DYNAMIC_MODULE(PdfImportModule)