public override void SetTransformation(double translateX, double translateY, double rotate, double scaleX, double scaleY)
        {
            translateX *= MmToPt;
            translateY *= MmToPt;

            _canvas.RestoreState();
            _lastStrokingColor    = 0;
            _lastNonStrokingColor = 0;
            _lastLineWidth        = 1;

            _lastFont     = null;
            _lastFontSize = 0;

            _canvas.SaveState();

            AffineTransform matrix = new AffineTransform();

            matrix.Translate(translateX, translateY);
            if (rotate != 0)
            {
                matrix.Rotate(rotate);
            }

            if (scaleX != 1 || scaleY != 1)
            {
                matrix.Scale(scaleX, scaleY);
            }

            _canvas.ConcatMatrix(matrix);
        }
Beispiel #2
0
        private AffineTransform GetGradientTransformToUserSpaceOnUse(Rectangle objectBoundingBox, bool isObjectBoundingBox
                                                                     )
        {
            AffineTransform gradientTransform = new AffineTransform();

            if (isObjectBoundingBox)
            {
                gradientTransform.Translate(objectBoundingBox.GetX(), objectBoundingBox.GetY());
                // We need to scale with dividing the lengths by 0.75 as further we should
                // concatenate gradient transformation matrix which has no absolute parsing.
                // For example, if gradientTransform is set to translate(1, 1) and gradientUnits
                // is set to "objectBoundingBox" then the gradient should be shifted horizontally
                // and vertically exactly by the size of the element bounding box. So, again,
                // as we parse translate(1, 1) to translation(0.75, 0.75) the bounding box in
                // the gradient vector space should be 0.75x0.75 in order for such translation
                // to shift by the complete size of bounding box.
                gradientTransform.Scale(objectBoundingBox.GetWidth() / 0.75, objectBoundingBox.GetHeight() / 0.75);
            }
            AffineTransform svgGradientTransformation = GetGradientTransform();

            if (svgGradientTransformation != null)
            {
                gradientTransform.Concatenate(svgGradientTransformation);
            }
            return(gradientTransform);
        }
Beispiel #3
0
        private static AffineTransform CreateGradientTransform(Rectangle2D r)
        {
            double          cx    = r.CenterX;
            double          cy    = r.CenterY;
            AffineTransform xform = AffineTransform.GetTranslateInstance(cx, cy);

            xform.Scale(r.Width / 2, r.Height / 2);
            xform.Translate(-cx, -cy);
            return(xform);
        }
Beispiel #4
0
// ---------------------------------------------------------------------------

        /**
         * Creates a PDF document.
         */
        public byte[] CreatePdf()
        {
            // step 1
            Rectangle rect = new Rectangle(-595, -842, 595, 842);

            using (MemoryStream ms = new MemoryStream()) {
                using (Document document = new Document(rect)) {
                    // step 2
                    PdfWriter writer = PdfWriter.GetInstance(document, ms);
                    // step 3
                    document.Open();
                    // step 4
                    PdfContentByte canvas = writer.DirectContent;
                    // draw coordinate system
                    canvas.MoveTo(-595, 0);
                    canvas.LineTo(595, 0);
                    canvas.MoveTo(0, -842);
                    canvas.LineTo(0, 842);
                    canvas.Stroke();
                    // read the PDF with the logo
                    PdfReader   reader   = new PdfReader(RESOURCE);
                    PdfTemplate template = writer.GetImportedPage(reader, 1);
                    // add it
                    canvas.SaveState();
                    canvas.AddTemplate(template, 0, 0);
                    AffineTransform af = new AffineTransform();
                    af.Translate(-595, 0);
                    af.Scale(0.5f, 0.5f);
                    canvas.Transform(af);
                    canvas.AddTemplate(template, 0, 0);
                    canvas.ConcatCTM(AffineTransform.GetTranslateInstance(595, 595));
                    canvas.AddTemplate(template, 0, 0);
                    canvas.RestoreState();

                    canvas.SaveState();
                    af = new AffineTransform(1f, 0f, 0.4f, 1f, -750f, -650f);
                    canvas.AddTemplate(template, af);
                    canvas.RestoreState();

                    canvas.SaveState();
                    af = new AffineTransform(0, -1, -1, 0, 650, 0);
                    canvas.AddTemplate(template, af);
                    af = new AffineTransform(0, -0.2f, -0.5f, 0, 350, 0);
                    canvas.AddTemplate(template, af);
                    canvas.RestoreState();
                }
                return(ms.ToArray());
            }
        }
