private void DrawText(PdfWriter writer,
                              string text,
                              int fontSize,
                              BaseColor color,
                              double x,
                              double y,
                              bool vertical)
        {
            AffineTransform textTransform = AffineTransform.GetTranslateInstance(x, y);

            if (vertical)
            {
                textTransform.Rotate(Math.PI / 2);
            }
            //writer.DirectContent.Transform(rotate90);

            PdfContentByte cb = writer.DirectContent;

            cb.BeginText();
            ////BaseFont textFont = BaseFont.CreateFont("Arial", BaseFont.CP1252, true);
            cb.SetColorStroke(color);
            cb.SetColorFill(color);
            cb.SetFontAndSize(SearchTextFont.GetCalculatedBaseFont(false), fontSize);
            cb.SetTextMatrix(textTransform); //(xPos, yPos)

            cb.ShowText(text);
            cb.EndText();
        }
        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 #3
0
        protected internal virtual void ApplyRotationLayout(Rectangle layoutBox)
        {
            float angle  = (float)this.GetPropertyAsFloat(Property.ROTATION_ANGLE);
            float x      = occupiedArea.GetBBox().GetX();
            float y      = occupiedArea.GetBBox().GetY();
            float height = occupiedArea.GetBBox().GetHeight();
            float width  = occupiedArea.GetBBox().GetWidth();

            SetProperty(Property.ROTATION_INITIAL_WIDTH, width);
            SetProperty(Property.ROTATION_INITIAL_HEIGHT, height);
            AffineTransform rotationTransform = new AffineTransform();

            // here we calculate and set the actual occupied area of the rotated content
            if (IsPositioned())
            {
                float?rotationPointX = this.GetPropertyAsFloat(Property.ROTATION_POINT_X);
                float?rotationPointY = this.GetPropertyAsFloat(Property.ROTATION_POINT_Y);
                if (rotationPointX == null || rotationPointY == null)
                {
                    // if rotation point was not specified, the most bottom-left point is used
                    rotationPointX = x;
                    rotationPointY = y;
                }
                // transforms apply from bottom to top
                rotationTransform.Translate((float)rotationPointX, (float)rotationPointY);
                // move point back at place
                rotationTransform.Rotate(angle);
                // rotate
                rotationTransform.Translate((float)-rotationPointX, (float)-rotationPointY);
                // move rotation point to origin
                IList <Point> rotatedPoints = TransformPoints(RectangleToPointsList(occupiedArea.GetBBox()), rotationTransform
                                                              );
                Rectangle newBBox = CalculateBBox(rotatedPoints);
                // make occupied area be of size and position of actual content
                occupiedArea.GetBBox().SetWidth(newBBox.GetWidth());
                occupiedArea.GetBBox().SetHeight(newBBox.GetHeight());
                float occupiedAreaShiftX = newBBox.GetX() - x;
                float occupiedAreaShiftY = newBBox.GetY() - y;
                Move(occupiedAreaShiftX, occupiedAreaShiftY);
            }
            else
            {
                rotationTransform = AffineTransform.GetRotateInstance(angle);
                IList <Point> rotatedPoints = TransformPoints(RectangleToPointsList(occupiedArea.GetBBox()), rotationTransform
                                                              );
                float[] shift = CalculateShiftToPositionBBoxOfPointsAt(x, y + height, rotatedPoints);
                foreach (Point point in rotatedPoints)
                {
                    point.SetLocation(point.GetX() + shift[0], point.GetY() + shift[1]);
                }
                Rectangle newBBox = CalculateBBox(rotatedPoints);
                occupiedArea.GetBBox().SetWidth(newBBox.GetWidth());
                occupiedArea.GetBBox().SetHeight(newBBox.GetHeight());
                float heightDiff = height - newBBox.GetHeight();
                Move(0, heightDiff);
            }
        }
        private byte[] CreatePdfWithRotatedXObject(String xobjectText)
        {
            MemoryStream baos   = new MemoryStream();
            Document     doc    = new Document();
            PdfWriter    writer = PdfWriter.GetInstance(doc, baos);

            writer.CompressionLevel = 0;
            doc.Open();

            doc.Add(new Paragraph("A"));
            doc.Add(new Paragraph("B"));

            bool rotate = true;

            PdfTemplate template = writer.DirectContent.CreateTemplate(20, 100);

            template.SetColorStroke(BaseColor.GREEN);
            template.Rectangle(0, 0, template.Width, template.Height);
            template.Stroke();
            AffineTransform tx = new AffineTransform();

            if (rotate)
            {
                tx.Translate(0, template.Height);
                tx.Rotate(-90 / 180f * Math.PI);
            }
            template.Transform(tx);
            template.BeginText();
            template.SetFontAndSize(BaseFont.CreateFont(), 12);
            if (rotate)
            {
                template.MoveText(0, template.Width - 12);
            }
            else
            {
                template.MoveText(0, template.Height - 12);
            }
            template.ShowText(xobjectText);

            template.EndText();

            Image xobjectImage = Image.GetInstance(template);

            if (rotate)
            {
                xobjectImage.RotationDegrees = 90;
            }
            doc.Add(xobjectImage);

            doc.Add(new Paragraph("C"));

            doc.Close();

            return(baos.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);
        }
        protected internal virtual float[] ApplyRotation()
        {
            float dx = 0;
            float dy = 0;

            if (!IsPositioned())
            {
                Point shift = GetLayoutShiftAndRotatedPoints(new List <Point>(), 0, 0);
                dy = (float)shift.GetY();
                dx = (float)shift.GetX();
            }
            float?          angle     = this.GetPropertyAsFloat(Property.ROTATION_ANGLE);
            AffineTransform transform = new AffineTransform();

            transform.Rotate((float)angle);
            float[] ctm = new float[6];
            transform.GetMatrix(ctm);
            ctm[4] = (float)this.GetPropertyAsFloat(Property.ROTATION_POINT_X) + dx;
            ctm[5] = (float)this.GetPropertyAsFloat(Property.ROTATION_POINT_Y) + dy;
            return(ctm);
        }
