Beispiel #1
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);
            }
        }
        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
        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);
        }
        public virtual void ProcessAspectRatioPositionXMidYMax()
        {
            String          alignValue   = SvgConstants.Values.XMID_YMAX;
            AffineTransform cmpTransform = new AffineTransform();

            cmpTransform.Translate(147.5, 442);
            ProcessAspectRatioPositionAndCompare(alignValue, cmpTransform);
        }
        public virtual void ProcessAspectRatioPositionXMinYMid()
        {
            String          alignValue   = SvgConstants.Values.XMIN_YMID;
            AffineTransform cmpTransform = new AffineTransform();

            cmpTransform.Translate(0, 221);
            ProcessAspectRatioPositionAndCompare(alignValue, cmpTransform);
        }
        public virtual void ProcessAspectRatioPositionNone()
        {
            String          alignValue   = SvgConstants.Values.NONE;
            AffineTransform cmpTransform = new AffineTransform();

            cmpTransform.Translate(0, 0);
            ProcessAspectRatioPositionAndCompare(alignValue, cmpTransform);
        }
        public virtual void ProcessAspectRatioPositionXMaxYMin()
        {
            String          alignValue   = SvgConstants.Values.XMAX_YMIN;
            AffineTransform cmpTransform = new AffineTransform();

            cmpTransform.Translate(295, 0);
            ProcessAspectRatioPositionAndCompare(alignValue, cmpTransform);
        }
        public virtual void ProcessAspectRatioPositionDefault()
        {
            //default aspect ration is xMidYMid
            String          alignValue   = SvgConstants.Values.DEFAULT_ASPECT_RATIO;
            AffineTransform cmpTransform = new AffineTransform();

            cmpTransform.Translate(147.5, 221);
            ProcessAspectRatioPositionAndCompare(alignValue, cmpTransform);
        }
Beispiel #9
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);
        }
        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 #11
0
 private void TranslateImage(float xDistance, float yDistance, AffineTransform t)
 {
     t.Translate(xDistance, yDistance);
     t.GetMatrix(matrix);
     if (fixedXPosition != null)
     {
         fixedXPosition += (float)t.GetTranslateX();
     }
     if (fixedYPosition != null)
     {
         fixedYPosition += (float)t.GetTranslateY();
     }
 }
Beispiel #12
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 #13
0
        private void MoveShape(Point start, Point end)
        {
            if (CurrentState.IsMoveShape == false)
            {
                return;
            }

            AffineTransform affine = new AffineTransform();

            affine.Translate(end.X - start.X, end.Y - start.Y);

            foreach (Shape currShape in ListOfInstances)
            {
                if (currShape.IsChosen == true)
                {
                    currShape.PixelsInLine = affine.Transform(savedPointInLine);
                    currShape.PixelsInArea = affine.Transform(savedPointInArea);
                }
            }
        }
Beispiel #14
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());
        }
Beispiel #15
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 });
        }
 public void TranslateAndRotate(double xT, double yT, double rad)
 {
     _transform.Translate(xT, yT);
     _transform.Rotate(rad);
 }