Beispiel #5
0
        public virtual void BuilderWithNoneSpreadingAndCanvasTransformTest()
        {
            AbstractLinearGradientBuilder gradientBuilder = new StrategyBasedLinearGradientBuilder().SetGradientDirectionAsStrategy
                                                                (StrategyBasedLinearGradientBuilder.GradientStrategy.TO_RIGHT).SetSpreadMethod(GradientSpreadMethod.NONE
                                                                                                                                               ).AddColorStop(new GradientColorStop(ColorConstants.RED.GetColorValue(), 0d, GradientColorStop.OffsetType
                                                                                                                                                                                    .RELATIVE)).AddColorStop(new GradientColorStop(ColorConstants.GREEN.GetColorValue(), 0.5, GradientColorStop.OffsetType
                                                                                                                                                                                                                                   .RELATIVE)).AddColorStop(new GradientColorStop(ColorConstants.BLUE.GetColorValue(), 1d, GradientColorStop.OffsetType
                                                                                                                                                                                                                                                                                  .RELATIVE));
            AffineTransform canvasTransform = AffineTransform.GetTranslateInstance(50, -50);

            canvasTransform.Scale(0.8, 1.1);
            canvasTransform.Rotate(Math.PI / 3, 400f, 550f);
            GenerateAndComparePdfs("builderWithNoneSpreadingAndCanvasTransformTest.pdf", canvasTransform, gradientBuilder
                                   );
        }
        private void AddLinearGradientITextAPIApproach(PdfDocument pdfDoc)
        {
            AbstractLinearGradientBuilder gradientBuilder = new StrategyBasedLinearGradientBuilder()
                                                            .SetGradientDirectionAsStrategy(StrategyBasedLinearGradientBuilder.GradientStrategy.TO_TOP_RIGHT)
                                                            .SetSpreadMethod(GradientSpreadMethod.PAD)
                                                            .AddColorStop(new GradientColorStop(ColorConstants.CYAN.GetColorValue()))
                                                            .AddColorStop(new GradientColorStop(ColorConstants.GREEN.GetColorValue()))
                                                            .AddColorStop(new GradientColorStop(new float[] { 1f, 0f, 0f }, 0.5f, GradientColorStop.OffsetType.RELATIVE));

            AffineTransform canvasTransform = AffineTransform.GetTranslateInstance(50, -50);

            canvasTransform.Scale(0.8, 1.1);
            canvasTransform.Rotate(Math.PI / 3, 400f, 550f);

            Rectangle rectangleToDraw = new Rectangle(50f, 450f, 500f, 300f);

            GeneratePdf(pdfDoc, canvasTransform, gradientBuilder, rectangleToDraw);
        }
Beispiel #7
0
        /// <summary>Evaluates the minimal domain that covers the box with vector normals.</summary>
        /// <remarks>
        /// Evaluates the minimal domain that covers the box with vector normals.
        /// The domain corresponding to the initial vector is [0, 1].
        /// </remarks>
        /// <param name="coords">
        /// the array of exactly two elements that describe
        /// the base vector (corresponding to [0,1] domain, that need to be adjusted
        /// to cover the box
        /// </param>
        /// <param name="toCover">the box that needs to be covered</param>
        /// <returns>
        /// the array of two elements in ascending order specifying the calculated covering
        /// domain
        /// </returns>
        protected internal static double[] EvaluateCoveringDomain(Point[] coords, Rectangle toCover)
        {
            if (toCover == null)
            {
                return(new double[] { 0d, 1d });
            }
            AffineTransform transform = new AffineTransform();
            double          scale     = 1d / (coords[0].Distance(coords[1]));
            double          sin       = -(coords[1].GetY() - coords[0].GetY()) * scale;
            double          cos       = (coords[1].GetX() - coords[0].GetX()) * scale;

            if (Math.Abs(cos) < ZERO_EPSILON)
            {
                cos = 0d;
                sin = sin > 0d ? 1d : -1d;
            }
            else
            {
                if (Math.Abs(sin) < ZERO_EPSILON)
                {
                    sin = 0d;
                    cos = cos > 0d ? 1d : -1d;
                }
            }
            transform.Concatenate(new AffineTransform(cos, sin, -sin, cos, 0, 0));
            transform.Scale(scale, scale);
            transform.Translate(-coords[0].GetX(), -coords[0].GetY());
            Point[] rectanglePoints = toCover.ToPointsArray();
            double  minX            = transform.Transform(rectanglePoints[0], null).GetX();
            double  maxX            = minX;

            for (int i = 1; i < rectanglePoints.Length; ++i)
            {
                double currentX = transform.Transform(rectanglePoints[i], null).GetX();
                minX = Math.Min(minX, currentX);
                maxX = Math.Max(maxX, currentX);
            }
            return(new double[] { minX, maxX });
        }