Beispiel #8
0
        /// <exception cref="System.Exception"/>
        private byte[] CreatePdfWithRotatedXObject(String xobjectText)
        {
            MemoryStream baos        = new MemoryStream();
            PdfDocument  pdfDocument = new PdfDocument(new PdfWriter(baos).SetCompressionLevel(0));
            Document     document    = new Document(pdfDocument);

            document.Add(new Paragraph("A"));
            document.Add(new Paragraph("B"));
            PdfFormXObject template = new PdfFormXObject(new Rectangle(20, 100));
            PdfCanvas      canvas   = new PdfCanvas(template, pdfDocument);

            canvas.SetStrokeColor(Color.GREEN).Rectangle(0, 0, template.GetWidth(), template.GetHeight()).Stroke();
            AffineTransform tx = new AffineTransform();

            tx.Translate(0, template.GetHeight());
            tx.Rotate((float)(-90 / 180f * Math.PI));
            canvas.ConcatMatrix(tx).BeginText().SetFontAndSize(PdfFontFactory.CreateFont(FontConstants.HELVETICA), 12)
            .MoveText(0, template.GetWidth() - 12).ShowText(xobjectText).EndText();
            document.Add(new Image(template).SetRotationAngle(Math.PI / 2)).Add(new Paragraph("C"));
            document.Close();
            return(baos.ToArray());
        }
        private Point GetLayoutShiftAndRotatedPoints(IList <Point> rotatedPoints, float shiftX, float shiftY)
        {
            float           angle           = (float)this.GetPropertyAsFloat(Property.ROTATION_ANGLE);
            float           width           = (float)this.GetPropertyAsFloat(Property.ROTATION_INITIAL_WIDTH);
            float           height          = (float)this.GetPropertyAsFloat(Property.ROTATION_INITIAL_HEIGHT);
            float           left            = occupiedArea.GetBBox().GetX() - shiftX;
            float           bottom          = occupiedArea.GetBBox().GetY() - shiftY;
            float           right           = left + width;
            float           top             = bottom + height;
            AffineTransform rotateTransform = new AffineTransform();

            rotateTransform.Rotate(angle);
            TransformBBox(left, bottom, right, top, rotateTransform, rotatedPoints);
            double minX = double.MaxValue;
            double maxY = -double.MaxValue;

            foreach (Point point in rotatedPoints)
            {
                if (point.GetX() < minX)
                {
                    minX = point.GetX();
                }
                if (point.GetY() > maxY)
                {
                    maxY = point.GetY();
                }
            }
            float dx = (float)(left - minX);
            float dy = (float)(top - maxY);

            foreach (Point point_1 in rotatedPoints)
            {
                point_1.SetLocation(point_1.GetX() + dx + shiftX, point_1.GetY() + dy + shiftY);
            }
            return(new Point(dx, dy));
        }
Beispiel #10
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 bool AddWaterMarkerToPdf(string pdfFile, string destFile, string text, string fontFamily, string fontColor, int fontSize = 50)
        {
            if (File.Exists(pdfFile))
            {
                try
                {
                    using (var pr = new PdfReader(pdfFile))
                    {
                        var rgbColor = System.Drawing.ColorTranslator.FromHtml(fontColor);


                        PdfFont font = fontFamily.Contains("STSong") ? PdfFontFactory.CreateFont(fontFamily, "UniGB-UCS2-H", true)
                            : PdfFontFactory.CreateFont(fontFamily);//PdfFontFactory.CreateFont(fontFamily, "UniGB-UCS2-H", true);
                        if (font != null)
                        {
                            var       textLength = font.GetWidth(text, fontSize);
                            var       pw         = new PdfWriter(destFile);
                            var       pdfDoc     = new PdfDocument(pr, pw);
                            Rectangle ps;
                            PdfCanvas canvas;
                            var       pageCount = pdfDoc.GetNumberOfPages();
                            for (var i = 1; i < pageCount + 1; i++)
                            {
                                var page = pdfDoc.GetPage(i);
                                ps = page.GetPageSize();
                                float watermarkTrimmingRectangleWidth  = textLength; //Math.Min(ps.GetWidth(), ps.GetHeight());
                                float watermarkTrimmingRectangleHeight = watermarkTrimmingRectangleWidth;
                                var   rotationInRads = MathF.Atan2(ps.GetHeight(), ps.GetWidth());
                                //var angle = rotationInRads * 180f / MathF.PI;
                                float formWidth   = ps.GetWidth();  //watermarkTrimmingRectangleWidth;
                                float formHeight  = ps.GetHeight(); //watermarkTrimmingRectangleWidth;
                                float formXOffset = 0;
                                float formYOffset = 0;

                                float xTranslation = (formWidth - watermarkTrimmingRectangleWidth * MathF.Cos(rotationInRads)) / 2;
                                float yTranslation = (formHeight - watermarkTrimmingRectangleWidth * MathF.Sin(rotationInRads)) / 2;

                                //Center the annotation
                                Rectangle watermarkTrimmingRectangle = new Rectangle(0, 0, formWidth, formHeight);//watermarkTrimmingRectangleWidth, watermarkTrimmingRectangleWidth);

                                PdfWatermarkAnnotation watermark = new PdfWatermarkAnnotation(watermarkTrimmingRectangle);

                                //Apply linear algebra rotation math
                                //Create identity matrix
                                AffineTransform transform = new AffineTransform(); //No-args constructor creates the identity transform
                                                                                   //Apply translation
                                                                                   //transform.Translate(xTranslation, yTranslation);
                                                                                   //Apply rotation
                                transform.Translate(xTranslation, yTranslation);
                                transform.Rotate(rotationInRads);

                                PdfFixedPrint fixedPrint = new PdfFixedPrint();
                                watermark.SetFixedPrint(fixedPrint);
                                //Create appearance
                                Rectangle formRectangle = new Rectangle(formXOffset, formYOffset, formWidth, formHeight);

                                //Observation: font XObject will be resized to fit inside the watermark rectangle
                                PdfFormXObject form = new PdfFormXObject(formRectangle);
                                PdfExtGState   gs1  = new PdfExtGState().SetFillOpacity(rgbColor.A / 255f);
                                canvas = new PdfCanvas(form, pdfDoc);

                                float[] transformValues = new float[6];
                                transform.GetMatrix(transformValues);
                                canvas.SaveState()
                                .BeginText().SetFillColorRgb(rgbColor.R / 225f, rgbColor.G / 225f, rgbColor.B / 255f).SetExtGState(gs1)
                                .SetTextMatrix(transformValues[0], transformValues[1], transformValues[2], transformValues[3], transformValues[4], transformValues[5])
                                .SetFontAndSize(font, fontSize)
                                .ShowText(text)
                                .EndText()
                                .RestoreState();

                                canvas.Release();

                                watermark.SetAppearance(PdfName.N, new PdfAnnotationAppearance(form.GetPdfObject()));
                                watermark.SetFlags(PdfAnnotation.PRINT);

                                page.AddAnnotation(watermark);
                            }
                            pdfDoc.Close();
                        }
                        else
                        {
                            App.Current.Dispatcher.Invoke(() =>
                            {
                                MessageBoxX.Show($"没有找到字体{fontFamily},请确认已安装", "字体错误");
                            });
                            return(false);
                        }
                        return(true);
                    }
                }
                catch (Exception ex)
                {
                    Analytics.TrackEvent("PDFError", new Dictionary <string, string>
                    {
                        ["message"] = ex.ToString()
                    });
                }
                finally
                {
                    File.Delete(pdfFile);
                }
            }
            return(false);
        }
        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));
        }
