LCOV - code coverage report
Current view: top level - frmts/pdf - pdfcreatefromcomposition.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 6 6 100.0 %
Date: 2025-06-08 21:14:40 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  PDF driver
       4             :  * Purpose:  GDALDataset driver for PDF dataset.
       5             :  * Author:   Even Rouault, <even dot rouault at spatialys dot com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2019, Even Rouault <even dot rouault at spatialys dot com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #ifndef PDFCREATEFROMCOMPOSITION_H_INCLUDED
      14             : #define PDFCREATEFROMCOMPOSITION_H_INCLUDED
      15             : 
      16             : #include "gdal_pdf.h"
      17             : #include "pdfcreatecopy.h"
      18             : #include "cpl_minixml.h"
      19             : #include "ogrsf_frmts.h"
      20             : #include "ogr_geometry.h"
      21             : 
      22             : #include <map>
      23             : #include <memory>
      24             : #include <vector>
      25             : 
      26             : class GDALPDFComposerWriter final : public GDALPDFBaseWriter
      27             : {
      28             :     CPLString m_osJPEG2000Driver{};
      29             : 
      30             :     struct TreeOfOCG
      31             :     {
      32             :         GDALPDFObjectNum m_nNum{};
      33             :         bool m_bInitiallyVisible{true};
      34             :         std::vector<std::unique_ptr<TreeOfOCG>> m_children{};
      35             :     };
      36             : 
      37             :     bool m_bDisplayLayersOnlyOnVisiblePages = false;
      38             :     TreeOfOCG m_oTreeOfOGC{};
      39             :     std::map<CPLString, std::vector<GDALPDFObjectNum>>
      40             :         m_oMapExclusiveOCGIdToOCGs{};
      41             : 
      42             :     std::map<CPLString, GDALPDFObjectNum> m_oMapLayerIdToOCG{};
      43             : 
      44             :     struct xyPair
      45             :     {
      46             :         double x = 0;
      47             :         double y = 0;
      48             : 
      49          10 :         explicit xyPair(double xin = 0.0, double yin = 0.0) : x(xin), y(yin)
      50             :         {
      51          10 :         }
      52             :     };
      53             : 
      54             :     struct Georeferencing
      55             :     {
      56             :         CPLString m_osID{};
      57             :         OGRSpatialReference m_oSRS{};
      58             :         double m_bboxX1{};
      59             :         double m_bboxY1{};
      60             :         double m_bboxX2{};
      61             :         double m_bboxY2{};
      62             :         double m_adfGT[6]{0, 1, 0, 0, 0, 1};
      63             :     };
      64             : 
      65             :     std::vector<GDALPDFObjectNum> m_anParentElements{};
      66             :     std::vector<GDALPDFObjectNum> m_anFeatureLayerId{};
      67             :     std::map<CPLString, GDALPDFObjectNum> m_oMapPageIdToObjectNum{};
      68             : 
      69             :     struct PageContext
      70             :     {
      71             :         double m_dfWidthInUserUnit = 0;
      72             :         double m_dfHeightInUserUnit = 0;
      73             :         CPLString m_osDrawingStream{};
      74             :         std::vector<GDALPDFObjectNum> m_anFeatureUserProperties{};
      75             :         int m_nMCID = 0;
      76             :         PDFCompressMethod m_eStreamCompressMethod = COMPRESS_DEFLATE;
      77             :         std::map<CPLString, GDALPDFObjectNum> m_oXObjects{};
      78             :         std::map<CPLString, GDALPDFObjectNum> m_oProperties{};
      79             :         std::map<CPLString, GDALPDFObjectNum> m_oExtGState{};
      80             :         std::vector<GDALPDFObjectNum> m_anAnnotationsId{};
      81             :         std::map<CPLString, Georeferencing> m_oMapGeoreferencedId{};
      82             :     };
      83             : 
      84             :     bool CreateLayerTree(const CPLXMLNode *psNode,
      85             :                          const GDALPDFObjectNum &nParentId, TreeOfOCG *parent);
      86             : 
      87          12 :     struct Action
      88             :     {
      89             :         virtual ~Action();
      90             :     };
      91             : 
      92          14 :     struct GotoPageAction final : public Action
      93             :     {
      94             :         ~GotoPageAction() override;
      95             : 
      96             :         GDALPDFObjectNum m_nPageDestId{};
      97             :         double m_dfX1 = 0;
      98             :         double m_dfX2 = 0;
      99             :         double m_dfY1 = 0;
     100             :         double m_dfY2 = 0;
     101             :     };
     102             : 
     103           8 :     struct SetLayerStateAction final : public Action
     104             :     {
     105             :         ~SetLayerStateAction() override;
     106             : 
     107             :         std::set<GDALPDFObjectNum> m_anONLayers{};
     108             :         std::set<GDALPDFObjectNum> m_anOFFLayers{};
     109             :     };
     110             : 
     111           2 :     struct JavascriptAction final : public Action
     112             :     {
     113             :         ~JavascriptAction() override;
     114             : 
     115             :         CPLString m_osScript{};
     116             :     };
     117             : 
     118             :     bool ParseActions(const CPLXMLNode *psNode,
     119             :                       std::vector<std::unique_ptr<Action>> &actions);
     120             :     static GDALPDFDictionaryRW *
     121             :     SerializeActions(GDALPDFDictionaryRW *poDictForDest,
     122             :                      const std::vector<std::unique_ptr<Action>> &actions);
     123             : 
     124             :     struct OutlineItem
     125             :     {
     126             :         GDALPDFObjectNum m_nObjId{};
     127             :         CPLString m_osName{};
     128             :         bool m_bOpen = true;
     129             :         int m_nFlags = 0;
     130             :         std::vector<std::unique_ptr<Action>> m_aoActions{};
     131             :         std::vector<std::unique_ptr<OutlineItem>> m_aoKids{};
     132             :         int m_nKidsRecCount = 0;
     133             :     };
     134             : 
     135             :     GDALPDFObjectNum m_nOutlinesId{};
     136             : 
     137             :     bool CreateOutlineFirstPass(const CPLXMLNode *psNode,
     138             :                                 OutlineItem *poParentItem);
     139             :     bool SerializeOutlineKids(const OutlineItem *poParentItem);
     140             :     bool CreateOutline(const CPLXMLNode *psNode);
     141             : 
     142             :     void WritePages();
     143             : 
     144             :     static GDALPDFArrayRW *CreateOCGOrder(const TreeOfOCG *parent);
     145             :     static void CollectOffOCG(std::vector<GDALPDFObjectNum> &ar,
     146             :                               const TreeOfOCG *parent);
     147             :     bool GeneratePage(const CPLXMLNode *psPage);
     148             :     bool GenerateGeoreferencing(const CPLXMLNode *psGeoreferencing,
     149             :                                 double dfWidthInUserUnit,
     150             :                                 double dfHeightInUserUnit,
     151             :                                 GDALPDFObjectNum &nViewportId,
     152             :                                 Georeferencing &georeferencing);
     153             : 
     154             :     GDALPDFObjectNum GenerateISO32000_Georeferencing(
     155             :         OGRSpatialReferenceH hSRS, double bboxX1, double bboxY1, double bboxX2,
     156             :         double bboxY2, const std::vector<gdal::GCP> &aGCPs,
     157             :         const std::vector<xyPair> &aBoundingPolygon);
     158             : 
     159             :     bool ExploreContent(const CPLXMLNode *psNode, PageContext &oPageContext);
     160             :     bool WriteRaster(const CPLXMLNode *psNode, PageContext &oPageContext);
     161             :     bool WriteVector(const CPLXMLNode *psNode, PageContext &oPageContext);
     162             :     bool WriteVectorLabel(const CPLXMLNode *psNode, PageContext &oPageContext);
     163             :     void StartBlending(const CPLXMLNode *psNode, PageContext &oPageContext,
     164             :                        double &dfOpacity);
     165             :     static void EndBlending(const CPLXMLNode *psNode,
     166             :                             PageContext &oPageContext);
     167             : 
     168             :     static bool SetupVectorGeoreferencing(
     169             :         const char *pszGeoreferencingId, OGRLayer *poLayer,
     170             :         const PageContext &oPageContext, double &dfClippingMinX,
     171             :         double &dfClippingMinY, double &dfClippingMaxX, double &dfClippingMaxY,
     172             :         double adfMatrix[4],
     173             :         std::unique_ptr<OGRCoordinateTransformation> &poCT);
     174             : 
     175             : #ifdef HAVE_PDF_READ_SUPPORT
     176             :     bool WritePDF(const CPLXMLNode *psNode, PageContext &oPageContext);
     177             : 
     178             :     typedef std::map<std::pair<int, int>, GDALPDFObjectNum> RemapType;
     179             :     GDALPDFObjectNum EmitNewObject(GDALPDFObject *poObj,
     180             :                                    RemapType &oRemapObjectRefs);
     181             :     GDALPDFObjectNum SerializeAndRenumber(GDALPDFObject *poObj);
     182             :     bool SerializeAndRenumber(CPLString &osStr, GDALPDFObject *poObj,
     183             :                               RemapType &oRemapObjectRefs);
     184             :     bool SerializeAndRenumberIgnoreRef(CPLString &osStr, GDALPDFObject *poObj,
     185             :                                        RemapType &oRemapObjectRefs);
     186             : #endif
     187             : 
     188             :   public:
     189             :     explicit GDALPDFComposerWriter(VSILFILE *fp);
     190             :     ~GDALPDFComposerWriter();
     191             : 
     192             :     bool Generate(const CPLXMLNode *psComposition);
     193             :     void Close();
     194             : };
     195             : 
     196             : GDALDataset *GDALPDFCreateFromCompositionFile(const char *pszPDFFilename,
     197             :                                               const char *pszXMLFilename);
     198             : 
     199             : #endif  // PDFCREATEFROMCOMPOSITION_H_INCLUDED

Generated by: LCOV version 1.14