Beispiel #17
0
        /// <summary>If present, process the preserveAspectRatio position.</summary>
        /// <param name="context">the svg draw context</param>
        /// <param name="viewBoxValues">the four values depicting the viewbox [min-x min-y width height]</param>
        /// <param name="align">alignment method to use</param>
        /// <param name="scaleWidth">the multiplier for scaling width</param>
        /// <param name="scaleHeight">the multiplier for scaling height</param>
        /// <returns>the transformation based on the preserveAspectRatio value</returns>
        internal virtual AffineTransform ProcessAspectRatioPosition(SvgDrawContext context, float[] viewBoxValues,
                                                                    String align, float scaleWidth, float scaleHeight)
        {
            AffineTransform transform       = new AffineTransform();
            Rectangle       currentViewPort = context.GetCurrentViewPort();
            float           midXBox         = viewBoxValues[0] + (viewBoxValues[2] / 2);
            float           midYBox         = viewBoxValues[1] + (viewBoxValues[3] / 2);
            float           midXPort        = currentViewPort.GetX() + (currentViewPort.GetWidth() / 2);
            float           midYPort        = currentViewPort.GetY() + (currentViewPort.GetHeight() / 2);
            float           x = 0f;
            float           y = 0f;

            // if x attribute of svg is present, then x value of current viewport should be set according to it
            if (attributesAndStyles.ContainsKey(SvgConstants.Attributes.X))
            {
                x = CssUtils.ParseAbsoluteLength(attributesAndStyles.Get(SvgConstants.Attributes.X));
            }
            // if y attribute of svg is present, then y value of current viewport should be set according to it
            if (attributesAndStyles.ContainsKey(SvgConstants.Attributes.Y))
            {
                y = CssUtils.ParseAbsoluteLength(attributesAndStyles.Get(SvgConstants.Attributes.Y));
            }
            // need to consider previous (parent) translation before applying the current one
            x -= currentViewPort.GetX();
            y -= currentViewPort.GetY();
            switch (align.ToLowerInvariant())
            {
            case SvgConstants.Values.NONE: {
                break;
            }

            case SvgConstants.Values.XMIN_YMIN: {
                x -= viewBoxValues[0];
                y -= viewBoxValues[1];
                break;
            }

            case SvgConstants.Values.XMIN_YMID: {
                x -= viewBoxValues[0];
                y += (midYPort - midYBox);
                break;
            }

            case SvgConstants.Values.XMIN_YMAX: {
                x -= viewBoxValues[0];
                y += (currentViewPort.GetHeight() - viewBoxValues[3]);
                break;
            }

            case SvgConstants.Values.XMID_YMIN: {
                x += (midXPort - midXBox);
                y -= viewBoxValues[1];
                break;
            }

            case SvgConstants.Values.XMID_YMAX: {
                x += (midXPort - midXBox);
                y += (currentViewPort.GetHeight() - viewBoxValues[3]);
                break;
            }

            case SvgConstants.Values.XMAX_YMIN: {
                x += (currentViewPort.GetWidth() - viewBoxValues[2]);
                y -= viewBoxValues[1];
                break;
            }

            case SvgConstants.Values.XMAX_YMID: {
                x += (currentViewPort.GetWidth() - viewBoxValues[2]);
                y += (midYPort - midYBox);
                break;
            }

            case SvgConstants.Values.XMAX_YMAX: {
                x += (currentViewPort.GetWidth() - viewBoxValues[2]);
                y += (currentViewPort.GetHeight() - viewBoxValues[3]);
                break;
            }

            case SvgConstants.Values.DEFAULT_ASPECT_RATIO:
            default: {
                x += (midXPort - midXBox);
                y += (midYPort - midYBox);
                break;
            }
            }
            //Rescale x and y
            x /= scaleWidth;
            y /= scaleHeight;
            transform.Translate(x, y);
            return(transform);
        }