Beispiel #13
0
        static int borderThickness = 1;   // It's just 1. Won't really change, but whatever. If you change it, things will get fucky.

        public static bool MakePDF(Ragecomic comic, string pdffile)
        {
            using (System.IO.FileStream fs = new FileStream(pdffile, FileMode.Create))
            {
                int rows   = (int)Math.Ceiling((double)comic.panels / 2);
                int width  = rowWidth * 2 + borderThickness * 3;
                int height = rowHeight * rows + borderThickness * rows + borderThickness; // 239 per row, plus 1 pixel border per row, plus 1 pixel extra border

                ZipFile drawImageZip  = new ZipFile();
                bool    hasDrawImages = comic.items.getDrawImageCount() > 0;

                if (hasDrawImages)
                {
                    drawImageZip.Dispose();
                    string addition = "";
                    int    nr       = 1;
                    while (File.Exists(pdffile + ".drawimages" + addition + ".zip"))
                    {
                        addition = "_" + (nr++).ToString();
                    }
                    drawImageZip = new ZipFile(pdffile + ".drawimages" + addition + ".zip");
                }


                // Create an instance of the document class which represents the PDF document itself.
                Rectangle pageSize = new Rectangle(width, height);
                Document  document = new Document(pageSize, 0, 0, 0, 0);
                // Create an instance to the PDF file by creating an instance of the PDF
                // Writer class using the document and the filestrem in the constructor.

                PdfWriter writer = PdfWriter.GetInstance(document, fs);

                document.AddAuthor("Derp");

                document.AddCreator("RagemakerToPDF");

                document.AddKeywords("rage, comic");

                document.AddSubject("A rage comic");

                document.AddTitle("A rage comic");
                // Open the document to enable you to write to the document

                document.Open();


                PdfContentByte cb = writer.DirectContent;

                // Fill background with white
                Rectangle rect = new iTextSharp.text.Rectangle(0, 0, width, height);
                rect.BackgroundColor = new BaseColor(255, 255, 255);
                cb.Rectangle(rect);

                // Draw grid on bottom if it isn't set to be on top.
                if (!comic.gridAboveAll && comic.showGrid)
                {
                    DrawGrid(cb, width, height, rows, comic);
                }

                //List<MyMedia.FontFamily> families =  MyMedia.Fonts.SystemFontFamilies.ToList();

                // This was a neat idea, but it's much too slow
                //List<string> files = FontFinder.GetFilesForFont("Courier New").ToList();

                //string filename = FontFinder.GetSystemFontFileName(families[0].)

                //Draw.Font testFont = new Draw.Font(new Draw.FontFamily("Courier New"),12f,Draw.FontStyle.Regular  | Draw.FontStyle.Bold);

                string courierPath     = FontFinder.GetSystemFontFileName("Courier New", true);
                string courierBoldPath = FontFinder.GetSystemFontFileName("Courier New", true, Draw.FontStyle.Bold);
                string tahomaPath      = FontFinder.GetSystemFontFileName("Tahoma", true, Draw.FontStyle.Bold);

                // Define base fonts
                Font[] fonts = new Font[3];
                fonts[0] = new Font(BaseFont.CreateFont(courierPath, BaseFont.CP1252, BaseFont.EMBEDDED));
                fonts[1] = new Font(BaseFont.CreateFont(courierBoldPath, BaseFont.CP1252, BaseFont.EMBEDDED));
                fonts[2] = new Font(BaseFont.CreateFont(tahomaPath, BaseFont.CP1252, BaseFont.EMBEDDED));

                /*fonts[0] = BaseFont.CreateFont("fonts/TRCourierNew.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
                 * fonts[1] = BaseFont.CreateFont("fonts/TRCourierNewBold.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
                 * fonts[2] = new Font(BaseFont.CreateFont("fonts/Tahoma-Bold.ttf", BaseFont.CP1252, BaseFont.EMBEDDED));*/

                int drawimageindex = 0;

                int index = 0;
                foreach (var item in comic.items)
                {
                    if (item is Face)
                    {
                        Face  face = (Face)item;
                        Image pdfImage;
                        System.Drawing.Image faceImage;
                        // If mirroring is necessary, we have to read the image via C# and use RotateFlip, as iTextSharp doesn't support mirroring.
                        if (face.mirrored)
                        {
                            // If it's a JPEG, open it with Flux.JPEG.Core, because the internal JPEG decoder (and also LibJpeg.NET) creates weird dithering artifacts with greyscale JPGs, which some of the rage faces are.
                            if (Path.GetExtension(face.file).ToLower() == ".jpeg" || Path.GetExtension(face.file).ToLower() == ".jpg")
                            {
                                FileStream jpegstream            = File.OpenRead("images/" + face.file);
                                FluxJpeg.Core.DecodedJpeg myJpeg = new JpegDecoder(jpegstream).Decode();

                                // Only use this JPEG decoder if the colorspace is Gray. Otherwise the normal one is just fine.
                                if (myJpeg.Image.ColorModel.colorspace == FluxJpeg.Core.ColorSpace.Gray)
                                {
                                    myJpeg.Image.ChangeColorSpace(FluxJpeg.Core.ColorSpace.YCbCr);
                                    faceImage = myJpeg.Image.ToBitmap();
                                }
                                else
                                {
                                    faceImage = System.Drawing.Image.FromFile("images/" + face.file);
                                }
                            }
                            else
                            {
                                faceImage = System.Drawing.Image.FromFile("images/" + face.file);
                            }

                            // Apply mirroring
                            faceImage.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipX);
                            pdfImage = Image.GetInstance(faceImage, System.Drawing.Imaging.ImageFormat.Png);
                        }
                        else
                        {
                            // Just let iTextSharp handle it if no mirroring is required. Will also save space (presumably)
                            pdfImage = Image.GetInstance("images/" + face.file);
                        }

                        pdfImage.ScalePercent(face.scalex * 100, face.scaley * 100);
                        pdfImage.Rotation = -(float)Math.PI * face.rotation / 180.0f;
                        pdfImage.SetAbsolutePosition(item.x, (height - item.y) - pdfImage.ScaledHeight);

                        // Set opacity to proper value
                        if (face.opacity < 1)
                        {
                            PdfGState graphicsState = new PdfGState();
                            graphicsState.FillOpacity = face.opacity;
                            cb.SetGState(graphicsState);
                        }

                        cb.AddImage(pdfImage);

                        // Set back to normal
                        if (face.opacity < 1)
                        {
                            PdfGState graphicsState = new PdfGState();
                            graphicsState.FillOpacity = 1f;
                            cb.SetGState(graphicsState);
                        }
                    }

                    else if (item is DrawImage)
                    {
                        DrawImage drawimage = (DrawImage)item;

                        drawImageZip.AddEntry("drawimage_" + (drawimageindex++).ToString() + ".png", drawimage.imagedata);

                        System.Drawing.Image pngImage = System.Drawing.Image.FromStream(new MemoryStream(drawimage.imagedata));
                        Image pdfImage = Image.GetInstance(pngImage, System.Drawing.Imaging.ImageFormat.Png);

                        // Rotation is NOT to be applied. Ragemaker actually has a bug that causes it to save rotated images in their rotated form, but save the rotation value anyway
                        // Thus rotating the image by the rotation value will actually rotate them double compared to what they originally looked like
                        // The irony is that ragemaker *itself* cannot properly load an xml it created with this rotation value, as it will also apply the rotation
                        // As such, this tool is currently the only way to correctly display that .xml file as it was originally meant to look, not even ragemaker itself can properly load it again.
                        //pdfImage.Rotation = -(float)Math.PI * item.rotation / 180.0f;

                        pdfImage.SetAbsolutePosition(item.x, (height - item.y) - pdfImage.ScaledHeight);

                        // Opacity likewise seems to be baked in, and in fact the opacity value doesn't even exist.
                        // Implementing it anyway, in case it ever becomes a thing.
                        if (drawimage.opacity < 1)
                        {
                            PdfGState graphicsState = new PdfGState();
                            graphicsState.FillOpacity = drawimage.opacity;
                            cb.SetGState(graphicsState);
                        }
                        cb.AddImage(pdfImage);

                        // Set back to normal
                        if (drawimage.opacity < 1)
                        {
                            PdfGState graphicsState = new PdfGState();
                            graphicsState.FillOpacity = 1f;
                            cb.SetGState(graphicsState);
                        }
                    }


                    else if (item is Text)
                    {
                        int  padding = 4;
                        Text text    = (Text)item;

                        // Create template
                        PdfTemplate xobject = cb.CreateTemplate(text.width, text.height);

                        // Background color (if set)
                        if (text.bgOn)
                        {
                            Rectangle            bgRectangle = new Rectangle(0, 0, text.width, text.height);
                            System.Drawing.Color bgColor     = System.Drawing.ColorTranslator.FromHtml(text.bgColor);
                            rect.BackgroundColor = new BaseColor(bgColor.R, bgColor.G, bgColor.B, (int)Math.Floor(text.opacity * 255));

                            xobject.Rectangle(rect);
                        }

                        // Create text
                        Rectangle  textangle = new Rectangle(padding, 0, text.width - padding, text.height);
                        ColumnText ct        = new ColumnText(xobject);
                        ct.SetSimpleColumn(textangle);
                        Paragraph paragraph = new Paragraph(text.text);

                        Font myFont = fonts[text.style];



                        // More specific treatment if it's an AnyFont element which allows the user to select any font and styles, not just the normal 3 presets
                        // This isn't perfect, as the current FontFinder doesn't indicate whether he actually found an Italic/Bold typeface, hence it's not possible
                        // to determine whether faux-italic/faux-bold should be applied. Currently it will only work correctly if each used font has a specific typeface
                        // for the needed styles (bold or italic), otherwise incorrect results.
                        // TODO Fix, for example let FontFinder return array of strings, one of which is indicating the suffix that was found.
                        if (text is AnyFontText)
                        {
                            AnyFontText anyfont  = (AnyFontText)text;
                            string      fontname = anyfont.font;
                            string      fontfile = "";
                            if (anyfont.bold)
                            {
                                fontfile = FontFinder.GetSystemFontFileName(fontname, true, Draw.FontStyle.Bold);
                                int fontStyle = 0;
                                if (anyfont.italic)
                                {
                                    fontStyle |= Font.ITALIC;
                                }
                                if (anyfont.underline)
                                {
                                    fontStyle |= Font.UNDERLINE;
                                }
                                myFont = new Font(BaseFont.CreateFont(fontfile, BaseFont.CP1252, BaseFont.EMBEDDED), 100f, fontStyle);
                            }
                            else if (anyfont.italic)
                            {
                                fontfile = FontFinder.GetSystemFontFileName(fontname, true, Draw.FontStyle.Italic);
                                int fontStyle = 0;
                                if (anyfont.underline)
                                {
                                    fontStyle |= Font.UNDERLINE;
                                }
                                myFont = new Font(BaseFont.CreateFont(fontfile, BaseFont.CP1252, BaseFont.EMBEDDED), 100f, fontStyle);
                            }
                            else
                            {
                                fontfile = FontFinder.GetSystemFontFileName(fontname, true, Draw.FontStyle.Regular);
                                int fontStyle = 0;
                                if (anyfont.underline)
                                {
                                    fontStyle |= Font.UNDERLINE;
                                }
                                myFont = new Font(BaseFont.CreateFont(fontfile, BaseFont.CP1252, BaseFont.EMBEDDED), 100f, fontStyle);
                            }
                        }



                        myFont.Size = text.size;
                        System.Drawing.Color color = (System.Drawing.Color)(new System.Drawing.ColorConverter()).ConvertFromString(text.color);
                        myFont.Color        = new BaseColor(color.R, color.G, color.B, (int)Math.Floor(text.opacity * 255));
                        paragraph.Font      = myFont;
                        paragraph.Alignment = text.align == Text.ALIGN.LEFT ? PdfContentByte.ALIGN_LEFT : (text.align == Text.ALIGN.RIGHT ? PdfContentByte.ALIGN_RIGHT : PdfContentByte.ALIGN_CENTER);
                        paragraph.SetLeading(0, 1.12f);
                        ct.AddElement(paragraph);
                        ct.Go();


                        // Angle to radians
                        float angle = (float)Math.PI * text.rotation / 180.0f;

                        // Calculate Bounding Box size for correct placement later
                        GraphicsPath gp = new GraphicsPath();
                        gp.AddRectangle(new System.Drawing.Rectangle(0, 0, (int)Math.Round(text.width), (int)Math.Round(text.height)));
                        Matrix translateMatrix = new Matrix();
                        translateMatrix.RotateAt(text.rotation, new System.Drawing.PointF(text.width / 2, text.height / 2));
                        gp.Transform(translateMatrix);
                        var   gbp = gp.GetBounds();
                        float newWidth = gbp.Width, newHeight = gbp.Height;

                        // Create correct placement
                        // Background info: I rotate around the center of the text box, thus the center of the text box is what I attempt to place correctly with the initial .Translate()
                        AffineTransform transform = new AffineTransform();
                        transform.Translate(item.x + newWidth / 2 - text.width / 2, height - (item.y + newHeight / 2 - text.height / 2) - text.height);
                        transform.Rotate(-angle, text.width / 2, text.height / 2);

                        cb.AddTemplate(xobject, transform);
                    }


                    index++;
                }

                if (comic.gridAboveAll && comic.showGrid)
                {
                    DrawGrid(cb, width, height, rows, comic);
                }

                //document.Add(new Paragraph("Hello World!"));
                // Close the document

                document.Close();
                // Close the writer instance

                writer.Close();
                // Always close open filehandles explicity
                fs.Close();

                if (hasDrawImages)
                {
                    drawImageZip.Save();
                }
                drawImageZip.Dispose();
            }


            return(false);
        }
