attachments (attachments.cpp) – this example shows how to attach files, or custom data, into a PDF document, and how to extract these files from the document. The example also tests whether read data are the same as those written.

    1 /*
    2  * (c) 2013-2016 http://www.litePDF.cz
    3  * (c) 2017 zyx [@:] zyx gmx [dot] us
    4  *
    5  * This software is provided 'as-is', without any express or implied
    6  * warranty.  In no event will the authors be held liable for any damages
    7  * arising from the use of this software.
    8  *
    9  * Permission is granted to anyone to use this software for any purpose,
   10  * including commercial applications, and to alter it and redistribute it
   11  * freely, subject to the following restrictions:
   12  *
   13  * 1. The origin of this software must not be misrepresented; you must not
   14  *    claim that you wrote the original software. If you use this software
   15  *    in a product, an acknowledgment in the product documentation would be
   16  *    appreciated but is not required.
   17  * 2. Altered source versions must be plainly marked as such, and must not be
   18  *    misrepresented as being the original software.
   19  * 3. This notice may not be removed or altered from any source distribution.
   20  */ 
   21 
   22 #include <windows.h>
   23 #include <stdio.h>
   24 #include <string.h>
   25 #include <string>
   26 
   27 #include "share/litePDF.h"
   28 
   29 static std::string to_string(unsigned int num)
   30 {
   31    char buff[128];
   32 
   33    sprintf(buff, "%u", num);
   34 
   35    return std::string(buff);
   36 }
   37 
   38 static void addPage(litePDF::TLitePDF &litePDF,
   39                     unsigned int pageWidth,
   40                     unsigned int pageHeight,
   41                     const char *msg)
   42 {
   43    // add a new page to it, with large-enough pixel scale
   44    HDC hDC = litePDF.AddPage(litePDF.MMToUnit(pageWidth), litePDF.MMToUnit(pageHeight),
   45                              pageWidth * 10, pageHeight * 10,
   46                              LitePDFDrawFlag_SubstituteFonts);
   47 
   48    // draw the text
   49    LOGFONTA lf = {0, };
   50    lf.lfHeight = -50; // ~5mm
   51    strcpy(lf.lfFaceName, "Helvetica");
   52 
   53    HFONT fnt;
   54    HGDIOBJ oldFnt;
   55 
   56    fnt = CreateFontIndirect(&lf);
   57    oldFnt = SelectObject(hDC, fnt);
   58 
   59    SetTextColor(hDC, RGB(0, 0, 0));
   60    TextOut(hDC, 100, 100, msg, strlen(msg));
   61 
   62    SelectObject(hDC, oldFnt);
   63    DeleteObject(fnt);
   64 
   65    // finish drawing
   66    litePDF.FinishPage(hDC);
   67 }
   68 
   69 int main(void)
   70 {
   71    int res = 0;
   72 
   73    using namespace litePDF;
   74 
   75    try {
   76       TLitePDF litePDF;
   77 
   78       // create a document
   79       litePDF.CreateMemDocument();
   80 
   81       // check expected counts
   82       if (litePDF.GetEmbeddedFileCount() != 0) {
   83          std::string msg = "Newly created document reports non-zero (" +
   84                            to_string(litePDF.GetEmbeddedFileCount()) +
   85                            ") embedded files";
   86          throw TLitePDFException(ERROR_CANNOT_MAKE, msg.c_str());
   87       }
   88 
   89       // create a page
   90       addPage(litePDF, 210, 297, "Document with two attachments");
   91 
   92       const char *customData = "This is\na multiline\ncustom data.";
   93       litePDF.EmbedData("custom data.txt",
   94                         (const BYTE *) customData, strlen(customData));
   95       litePDF.EmbedFile("..\\attachments\\attachments.cpp");
   96 
   97       // check expected counts
   98       if (litePDF.GetEmbeddedFileCount() != 2) {
   99          std::string msg = "Newly created document reports other than two (" +
  100                            to_string(litePDF.GetEmbeddedFileCount()) +
  101                            ") embedded files";
  102          throw TLitePDFException(ERROR_CANNOT_MAKE, msg.c_str());
  103       }
  104 
  105       // save to file
  106       litePDF.SaveToFile("attachments-1.pdf");
  107 
  108       // close the document
  109       litePDF.Close();
  110 
  111       //-----------------------------------------------------------------
  112 
  113       // load from file
  114       litePDF.LoadFromFile("attachments-1.pdf", NULL, true);
  115 
  116       // check expected counts
  117       if (litePDF.GetEmbeddedFileCount() != 2) {
  118          std::string msg = "Loaded document reports other than two (" +
  119                            to_string(litePDF.GetEmbeddedFileCount()) +
  120                            ") embedded files";
  121          throw TLitePDFException(ERROR_CANNOT_MAKE, msg.c_str());
  122       }
  123 
  124       unsigned int ii = 0, sz = litePDF.GetEmbeddedFileCount();
  125       for (ii = 0; ii < sz; ii++) {
  126          std::string fileName;
  127 
  128          fileName = litePDF.GetEmbeddedFileName(ii);
  129          printf("embedded file [%d]: fileName: '%s' ", ii, fileName.c_str());
  130 
  131          unsigned int dataLength = 0;
  132          if (!litePDF.GetEmbeddedFileData(ii, NULL, &dataLength)) {
  133             throw TLitePDFException(ERROR_CANNOT_MAKE,
  134                                     "Failed to get attachment data length");
  135          }
  136 
  137          BYTE *data = (BYTE *) malloc(sizeof(BYTE) * dataLength);
  138          if (!data) {
  139             std::string msg = "Failed to allocate " + to_string(dataLength) + " bytes";
  140             throw TLitePDFException(ERROR_OUTOFMEMORY, msg.c_str());
  141          }
  142 
  143          if (!litePDF.GetEmbeddedFileData(ii, data, &dataLength)) {
  144             free(data);
  145             throw TLitePDFException(ERROR_CANNOT_MAKE, "Failed to get attachment data");
  146          }
  147 
  148          printf("dataLength: %u\n", dataLength);
  149          printf("data:\n%.*s\n******************************************************\n",
  150                  dataLength, data);
  151 
  152          free(data);
  153       }
  154 
  155       // close the document
  156       litePDF.Close();
  157    } catch (TLitePDFException &ex) {
  158       fprintf(stderr, "litePDF Exception: %x: %s\n", ex.getCode(), ex.getMessage());
  159       res = 1;
  160    }
  161 
  162    return res;
  163 }