Beispiel #8
0
        public override LayoutResult Layout(LayoutContext layoutContext)
        {
            LayoutArea area      = layoutContext.GetArea().Clone();
            Rectangle  layoutBox = area.GetBBox();

            ApplyMargins(layoutBox, false);
            occupiedArea = new LayoutArea(area.GetPageNumber(), new Rectangle(layoutBox.GetX(), layoutBox.GetY() + layoutBox
                                                                              .GetHeight(), 0, 0));
            width = RetrieveWidth(layoutBox.GetWidth());
            float?     angle   = this.GetPropertyAsFloat(Property.ROTATION_ANGLE);
            PdfXObject xObject = ((Image)(GetModelElement())).GetXObject();

            imageWidth     = xObject.GetWidth();
            imageHeight    = xObject.GetHeight();
            width          = width == null ? imageWidth : width;
            height         = (float)width / imageWidth * imageHeight;
            fixedXPosition = this.GetPropertyAsFloat(Property.X);
            fixedYPosition = this.GetPropertyAsFloat(Property.Y);
            float?          horizontalScaling = this.GetPropertyAsFloat(Property.HORIZONTAL_SCALING, 1f);
            float?          verticalScaling   = this.GetPropertyAsFloat(Property.VERTICAL_SCALING, 1f);
            AffineTransform t = new AffineTransform();

            if (xObject is PdfFormXObject && width != imageWidth)
            {
                horizontalScaling *= width / imageWidth;
                verticalScaling   *= height / imageHeight;
            }
            if (horizontalScaling != 1)
            {
                if (xObject is PdfFormXObject)
                {
                    t.Scale((float)horizontalScaling, 1);
                }
                width *= (float)horizontalScaling;
            }
            if (verticalScaling != 1)
            {
                if (xObject is PdfFormXObject)
                {
                    t.Scale(1, (float)verticalScaling);
                }
                height *= (float)verticalScaling;
            }
            float imageItselfScaledWidth  = (float)width;
            float imageItselfScaledHeight = (float)height;

            // See in adjustPositionAfterRotation why angle = 0 is necessary
            if (null == angle)
            {
                angle = 0f;
            }
            t.Rotate((float)angle);
            float scaleCoef = AdjustPositionAfterRotation((float)angle, layoutBox.GetWidth(), layoutBox.GetHeight());

            imageItselfScaledHeight *= scaleCoef;
            imageItselfScaledWidth  *= scaleCoef;
            if (xObject is PdfFormXObject)
            {
                t.Scale(scaleCoef, scaleCoef);
            }
            GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight);
            // indicates whether the placement is forced
            bool isPlacingForced = false;

            if (width > layoutBox.GetWidth() || height > layoutBox.GetHeight())
            {
                if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)))
                {
                    isPlacingForced = true;
                }
                else
                {
                    return(new LayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, this));
                }
            }
            occupiedArea.GetBBox().MoveDown(height);
            occupiedArea.GetBBox().SetHeight(height);
            occupiedArea.GetBBox().SetWidth((float)width);
            float leftMargin = (float)this.GetPropertyAsFloat(Property.MARGIN_LEFT);
            float topMargin  = (float)this.GetPropertyAsFloat(Property.MARGIN_TOP);

            if (leftMargin != 0 || topMargin != 0)
            {
                TranslateImage(leftMargin, topMargin, t);
                GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight);
            }
            ApplyMargins(occupiedArea.GetBBox(), true);
            return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null, isPlacingForced ? this : null));
        }
        public override LayoutResult Layout(LayoutContext layoutContext)
        {
            LayoutArea      area         = layoutContext.GetArea().Clone();
            Rectangle       layoutBox    = area.GetBBox().Clone();
            AffineTransform t            = new AffineTransform();
            Image           modelElement = (Image)(GetModelElement());
            PdfXObject      xObject      = modelElement.GetXObject();

            imageWidth  = modelElement.GetImageWidth();
            imageHeight = modelElement.GetImageHeight();
            CalculateImageDimensions(layoutBox, t, xObject);
            OverflowPropertyValue?overflowX = null != parent?parent.GetProperty <OverflowPropertyValue?>(Property.OVERFLOW_X
                                                                                                         ) : OverflowPropertyValue.FIT;

            bool nowrap = false;

            if (parent is LineRenderer)
            {
                nowrap = true.Equals(this.parent.GetOwnProperty <bool?>(Property.NO_SOFT_WRAP_INLINE));
            }
            IList <Rectangle> floatRendererAreas    = layoutContext.GetFloatRendererAreas();
            float             clearHeightCorrection = FloatingHelper.CalculateClearHeightCorrection(this, floatRendererAreas, layoutBox
                                                                                                    );
            FloatPropertyValue?floatPropertyValue = this.GetProperty <FloatPropertyValue?>(Property.FLOAT);

            if (FloatingHelper.IsRendererFloating(this, floatPropertyValue))
            {
                layoutBox.DecreaseHeight(clearHeightCorrection);
                FloatingHelper.AdjustFloatedBlockLayoutBox(this, layoutBox, width, floatRendererAreas, floatPropertyValue,
                                                           overflowX);
            }
            else
            {
                clearHeightCorrection = FloatingHelper.AdjustLayoutBoxAccordingToFloats(floatRendererAreas, layoutBox, width
                                                                                        , clearHeightCorrection, null);
            }
            ApplyMargins(layoutBox, false);
            Border[] borders = GetBorders();
            ApplyBorderBox(layoutBox, borders, false);
            float?declaredMaxHeight         = RetrieveMaxHeight();
            OverflowPropertyValue?overflowY = null == parent || ((null == declaredMaxHeight || declaredMaxHeight > layoutBox
                                                                  .GetHeight()) && !layoutContext.IsClippedHeight()) ? OverflowPropertyValue.FIT : parent.GetProperty <OverflowPropertyValue?
                                                                                                                                                                       >(Property.OVERFLOW_Y);
            bool processOverflowX = !IsOverflowFit(overflowX) || nowrap;
            bool processOverflowY = !IsOverflowFit(overflowY);

            if (IsAbsolutePosition())
            {
                ApplyAbsolutePosition(layoutBox);
            }
            occupiedArea = new LayoutArea(area.GetPageNumber(), new Rectangle(layoutBox.GetX(), layoutBox.GetY() + layoutBox
                                                                              .GetHeight(), 0, 0));
            float imageItselfScaledWidth  = (float)width;
            float imageItselfScaledHeight = (float)height;

            if (IsFixedLayout())
            {
                fixedXPosition = this.GetPropertyAsFloat(Property.LEFT);
                fixedYPosition = this.GetPropertyAsFloat(Property.BOTTOM);
            }
            float?angle = this.GetPropertyAsFloat(Property.ROTATION_ANGLE);

            // See in adjustPositionAfterRotation why angle = 0 is necessary
            if (null == angle)
            {
                angle = 0f;
            }
            t.Rotate((float)angle);
            initialOccupiedAreaBBox = GetOccupiedAreaBBox().Clone();
            float scaleCoef = AdjustPositionAfterRotation((float)angle, layoutBox.GetWidth(), layoutBox.GetHeight());

            imageItselfScaledHeight *= scaleCoef;
            imageItselfScaledWidth  *= scaleCoef;
            initialOccupiedAreaBBox.MoveDown(imageItselfScaledHeight);
            initialOccupiedAreaBBox.SetHeight(imageItselfScaledHeight);
            initialOccupiedAreaBBox.SetWidth(imageItselfScaledWidth);
            if (xObject is PdfFormXObject)
            {
                t.Scale(scaleCoef, scaleCoef);
            }
            GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight);
            // indicates whether the placement is forced
            bool isPlacingForced = false;

            if (width > layoutBox.GetWidth() || height > layoutBox.GetHeight())
            {
                if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)) || (width > layoutBox.GetWidth() && processOverflowX
                                                                                     ) || (height > layoutBox.GetHeight() && processOverflowY))
                {
                    isPlacingForced = true;
                }
                else
                {
                    ApplyMargins(initialOccupiedAreaBBox, true);
                    ApplyBorderBox(initialOccupiedAreaBBox, true);
                    occupiedArea.GetBBox().SetHeight(initialOccupiedAreaBBox.GetHeight());
                    return(new MinMaxWidthLayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, this));
                }
            }
            occupiedArea.GetBBox().MoveDown((float)height);
            if (borders[3] != null)
            {
                height += (float)Math.Sin((float)angle) * borders[3].GetWidth();
            }
            occupiedArea.GetBBox().SetHeight((float)height);
            occupiedArea.GetBBox().SetWidth((float)width);
            UnitValue leftMargin = this.GetPropertyAsUnitValue(Property.MARGIN_LEFT);

            if (!leftMargin.IsPointValue())
            {
                ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ImageRenderer));
                logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property
                                                      .MARGIN_LEFT));
            }
            UnitValue topMargin = this.GetPropertyAsUnitValue(Property.MARGIN_TOP);

            if (!topMargin.IsPointValue())
            {
                ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ImageRenderer));
                logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property
                                                      .MARGIN_TOP));
            }
            if (0 != leftMargin.GetValue() || 0 != topMargin.GetValue())
            {
                TranslateImage(leftMargin.GetValue(), topMargin.GetValue(), t);
                GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight);
            }
            ApplyBorderBox(occupiedArea.GetBBox(), borders, true);
            ApplyMargins(occupiedArea.GetBBox(), true);
            if (angle != 0)
            {
                ApplyRotationLayout((float)angle);
            }
            float       unscaledWidth = occupiedArea.GetBBox().GetWidth() / scaleCoef;
            MinMaxWidth minMaxWidth   = new MinMaxWidth(unscaledWidth, unscaledWidth, 0);
            UnitValue   rendererWidth = this.GetProperty <UnitValue>(Property.WIDTH);

            if (rendererWidth != null && rendererWidth.IsPercentValue())
            {
                minMaxWidth.SetChildrenMinWidth(0);
                float coeff = imageWidth / (float)RetrieveWidth(area.GetBBox().GetWidth());
                minMaxWidth.SetChildrenMaxWidth(unscaledWidth * coeff);
            }
            else
            {
                bool autoScale      = HasProperty(Property.AUTO_SCALE) && (bool)this.GetProperty <bool?>(Property.AUTO_SCALE);
                bool autoScaleWidth = HasProperty(Property.AUTO_SCALE_WIDTH) && (bool)this.GetProperty <bool?>(Property.AUTO_SCALE_WIDTH
                                                                                                               );
                if (autoScale || autoScaleWidth)
                {
                    minMaxWidth.SetChildrenMinWidth(0);
                }
            }
            FloatingHelper.RemoveFloatsAboveRendererBottom(floatRendererAreas, this);
            LayoutArea editedArea = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, floatRendererAreas,
                                                                                            layoutContext.GetArea().GetBBox(), clearHeightCorrection, false);

            ApplyAbsolutePositionIfNeeded(layoutContext);
            return(new MinMaxWidthLayoutResult(LayoutResult.FULL, editedArea, null, null, isPlacingForced ? this : null
                                               ).SetMinMaxWidth(minMaxWidth));
        }
        private void CalculateImageDimensions(Rectangle layoutBox, AffineTransform t, PdfXObject xObject)
        {
            width = this.GetProperty <UnitValue>(Property.WIDTH) != null?RetrieveWidth(layoutBox.GetWidth()) : null;

            float?declaredHeight = RetrieveHeight();

            height = declaredHeight;
            if (width == null && height == null)
            {
                width  = imageWidth;
                height = (float)width / imageWidth * imageHeight;
            }
            else
            {
                if (width == null)
                {
                    width = (float)height / imageHeight * imageWidth;
                }
                else
                {
                    if (height == null)
                    {
                        height = (float)width / imageWidth * imageHeight;
                    }
                }
            }
            float?horizontalScaling = this.GetPropertyAsFloat(Property.HORIZONTAL_SCALING, 1f);
            float?verticalScaling   = this.GetPropertyAsFloat(Property.VERTICAL_SCALING, 1f);

            if (xObject is PdfFormXObject && width != imageWidth)
            {
                horizontalScaling *= width / imageWidth;
                verticalScaling   *= height / imageHeight;
            }
            if (horizontalScaling != 1)
            {
                if (xObject is PdfFormXObject)
                {
                    t.Scale((float)horizontalScaling, 1);
                    width = imageWidth * (float)horizontalScaling;
                }
                else
                {
                    width *= (float)horizontalScaling;
                }
            }
            if (verticalScaling != 1)
            {
                if (xObject is PdfFormXObject)
                {
                    t.Scale(1, (float)verticalScaling);
                    height = imageHeight * (float)verticalScaling;
                }
                else
                {
                    height *= (float)verticalScaling;
                }
            }
            // Constrain width and height according to min/max width
            float?minWidth = RetrieveMinWidth(layoutBox.GetWidth());
            float?maxWidth = RetrieveMaxWidth(layoutBox.GetWidth());

            if (null != minWidth && width < minWidth)
            {
                height *= minWidth / width;
                width   = minWidth;
            }
            else
            {
                if (null != maxWidth && width > maxWidth)
                {
                    height *= maxWidth / width;
                    width   = maxWidth;
                }
            }
            // Constrain width and height according to min/max height, which has precedence over width settings
            float?minHeight = RetrieveMinHeight();
            float?maxHeight = RetrieveMaxHeight();

            if (null != minHeight && height < minHeight)
            {
                width *= minHeight / height;
                height = minHeight;
            }
            else
            {
                if (null != maxHeight && height > maxHeight)
                {
                    width      *= maxHeight / height;
                    this.height = maxHeight;
                }
                else
                {
                    if (null != declaredHeight && !height.Equals(declaredHeight))
                    {
                        width *= declaredHeight / height;
                        height = declaredHeight;
                    }
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// 每页两张发票
        /// </summary>
        /// <param name="files"></param>
        /// <param name="outputFile"></param>
        public static void Merge4(IEnumerable <string> files, string outputFile)
        {
            var queue    = new ConcurrentQueue <string>(files);
            var document = new Document();
            var margin   = 20;

            try
            {
                var writer = PdfWriter.GetInstance(document, new FileStream(outputFile, FileMode.Create));
                var size   = PageSize.A4.Rotate();
                document.Open();
                document.SetPageSize(size);
                PdfContentByte cb = writer.DirectContent;

                do
                {
                    document.NewPage();
                    for (int i = 0; i < 4; i++)
                    {
                        if (TryAppendPage(i) == false)
                        {
                            break;
                        }
                    }
                } while (queue.Count > 0);

                bool TryAppendPage(int type)
                {
                    if (queue.TryDequeue(out var p) == false)
                    {
                        return(false);
                    }

                    var reader = new PdfReader(p);
                    var page   = writer.GetImportedPage(reader, 1);

                    AffineTransform af = new AffineTransform();

                    var scaleHeight = (size.Height - margin * 4) / 2 / page.Height;
                    var scaleWidth  = (size.Width - margin * 4) / 2 / page.Width;
                    var scale       = Math.Min(scaleHeight, scaleWidth);

                    var height = ((size.Height - margin * 4) / 2 - scale * page.Height) / 2;
                    var width  = ((size.Width - margin * 4) / 2 - scale * page.Width) / 2;

                    switch (type)
                    {
                    case 2:
                    default:
                        af.Translate(margin + width, margin + height);
                        break;

                    case 3:
                        af.Translate(margin + width + size.Width / 2, margin + height);
                        break;

                    case 0:
                        af.Translate(margin + width, margin + height + size.Height / 2);
                        break;

                    case 1:
                        af.Translate(margin + width + size.Width / 2, margin + height + size.Height / 2);
                        break;
                    }
                    af.Scale(scale, scale);

                    cb.AddTemplate(page, af);
                    return(true);
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                document.Close();
            }
        }