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 }