/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// #ifndef _DBPDFIMPORTOBJECTGRABBER_INCLUDED_ #define _DBPDFIMPORTOBJECTGRABBER_INCLUDED_ #include "TD_PackPush.h" #include "DbRasterImage.h" #include "DbBasePdfImportObjectGrabber.h" #include #include #include #include #include "Ge/GePoint2dArray.h" #include "Ge/GeMatrix3d.h" #include "Ge/GeClipBoundary2d.h" #include "PdfImport.h" #include "ShapeFitters.h" #include "DbCurve.h" #include "Ge/GeCurve2dPtrArray.h" #include "SharedPtr.h" #include "DbMText.h" #include "DbLinetypeTableRecord.h" #include "Ge/GeExtents2d.h" #include "Ge/GeLine2d.h" #include "PdfImportGeo.h" class OdDbDatabase; class MdFaceWrapper { public: MdFaceWrapper(); MdFaceWrapper(void* object); MdFaceWrapper(const MdFaceWrapper& other); ~MdFaceWrapper(); OdGe::PointContainment checkPointLocation(const OdGePoint3d& point, const OdGeTol& tol = OdGeContext::gTol) const; void* clone(bool iSaveIds = false) const; OdGeExtents3d getGeomExtents(const OdGeMatrix3d* coordSystem = NULL) const; void* getOdMdFaces(); bool processFaces(void* context); bool processLoops(void* context); void* get() const { return m_pMdBody; } void* detach(); operator void* () { return m_pMdBody; } operator const void* () const { return m_pMdBody; } bool isNull() const { return nullptr == m_pMdBody; } MdFaceWrapper& operator=(const MdFaceWrapper& other); private: int* m_refCount; void* m_pMdBody; void* m_pMdFaces; }; class OdDbPdfImportObjectGrabber : public OdDbBasePdfImportObjectGrabber { class BaseCurve { public: enum SegmentType { kLine, kBezier, kCircleArc, kCircle, kEllipseArc, kEllipse }; class Segment { public: Segment(const OdGePoint2dArray& points, const SegmentType type, const OdPdfImportPtType points_type) :m_PointStorage(points) ,m_SegmentType(type) ,m_PointsType(points_type) {} ~Segment(){} SegmentType getType() const { return m_SegmentType; } void setType(SegmentType type) { m_SegmentType = type; } OdPdfImportPtType getPointsType() const { return m_PointsType; } OdGeCurve3dPtr getCurve() const { return m_OptimizedCurve; } void setCurve(OdGeCurve3dPtr& curve) { m_OptimizedCurve = curve; } const OdGePoint2dArray& getPointStorage() const { return m_PointStorage; } OdGePoint2dArray& getPointStorage() { return m_PointStorage; } bool isClosed() const { return (2 < m_PointStorage.size()) && (m_PointStorage.first() == m_PointStorage.last()); } OdGeCurve3dPtrArray m_Curves; protected: OdGeCurve3dPtr m_OptimizedCurve; OdGePoint2dArray m_PointStorage; SegmentType m_SegmentType{ kLine }; OdPdfImportPtType m_PointsType; }; BaseCurve() {} ~BaseCurve() {} void addSeg(const OdGePoint2dArray& points, const OdPdfImportPtType type) { SegmentType seg_type(kLine); if (OdPdfImportPtType::OdBezierTo == type) seg_type = kBezier; m_Segments.emplace_back(Segment(points, seg_type, type)); } void setClosed(bool state) { m_isClosed = state; } bool getClosed() const { return m_isClosed; } bool isPolyline() const { for (auto& seg : m_Segments) { if (OdPdfImportPtType::OdLineTo != seg.getPointsType()) return false; } return true; } const std::vector& getSegments() const { return m_Segments; } std::vector& getSegments() { return m_Segments; } void clear() { m_Segments.clear(); m_isClosed = false; } protected: std::vector m_Segments; bool m_isClosed{ false }; }; public: OdDbPdfImportObjectGrabber(PdfImportInfoHolderPtr& info, const std::map& layers_info, const OdGePoint2dArray& clipBoundary, const bool is_clip_boundary_inverted, const OdString& images_path, PreferableFontCallback callback); virtual ~OdDbPdfImportObjectGrabber(); static OdString extractFileName(const OdString& file_path); virtual void addPath(const OdPdfImportPathData* path_data, const unsigned long path_point_count, const OdPdfImportColor* fill_color, const OdPdfImportColor* stroke_color, const float* line_width, const bool is_object_visible, const wchar_t* cur_layer_name, const bool is_clipping_required = true, const LineTypeInfo* line_type = nullptr, const char* hyperlink = nullptr, bool isTextAsGeometryMode = false); virtual void addCosmeticLine(const OdPdfImportPoint* point1, const OdPdfImportPoint* point2, const OdPdfImportColor* color, const bool is_object_visible, const wchar_t* cur_layer_name, const char* hyperlink = nullptr, const bool is_clipping_required = true); virtual void addPixel(const OdPdfImportPoint* point, const OdPdfImportColor* color, const bool is_object_visible, const wchar_t* cur_layer_name, const char* hyperlink = nullptr, const bool is_clipping_required = true); virtual bool addShadingAsHatch(const OdPdfImportRect* path_data, const ImportShadingType shading_type, const std::array& colors, const std::array& values, const double angle, const double radius, const OdPdfImportColor* background, const bool is_object_visible, const wchar_t* cur_layer_name, const int alpha, const char* hyperlink = nullptr); virtual bool isImageClippingEnabled() const; virtual bool ImportShadingAsGradientHatch() const; virtual void addImage(const BmiHeaderInfo* bmi, const unsigned char* imagedata, const OdPdfImportRect* rect, const OdPdfImportMatrix* object_matrix, const bool is_object_visible, const wchar_t* cur_layer_name, const char* hyperlink = nullptr, const ImageIndexInfo* img_idx_info = nullptr); virtual bool getClipBoundary(std::vector& path_data); virtual double dpiMultiplierForImagePattern() const; virtual bool useDownScaleForImagePattern() const; 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); virtual bool combineTextObjects() const; virtual void getSpaceFactors(double& char_space_factor, double& space_factor) const; virtual bool extractEmbeddedFonts() const; virtual void addShading(const BmiHeaderInfo* bmi, const unsigned char* imagedata, const OdPdfImportRect* rect, const OdPdfImportMatrix* object_matrix, const bool is_object_visible, const wchar_t* cur_layer_name, const char* hyperlink = nullptr); virtual void addClipPath(const OdPdfImportPathData* path_data, const unsigned long path_point_count); virtual void SaveClipState(); virtual void RestoreClipState(bool bKeepSaved); virtual bool isClippingEnabled() const; virtual ImportHyperlinkMethod getImportHyperlinkMethod(); virtual void addHyperlinkAsTransparentRegion(const OdPdfImportPathData* path_data, const unsigned long path_point_count, const char* hyperlink); 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); private: void savePath(const std::vector& paths, const ODCOLORREF cr_color, const float* line_width, const bool is_object_visible, const wchar_t* cur_layer_name, const OdUInt8 alpha, const LineTypeInfo* line_type, const char* hyperlink = nullptr, const bool clipping_is_not_required = false); void saveSolid(const std::vector& paths, const ODCOLORREF cr_color, const bool is_object_visible, const wchar_t* cur_layer_name, const OdUInt8 alpha, const char* hyperlink = nullptr, const bool clipping_is_not_required = false, bool stroke_is_not_required = false); OdDbObjectId getLayer(const OdString& name, const bool is_object_visible, const wchar_t* cur_layer_name); bool createRasterImage(const BmiHeaderInfo* bmi_info, const unsigned char* imagedata, const OdPdfImportRect* rect, const OdPdfImportMatrix* object_matrix, const char* hyperlink, const OdString& layer_name, const bool is_object_visible, const wchar_t* cur_layer_name, OdDbRasterImagePtr& pImage, const ImageIndexInfo* img_idx_info = nullptr); bool pointInPolygon(const OdGePoint2d& point); void OptimizePath(std::vector& paths); bool fitSerment(const OdGePoint2dArray& samples, const OdGeCurve2dPtr& in_curve, const double& tol, const bool is_closed, OdGeCurve3dPtr& out_curve, BaseCurve::SegmentType& seg_type); void fillPathData(const OdPdfImportPathData* path_data, const unsigned long path_point_count, std::vector& paths, const bool always_close = false); void fillLoops(const std::vector& paths, OdArray< OdArray >& loops, bool fill_solid = false); void cutPath(std::vector& clipped_paths, const std::function& check_point_func); void addHyperlink(OdDbEntityPtr ent, OdString hyperlink); OdCmColor toCmColor(const ODCOLORREF color); void closeSegAddData(const OdPdfImportPathData* path_data, std::vector& paths, OdGePoint2dArray& pt_cache, const size_t counter, const bool always = false); void processPathData(std::vector& paths, const OdPdfImportColor* fill_color, const OdPdfImportColor* stroke_color, const float* line_width, const bool is_object_visible, const wchar_t* cur_layer_name, const bool is_clipping_required, const LineTypeInfo* line_type, const char* hyperlink, bool isTextAsGeometryMode, bool fill, bool stroke); void flushLinePathContext(); OdDbBlockTableRecordPtr m_pBTR; OdString m_PdfFileName; OdGeMatrix3d m_TransforMatrix; const std::map& m_LayersInfo; OdGePoint2dArray m_ClipBoundary; bool m_isClipBoundaryInverted; OdGeExtents2d m_ClipBoundaryExtents; OdString m_ImagesPath; CircleFitter m_CircleFitter; EllipseFitter m_EllipseFitter; std::map>> m_LayerItems; MdFaceWrapper m_ClipPath; std::vector m_ClipStack; MdFaceWrapper m_ClipBoundaryBody; OdGePoint2dArray m_PageBorder; OdString m_FormatString; OdString m_ItalicFormatString; OdString m_ContentStr; OdDbMTextPtr m_pLastMText; std::vector m_LineStyles; PreferableFontCallback m_PreferableFontCallback; OdString m_GeometryLayerName; OdString m_SolidFillsLayerName; OdString m_TextLayerName; OdString m_ImagesLayerName; OdString m_GradientLayerName; std::map> m_ImageObjMap; struct LinePathContext { OdPdfImportColor fill_color; OdPdfImportColor stroke_color; float line_width{ -1.f }; bool is_object_visible{false}; OdString cur_layer_name; std::vector hyperlinks; std::vector> paths; std::vector line_types; }; LinePathContext m_LinePathContext; struct LineTypeInfoBuf { LineTypeInfoBuf() { line_type.dash_array = dash_array.data(); } OdGeLine2d line; double start_param{ 0. }; double end_param{ 0. }; std::vector dash_array; LineTypeInfo line_type; }; std::vector m_LineTypeInfoBuf; std::unique_ptr m_GeoTransformer; }; #include "TD_PackPop.h" #endif // _DBPDFIMPORTOBJECTGRABBER_INCLUDED_