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