/// <summary>Applies opacity to an element.</summary> /// <param name="cssProps">the CSS properties</param> /// <param name="context">the processor context</param> /// <param name="container">the container element</param> public static void ApplyOpacity(IDictionary <String, String> cssProps, ProcessorContext context, IPropertyContainer container) { float?opacity = CssUtils.ParseFloat(cssProps.Get(CssConstants.OPACITY)); if (opacity != null) { container.SetProperty(Property.OPACITY, opacity); } }
/// <summary>Creates a skewX transformation.</summary> /// <param name="values">values of the transformation</param> /// <returns>AffineTransform for the skew operation</returns> private static AffineTransform CreateSkewXTransformation(IList <String> values) { if (values.Count != 1) { throw new SvgProcessingException(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); } double tan = Math.Tan(MathUtil.ToRadians((float)CssUtils.ParseFloat(values[0]))); //Differs from the notation in the PDF-spec for skews return(new AffineTransform(1, 0, tan, 1, 0, 0)); }
/// <summary>Evaluates the stop opacity of the specified stop color</summary> /// <returns>the stop opacity value specified in the stop color</returns> public virtual float GetStopOpacity() { float? result = null; String opacityValue = GetAttribute(SvgConstants.Tags.STOP_OPACITY); if (opacityValue != null && !SvgConstants.Values.NONE.EqualsIgnoreCase(opacityValue)) { result = CssUtils.ParseFloat(opacityValue); } return(result != null ? result.Value : 1f); }
/* (non-Javadoc) * @see com.itextpdf.html2pdf.css.resolve.HtmlStylesToCssConverter.IAttributeConverter#convert(com.itextpdf.styledxmlparser.html.node.IElementNode, java.lang.String) */ public virtual IList <CssDeclaration> Convert(IElementNode element, String value) { float?cellPadding = CssUtils.ParseFloat(value); if (cellPadding != null) { if (TagConstants.TABLE.Equals(element.Name())) { IDictionary <String, String> styles = new Dictionary <String, String>(); styles.Put(CssConstants.PADDING, value + "px"); ApplyPaddingsToTableCells(element, styles); } } return(JavaCollectionsUtil.EmptyList <CssDeclaration>()); }
/// <summary>Creates a rotate transformation.</summary> /// <param name="values">values of the transformation</param> /// <returns>AffineTransform for the rotate operation</returns> private static AffineTransform CreateRotationTransformation(IList <String> values) { if (values.Count != 1 && values.Count != 3) { throw new SvgProcessingException(SvgLogMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); } double angle = MathUtil.ToRadians((float)CssUtils.ParseFloat(values[0])); if (values.Count == 3) { float centerX = CssUtils.ParseAbsoluteLength(values[1]); float centerY = CssUtils.ParseAbsoluteLength(values[2]); return(AffineTransform.GetRotateInstance(angle, centerX, centerY)); } return(AffineTransform.GetRotateInstance(angle)); }
private static void SetLineHeight(IPropertyContainer elementToSet, String lineHeight, float em, float rem) { if (lineHeight != null && !CssConstants.NORMAL.Equals(lineHeight) && !CssConstants.AUTO.Equals(lineHeight) ) { if (CssUtils.IsNumericValue(lineHeight)) { float?number = CssUtils.ParseFloat(lineHeight); if (number != null) { elementToSet.SetProperty(Property.LINE_HEIGHT, LineHeight.CreateMultipliedValue((float)number)); } else { elementToSet.SetProperty(Property.LINE_HEIGHT, LineHeight.CreateNormalValue()); } } else { UnitValue lineHeightValue = CssUtils.ParseLengthValueToPt(lineHeight, em, rem); if (lineHeightValue != null && lineHeightValue.IsPointValue()) { elementToSet.SetProperty(Property.LINE_HEIGHT, LineHeight.CreateFixedValue(lineHeightValue.GetValue())); } else { if (lineHeightValue != null) { elementToSet.SetProperty(Property.LINE_HEIGHT, LineHeight.CreateMultipliedValue(lineHeightValue.GetValue() / 100f)); } else { elementToSet.SetProperty(Property.LINE_HEIGHT, LineHeight.CreateNormalValue()); } } } } else { elementToSet.SetProperty(Property.LINE_HEIGHT, LineHeight.CreateNormalValue()); } }
public override void SetCoordinates(String[] coordinates, Point startPoint) { if (coordinates.Length == 0 || coordinates.Length % 2 != 0) { throw new ArgumentException(MessageFormatUtil.Format(SvgExceptionMessageConstant.LINE_TO_EXPECTS_FOLLOWING_PARAMETERS_GOT_0 , JavaUtil.ArraysToString(coordinates))); } this.coordinates = new String[coordinates.Length / 2][]; double[] initialPoint = new double[] { startPoint.GetX(), startPoint.GetY() }; for (int i = 0; i < coordinates.Length; i += 2) { String[] curCoordinates = new String[] { coordinates[i], coordinates[i + 1] }; if (IsRelative()) { curCoordinates = SvgCoordinateUtils.MakeRelativeOperatorCoordinatesAbsolute(curCoordinates, initialPoint); initialPoint[0] = (float)CssUtils.ParseFloat(curCoordinates[0]); initialPoint[1] = (float)CssUtils.ParseFloat(curCoordinates[1]); } this.coordinates[i / 2] = curCoordinates; } }
private static void SetLineHeightByLeading(IPropertyContainer element, String lineHeight, float em, float rem) { // specification does not give auto as a possible lineHeight value // nevertheless some browsers compute it as normal so we apply the same behaviour. // What's more, it's basically the same thing as if lineHeight is not set in the first place if (lineHeight != null && !CssConstants.NORMAL.Equals(lineHeight) && !CssConstants.AUTO.Equals(lineHeight) ) { if (CssUtils.IsNumericValue(lineHeight)) { float?mult = CssUtils.ParseFloat(lineHeight); if (mult != null) { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, (float)mult)); } } else { UnitValue lineHeightValue = CssUtils.ParseLengthValueToPt(lineHeight, em, rem); if (lineHeightValue != null && lineHeightValue.IsPointValue()) { element.SetProperty(Property.LEADING, new Leading(Leading.FIXED, lineHeightValue.GetValue())); } else { if (lineHeightValue != null) { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, lineHeightValue.GetValue() / 100)); } } } } else { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, DEFAULT_LINE_HEIGHT)); } }
/* (non-Javadoc) * @see com.itextpdf.html2pdf.css.resolve.HtmlStylesToCssConverter.IAttributeConverter#convert(com.itextpdf.styledxmlparser.html.node.IElementNode, java.lang.String) */ public virtual IList <CssDeclaration> Convert(IElementNode element, String value) { float?width = CssUtils.ParseFloat(value); if (width != null) { if (TagConstants.TABLE.Equals(element.Name()) && width != 0) { IList <CssDeclaration> declarations = new BorderShorthandResolver().ResolveShorthand("1px solid"); IDictionary <String, String> styles = new Dictionary <String, String>(declarations.Count); foreach (CssDeclaration declaration in declarations) { styles.Put(declaration.GetProperty(), declaration.GetExpression()); } ApplyBordersToTableCells(element, styles); } if (width >= 0) { return(JavaUtil.ArraysAsList(new CssDeclaration(CssConstants.BORDER, value + "px solid"))); } } return(JavaCollectionsUtil.EmptyList <CssDeclaration>()); }
public virtual void NinetyDegreesTest() { AffineTransform expected = new AffineTransform(1d, 0d, Math.Tan(MathUtil.ToRadians((float)CssUtils.ParseFloat ("90"))), 1d, 0d, 0d); AffineTransform actual = TransformUtils.ParseTransform("skewX(90)"); NUnit.Framework.Assert.AreEqual(expected, actual); }
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]); } } } }
protected internal virtual Point CreatePoint(String coordX, String coordY) { return(new Point((float)CssUtils.ParseFloat(coordX), (float)CssUtils.ParseFloat(coordY))); }
/// <summary>Applies font styles to an element.</summary> /// <param name="cssProps">the CSS props</param> /// <param name="context">the processor context</param> /// <param name="stylesContainer">the styles container</param> /// <param name="element">the element</param> public static void ApplyFontStyles(IDictionary <String, String> cssProps, ProcessorContext context, IStylesContainer stylesContainer, IPropertyContainer element) { float em = CssUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); if (em != 0) { element.SetProperty(Property.FONT_SIZE, UnitValue.CreatePointValue(em)); } if (cssProps.Get(CssConstants.FONT_FAMILY) != null) { // TODO DEVSIX-2534 IList <String> fontFamilies = FontFamilySplitter.SplitFontFamily(cssProps.Get(CssConstants.FONT_FAMILY)); element.SetProperty(Property.FONT, fontFamilies.ToArray(new String[fontFamilies.Count])); } if (cssProps.Get(CssConstants.FONT_WEIGHT) != null) { element.SetProperty(Property.FONT_WEIGHT, cssProps.Get(CssConstants.FONT_WEIGHT)); } if (cssProps.Get(CssConstants.FONT_STYLE) != null) { element.SetProperty(Property.FONT_STYLE, cssProps.Get(CssConstants.FONT_STYLE)); } String cssColorPropValue = cssProps.Get(CssConstants.COLOR); if (cssColorPropValue != null) { TransparentColor transparentColor; if (!CssConstants.TRANSPARENT.Equals(cssColorPropValue)) { float[] rgbaColor = CssUtils.ParseRgbaColor(cssColorPropValue); Color color = new DeviceRgb(rgbaColor[0], rgbaColor[1], rgbaColor[2]); float opacity = rgbaColor[3]; transparentColor = new TransparentColor(color, opacity); } else { transparentColor = new TransparentColor(ColorConstants.BLACK, 0f); } element.SetProperty(Property.FONT_COLOR, transparentColor); } // Make sure to place that before text-align applier String direction = cssProps.Get(CssConstants.DIRECTION); if (CssConstants.RTL.Equals(direction)) { element.SetProperty(Property.BASE_DIRECTION, BaseDirection.RIGHT_TO_LEFT); element.SetProperty(Property.TEXT_ALIGNMENT, TextAlignment.RIGHT); } else { if (CssConstants.LTR.Equals(direction)) { element.SetProperty(Property.BASE_DIRECTION, BaseDirection.LEFT_TO_RIGHT); element.SetProperty(Property.TEXT_ALIGNMENT, TextAlignment.LEFT); } } if (stylesContainer is IElementNode && ((IElementNode)stylesContainer).ParentNode() is IElementNode && CssConstants .RTL.Equals(((IElementNode)((IElementNode)stylesContainer).ParentNode()).GetStyles().Get(CssConstants. DIRECTION)) && !element.HasProperty(Property.HORIZONTAL_ALIGNMENT)) { // We should only apply horizontal alignment if parent has dir attribute or direction property element.SetProperty(Property.HORIZONTAL_ALIGNMENT, HorizontalAlignment.RIGHT); } // Make sure to place that after direction applier String align = cssProps.Get(CssConstants.TEXT_ALIGN); if (CssConstants.LEFT.Equals(align)) { element.SetProperty(Property.TEXT_ALIGNMENT, TextAlignment.LEFT); } else { if (CssConstants.RIGHT.Equals(align)) { element.SetProperty(Property.TEXT_ALIGNMENT, TextAlignment.RIGHT); } else { if (CssConstants.CENTER.Equals(align)) { element.SetProperty(Property.TEXT_ALIGNMENT, TextAlignment.CENTER); } else { if (CssConstants.JUSTIFY.Equals(align)) { element.SetProperty(Property.TEXT_ALIGNMENT, TextAlignment.JUSTIFIED); element.SetProperty(Property.SPACING_RATIO, 1f); } } } } String whiteSpace = cssProps.Get(CssConstants.WHITE_SPACE); element.SetProperty(Property.NO_SOFT_WRAP_INLINE, CssConstants.NOWRAP.Equals(whiteSpace) || CssConstants.PRE .Equals(whiteSpace)); String textDecorationProp = cssProps.Get(CssConstants.TEXT_DECORATION); if (textDecorationProp != null) { String[] textDecorations = iText.IO.Util.StringUtil.Split(textDecorationProp, "\\s+"); IList <Underline> underlineList = new List <Underline>(); foreach (String textDecoration in textDecorations) { if (CssConstants.BLINK.Equals(textDecoration)) { logger.Error(iText.Html2pdf.LogMessageConstant.TEXT_DECORATION_BLINK_NOT_SUPPORTED); } else { if (CssConstants.LINE_THROUGH.Equals(textDecoration)) { underlineList.Add(new Underline(null, .75f, 0, 0, 1 / 4f, PdfCanvasConstants.LineCapStyle.BUTT)); } else { if (CssConstants.OVERLINE.Equals(textDecoration)) { underlineList.Add(new Underline(null, .75f, 0, 0, 9 / 10f, PdfCanvasConstants.LineCapStyle.BUTT)); } else { if (CssConstants.UNDERLINE.Equals(textDecoration)) { underlineList.Add(new Underline(null, .75f, 0, 0, -1 / 10f, PdfCanvasConstants.LineCapStyle.BUTT)); } else { if (CssConstants.NONE.Equals(textDecoration)) { underlineList = null; // if none and any other decoration are used together, none is displayed break; } } } } } } element.SetProperty(Property.UNDERLINE, underlineList); } String textIndent = cssProps.Get(CssConstants.TEXT_INDENT); if (textIndent != null) { UnitValue textIndentValue = CssUtils.ParseLengthValueToPt(textIndent, em, rem); if (textIndentValue != null) { if (textIndentValue.IsPointValue()) { element.SetProperty(Property.FIRST_LINE_INDENT, textIndentValue.GetValue()); } else { logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.CSS_PROPERTY_IN_PERCENTS_NOT_SUPPORTED , CssConstants.TEXT_INDENT)); } } } String letterSpacing = cssProps.Get(CssConstants.LETTER_SPACING); if (letterSpacing != null && !letterSpacing.Equals(CssConstants.NORMAL)) { UnitValue letterSpacingValue = CssUtils.ParseLengthValueToPt(letterSpacing, em, rem); if (letterSpacingValue.IsPointValue()) { element.SetProperty(Property.CHARACTER_SPACING, letterSpacingValue.GetValue()); } } // browsers ignore values in percents String wordSpacing = cssProps.Get(CssConstants.WORD_SPACING); if (wordSpacing != null) { UnitValue wordSpacingValue = CssUtils.ParseLengthValueToPt(wordSpacing, em, rem); if (wordSpacingValue != null) { if (wordSpacingValue.IsPointValue()) { element.SetProperty(Property.WORD_SPACING, wordSpacingValue.GetValue()); } } } // browsers ignore values in percents String lineHeight = cssProps.Get(CssConstants.LINE_HEIGHT); // specification does not give auto as a possible lineHeight value // nevertheless some browsers compute it as normal so we apply the same behaviour. // What's more, it's basically the same thing as if lineHeight is not set in the first place if (lineHeight != null && !CssConstants.NORMAL.Equals(lineHeight) && !CssConstants.AUTO.Equals(lineHeight) ) { if (CssUtils.IsNumericValue(lineHeight)) { float?mult = CssUtils.ParseFloat(lineHeight); if (mult != null) { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, (float)mult)); } } else { UnitValue lineHeightValue = CssUtils.ParseLengthValueToPt(lineHeight, em, rem); if (lineHeightValue != null && lineHeightValue.IsPointValue()) { element.SetProperty(Property.LEADING, new Leading(Leading.FIXED, lineHeightValue.GetValue())); } else { if (lineHeightValue != null) { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, lineHeightValue.GetValue() / 100)); } } } } else { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, 1.2f)); } }