Example #1
0
        private void MultiplePages(string aSourceFile, string aDestFile, int aPages, bool aLandscape)
        {
            iTextSharp.text.Document document = null;
            try {
                if (aPages < kMultiplePagesMin || aPages > kMultiplePagesMax)
                {
                    throw new Exception("Multiple Pages only supports " + kMultiplePagesMin + " to " + kMultiplePagesMin + " pages per sheet (Invalid value: " + aPages.ToString() + ")");
                }
                iProgressChanged(0, "Generating Multiple Pages Per Sheet: Initialising Document", Progress.State.eInProgress);
                iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(aSourceFile);
                int n = reader.NumberOfPages;

                // step 1: creation of a document-object
                if (aLandscape && aPages != 2 && aPages != 8 && aPages != 32)                      // pages = 2,8,32: print landscape pages onto portrait document in landscape orientation
                {
                    document = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4.Rotate()); // landscape
                }
                else
                {
                    document = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4); // portrait
                }

                // step 2: we create a writer that listens to the document
                iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, new FileStream(aDestFile, FileMode.Create));
                writer.ViewerPreferences = iTextSharp.text.pdf.PdfWriter.PageLayoutSinglePage;

                // step 3: we open the document
                document.Open();
                iTextSharp.text.pdf.PdfContentByte  cb   = writer.DirectContent;
                iTextSharp.text.pdf.PdfImportedPage page = null;

                float[] xPoints = new float[7] {
                    -1f, -1f, -1f, -1f, -1f, -1f, -1f
                };
                float[] yPoints = new float[9] {
                    -1f, -1f, -1f, -1f, -1f, -1f, -1f, -1f, -1f
                };
                int[] xFactors = new int[37] {
                    0, 1, 1, 0, 2, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6
                };
                int[] yFactors = new int[37] {
                    0, 1, 2, 0, 2, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 6
                };

                int   xFactor       = xFactors[aPages];
                int   yFactor       = yFactors[aPages];
                float xScaler       = 1f / xFactor;
                float yScaler       = 1f / yFactor;
                float docWidth      = document.PageSize.Width;
                float docHeight     = document.PageSize.Height;
                float specialScaler = (docWidth / docHeight) / xFactor;
                int   pyBase        = yFactor;
                if (!aLandscape)
                {
                    pyBase--;
                }

                for (uint i = 0; i <= xFactor; i++)
                {
                    xPoints[i] = (docWidth / xFactor) * i;
                }
                for (uint i = 0; i <= yFactor; i++)
                {
                    yPoints[i] = (docHeight / yFactor) * i;
                }
                int px        = 0;
                int py        = pyBase;
                int pxSpecial = xFactor - 1;
                int pySpecial = yFactor;
                int j         = 0;
                int p         = 0;

                // step 4: we add content
                int finalTotal = n / aPages;
                if (n % aPages != 0)
                {
                    finalTotal++;
                }

                int  forward           = 1;
                int  backwardBase      = (finalTotal * aPages) - (aPages / 2) + 1;
                int  backward          = backwardBase;
                int  getPage           = 0;
                bool flip              = !aLandscape;
                int  forward2          = 0;
                int  backward2         = 0;
                bool booklet           = iPrintOrderBooklet.Enabled && iPrintOrderBooklet.Checked;
                bool upsideDown        = ((aPages == 4 || aPages == 16 || aPages == 36) && !aLandscape && booklet);
                bool upsideDownSpecial = ((aPages == 2 || aPages == 8 || aPages == 32) && aLandscape && booklet);
                if (upsideDownSpecial)
                {
                    upsideDown = true;
                    flip       = true;
                }

                while (j < n)
                {
                    j++;
                    iProgressChanged((((j / aPages) + 1) * 100 / finalTotal), "Generating Multiple Pages Per Sheet: Page " + ((j / aPages) + 1) + " of " + finalTotal, Progress.State.eInProgress);

                    if (booklet)
                    {
                        bool test = false;
                        if ((aPages == 2 || aPages == 8 || aPages == 32) && !aLandscape)
                        {
                            test = (pySpecial <= (yFactor / 2));
                        }
                        else
                        {
                            if (upsideDownSpecial)
                            {
                                test = (py <= (yFactor / 2));
                            }
                            else if (upsideDown)
                            {
                                test = (py < (yFactor / 2));
                            }
                            else
                            {
                                test = (px < (xFactor / 2));
                            }
                        }
                        if (test)
                        {
                            if (!flip)
                            {
                                getPage = backward++;
                                backwardBase--;
                                if (upsideDown)
                                {
                                    getPage = forward2--;
                                }
                            }
                            else
                            {
                                getPage = forward++;
                            }
                        }
                        else
                        {
                            if (!flip)
                            {
                                getPage = forward++;
                                if (upsideDown)
                                {
                                    getPage = backward2--;
                                }
                            }
                            else
                            {
                                getPage = backward++;
                                backwardBase--;
                            }
                        }
                    }
                    else
                    {
                        getPage = j;
                    }
                    if (getPage <= n)
                    {
                        page = writer.GetImportedPage(reader, getPage);
                    }
                    else
                    {
                        j--;
                    }

                    if (p == 0)
                    {
                        // draw layout lines (once per destination document page)
                        cb.SetRGBColorStroke(0xC0, 0xC0, 0xC0);
                        foreach (float xPoint in xPoints)
                        {
                            if (xPoint >= 0)
                            {
                                cb.MoveTo(xPoint, 0);
                                cb.LineTo(xPoint, docHeight);
                                if (docWidth > docHeight && booklet)
                                {
                                    if (xPoint == (docWidth / 2))
                                    {
                                        cb.SetLineDash(2f, 4f, 0);
                                    }
                                }
                                cb.Stroke();
                                cb.SetLineDash(0);
                            }
                        }
                        foreach (float yPoint in yPoints)
                        {
                            if (yPoint >= 0)
                            {
                                cb.MoveTo(0, yPoint);
                                cb.LineTo(docWidth, yPoint);
                                if (docHeight > docWidth && booklet)
                                {
                                    if (yPoint == (docHeight / 2))
                                    {
                                        cb.SetLineDash(2f, 4f, 0);
                                    }
                                }
                                cb.Stroke();
                                cb.SetLineDash(0);
                            }
                        }
                    }

                    if (getPage <= n)
                    {
                        if (aPages == 2 || aPages == 8 || aPages == 32)
                        {
                            if (aLandscape)
                            {
                                if (upsideDown && !flip)
                                {
                                    cb.AddTemplate(page, 0, specialScaler, -specialScaler, 0, xPoints[px + 1], yPoints[py - 1]);
                                }
                                else
                                {
                                    cb.AddTemplate(page, 0, -specialScaler, specialScaler, 0, xPoints[px], yPoints[py]);
                                }
                            }
                            else
                            {
                                cb.AddTemplate(page, 0, -specialScaler, specialScaler, 0, xPoints[pxSpecial], yPoints[pySpecial]);
                            }
                        }
                        else
                        {
                            if (aLandscape)
                            {
                                cb.AddTemplate(page, 0, -xScaler, yScaler, 0, xPoints[px], yPoints[py]);
                            }
                            else
                            {
                                if (upsideDown && !flip)
                                {
                                    cb.AddTemplate(page, -xScaler, 0, 0, -yScaler, xPoints[px + 1], yPoints[py + 1]);
                                }
                                else
                                {
                                    cb.AddTemplate(page, xScaler, 0, 0, yScaler, xPoints[px], yPoints[py]);
                                }
                            }
                        }
                    }

                    cb.Stroke();
                    p++;
                    if ((p % xFactor) == 0)
                    {
                        px = 0;
                        py--;
                    }
                    else
                    {
                        px++;
                    }
                    if ((p % yFactor) == 0)
                    {
                        pxSpecial--;
                        pySpecial = yFactor;
                    }
                    else
                    {
                        pySpecial--;
                    }
                    if (p == aPages)
                    {
                        p         = 0;
                        px        = 0;
                        py        = pyBase;
                        pxSpecial = xFactor - 1;
                        pySpecial = yFactor;
                        backward  = backwardBase;
                        forward2  = (forward - 1) + (aPages / 2);
                        backward2 = (backward - 1) + (aPages / 2);
                        flip      = !flip;
                        document.NewPage();
                    }
                }
                iProgressChanged(100, "Generating Multiple Pages Per Sheet: Finalising Document", Progress.State.eInProgress);
            }
            catch (Exception e) {
                throw e;
            }
            finally {
                try {
                    // step 5: we close the document
                    if (document != null)
                    {
                        document.Close();
                    }
                }
                catch (System.IO.IOException) { // document has no pages
                }
            }
        }