pagesperpage (pagesperpage.cpp) – this example is similar as the fromdoc example, it only demonstrates other method of copying document content. It consist of two sections, the first creates a document with multiple pages. The second section opens the save document, checks the pages are the same size as they were written, then converts each page into a resource. The pages are deleted afterwards and the resources are drawn in a way of two-pages-per-page into the new document.

    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 void addPage(litePDF::TLitePDF &litePDF,
   30                     unsigned int pageWidth,
   31                     unsigned int pageHeight,
   32                     const char *msg,
   33                     bool center,
   34                     int insertPos = -1)
   35 {
   36    // add a new page to it, with large-enough pixel scale
   37    HDC hDC;
   38    
   39    if (insertPos == -1) {
   40       hDC = litePDF.AddPage(litePDF.MMToUnit(pageWidth), litePDF.MMToUnit(pageHeight),
   41                             pageWidth * 10, pageHeight * 10,
   42                             LitePDFDrawFlag_SubstituteFonts);
   43    } else {
   44       hDC = litePDF.InsertPage(insertPos,
   45                                litePDF.MMToUnit(pageWidth), litePDF.MMToUnit(pageHeight),
   46                                pageWidth * 10, pageHeight * 10,
   47                                LitePDFDrawFlag_SubstituteFonts);
   48    }
   49 
   50    // draw the text
   51    LOGFONTA lf = {0, };
   52    lf.lfHeight = -50 * (center ? 3 : 1); // ~5mm or ~15mm
   53    strcpy(lf.lfFaceName, "Helvetica");
   54 
   55    HFONT fnt;
   56    HGDIOBJ oldFnt;
   57 
   58    fnt = CreateFontIndirect(&lf);
   59    oldFnt = SelectObject(hDC, fnt);
   60 
   61    SetTextColor(hDC, RGB(0, 0, 0));
   62    if (center) {
   63       int len = strlen(msg);
   64       TextOut(hDC, (pageWidth - 5 * len) * 10 / 2, (pageHeight - 15) * 10 / 2, msg, len);
   65    } else {
   66       TextOut(hDC, 100, 100, msg, strlen(msg));
   67    }
   68 
   69    SelectObject(hDC, oldFnt);
   70    DeleteObject(fnt);
   71 
   72    // finish drawing
   73    litePDF.FinishPage(hDC);
   74 }
   75 
   76 static void drawPageRect(litePDF::TLitePDF &litePDF,
   77                          unsigned int pageIndex)
   78 {
   79    unsigned int width_mm, height_mm;
   80 
   81    litePDF.GetPageSize(pageIndex, &width_mm, &height_mm);
   82 
   83    // the conversion is not needed here, because the current
   84    // unit set on the litePDF is in millimeters, but done anyway,
   85    // to show the usage of the conversion routine
   86    width_mm = litePDF.UnitToMM(width_mm);
   87    height_mm = litePDF.UnitToMM(height_mm);
   88 
   89    // use the same scale as the addPage() function
   90    HDC hDC = litePDF.UpdatePage(pageIndex,
   91                                 width_mm * 10, height_mm * 10,
   92                                 LitePDFDrawFlag_None);
   93    HGDIOBJ oldPen;
   94 
   95    oldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
   96 
   97    MoveToEx(hDC, 10, 10, NULL);
   98    LineTo(hDC, width_mm * 10 - 10, 10);
   99    LineTo(hDC, width_mm * 10 - 10, height_mm * 10 - 10);
  100    LineTo(hDC, 10, height_mm * 10 - 10);
  101    LineTo(hDC, 10, 10);
  102 
  103    SelectObject(hDC, oldPen);
  104 
  105    // finish drawing
  106    litePDF.FinishPage(hDC);
  107 }
  108 
  109 int main(void)
  110 {
  111    int res = 0;
  112    struct _size {
  113       unsigned int cx, cy;
  114    } sizes[] = {
  115       {210, 297},
  116       {210, 297},
  117       {210, 297},
  118       {297, 210},
  119       {297, 210}
  120    };
  121    unsigned int ii, pages, resources[5];
  122 
  123    using namespace litePDF;
  124 
  125    try {
  126       TLitePDF litePDF;
  127 
  128       // create a to-be-multipage document
  129       litePDF.CreateMemDocument();
  130 
  131       // add pages
  132       for (ii = 0; ii < 5; ii++) {
  133          char msg[128];
  134          sprintf(msg, "Page %d", ii + 1);
  135 
  136          addPage(litePDF, sizes[ii].cx, sizes[ii].cy, msg, true);
  137 
  138          // draw page rectangle
  139          drawPageRect(litePDF, ii - (ii > 1 ? 1 : 0));
  140 
  141          // skip the third page, it'll be inserted
  142          if (ii == 1) {
  143             ii++;
  144          }
  145       }
  146 
  147       // insert the third page
  148       addPage(litePDF, sizes[2].cx, sizes[2].cy, "Page 3 [inserted]", true, 2);
  149 
  150       // draw page rectangle
  151       drawPageRect(litePDF, 2);
  152 
  153       // test stored page sizes
  154       for (ii = 0; ii < 5; ii++) {
  155          unsigned int width_mm, height_mm;
  156 
  157          width_mm = -1;
  158          height_mm = -1;
  159 
  160          litePDF.GetPageSize(ii, &width_mm, &height_mm);
  161 
  162          // the conversion is not needed here, because the current
  163          // unit set on the litePDF is in millimeters, but done anyway,
  164          // to show the usage of the conversion routine
  165          width_mm = litePDF.UnitToMM(width_mm);
  166          height_mm = litePDF.UnitToMM(height_mm);
  167 
  168          if (width_mm != sizes[ii].cx || height_mm != sizes[ii].cy) {
  169             char msg[128];
  170 
  171             sprintf(msg,
  172                     "page[%d] size doesn't match; expected %d x %d, but got %d x %d",
  173                     ii, sizes[ii].cx, sizes[ii].cy, width_mm, height_mm);
  174             throw TLitePDFException(ERROR_CANNOT_MAKE, msg);
  175          }
  176       }
  177 
  178       // save to file
  179       litePDF.SaveToFile("pagesperpage-1.pdf");
  180 
  181       // close the document
  182       litePDF.Close();
  183 
  184       //-----------------------------------------------------------------
  185 
  186       // load from file
  187       litePDF.LoadFromFile("pagesperpage-1.pdf", NULL, true);
  188 
  189       // check the opened file has correct page count
  190       pages = litePDF.GetPageCount();
  191       if (pages != 5) {
  192          char msg[128];
  193          sprintf(msg, "The opened document doesn't have 5 pages, but %d", pages);
  194 
  195          throw TLitePDFException(ERROR_CANNOT_MAKE, msg);
  196       }
  197 
  198       // convert pages to resources
  199       for (ii = 0; ii < 5; ii++) {
  200          unsigned int width_mm, height_mm;
  201 
  202          width_mm = -1;
  203          height_mm = -1;
  204 
  205          litePDF.GetPageSize(ii, &width_mm, &height_mm);
  206 
  207          // the conversion is not needed here, because the current
  208          // unit set on the litePDF is in millimeters, but done anyway,
  209          // to show the usage of the conversion routine
  210          width_mm = litePDF.UnitToMM(width_mm);
  211          height_mm = litePDF.UnitToMM(height_mm);
  212 
  213          if (width_mm != sizes[ii].cx || height_mm != sizes[ii].cy) {
  214             char msg[128];
  215 
  216             sprintf(msg,
  217                     "page[%d] size doesn't match; expected %d x %d, but got %d x %d",
  218                     ii, sizes[ii].cx, sizes[ii].cy, width_mm, height_mm);
  219             throw TLitePDFException(ERROR_CANNOT_MAKE, msg);
  220          }
  221 
  222          resources[ii] = litePDF.PageToResource(ii);
  223 
  224          width_mm = -1;
  225          height_mm = -1;
  226          
  227          litePDF.GetResourceSize(resources[ii], &width_mm, &height_mm);
  228 
  229          // the conversion is not needed here, because the current
  230          // unit set on the litePDF is in millimeters, but done anyway,
  231          // to show the usage of the conversion routine
  232          width_mm = litePDF.UnitToMM(width_mm);
  233          height_mm = litePDF.UnitToMM(height_mm);
  234 
  235          if (width_mm != sizes[ii].cx || height_mm != sizes[ii].cy) {
  236             char msg[128];
  237 
  238             sprintf(msg,
  239                     "resource ID %d from page[%d] size doesn't match;"
  240                     " expected %d x %d, but got %d x %d",
  241                     resources[ii], ii,
  242                     sizes[ii].cx, sizes[ii].cy, width_mm, height_mm);
  243             throw TLitePDFException(ERROR_CANNOT_MAKE, msg);
  244          }
  245       }
  246 
  247       // delete pages
  248       for (ii = 0; ii < 5; ii++) {
  249          litePDF.DeletePage(0);
  250       }
  251 
  252       // there should be no pages now
  253       pages = litePDF.GetPageCount();
  254       if (pages != 0) {
  255          char msg[128];
  256          sprintf(msg, "The opened document doesn't have 0 pages, but %d", pages);
  257 
  258          throw TLitePDFException(ERROR_CANNOT_MAKE, msg);
  259       }
  260 
  261       // draw resources (former pages) into new pages
  262       for (ii = 0; ii < 5; ii += 2) {
  263          unsigned int pageSzX = sizes[ii].cy, pageSzY = sizes[ii].cx;
  264 
  265          // create a new page without drawing into it
  266          HDC hDC = litePDF.AddPage(litePDF.MMToUnit(pageSzX), litePDF.MMToUnit(pageSzY),
  267                                    pageSzX, pageSzY,
  268                                    LitePDFDrawFlag_None);
  269          litePDF.FinishPage(hDC);
  270 
  271          double scaleX, scaleY, offsetY = 0.0;
  272          unsigned int width_mm, height_mm;
  273 
  274          litePDF.GetResourceSize(resources[ii], &width_mm, &height_mm);
  275 
  276          // the conversion is not needed here, because the current
  277          // unit set on the litePDF is in millimeters, but done anyway,
  278          // to show the usage of the conversion routine
  279          width_mm = litePDF.UnitToMM(width_mm);
  280          height_mm = litePDF.UnitToMM(height_mm);
  281 
  282          scaleX = (double) pageSzX / 2.0 / (double) width_mm;
  283          scaleY = (double) pageSzY / (double) height_mm;
  284 
  285          if (width_mm > height_mm) {
  286             scaleY /= 2.0;
  287             scaleX *= 2.0;
  288             offsetY = (double) pageSzY / 2.0;
  289          }
  290 
  291          // draw the first page on the left part
  292          litePDF.DrawResourceWithMatrix(resources[ii], litePDF.GetPageCount() - 1,
  293                                         scaleX, 0.0, 0.0, scaleY, 0.0, offsetY);
  294 
  295          if (ii + 1 < 5) {
  296             litePDF.GetResourceSize(resources[ii + 1], &width_mm, &height_mm);
  297 
  298             // the conversion is not needed here, because the current
  299             // unit set on the litePDF is in millimeters, but done anyway,
  300             // to show the usage of the conversion routine
  301             width_mm = litePDF.UnitToMM(width_mm);
  302             height_mm = litePDF.UnitToMM(height_mm);
  303 
  304             scaleX = (double) pageSzX / 2.0 / (double) width_mm;
  305             scaleY = (double) pageSzY / (double) height_mm;
  306 
  307             if (width_mm > height_mm) {
  308                scaleY /= 2.0;
  309             }
  310 
  311             // draw the second page on the right part
  312             litePDF.DrawResource(resources[ii + 1], litePDF.GetPageCount() - 1,
  313                                  LitePDFUnit_1000th_mm, // for better accuracy
  314                                  litePDF.MMToUnitEx(LitePDFUnit_1000th_mm, pageSzX / 2),
  315                                  litePDF.MMToUnitEx(LitePDFUnit_1000th_mm, 0.0),
  316                                  litePDF.MMToUnitEx(LitePDFUnit_1000th_mm, scaleX),
  317                                  litePDF.MMToUnitEx(LitePDFUnit_1000th_mm, scaleY));
  318          }
  319       }
  320 
  321       // save to file
  322       litePDF.SaveToFile("pagesperpage-2.pdf");
  323 
  324       // close the document
  325       litePDF.Close();
  326    } catch (TLitePDFException &ex) {
  327       fprintf(stderr, "litePDF Exception: %x: %s\n", ex.getCode(), ex.getMessage());
  328       res = 1;
  329    }
  330 
  331    return res;
  332 }