Beispiel #14
0
        public void writePage(Page pPage)
        {
            // page size is given per <fotobook/page>. iTextSharp needs it set before adding page or opening document.
            _doc.SetPageSize(new Rectangle(0f, 0f, pPage.bundleSize.X, pPage.bundleSize.Y));

            // handle first page case
            try {
                if (!_doc.IsOpen())
                {
                    _doc.Open();
                }
                else
                {
                    _doc.NewPage();
                }
            } catch (Exception e) {
                Log.Error("Creating pdf page failed with error: '" + e.Message + "'.");
                return;
            }


            PdfContentByte canvas = _writer.DirectContent;

            // TOOD: de-duplicate
            // draw left part of background
            if (pPage.backgroundLeft != null)
            {
                canvas.Rectangle(0, 0, pPage.bundleSize.X / 2, pPage.bundleSize.Y);
#if DEBUG || _DEBUG
                canvas.SetColorFill(BaseColor.CYAN);
#else
                canvas.SetColorFill(BaseColor.WHITE);
#endif
                canvas.Fill();

                string id = pPage.backgroundLeft;
                System.Drawing.Image sysImg = DesignIdConverter.getImageFromID(id);
                if (sysImg == null)
                {
                    Log.Error("Background image for id '" + id + "' was null.");
#if DEBUG || _DEBUG
                    canvas.SetColorFill(BaseColor.MAGENTA);
#else
                    canvas.SetColorFill(BaseColor.WHITE);
#endif
                    canvas.Fill();
                }
                else
                {
                    Image img = sysImageToITextImage(sysImg);

                    float facY = pPage.bundleSize.Y / img.PlainHeight;
                    float facX = pPage.bundleSize.X / img.PlainWidth;
                    float fac  = Math.Max(facX, facY);

                    img.ScalePercent(fac * 100f);

                    float yoffset = (img.ScaledHeight - pPage.bundleSize.Y) * -0.5f;
                    float xoffset = (img.ScaledWidth - pPage.bundleSize.X) * -0.5f;

                    img.SetAbsolutePosition(xoffset, yoffset);

                    float width = -xoffset + ((pPage.type == Page.Type.Fullcover) ? pPage.bundleSize.X : pPage.bundleSize.X / 2f);

                    Image imgCropped = cropImage(img, _writer, 0, 0, width, img.ScaledHeight);

                    imgCropped.SetAbsolutePosition(xoffset, yoffset);
                    canvas.AddImage(imgCropped);
                }
            }

            // draw right background
            if (pPage.backgroundRight != null)
            {
                canvas.Rectangle(pPage.bundleSize.X / 2, 0, pPage.bundleSize.X / 2, pPage.bundleSize.Y);
#if DEBUG || _DEBUG
                canvas.SetColorFill(BaseColor.CYAN);
                canvas.SetColorFill(BaseColor.WHITE);
#endif
                canvas.Fill();

                string id = pPage.backgroundRight;
                System.Drawing.Image sysImg = DesignIdConverter.getImageFromID(id);
                if (sysImg == null)
                {
                    Log.Error("Background image for id '" + id + "' was null.");
#if DEBUG || _DEBUG
                    canvas.SetColorFill(BaseColor.MAGENTA);
#else
                    canvas.SetColorFill(BaseColor.WHITE);
#endif
                    canvas.Fill();
                    canvas.Fill();
                }
                else
                {
                    Image img = sysImageToITextImage(sysImg);

                    float facY = pPage.bundleSize.Y / img.PlainHeight;
                    float facX = pPage.bundleSize.X / img.PlainWidth;
                    float fac  = Math.Max(facX, facY);

                    img.ScalePercent(fac * 100f);

                    float yoffset = (img.ScaledHeight - pPage.bundleSize.Y) * -0.5f;
                    float xoffset = (img.ScaledWidth - pPage.bundleSize.X) * -0.5f;

                    img.SetAbsolutePosition(xoffset, yoffset);

                    Image imgCropped = cropImage(img, _writer, pPage.bundleSize.X / 2f, 0, img.ScaledWidth, img.ScaledHeight);

                    imgCropped.SetAbsolutePosition(xoffset + pPage.bundleSize.X / 2, yoffset);
                    canvas.AddImage(imgCropped);
                }
            }

            // draw all supported content areas stored in this page
            foreach (Area area in pPage.areas)
            {
                // calculate rect dimensions // TODO: de-duplicate?
                float pX = area.rect.X;
                float pY = pPage.bundleSize.Y - area.rect.Y - area.rect.Height;

                // handle rotation
                canvas.SaveState();
                AffineTransform tf    = new AffineTransform();
                double          angle = area.rotation * Math.PI / 180.0;
                tf.Rotate(-angle, pX + area.rect.Width / 2f, pY + area.rect.Height / 2f); // rotate around center ccw
                canvas.Transform(tf);

                if (area is ImageArea || area is ImageBackgroundArea)
                {
                    // TODO: This is somewhat hacky - there is probably a better way to do this.
                    if (area is ImageBackgroundArea)
                    {
                        ImageBackgroundArea bgArea = (ImageBackgroundArea)area;

                        if (bgArea.type == ImageBackgroundArea.ImageBackgroundType.Right)
                        {
                            bgArea.rect.X += pPage.bundleSize.X / 2f + pPage.spineSize / 2f;
                        }
                    }

                    ImageArea imgArea = (ImageArea)area;

                    // if image path was not valid draw magenta outline and print error
                    if (imgArea.path == "NULL")
                    {
#if DEBUG || _DEBUG
                        // calculate rect dimensions
                        Rectangle nullRect = new Rectangle(pX, pY, pX + imgArea.rect.Width, pY + imgArea.rect.Height);

                        // configure border
                        nullRect.Border      = 1 | 2 | 4 | 8;
                        nullRect.BorderColor = BaseColor.MAGENTA;
                        nullRect.BorderWidth = 4.0f;

                        // draw to document
                        canvas.Rectangle(nullRect);

                        Log.Error("Image path was null. Probably caused by an empty image area.");
                        canvas.RestoreState();
#endif
                        continue;
                    }

                    // load image file.
                    System.Drawing.Image sysImg;
                    try {
                        sysImg = System.Drawing.Image.FromFile(imgArea.path);
                    } catch (System.Exception e) {
                        if (e is System.IO.FileNotFoundException)
                        {
                            Log.Error("Loading image failed. Image at '" + imgArea.path + "' not found.");
                        }
                        else
                        {
                            Log.Error("Loading image failed wit error: '" + e.Message + "'");
                        }
                        canvas.RestoreState();
                        continue;
                    }


                    // fix exif orientation
                    ExifRotate(sysImg);

                    // calculate resizing factor, results in equal pixel density for all images.
                    float scale = 1f / imgArea.scale * Config.ImgScale; // the higher this value, the lower pixel density is. 0.0f = original resolution
                    scale = scale < 1.0f ? 1.0f : scale;                // never scale image up

                    System.Drawing.Size newSize = new System.Drawing.Size((int)(sysImg.Width / scale), (int)(sysImg.Height / scale));

                    // resize image
                    sysImg = (System.Drawing.Image)(new System.Drawing.Bitmap(sysImg, newSize));

                    Image img = sysImageToITextImage(sysImg);

                    // apply scale as defined in .mcf
                    img.ScalePercent(imgArea.scale * 100.0f * scale);

                    // calculate image position in pdf page
                    float posX = imgArea.rect.X + imgArea.cutout.X;
                    float posY = pPage.bundleSize.Y - imgArea.rect.Y - imgArea.rect.Height; // pdf origin is in lower left, mcf origin is in upper left

                    // yaaaaa... whatever. This way everything fits
                    float cropBottom = img.ScaledHeight - imgArea.rect.Height + imgArea.cutout.Y;

                    // crop image to mcf specified rect
                    Image cropped = cropImage(img, _writer, -imgArea.cutout.X, cropBottom, imgArea.rect.Width, imgArea.rect.Height);

                    // move to mcf specified position
                    cropped.SetAbsolutePosition(imgArea.rect.X, posY);

                    string imgType = area is ImageBackgroundArea ? "ImageBackground" : "Image";
                    Log.Info("Rendering " + imgType + " (." + imgArea.path.Split(".").Last() + "): " +
                             "original: " + sysImg.Width + "x" + sysImg.Height + "; " +
                             "scaled: " + newSize.Width + "x" + newSize.Height + "; " +
                             "cropped: " + (int)cropped.Width + "x" + (int)cropped.Height + "; " +
                             "at: " + (int)cropped.AbsoluteX + ", " + (int)cropped.AbsoluteY);

                    // draw the image
                    canvas.AddImage(cropped);

                    // draw image border if specified in .mcf
                    if (imgArea.border)
                    {
                        // TODO mcf as an outside property that is currently not taken into account.
                        // seems like all borders are 'outside' in photobook.
                        // iTextSharp draws Borders centered (BorderWidth/2 pixels overlap image)
                        // this should be corrected.

                        // calc border rect
                        Rectangle rect = new Rectangle(pX, pY, pX + imgArea.rect.Width, pY + imgArea.rect.Height);

                        // convert .mcf's html style color hex code to Color, based on: https://stackoverflow.com/a/2109904
                        int argb = Int32.Parse(imgArea.borderColor.Replace("#", ""), System.Globalization.NumberStyles.HexNumber);
                        System.Drawing.Color clr = System.Drawing.Color.FromArgb(argb);

                        // configure border
                        rect.Border      = 1 | 2 | 4 | 8;
                        rect.BorderColor = new BaseColor(clr);
                        rect.BorderWidth = imgArea.borderWidth;

                        // draw border
                        canvas.Rectangle(rect);
                    }
                }
                else if (area is TextArea)
                {
                    TextArea textArea = (TextArea)area;

                    // Render text background if not transparent
                    if (!textArea.backgroundcolor.EndsWith("00"))
                    {
                        Log.Info("Rendering Text background: color=" + textArea.backgroundcolor);

                        canvas.Rectangle(pX, pY, textArea.rect.Width, textArea.rect.Height);
                        canvas.SetColorFill(argb2BaseColor(textArea.backgroundcolor));
                        canvas.Fill();
                    }

                    // just in case something went wrong
                    if (String.IsNullOrWhiteSpace(textArea.text))
                    {
                        Log.Error("Text was empty.");
                        canvas.RestoreState();
                        continue;
                    }
                    else
                    {
                        Log.Info("Rendering Text: font=" + textArea.font + "; size=" + textArea.fontsize + "; align=" + textArea.align + "; valign=" + textArea.valign);
                    }

                    // iTextSharp textbox
                    ColumnText colText = new ColumnText(canvas);


                    // calculate rect
                    float     llx      = textArea.rect.X;
                    float     lly      = pPage.bundleSize.Y - textArea.rect.Y - textArea.rect.Height;
                    float     urx      = llx + textArea.rect.Width;
                    float     ury      = lly + textArea.rect.Height;
                    Rectangle textRect = new Rectangle(llx, lly, urx, ury);

                    // apply rect to textbox
                    colText.SetSimpleColumn(textRect);

                    // The actual text object
                    Paragraph par = new Paragraph();

                    // magic number that closely matches photobook
                    // TODO there is probably more information in the .mcf's css part
                    par.SetLeading(0, 1.3f);

                    // apply corrent alignment
                    if (textArea.align == "ALIGNHCENTER")
                    {
                        par.Alignment = Element.ALIGN_CENTER;
                    }
                    else if (textArea.align == "ALIGNLEFT")
                    {
                        par.Alignment = Element.ALIGN_LEFT;
                    }
                    else if (textArea.align == "ALIGNRIGHT")
                    {
                        par.Alignment = Element.ALIGN_RIGHT;
                    }
                    else if (textArea.align == "ALIGNJUSTIFY")
                    {
                        par.Alignment = Element.ALIGN_JUSTIFIED;
                    }
                    else
                    {
                        Log.Warning("Unhandled text align: '" + textArea.align + "'.");
                    }

                    // add text chunks
                    foreach (TextElement elem in textArea.textElements)
                    {
                        int style = 0;
                        style += elem.bold ? Font.BOLD : 0;
                        style += elem.italic ? Font.ITALIC : 0;
                        style += elem.underlined ? Font.UNDERLINE : 0;
                        Font fnt = FontFactory.GetFont(elem.family, elem.size, style, argb2BaseColor(elem.color));

                        par.Add(new Chunk(elem.text + (elem.newline ? "\n" : " "), fnt));
                    }

                    int valign = 0;
                    if (textArea.valign == "ALIGNVCENTER")
                    {
                        valign = Element.ALIGN_MIDDLE;
                    }
                    else if (textArea.valign == "ALIGNVTOP")
                    {
                        valign = Element.ALIGN_TOP;
                    }
                    else if (textArea.valign == "ALIGNVBOTTOM")
                    {
                        valign = Element.ALIGN_BOTTOM;
                    }
                    else
                    {
                        Log.Warning("Unhandled text vertical align: '" + textArea.valign + "'.");
                    }

                    // v align needs a table...
                    PdfPTable table = new PdfPTable(1);
                    table.SetWidths(new int[] { 1 });
                    table.WidthPercentage = 100;
                    table.AddCell(new PdfPCell(par)
                    {
                        HorizontalAlignment = par.Alignment,
                        VerticalAlignment   = valign,
                        FixedHeight         = textArea.rect.Height,
                        Border = 0,
                    });

                    // add paragraph to textbox
                    colText.AddElement(table);

                    // draw textbox
                    colText.Go();
                }

                // restore canvas transform before rotation
                canvas.RestoreState();
            }

            // draw pagenumbers
            // TODO remove magic numbers, at least comment
            const float PAGE_NR_Y_OFFSET  = -4.0f;
            const float PAGE_NR_X_OFFSET  = 0.0f;
            float       PAGE_NR_FONT_SIZE = Page.pageNoFontSize * 1.1f;
            float       PAGE_NR_HEIGHT    = PAGE_NR_FONT_SIZE + 12.0f; // add some extra space... this is needed.
            float       PAGE_Y_POS        = Page.pageNoMargin.Y + PAGE_NR_Y_OFFSET;

            // TODO de-duplicate all these conversions and move to helper method
            // convert .mcf's html style color hex code to Color, based on: https://stackoverflow.com/a/2109904
            int argb_ = Int32.Parse(Page.pageNoColor.Replace("#", ""), System.Globalization.NumberStyles.HexNumber);
            System.Drawing.Color clr_ = System.Drawing.Color.FromArgb(argb_);

            // left
            Paragraph pageNoLeft = new Paragraph(pPage.pageNoLeft, FontFactory.GetFont(Page.pageNoFont, PAGE_NR_FONT_SIZE, new BaseColor(clr_)));
            pageNoLeft.Alignment = Element.ALIGN_LEFT + Element.ALIGN_BOTTOM;

            ColumnText leftNo     = new ColumnText(_writer.DirectContent);
            Rectangle  leftNoRect = new Rectangle(Page.pageNoMargin.X + PAGE_NR_X_OFFSET, PAGE_Y_POS, 500, PAGE_Y_POS + PAGE_NR_HEIGHT);
            leftNo.SetSimpleColumn(leftNoRect);

            leftNo.AddElement(pageNoLeft);
            leftNo.Go();

            //leftNoRect.Border = 1 | 2 | 4 | 8;
            //leftNoRect.BorderColor = BaseColor.GREEN;
            //leftNoRect.BorderWidth = 1.0f;
            //_writer.DirectContent.Rectangle(leftNoRect);

            // right
            Paragraph pageNoRight = new Paragraph(pPage.pageNoRight, FontFactory.GetFont(Page.pageNoFont, PAGE_NR_FONT_SIZE, new BaseColor(clr_)));
            pageNoRight.Alignment = Element.ALIGN_RIGHT;

            ColumnText rightNo     = new ColumnText(_writer.DirectContent);
            Rectangle  rightNoRect = new Rectangle(pPage.bundleSize.X - Page.pageNoMargin.X - PAGE_NR_X_OFFSET - 500, PAGE_Y_POS, pPage.bundleSize.X - Page.pageNoMargin.X - PAGE_NR_X_OFFSET, PAGE_Y_POS + PAGE_NR_HEIGHT);
            rightNo.SetSimpleColumn(rightNoRect);

            rightNo.AddElement(pageNoRight);
            rightNo.Go();

            //rightNoRect.Border = 1 | 2 | 4 | 8;
            //rightNoRect.BorderColor = BaseColor.YELLOW;
            //rightNoRect.BorderWidth = 1.0f;
            //_writer.DirectContent.Rectangle(rightNoRect);

            //Console.WriteLine("Page drawn: " + pPage.type.ToString() + " left: " + pPage.pageNoLeft + "; right: " + pPage.pageNoRight + "!");
        }
