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