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 )); } } }
protected internal override void DoDraw(SvgDrawContext context) { if (this.attributesAndStyles != null && this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.TEXT_CONTENT )) { PdfCanvas currentCanvas = context.GetCurrentCanvas(); String xRawValue = this.attributesAndStyles.Get(SvgConstants.Attributes.X); String yRawValue = this.attributesAndStyles.Get(SvgConstants.Attributes.Y); String fontSizeRawValue = this.attributesAndStyles.Get(SvgConstants.Attributes.FONT_SIZE); IList <String> xValuesList = SvgCssUtils.SplitValueList(xRawValue); IList <String> yValuesList = SvgCssUtils.SplitValueList(yRawValue); float x = 0f; float y = 0f; float fontSize = 0f; if (fontSizeRawValue != null && !String.IsNullOrEmpty(fontSizeRawValue)) { fontSize = CssUtils.ParseAbsoluteLength(fontSizeRawValue, CommonCssConstants.PT); } if (!xValuesList.IsEmpty()) { x = CssUtils.ParseAbsoluteLength(xValuesList[0]); } if (!yValuesList.IsEmpty()) { y = CssUtils.ParseAbsoluteLength(yValuesList[0]); } currentCanvas.BeginText(); FontProvider provider = context.GetFontProvider(); FontSet tempFonts = context.GetTempFonts(); PdfFont font = null; if (!provider.GetFontSet().IsEmpty() || (tempFonts != null && !tempFonts.IsEmpty())) { String fontFamily = this.attributesAndStyles.Get(SvgConstants.Attributes.FONT_FAMILY); String fontWeight = this.attributesAndStyles.Get(SvgConstants.Attributes.FONT_WEIGHT); String fontStyle = this.attributesAndStyles.Get(SvgConstants.Attributes.FONT_STYLE); fontFamily = fontFamily != null?fontFamily.Trim() : ""; FontInfo fontInfo = ResolveFontName(fontFamily, fontWeight, fontStyle, provider, tempFonts); font = provider.GetPdfFont(fontInfo, tempFonts); } if (font == null) { try { // TODO (DEVSIX-2057) // TODO each call of createFont() create a new instance of PdfFont. // TODO FontProvider shall be used instead. font = PdfFontFactory.CreateFont(); } catch (System.IO.IOException e) { throw new SvgProcessingException(SvgLogMessageConstant.FONT_NOT_FOUND, e); } } currentCanvas.SetFontAndSize(font, fontSize); //Current transformation matrix results in the character glyphs being mirrored, correct with inverse tf currentCanvas.SetTextMatrix(1, 0, 0, -1, x, y); currentCanvas.SetColor(ColorConstants.BLACK, true); currentCanvas.ShowText(this.attributesAndStyles.Get(SvgConstants.Attributes.TEXT_CONTENT)); currentCanvas.EndText(); } }
internal virtual String[] RetrieveAlignAndMeet() { String meetOrSlice = SvgConstants.Values.MEET; String align = SvgConstants.Values.DEFAULT_ASPECT_RATIO; if (this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.PRESERVE_ASPECT_RATIO)) { String preserveAspectRatioValue = this.attributesAndStyles.Get(SvgConstants.Attributes.PRESERVE_ASPECT_RATIO ); IList <String> aspectRatioValuesSplitValues = SvgCssUtils.SplitValueList(preserveAspectRatioValue); align = aspectRatioValuesSplitValues[0].ToLowerInvariant(); if (aspectRatioValuesSplitValues.Count > 1) { meetOrSlice = aspectRatioValuesSplitValues[1].ToLowerInvariant(); } } if (this is MarkerSvgNodeRenderer && !SvgConstants.Values.NONE.Equals(align) && SvgConstants.Values.MEET.Equals (meetOrSlice)) { // Browsers do not correctly display markers with 'meet' option in the preserveAspectRatio attribute. // The Chrome, IE, and Firefox browsers set the align value to 'xMinYMin' regardless of the actual align. align = SvgConstants.Values.XMIN_YMIN; } return(new String[] { align, meetOrSlice }); }
public override void SetCoordinates(String[] inputCoordinates, Point startPoint) { String[] normalizedCoords = new String[LineTo.ARGUMENT_SIZE]; // An H or h command is equivalent to an L or l command with 0 specified for the y coordinate. normalizedCoords[0] = inputCoordinates[0]; normalizedCoords[1] = IsRelative() ? "0" : SvgCssUtils.ConvertDoubleToString(startPoint.GetY()); base.SetCoordinates(normalizedCoords, startPoint); }
public override void SetCoordinates(String[] coordinates, Point startPoint) { String[] normalizedCoords = new String[coordinates.Length * 2]; // An H or h command is equivalent to an L or l command with 0 specified for the y coordinate. for (int i = 0; i < coordinates.Length; i++) { normalizedCoords[i * 2] = coordinates[i]; normalizedCoords[i * 2 + 1] = IsRelative() ? "0" : SvgCssUtils.ConvertDoubleToString(startPoint.GetY()); } base.SetCoordinates(normalizedCoords, startPoint); }
// transformation already happened in AbstractSvgNodeRenderer, so no need to do a transformation here /// <summary>Applies a transformation based on a viewBox for a given branch node.</summary> /// <param name="context">current svg draw context</param> internal virtual void ApplyViewBox(SvgDrawContext context) { if (this.attributesAndStyles != null && this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.VIEWBOX )) { //Parse aspect ratio related stuff String viewBoxValues = attributesAndStyles.Get(SvgConstants.Attributes.VIEWBOX); IList <String> valueStrings = SvgCssUtils.SplitValueList(viewBoxValues); float[] values = new float[valueStrings.Count]; for (int i = 0; i < values.Length; i++) { values[i] = CssUtils.ParseAbsoluteLength(valueStrings[i]); } Rectangle currentViewPort = context.GetCurrentViewPort(); String[] alignAndMeet = RetrieveAlignAndMeet(); String align = alignAndMeet[0]; String meetOrSlice = alignAndMeet[1]; float scaleWidth = currentViewPort.GetWidth() / values[2]; float scaleHeight = currentViewPort.GetHeight() / values[3]; bool forceUniformScaling = !(SvgConstants.Values.NONE.Equals(align)); if (forceUniformScaling) { //Scaling should preserve aspect ratio if (SvgConstants.Values.MEET.Equals(meetOrSlice)) { scaleWidth = Math.Min(scaleWidth, scaleHeight); } else { scaleWidth = Math.Max(scaleWidth, scaleHeight); } scaleHeight = scaleWidth; } AffineTransform scale = AffineTransform.GetScaleInstance(scaleWidth, scaleHeight); float[] scaledViewBoxValues = ScaleViewBoxValues(values, scaleWidth, scaleHeight); AffineTransform transform = ProcessAspectRatioPosition(context, scaledViewBoxValues, align, scaleWidth, scaleHeight ); if (!scale.IsIdentity()) { context.GetCurrentCanvas().ConcatMatrix(scale); //Inverse scaling needs to be applied to viewport dimensions context.GetCurrentViewPort().SetWidth(currentViewPort.GetWidth() / scaleWidth).SetX(currentViewPort.GetX() / scaleWidth).SetHeight(currentViewPort.GetHeight() / scaleHeight).SetY(currentViewPort.GetY() / scaleHeight ); } if (!transform.IsIdentity()) { context.GetCurrentCanvas().ConcatMatrix(transform); //Apply inverse translation to viewport to make it line up nicely context.GetCurrentViewPort().SetX(currentViewPort.GetX() + -1 * (float)transform.GetTranslateX()).SetY(currentViewPort .GetY() + -1 * (float)transform.GetTranslateY()); } } }
internal virtual float[] GetViewBoxValues() { String viewBoxValues = attributesAndStyles.Get(SvgConstants.Attributes.VIEWBOX); IList <String> valueStrings = SvgCssUtils.SplitValueList(viewBoxValues); float[] values = new float[valueStrings.Count]; for (int i = 0; i < values.Length; i++) { values[i] = CssUtils.ParseAbsoluteLength(valueStrings[i]); } return(values); }
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); } }
private static float[] GetPositionsFromString(String rawValuesString) { float[] result = null; IList <String> valuesList = SvgCssUtils.SplitValueList(rawValuesString); if (!valuesList.IsEmpty()) { result = new float[valuesList.Count]; for (int i = 0; i < valuesList.Count; i++) { result[i] = CssUtils.ParseAbsoluteLength(valuesList[i]); } } return(result); }
internal virtual String[] RetrieveAlignAndMeet() { String meetOrSlice = SvgConstants.Values.MEET; String align = SvgConstants.Values.DEFAULT_ASPECT_RATIO; if (this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.PRESERVE_ASPECT_RATIO)) { String preserveAspectRatioValue = this.attributesAndStyles.Get(SvgConstants.Attributes.PRESERVE_ASPECT_RATIO ); IList <String> aspectRatioValuesSplitValues = SvgCssUtils.SplitValueList(preserveAspectRatioValue); align = aspectRatioValuesSplitValues[0].ToLowerInvariant(); if (aspectRatioValuesSplitValues.Count > 1) { meetOrSlice = aspectRatioValuesSplitValues[1].ToLowerInvariant(); } } return(new String[] { align, meetOrSlice }); }
/// <summary> /// Gets the coordinates that shall be passed to /// <see cref="iText.Svg.Renderers.Path.IPathShape.SetCoordinates(System.String[], iText.Kernel.Geom.Point)"/> /// for the current shape. /// </summary> /// <param name="shape">The current shape.</param> /// <param name="previousShape">The previous shape which can affect the coordinates of the current shape.</param> /// <param name="pathProperties"> /// The operator and all arguments as a /// <see>String[]</see> /// </param> /// <returns> /// a /// <see>String[]</see> /// of coordinates that shall be passed to /// <see cref="iText.Svg.Renderers.Path.IPathShape.SetCoordinates(System.String[], iText.Kernel.Geom.Point)"/> /// </returns> private String[] GetShapeCoordinates(IPathShape shape, IPathShape previousShape, String[] pathProperties) { if (shape is ClosePath) { return(null); } String[] shapeCoordinates = null; String[] operatorArgs = JavaUtil.ArraysCopyOfRange(pathProperties, 1, pathProperties.Length); if (shape is SmoothSCurveTo) { String[] startingControlPoint = new String[2]; if (previousShape != null) { Point previousEndPoint = previousShape.GetEndingPoint(); //if the previous command was a C or S use its last control point if (((previousShape is CurveTo))) { Point lastControlPoint = ((CurveTo)previousShape).GetLastControlPoint(); float reflectedX = (float)(2 * previousEndPoint.GetX() - lastControlPoint.GetX()); float reflectedY = (float)(2 * previousEndPoint.GetY() - lastControlPoint.GetY()); startingControlPoint[0] = SvgCssUtils.ConvertFloatToString(reflectedX); startingControlPoint[1] = SvgCssUtils.ConvertFloatToString(reflectedY); } else { startingControlPoint[0] = SvgCssUtils.ConvertDoubleToString(previousEndPoint.GetX()); startingControlPoint[1] = SvgCssUtils.ConvertDoubleToString(previousEndPoint.GetY()); } } else { // TODO RND-951 startingControlPoint[0] = pathProperties[1]; startingControlPoint[1] = pathProperties[2]; } shapeCoordinates = Concatenate(startingControlPoint, operatorArgs); } if (shapeCoordinates == null) { shapeCoordinates = operatorArgs; } return(shapeCoordinates); }
/// <summary> /// Gets the coordinates that shall be passed to /// <see cref="iText.Svg.Renderers.Path.IPathShape.SetCoordinates(System.String[], iText.Kernel.Geom.Point)"/> /// for the current shape. /// </summary> /// <param name="shape">The current shape.</param> /// <param name="previousShape">The previous shape which can affect the coordinates of the current shape.</param> /// <param name="pathProperties"> /// The operator and all arguments as a /// <see>String[]</see> /// </param> /// <returns> /// a /// <see>String[]</see> /// of coordinates that shall be passed to /// <see cref="iText.Svg.Renderers.Path.IPathShape.SetCoordinates(System.String[], iText.Kernel.Geom.Point)"/> /// </returns> private String[] GetShapeCoordinates(IPathShape shape, IPathShape previousShape, String[] pathProperties) { if (shape is ClosePath) { return(null); } String[] shapeCoordinates = null; if (shape is SmoothSCurveTo || shape is QuadraticSmoothCurveTo) { String[] startingControlPoint = new String[2]; if (previousShape != null) { Point previousEndPoint = previousShape.GetEndingPoint(); //if the previous command was a Bezier curve, use its last control point if (previousShape is IControlPointCurve) { Point lastControlPoint = ((IControlPointCurve)previousShape).GetLastControlPoint(); float reflectedX = (float)(2 * previousEndPoint.GetX() - lastControlPoint.GetX()); float reflectedY = (float)(2 * previousEndPoint.GetY() - lastControlPoint.GetY()); startingControlPoint[0] = SvgCssUtils.ConvertFloatToString(reflectedX); startingControlPoint[1] = SvgCssUtils.ConvertFloatToString(reflectedY); } else { startingControlPoint[0] = SvgCssUtils.ConvertDoubleToString(previousEndPoint.GetX()); startingControlPoint[1] = SvgCssUtils.ConvertDoubleToString(previousEndPoint.GetY()); } } else { // TODO RND-951 startingControlPoint[0] = pathProperties[0]; startingControlPoint[1] = pathProperties[1]; } shapeCoordinates = Concatenate(startingControlPoint, pathProperties); } if (shapeCoordinates == null) { shapeCoordinates = pathProperties; } return(shapeCoordinates); }
private void ResolveTextMove() { if (this.attributesAndStyles != null) { String xRawValue = this.attributesAndStyles.Get(SvgConstants.Attributes.DX); String yRawValue = this.attributesAndStyles.Get(SvgConstants.Attributes.DY); IList <String> xValuesList = SvgCssUtils.SplitValueList(xRawValue); IList <String> yValuesList = SvgCssUtils.SplitValueList(yRawValue); xMove = 0f; yMove = 0f; if (!xValuesList.IsEmpty()) { xMove = CssUtils.ParseAbsoluteLength(xValuesList[0]); } if (!yValuesList.IsEmpty()) { yMove = CssUtils.ParseAbsoluteLength(yValuesList[0]); } moveResolved = true; } }
public virtual void DrawMarker(SvgDrawContext context, MarkerVertexType markerVertexType) { Point point = null; if (MarkerVertexType.MARKER_START.Equals(markerVertexType)) { point = points[0]; } else { if (MarkerVertexType.MARKER_END.Equals(markerVertexType)) { point = points[points.Count - 1]; } } if (point != null) { String moveX = SvgCssUtils.ConvertDoubleToString(CssUtils.ConvertPtsToPx(point.x)); String moveY = SvgCssUtils.ConvertDoubleToString(CssUtils.ConvertPtsToPx(point.y)); MarkerSvgNodeRenderer.DrawMarker(context, moveX, moveY, markerVertexType, this); } }
/// <summary> /// Parses a string of space separated x,y pairs into individual /// <see cref="iText.Kernel.Geom.Point"/> /// objects and appends them to /// <see cref="points"/> /// . /// Throws an /// <see cref="iText.Svg.Exceptions.SvgProcessingException"/> /// if pointsAttribute does not have a valid list of numerical x,y pairs. /// </summary> /// <param name="pointsAttribute">A string of space separated x,y value pairs</param> protected internal virtual void SetPoints(String pointsAttribute) { if (pointsAttribute == null) { return; } IList <String> points = SvgCssUtils.SplitValueList(pointsAttribute); if (points.Count % 2 != 0) { throw new SvgProcessingException(SvgLogMessageConstant.POINTS_ATTRIBUTE_INVALID_LIST).SetMessageParams(pointsAttribute ); } float x; float y; for (int i = 0; i < points.Count; i = i + 2) { x = CssUtils.ParseAbsoluteLength(points[i]); y = CssUtils.ParseAbsoluteLength(points[i + 1]); this.points.Add(new Point(x, y)); } }
public virtual void DrawMarker(SvgDrawContext context, MarkerVertexType markerVertexType) { Object[] allShapesOrdered = GetShapes().ToArray(); Point point = null; if (MarkerVertexType.MARKER_START.Equals(markerVertexType)) { point = ((AbstractPathShape)allShapesOrdered[0]).GetEndingPoint(); } else { if (MarkerVertexType.MARKER_END.Equals(markerVertexType)) { point = ((AbstractPathShape)allShapesOrdered[allShapesOrdered.Length - 1]).GetEndingPoint(); } } if (point != null) { String moveX = SvgCssUtils.ConvertDoubleToString(point.x); String moveY = SvgCssUtils.ConvertDoubleToString(point.y); MarkerSvgNodeRenderer.DrawMarker(context, moveX, moveY, markerVertexType, this); } }
// transformation already happened in AbstractSvgNodeRenderer, so no need to do a transformation here /// <summary>Applies a transformation based on a viewBox for a given branch node.</summary> /// <param name="context">current svg draw context</param> private void ApplyViewBox(SvgDrawContext context) { if (this.attributesAndStyles != null) { if (this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.VIEWBOX)) { //Parse aspect ratio related stuff String viewBoxValues = attributesAndStyles.Get(SvgConstants.Attributes.VIEWBOX); IList <String> valueStrings = SvgCssUtils.SplitValueList(viewBoxValues); float[] values = new float[valueStrings.Count]; for (int i = 0; i < values.Length; i++) { values[i] = CssUtils.ParseAbsoluteLength(valueStrings[i]); } Rectangle currentViewPort = context.GetCurrentViewPort(); float scaleWidth = currentViewPort.GetWidth() / values[2]; float scaleHeight = currentViewPort.GetHeight() / values[3]; AffineTransform scale = AffineTransform.GetScaleInstance(scaleWidth, scaleHeight); if (!scale.IsIdentity()) { context.GetCurrentCanvas().ConcatMatrix(scale); //Inverse scaling needs to be applied to viewport dimensions context.GetCurrentViewPort().SetWidth(currentViewPort.GetWidth() / scaleWidth); context.GetCurrentViewPort().SetX(currentViewPort.GetX() / scaleWidth); context.GetCurrentViewPort().SetHeight(currentViewPort.GetHeight() / scaleHeight); context.GetCurrentViewPort().SetY(currentViewPort.GetY() / scaleHeight); } AffineTransform transform = ProcessAspectRatio(context, values); if (!transform.IsIdentity()) { //TODO (RND-876) context.GetCurrentCanvas().WriteLiteral("% applying viewbox aspect ratio correction (not correct) \n"); } } } }
private void CollectCssDeclarations(INode rootNode, ResourceResolver resourceResolver) { this.css = new CssStyleSheet(); LinkedList <INode> q = new LinkedList <INode>(); if (rootNode != null) { q.Add(rootNode); } while (!q.IsEmpty()) { INode currentNode = q.JRemoveFirst(); if (currentNode is IElementNode) { IElementNode headChildElement = (IElementNode)currentNode; if (SvgConstants.Tags.STYLE.Equals(headChildElement.Name())) { //XML parser will parse style tag contents as text nodes if (!currentNode.ChildNodes().IsEmpty() && (currentNode.ChildNodes()[0] is IDataNode || currentNode.ChildNodes ()[0] is ITextNode)) { String styleData; if (currentNode.ChildNodes()[0] is IDataNode) { styleData = ((IDataNode)currentNode.ChildNodes()[0]).GetWholeData(); } else { styleData = ((ITextNode)currentNode.ChildNodes()[0]).WholeText(); } CssStyleSheet styleSheet = CssStyleSheetParser.Parse(styleData); //TODO (DEVSIX-2263): media query wrap //styleSheet = wrapStyleSheetInMediaQueryIfNecessary(headChildElement, styleSheet); this.css.AppendCssStyleSheet(styleSheet); } } else { if (SvgCssUtils.IsStyleSheetLink(headChildElement)) { String styleSheetUri = headChildElement.GetAttribute(SvgConstants.Attributes.HREF); try { Stream stream = resourceResolver.RetrieveStyleSheet(styleSheetUri); byte[] bytes = StreamUtil.InputStreamToArray(stream); CssStyleSheet styleSheet = CssStyleSheetParser.Parse(new MemoryStream(bytes), resourceResolver.ResolveAgainstBaseUri (styleSheetUri).ToExternalForm()); this.css.AppendCssStyleSheet(styleSheet); } catch (System.IO.IOException exc) { ILog logger = LogManager.GetLogger(typeof(iText.Svg.Css.Impl.SvgStyleResolver)); logger.Error(iText.StyledXmlParser.LogMessageConstant.UNABLE_TO_PROCESS_EXTERNAL_CSS_FILE, exc); } } } } foreach (INode child in currentNode.ChildNodes()) { if (child is IElementNode) { q.Add(child); } } } }
/// <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); }