LCOV - code coverage report
Current view: top level - frmts/pdf - pdfcreatefromcomposition.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 3 3 100.0 %
Date: 2025-02-20 10:14:44 Functions: 2 3 66.7 %

          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             :     struct Action
      88             :     {
      89          12 :         virtual ~Action() = default;
      90             :     };
      91             : 
      92             :     struct GotoPageAction final : public Action
      93             :     {
      94             :         GDALPDFObjectNum m_nPageDestId{};
      95             :         double m_dfX1 = 0;
      96             :         double m_dfX2 = 0;
      97             :         double m_dfY1 = 0;
      98             :         double m_dfY2 = 0;
      99             :     };
     100             : 
     101             :     struct SetLayerStateAction final : public Action
     102             :     {
     103             :         std::set<GDALPDFObjectNum> m_anONLayers{};
     104             :         std::set<GDALPDFObjectNum> m_anOFFLayers{};
     105             :     };
     106             : 
     107             :     struct JavascriptAction final : public Action
     108             :     {
     109             :         CPLString m_osScript{};
     110             :     };
     111             : 
     112             :     bool ParseActions(const CPLXMLNode *psNode,
     113             :                       std::vector<std::unique_ptr<Action>> &actions);
     114             :     static GDALPDFDictionaryRW *
     115             :     SerializeActions(GDALPDFDictionaryRW *poDictForDest,
     116             :                      const std::vector<std::unique_ptr<Action>> &actions);
     117             : 
     118             :     struct OutlineItem
     119             :     {
     120             :         GDALPDFObjectNum m_nObjId{};
     121             :         CPLString m_osName{};
     122             :         bool m_bOpen = true;
     123             :         int m_nFlags = 0;
     124             :         std::vector<std::unique_ptr<Action>> m_aoActions{};
     125             :         std::vector<std::unique_ptr<OutlineItem>> m_aoKids{};
     126             :         int m_nKidsRecCount = 0;
     127             :     };
     128             : 
     129             :     GDALPDFObjectNum m_nOutlinesId{};
     130             : 
     131             :     bool CreateOutlineFirstPass(const CPLXMLNode *psNode,
     132             :                                 OutlineItem *poParentItem);
     133             :     bool SerializeOutlineKids(const OutlineItem *poParentItem);
     134             :     bool CreateOutline(const CPLXMLNode *psNode);
     135             : 
     136             :     void WritePages();
     137             : 
     138             :     static GDALPDFArrayRW *CreateOCGOrder(const TreeOfOCG *parent);
     139             :     static void CollectOffOCG(std::vector<GDALPDFObjectNum> &ar,
     140             :                               const TreeOfOCG *parent);
     141             :     bool GeneratePage(const CPLXMLNode *psPage);
     142             :     bool GenerateGeoreferencing(const CPLXMLNode *psGeoreferencing,
     143             :                                 double dfWidthInUserUnit,
     144             :                                 double dfHeightInUserUnit,
     145             :                                 GDALPDFObjectNum &nViewportId,
     146             :                                 Georeferencing &georeferencing);
     147             : 
     148             :     GDALPDFObjectNum GenerateISO32000_Georeferencing(
     149             :         OGRSpatialReferenceH hSRS, double bboxX1, double bboxY1, double bboxX2,
     150             :         double bboxY2, const std::vector<gdal::GCP> &aGCPs,
     151             :         const std::vector<xyPair> &aBoundingPolygon);
     152             : 
     153             :     bool ExploreContent(const CPLXMLNode *psNode, PageContext &oPageContext);
     154             :     bool WriteRaster(const CPLXMLNode *psNode, PageContext &oPageContext);
     155             :     bool WriteVector(const CPLXMLNode *psNode, PageContext &oPageContext);
     156             :     bool WriteVectorLabel(const CPLXMLNode *psNode, PageContext &oPageContext);
     157             :     void StartBlending(const CPLXMLNode *psNode, PageContext &oPageContext,
     158             :                        double &dfOpacity);
     159             :     static void EndBlending(const CPLXMLNode *psNode,
     160             :                             PageContext &oPageContext);
     161             : 
     162             :     static bool SetupVectorGeoreferencing(
     163             :         const char *pszGeoreferencingId, OGRLayer *poLayer,
     164             :         const PageContext &oPageContext, double &dfClippingMinX,
     165             :         double &dfClippingMinY, double &dfClippingMaxX, double &dfClippingMaxY,
     166             :         double adfMatrix[4],
     167             :         std::unique_ptr<OGRCoordinateTransformation> &poCT);
     168             : 
     169             : #ifdef HAVE_PDF_READ_SUPPORT
     170             :     bool WritePDF(const CPLXMLNode *psNode, PageContext &oPageContext);
     171             : 
     172             :     typedef std::map<std::pair<int, int>, GDALPDFObjectNum> RemapType;
     173             :     GDALPDFObjectNum EmitNewObject(GDALPDFObject *poObj,
     174             :                                    RemapType &oRemapObjectRefs);
     175             :     GDALPDFObjectNum SerializeAndRenumber(GDALPDFObject *poObj);
     176             :     bool SerializeAndRenumber(CPLString &osStr, GDALPDFObject *poObj,
     177             :                               RemapType &oRemapObjectRefs);
     178             :     bool SerializeAndRenumberIgnoreRef(CPLString &osStr, GDALPDFObject *poObj,
     179             :                                        RemapType &oRemapObjectRefs);
     180             : #endif
     181             : 
     182             :   public:
     183             :     explicit GDALPDFComposerWriter(VSILFILE *fp);
     184             :     ~GDALPDFComposerWriter();
     185             : 
     186             :     bool Generate(const CPLXMLNode *psComposition);
     187             :     void Close();
     188             : };
     189             : 
     190             : GDALDataset *GDALPDFCreateFromCompositionFile(const char *pszPDFFilename,
     191             :                                               const char *pszXMLFilename);
     192             : 
     193             : #endif  // PDFCREATEFROMCOMPOSITION_H_INCLUDED

Generated by: LCOV version 1.14