private void ApplyUserSpaceScaling(SvgDrawContext context)
 {
     if (!this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.MARKER_UNITS) || SvgConstants.Values.STROKEWIDTH
         .Equals(this.attributesAndStyles.Get(SvgConstants.Attributes.MARKER_UNITS)))
     {
         String parentValue = this.GetParent().GetAttribute(SvgConstants.Attributes.STROKE_WIDTH);
         if (parentValue != null)
         {
             float strokeWidthScale;
             if (CssUtils.IsPercentageValue(parentValue))
             {
                 // If stroke width is a percentage value is always computed as a percentage of the normalized viewBox diagonal length.
                 double rootViewPortHeight    = context.GetRootViewPort().GetHeight();
                 double rootViewPortWidth     = context.GetRootViewPort().GetWidth();
                 double viewBoxDiagonalLength = Math.Sqrt(rootViewPortHeight * rootViewPortHeight + rootViewPortWidth * rootViewPortWidth
                                                          );
                 strokeWidthScale = CssUtils.ParseRelativeValue(parentValue, (float)viewBoxDiagonalLength);
             }
             else
             {
                 strokeWidthScale = SvgCssUtils.ConvertPtsToPx(ParseFontRelativeOrAbsoluteLengthOnMarker(parentValue));
             }
             context.GetCurrentCanvas().ConcatMatrix(AffineTransform.GetScaleInstance(strokeWidthScale, strokeWidthScale
                                                                                      ));
         }
     }
 }
        private void ApplyCoordinatesTranslation(SvgDrawContext context)
        {
            float xScale = 1;
            float yScale = 1;

            if (this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.VIEWBOX))
            {
                //Parse viewbox parameters stuff
                String         viewBoxValues = attributesAndStyles.Get(SvgConstants.Attributes.VIEWBOX);
                IList <String> valueStrings  = SvgCssUtils.SplitValueList(viewBoxValues);
                float[]        viewBox       = GetViewBoxValues();
                xScale = context.GetCurrentViewPort().GetWidth() / viewBox[2];
                yScale = context.GetCurrentViewPort().GetHeight() / viewBox[3];
            }
            float moveX = DEFAULT_REF_X;

            if (this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.REFX))
            {
                String refX = this.attributesAndStyles.Get(SvgConstants.Attributes.REFX);
                if (CssUtils.IsPercentageValue(refX))
                {
                    moveX = CssUtils.ParseRelativeValue(refX, context.GetRootViewPort().GetWidth());
                }
                else
                {
                    moveX = ParseFontRelativeOrAbsoluteLengthOnMarker(refX);
                }
                //Apply scale
                moveX *= -1 * xScale;
            }
            float moveY = DEFAULT_REF_Y;

            if (this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.REFY))
            {
                String refY = this.attributesAndStyles.Get(SvgConstants.Attributes.REFY);
                if (CssUtils.IsPercentageValue(refY))
                {
                    moveY = CssUtils.ParseRelativeValue(refY, context.GetRootViewPort().GetHeight());
                }
                else
                {
                    moveY = ParseFontRelativeOrAbsoluteLengthOnMarker(refY);
                }
                moveY *= -1 * yScale;
            }
            AffineTransform translation = AffineTransform.GetTranslateInstance(moveX, moveY);

            if (!translation.IsIdentity())
            {
                context.GetCurrentCanvas().ConcatMatrix(translation);
            }
        }
Beispiel #3
0
        /// <summary>
        /// When in the svg element
        /// <c>overflow</c>
        /// is
        /// <c>visible</c>
        /// the corresponding formXObject
        /// should have a BBox (form XObject’s bounding box; see PDF 32000-1:2008 - 8.10.2 Form Dictionaries)
        /// that should cover the entire svg space (page in pdf) in order to be able to show parts of the element which are outside the current element viewPort.
        /// </summary>
        /// <remarks>
        /// When in the svg element
        /// <c>overflow</c>
        /// is
        /// <c>visible</c>
        /// the corresponding formXObject
        /// should have a BBox (form XObject’s bounding box; see PDF 32000-1:2008 - 8.10.2 Form Dictionaries)
        /// that should cover the entire svg space (page in pdf) in order to be able to show parts of the element which are outside the current element viewPort.
        /// To do this, we get the inverse matrix of all the current transformation matrix changes and apply it to the root viewPort.
        /// This allows you to get the root rectangle in the final coordinate system.
        /// </remarks>
        /// <param name="context">current context to get canvases and view ports</param>
        /// <param name="stream">stream to write a BBox</param>
        private static void WriteBBoxAccordingToVisibleOverflow(SvgDrawContext context, PdfStream stream)
        {
            IList <PdfCanvas> canvases = new List <PdfCanvas>();
            int canvasesSize           = context.Size();

            for (int i = 0; i < canvasesSize; i++)
            {
                canvases.Add(context.PopCanvas());
            }
            AffineTransform transform = new AffineTransform();

            for (int i = canvases.Count - 1; i >= 0; i--)
            {
                PdfCanvas canvas = canvases[i];
                Matrix    matrix = canvas.GetGraphicsState().GetCtm();
                transform.Concatenate(new AffineTransform(matrix.Get(0), matrix.Get(1), matrix.Get(3), matrix.Get(4), matrix
                                                          .Get(6), matrix.Get(7)));
                context.PushCanvas(canvas);
            }
            try {
                transform = transform.CreateInverse();
            }
            catch (NoninvertibleTransformException) {
                // Case with zero determiner (see PDF 32000-1:2008 - 8.3.4 Transformation Matrices - NOTE 3)
                // for example with a, b, c, d in cm equal to 0
                stream.Put(PdfName.BBox, new PdfArray(new Rectangle(0, 0, 0, 0)));
                ILog logger = LogManager.GetLogger(typeof(AbstractBranchSvgNodeRenderer));
                logger.Warn(SvgLogMessageConstant.UNABLE_TO_GET_INVERSE_MATRIX_DUE_TO_ZERO_DETERMINANT);
                return;
            }
            Point[] points = context.GetRootViewPort().ToPointsArray();
            transform.Transform(points, 0, points, 0, points.Length);
            Rectangle bbox = Rectangle.CalculateBBox(JavaUtil.ArraysAsList(points));

            stream.Put(PdfName.BBox, new PdfArray(bbox));
        }