Beispiel #18
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 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 void Draw(PdfCanvas canvas)
        {
            Point start = new Point(startPoint.x * .75, startPoint.y * .75);
            // pixels to points
            double rx = Math.Abs(CssUtils.ParseAbsoluteLength(coordinates[0]));
            double ry = Math.Abs(CssUtils.ParseAbsoluteLength(coordinates[1]));
            // φ is taken mod 360 degrees.
            double rotation = Double.Parse(coordinates[2], System.Globalization.CultureInfo.InvariantCulture) % 360.0;

            // rotation argument is given in degrees, but we need radians for easier trigonometric calculations
            rotation = MathUtil.ToRadians(rotation);
            // binary flags (Value correction: any nonzero value for either of the flags fA or fS is taken to mean the value 1.)
            bool  largeArc = !CssUtils.CompareFloats((float)CssUtils.ParseFloat(coordinates[3]), 0);
            bool  sweep    = !CssUtils.CompareFloats((float)CssUtils.ParseFloat(coordinates[4]), 0);
            Point end      = new Point(CssUtils.ParseAbsoluteLength(coordinates[5]), CssUtils.ParseAbsoluteLength(coordinates
                                                                                                                  [6]));

            if (CssUtils.CompareFloats(start.x, end.x) && CssUtils.CompareFloats(start.y, end.y))
            {
                /* edge case: If the endpoints (x1, y1) and (x2, y2) are identical,
                 * then this is equivalent to omitting the elliptical arc segment entirely.
                 */
                return;
            }
            if (CssUtils.CompareFloats(rx, 0) || CssUtils.CompareFloats(ry, 0))
            {
                /* edge case: If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a "lineto")
                 * joining the endpoints.
                 */
                canvas.LineTo(end.x, end.y);
            }
            else
            {
                /* This is the first step of calculating a rotated elliptical path.
                 * We must simulate a transformation on the end-point in order to calculate appropriate EllipseArc angles;
                 * if we don't do this, then the EllipseArc class will calculate the correct bounding rectangle,
                 * but an incorrect starting angle and/or extent.
                 */
                EllipticalCurveTo.EllipseArc arc;
                if (CssUtils.CompareFloats(rotation, 0))
                {
                    arc = EllipticalCurveTo.EllipseArc.GetEllipse(start, end, rx, ry, sweep, largeArc);
                }
                else
                {
                    AffineTransform normalizer = AffineTransform.GetRotateInstance(-rotation);
                    normalizer.Translate(-start.x, -start.y);
                    Point newArcEnd = normalizer.Transform(end, null);
                    newArcEnd.Translate(start.x, start.y);
                    arc = EllipticalCurveTo.EllipseArc.GetEllipse(start, newArcEnd, rx, ry, sweep, largeArc);
                }
                Point[][] points = MakePoints(PdfCanvas.BezierArc(arc.ll.x, arc.ll.y, arc.ur.x, arc.ur.y, arc.startAng, arc
                                                                  .extent));
                if (sweep)
                {
                    points = Rotate(points, rotation, points[0][0]);
                    for (int i = 0; i < points.Length; i++)
                    {
                        DrawCurve(canvas, points[i][1], points[i][2], points[i][3]);
                    }
                }
                else
                {
                    points = Rotate(points, rotation, points[points.Length - 1][3]);
                    for (int i = points.Length - 1; i >= 0; i--)
                    {
                        DrawCurve(canvas, points[i][2], points[i][1], points[i][0]);
                    }
                }
            }
        }
        /// <summary>If present, process the preserveAspectRatio.</summary>
        /// <param name="context">the svg draw context</param>
        /// <param name="viewBoxValues">the four values depicting the viewbox [min-x min-y width height]</param>
        /// <returns>the transformation based on the preserveAspectRatio value</returns>
        private AffineTransform ProcessAspectRatio(SvgDrawContext context, float[] viewBoxValues)
        {
            AffineTransform transform = new AffineTransform();

            if (this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.PRESERVE_ASPECT_RATIO))
            {
                Rectangle currentViewPort          = context.GetCurrentViewPort();
                String    preserveAspectRatioValue = this.attributesAndStyles.Get(SvgConstants.Attributes.PRESERVE_ASPECT_RATIO
                                                                                  );
                IList <String> values = SvgCssUtils.SplitValueList(preserveAspectRatioValue);
                if (SvgConstants.Values.DEFER.EqualsIgnoreCase(values[0]))
                {
                    values.JRemoveAt(0);
                }
                String align    = values[0];
                float  x        = 0f;
                float  y        = 0f;
                float  midXBox  = viewBoxValues[0] + (viewBoxValues[2] / 2);
                float  midYBox  = viewBoxValues[1] + (viewBoxValues[3] / 2);
                float  midXPort = currentViewPort.GetX() + (currentViewPort.GetWidth() / 2);
                float  midYPort = currentViewPort.GetY() + (currentViewPort.GetHeight() / 2);
                switch (align.ToLowerInvariant())
                {
                case SvgConstants.Values.NONE: {
                    break;
                }

                case SvgConstants.Values.XMIN_YMIN: {
                    x = -viewBoxValues[0];
                    y = -viewBoxValues[1];
                    break;
                }

                case SvgConstants.Values.XMIN_YMID: {
                    x = -viewBoxValues[0];
                    y = midYPort - midYBox;
                    break;
                }

                case SvgConstants.Values.XMIN_YMAX: {
                    x = -viewBoxValues[0];
                    y = currentViewPort.GetHeight() - viewBoxValues[3];
                    break;
                }

                case SvgConstants.Values.XMID_YMIN: {
                    x = midXPort - midXBox;
                    y = -viewBoxValues[1];
                    break;
                }

                case SvgConstants.Values.XMID_YMAX: {
                    x = midXPort - midXBox;
                    y = currentViewPort.GetHeight() - viewBoxValues[3];
                    break;
                }

                case SvgConstants.Values.XMAX_YMIN: {
                    x = currentViewPort.GetWidth() - viewBoxValues[2];
                    y = -viewBoxValues[1];
                    break;
                }

                case SvgConstants.Values.XMAX_YMID: {
                    x = currentViewPort.GetWidth() - viewBoxValues[2];
                    y = midYPort - midYBox;
                    break;
                }

                case SvgConstants.Values.XMAX_YMAX: {
                    x = currentViewPort.GetWidth() - viewBoxValues[2];
                    y = currentViewPort.GetHeight() - viewBoxValues[3];
                    break;
                }

                case SvgConstants.Values.DEFAULT_ASPECT_RATIO:
                default: {
                    x = midXPort - midXBox;
                    y = midYPort - midYBox;
                    break;
                }
                }
                transform.Translate(x, y);
            }
            return(transform);
        }
Beispiel #22
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();
            }
        }
Beispiel #23
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);
        }