Beispiel #15
0
        /// <summary>
        /// Watermarks a PDF file.
        /// </summary>
        /// <paramref name="fileName"/>
        private void WatermarkPdf(string fileName)
        {
            var watermarkText   = _operation.WatermarkText;
            var sourceFile      = $"{_operation.SourcePath}\\{fileName}";
            var destinationPath = $"{_operation.DestinationPath}\\{PathWatermarked}";
            var destinationFile = $"{destinationPath}\\{fileName}";

            ValidatePath(destinationPath);

            const float watermarkTrimmingRectangleWidth  = 600;
            const float watermarkTrimmingRectangleHeight = 600;

            const float formWidth   = 300;
            const float formHeight  = 300;
            const float formXOffset = 0;
            const float formYOffset = 0;

            const float xTranslation = 50;
            const float yTranslation = 25;

            const double rotationInRads = Math.PI / 3;

            try
            {
                FontCache.ClearSavedFonts();
            }
            catch (Exception exception)
            {
                Log.Error(exception.Message);
            }

            var         font     = PdfFontFactory.CreateFont(StandardFonts.COURIER);
            const float fontSize = 119;

            using var reader = new PdfReader(new MemoryStream(File.ReadAllBytes(sourceFile)));
            using var pdfDoc = new PdfDocument(reader, new PdfWriter(destinationFile));
            var     numberOfPages = pdfDoc.GetNumberOfPages();
            PdfPage page          = null;

            for (var i = 1; i <= numberOfPages; i++)
            {
                page = pdfDoc.GetPage(i);

                var ps = page.GetPageSize();

                //Center the annotation
                var bottomLeftX = ps.GetWidth() / 2 - watermarkTrimmingRectangleWidth / 2;
                var bottomLeftY = ps.GetHeight() / 2 - watermarkTrimmingRectangleHeight / 2;
                var watermarkTrimmingRectangle = new Rectangle(bottomLeftX, bottomLeftY,
                                                               watermarkTrimmingRectangleWidth, watermarkTrimmingRectangleHeight);

                var watermark = new PdfWatermarkAnnotation(watermarkTrimmingRectangle);

                //Apply linear algebra rotation math
                //Create identity matrix
                var transform = new AffineTransform(); //No-args constructor creates the identity transform
                //Apply translation
                transform.Translate(xTranslation, yTranslation);
                //Apply rotation
                transform.Rotate(rotationInRads);

                var fixedPrint = new PdfFixedPrint();
                watermark.SetFixedPrint(fixedPrint);
                //Create appearance
                var formRectangle = new Rectangle(formXOffset, formYOffset, formWidth, formHeight);

                //Observation: font XObject will be resized to fit inside the watermark rectangle
                var form   = new PdfFormXObject(formRectangle);
                var gs1    = new PdfExtGState().SetFillOpacity(0.6f);
                var canvas = new PdfCanvas(form, pdfDoc);

                var transformValues = new float[6];
                transform.GetMatrix(transformValues);

                canvas.SaveState()
                .BeginText().SetColor(ColorConstants.GRAY, true).SetExtGState(gs1)
                .SetTextMatrix(transformValues[0], transformValues[1], transformValues[2], transformValues[3],
                               transformValues[4], transformValues[5])
                .SetFontAndSize(font, fontSize)
                .ShowText(watermarkText)
                .EndText()
                .RestoreState();

                canvas.Release();

                watermark.SetAppearance(PdfName.N, new PdfAnnotationAppearance(form.GetPdfObject()));
                watermark.SetFlags(PdfAnnotation.PRINT);

                page.AddAnnotation(watermark);
            }

            page?.Flush();
            pdfDoc.Close();
        }
 public void TranslateAndRotate(double xT, double yT, double rad)
 {
     _transform.Translate(xT, yT);
     _transform.Rotate(rad);
 }