/// <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)); }