private static void ApplyBackgroundPositionX(BackgroundPosition position, String xPosition, float em, float rem) { foreach (String value in iText.IO.Util.StringUtil.Split(xPosition, " ")) { switch (value) { case CommonCssConstants.LEFT: { position.SetPositionX(BackgroundPosition.PositionX.LEFT); break; } case CommonCssConstants.RIGHT: { position.SetPositionX(BackgroundPosition.PositionX.RIGHT); break; } case CommonCssConstants.CENTER: { position.SetPositionX(BackgroundPosition.PositionX.CENTER); break; } default: { UnitValue unitValue = CssUtils.ParseLengthValueToPt(value, em, rem); if (unitValue != null) { position.SetXShift(unitValue); } break; } } } }
/// <summary>Applies outlines to an element.</summary> /// <param name="cssProps">the CSS properties</param> /// <param name="context">the Processor context</param> /// <param name="element">the element</param> public static void ApplyOutlines(IDictionary <String, String> cssProps, ProcessorContext context, IPropertyContainer element) { float em = CssUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); Border outline = GetCertainBorder(cssProps.Get(CssConstants.OUTLINE_WIDTH), cssProps.Get(CssConstants.OUTLINE_STYLE ), GetSpecificOutlineColorOrDefaultColor(cssProps, CssConstants.OUTLINE_COLOR), em, rem); if (outline != null) { element.SetProperty(Property.OUTLINE, outline); } if (cssProps.Get(CssConstants.OUTLINE_OFFSET) != null && element.GetProperty <Border>(Property.OUTLINE) != null) { UnitValue unitValue = CssUtils.ParseLengthValueToPt(cssProps.Get(CssConstants.OUTLINE_OFFSET), em, rem); if (unitValue != null) { if (unitValue.IsPercentValue()) { LOGGER.Error("outline-width in percents is not supported"); } else { if (unitValue.GetValue() != 0) { element.SetProperty(Property.OUTLINE_OFFSET, unitValue.GetValue()); } } } } }
private static void ApplyBackgroundPositionY(BackgroundPosition position, String yPosition, float em, float rem) { foreach (String value in iText.IO.Util.StringUtil.Split(yPosition, " ")) { switch (value) { case CommonCssConstants.TOP: { position.SetPositionY(BackgroundPosition.PositionY.TOP); break; } case CommonCssConstants.BOTTOM: { position.SetPositionY(BackgroundPosition.PositionY.BOTTOM); break; } case CommonCssConstants.CENTER: { position.SetPositionY(BackgroundPosition.PositionY.CENTER); break; } default: { UnitValue unitValue = CssUtils.ParseLengthValueToPt(value, em, rem); if (unitValue != null) { position.SetYShift(unitValue); } break; } } } }
/* (non-Javadoc) * @see com.itextpdf.html2pdf.css.apply.impl.BlockCssApplier#apply(com.itextpdf.html2pdf.attach.ProcessorContext, com.itextpdf.html2pdf.html.node.IStylesContainer, com.itextpdf.html2pdf.attach.ITagWorker) */ public override void Apply(ProcessorContext context, IStylesContainer stylesContainer, ITagWorker tagWorker ) { if (!(tagWorker.GetElementResult() is List)) { return; } IDictionary <String, String> css = stylesContainer.GetStyles(); List list = (List)tagWorker.GetElementResult(); if (CssConstants.INSIDE.Equals(css.Get(CssConstants.LIST_STYLE_POSITION))) { list.SetProperty(Property.LIST_SYMBOL_POSITION, ListSymbolPosition.INSIDE); } else { list.SetProperty(Property.LIST_SYMBOL_POSITION, ListSymbolPosition.OUTSIDE); } ListStyleApplierUtil.ApplyListStyleTypeProperty(stylesContainer, css, context, list); ListStyleApplierUtil.ApplyListStyleImageProperty(css, context, list); base.Apply(context, stylesContainer, tagWorker); // process the padding considering the direction bool isRtl = BaseDirection.RIGHT_TO_LEFT.Equals(list.GetProperty <BaseDirection?>(Property.BASE_DIRECTION)); if ((isRtl && !list.HasProperty(Property.PADDING_RIGHT)) || (!isRtl && !list.HasProperty(Property.PADDING_LEFT ))) { float em = CssUtils.ParseAbsoluteLength(css.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); UnitValue startPadding = CssUtils.ParseLengthValueToPt(css.Get(CssConstants.PADDING_INLINE_START), em, rem ); list.SetProperty(isRtl ? Property.PADDING_RIGHT : Property.PADDING_LEFT, startPadding); } }
/// <summary>Gets the array that defines the borders.</summary> /// <param name="styles">the styles mapping</param> /// <param name="em">the em value</param> /// <param name="rem">the root em value</param> /// <returns>the borders array</returns> public static BorderRadius[] GetBorderRadiiArray(IDictionary <String, String> styles, float em, float rem) { BorderRadius[] borderRadii = new BorderRadius[4]; BorderRadius borderRadius = null; UnitValue borderRadiusUV = CssUtils.ParseLengthValueToPt(styles.Get(CssConstants.BORDER_RADIUS), em, rem); if (null != borderRadiusUV) { borderRadius = new BorderRadius(borderRadiusUV); } UnitValue[] borderTopLeftRadiusUV = CssUtils.ParseSpecificCornerBorderRadius(styles.Get(CssConstants.BORDER_TOP_LEFT_RADIUS ), em, rem); borderRadii[0] = null == borderTopLeftRadiusUV ? borderRadius : new BorderRadius(borderTopLeftRadiusUV[0], borderTopLeftRadiusUV[1]); UnitValue[] borderTopRightRadiusUV = CssUtils.ParseSpecificCornerBorderRadius(styles.Get(CssConstants.BORDER_TOP_RIGHT_RADIUS ), em, rem); borderRadii[1] = null == borderTopRightRadiusUV ? borderRadius : new BorderRadius(borderTopRightRadiusUV[0 ], borderTopRightRadiusUV[1]); UnitValue[] borderBottomRightRadiusUV = CssUtils.ParseSpecificCornerBorderRadius(styles.Get(CssConstants.BORDER_BOTTOM_RIGHT_RADIUS ), em, rem); borderRadii[2] = null == borderBottomRightRadiusUV ? borderRadius : new BorderRadius(borderBottomRightRadiusUV [0], borderBottomRightRadiusUV[1]); UnitValue[] borderBottomLeftRadiusUV = CssUtils.ParseSpecificCornerBorderRadius(styles.Get(CssConstants.BORDER_BOTTOM_LEFT_RADIUS ), em, rem); borderRadii[3] = null == borderBottomLeftRadiusUV ? borderRadius : new BorderRadius(borderBottomLeftRadiusUV [0], borderBottomLeftRadiusUV[1]); return(borderRadii); }
/*TODO Note: visibility doesn't work on "chrome" or "safari" and though it technically works on "firefox" and "edge" the results differ, * with "edge" surprisingly giving the closest result to expected one. * The supported values are 'collapse' and 'visible'. The expected behaviour for 'collapse' is not to render those cols * (the table layout should change ann the width should be diminished), and to clip cells that are spaned to none-collapsed one. * The state of the content in clipped cells is not specified*/ /// <summary>Gets the width.</summary> /// <param name="resolvedCssProps">the resolved CSS properties</param> /// <param name="context">the processor context</param> /// <returns>the width</returns> public static UnitValue GetWidth(IDictionary <String, String> resolvedCssProps, ProcessorContext context) { //The Width is a special case, casue it should be transferred from <colgroup> to <col> but it not applied to <td> or <th> float em = CssUtils.ParseAbsoluteLength(resolvedCssProps.Get(CssConstants.FONT_SIZE)); String width = resolvedCssProps.Get(CssConstants.WIDTH); return(width != null?CssUtils.ParseLengthValueToPt(width, em, context.GetCssContext().GetRootFontSize()) : null); }
/// <summary>Try to parse a page length value.</summary> /// <param name="valueChunk">a string containing a value</param> /// <param name="em">the em value</param> /// <param name="rem">the root em value</param> /// <returns>the value as a float</returns> private static float?TryParsePageLengthValue(String valueChunk, float em, float rem) { UnitValue unitValue = CssUtils.ParseLengthValueToPt(valueChunk, em, rem); if (unitValue == null || unitValue.IsPercentValue()) { return(null); } return(unitValue.GetValue()); }
internal virtual float ParseDimension(CssContextNode node, String content, float maxAvailableDimension, float additionalWidthFix) { float fontSize = FontStyleApplierUtil.ParseAbsoluteFontSize(node.GetStyles().Get(CssConstants.FONT_SIZE)); UnitValue unitValue = CssUtils.ParseLengthValueToPt(content, fontSize, 0); if (unitValue == null) { return(0); } if (unitValue.IsPointValue()) { return(unitValue.GetValue() + additionalWidthFix); } return(maxAvailableDimension * unitValue.GetValue() / 100f); }
private static void ApplyBackgroundWidth(String widthValue, BackgroundImage image, float em, float rem) { if (CommonCssConstants.BACKGROUND_SIZE_VALUES.Contains(widthValue)) { if (widthValue.Equals(CommonCssConstants.CONTAIN)) { image.GetBackgroundSize().SetBackgroundSizeToContain(); } if (widthValue.Equals(CommonCssConstants.COVER)) { image.GetBackgroundSize().SetBackgroundSizeToCover(); } return; } image.GetBackgroundSize().SetBackgroundSizeToValues(CssUtils.ParseLengthValueToPt(widthValue, em, rem), null ); }
/// <summary>Parses the box value.</summary> /// <param name="em">a measurement expressed in em</param> /// <param name="rem">a measurement expressed in rem (root em)</param> /// <param name="dimensionSize">the dimension size</param> /// <returns>a float value</returns> private static float?ParseBoxValue(String valString, float em, float rem, float dimensionSize) { UnitValue marginUnitVal = CssUtils.ParseLengthValueToPt(valString, em, rem); if (marginUnitVal != null) { if (marginUnitVal.IsPointValue()) { return(marginUnitVal.GetValue()); } if (marginUnitVal.IsPercentValue()) { return(marginUnitVal.GetValue() * dimensionSize / 100); } } return(null); }
/// <summary>Applies the "bottom" property.</summary> /// <param name="cssProps">the CSS properties</param> /// <param name="element">the element</param> /// <param name="em">the em value</param> /// <param name="rem">the root em value</param> /// <param name="layoutPropertyMapping">the layout property mapping</param> private static void ApplyBottomProperty(IDictionary <String, String> cssProps, IPropertyContainer element, float em, float rem, int layoutPropertyMapping) { String bottom = cssProps.Get(CssConstants.BOTTOM); UnitValue bottomVal = CssUtils.ParseLengthValueToPt(bottom, em, rem); if (bottomVal != null) { if (bottomVal.IsPointValue()) { element.SetProperty(layoutPropertyMapping, bottomVal.GetValue()); } else { logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.CSS_PROPERTY_IN_PERCENTS_NOT_SUPPORTED , CssConstants.BOTTOM)); } } }
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()); } }
private static void ApplyBackgroundWidthHeight(IList <String> backgroundSizeValues, BackgroundImage image, float em, float rem) { String widthValue = backgroundSizeValues[0]; if (CommonCssConstants.BACKGROUND_SIZE_VALUES.Contains(widthValue)) { if (widthValue.Equals(CommonCssConstants.AUTO)) { UnitValue height = CssUtils.ParseLengthValueToPt(backgroundSizeValues[1], em, rem); if (height != null) { image.GetBackgroundSize().SetBackgroundSizeToValues(null, height); } } return; } image.GetBackgroundSize().SetBackgroundSizeToValues(CssUtils.ParseLengthValueToPt(backgroundSizeValues[0], em, rem), CssUtils.ParseLengthValueToPt(backgroundSizeValues[1], em, rem)); }
/// <summary>Parses the margin value.</summary> /// <param name="marginValString"> /// the margin value as a /// <see cref="System.String"/> /// </param> /// <param name="em">the em value</param> /// <param name="rem">the root em value</param> /// <param name="baseValue">value used my default</param> /// <returns> /// the margin value as a /// <see cref="float?"/> /// </returns> private static float?ParseMarginValue(String marginValString, float em, float rem, float baseValue) { UnitValue marginUnitVal = CssUtils.ParseLengthValueToPt(marginValString, em, rem); if (marginUnitVal != null) { if (!marginUnitVal.IsPointValue()) { if (baseValue != 0.0f) { return(System.Convert.ToSingle(baseValue * marginUnitVal.GetValue() * 0.01)); } logger.Error(iText.Html2pdf.LogMessageConstant.MARGIN_VALUE_IN_PERCENT_NOT_SUPPORTED); return(null); } return(marginUnitVal.GetValue()); } else { return(null); } }
/// <summary> /// Re-initializes page context processor based on default current page size and page margins /// and on properties from css page at-rules. /// </summary> /// <remarks> /// Re-initializes page context processor based on default current page size and page margins /// and on properties from css page at-rules. Css properties priority is higher than default document values. /// </remarks> /// <param name="defaultPageSize">current default page size to be used if it is not defined in css</param> /// <param name="defaultPageMargins">current default page margins to be used if they are not defined in css</param> /// <returns> /// this /// <see cref="PageContextProcessor"/> /// instance /// </returns> internal virtual iText.Html2pdf.Attach.Impl.Layout.PageContextProcessor Reset(PageSize defaultPageSize, float [] defaultPageMargins) { IDictionary <String, String> styles = properties.GetResolvedPageContextNode().GetStyles(); float em = CssUtils.ParseAbsoluteLength(styles.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); pageSize = PageSizeParser.FetchPageSize(styles.Get(CssConstants.SIZE), em, rem, defaultPageSize); UnitValue bleedValue = CssUtils.ParseLengthValueToPt(styles.Get(CssConstants.BLEED), em, rem); if (bleedValue != null && bleedValue.IsPointValue()) { bleed = bleedValue.GetValue(); } marks = ParseMarks(styles.Get(CssConstants.MARKS)); ParseMargins(styles, em, rem, defaultPageMargins); ParseBorders(styles, em, rem); ParsePaddings(styles, em, rem); CreatePageSimulationElements(styles, context); PrepareMarginBoxesSizing(properties.GetResolvedPageMarginBoxes()); return(this); }
/// <summary>Parse absolute length.</summary> /// <param name="length"> /// /// <see cref="System.String"/> /// for parsing /// </param> /// <param name="percentRelativeValue">the value on which percent length is based on</param> /// <param name="defaultValue">default value if length is not recognized</param> /// <param name="context"> /// current /// <see cref="iText.Svg.Renderers.SvgDrawContext"/> /// </param> /// <returns>absolute value in points</returns> protected internal virtual float ParseAbsoluteLength(String length, float percentRelativeValue, float defaultValue , SvgDrawContext context) { if (CssUtils.IsPercentageValue(length)) { return(CssUtils.ParseRelativeValue(length, percentRelativeValue)); } else { float em = GetCurrentFontSize(); float rem = context.GetRemValue(); UnitValue unitValue = CssUtils.ParseLengthValueToPt(length, em, rem); if (unitValue != null && unitValue.IsPointValue()) { return(unitValue.GetValue()); } else { return(defaultValue); } } }
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)); } }
/// <summary>Gets the actual value of the line height.</summary> /// <param name="fontSize">the font size</param> /// <param name="rootFontSize">the root font size</param> /// <param name="lineHeightStr"> /// the line height as a /// <see cref="System.String"/> /// </param> /// <returns> /// the actual line height as a /// <c>float</c> /// </returns> private static float GetLineHeightActualValue(float fontSize, float rootFontSize, String lineHeightStr) { float lineHeightActualValue; if (lineHeightStr != null) { if (CssConstants.NORMAL.Equals(lineHeightStr) || CssConstants.AUTO.Equals(lineHeightStr)) { lineHeightActualValue = (float)(fontSize * 1.2); } else { UnitValue lineHeightValue = CssUtils.ParseLengthValueToPt(lineHeightStr, fontSize, rootFontSize); if (CssUtils.IsNumericValue(lineHeightStr)) { lineHeightActualValue = fontSize * lineHeightValue.GetValue(); } else { if (lineHeightValue.IsPointValue()) { lineHeightActualValue = lineHeightValue.GetValue(); } else { lineHeightActualValue = fontSize * lineHeightValue.GetValue() / 100; } } } } else { lineHeightActualValue = (float)(fontSize * 1.2); } return(lineHeightActualValue); }
private double GetCoordinateForUserSpaceOnUse(String attributeName, double defaultValue, double start, double length, float em, float rem) { String attributeValue = GetAttribute(attributeName); double absoluteValue; UnitValue unitValue = CssUtils.ParseLengthValueToPt(attributeValue, em, rem); if (unitValue == null) { absoluteValue = defaultValue; } else { if (unitValue.GetUnitType() == UnitValue.PERCENT) { absoluteValue = start + (length * unitValue.GetValue() / 100); } else { absoluteValue = unitValue.GetValue(); } } return(absoluteValue); }
/// <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)); float[] colors = new float[4]; Color textDecorationColor; float opacity_1 = 1f; String textDecorationColorProp = cssProps.Get(CssConstants.TEXT_DECORATION_COLOR); if (textDecorationColorProp == null || CssConstants.CURRENTCOLOR.Equals(textDecorationColorProp)) { if (element.GetProperty <TransparentColor>(Property.FONT_COLOR) != null) { TransparentColor transparentColor = element.GetProperty <TransparentColor>(Property.FONT_COLOR); textDecorationColor = transparentColor.GetColor(); opacity_1 = transparentColor.GetOpacity(); } else { textDecorationColor = ColorConstants.BLACK; } } else { if (textDecorationColorProp.StartsWith("hsl")) { logger.Error(iText.Html2pdf.LogMessageConstant.HSL_COLOR_NOT_SUPPORTED); textDecorationColor = ColorConstants.BLACK; } else { colors = CssUtils.ParseRgbaColor(textDecorationColorProp); textDecorationColor = new DeviceRgb(colors[0], colors[1], colors[2]); opacity_1 = colors[3]; } } String textDecorationLineProp = cssProps.Get(CssConstants.TEXT_DECORATION_LINE); if (textDecorationLineProp != null) { String[] textDecorationLines = iText.IO.Util.StringUtil.Split(textDecorationLineProp, "\\s+"); IList <Underline> underlineList = new List <Underline>(); foreach (String textDecorationLine in textDecorationLines) { if (CssConstants.BLINK.Equals(textDecorationLine)) { logger.Error(iText.Html2pdf.LogMessageConstant.TEXT_DECORATION_BLINK_NOT_SUPPORTED); } else { if (CssConstants.LINE_THROUGH.Equals(textDecorationLine)) { underlineList.Add(new Underline(textDecorationColor, opacity_1, .75f, 0, 0, 1 / 4f, PdfCanvasConstants.LineCapStyle .BUTT)); } else { if (CssConstants.OVERLINE.Equals(textDecorationLine)) { underlineList.Add(new Underline(textDecorationColor, opacity_1, .75f, 0, 0, 9 / 10f, PdfCanvasConstants.LineCapStyle .BUTT)); } else { if (CssConstants.UNDERLINE.Equals(textDecorationLine)) { underlineList.Add(new Underline(textDecorationColor, opacity_1, .75f, 0, 0, -1 / 10f, PdfCanvasConstants.LineCapStyle .BUTT)); } else { if (CssConstants.NONE.Equals(textDecorationLine)) { 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 && !CssConstants.NORMAL.Equals(letterSpacing)) { 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); SetLineHeight(element, lineHeight, em, rem); SetLineHeightByLeading(element, lineHeight, em, rem); }
/// <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)); } }
public static UnitValue GetBorderRadius(IDictionary <String, String> styles, float em, float rem) { String borderRadius = styles.Get(CssConstants.BORDER_RADIUS); return(CssUtils.ParseLengthValueToPt(borderRadius, em, rem)); }
/// <summary>Applies a width or a height to an element.</summary> /// <param name="cssProps">the CSS properties</param> /// <param name="context">the processor context</param> /// <param name="element">the element</param> public static void ApplyWidthHeight(IDictionary <String, String> cssProps, ProcessorContext context, IPropertyContainer element) { float em = CssUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); String widthVal = cssProps.Get(CssConstants.WIDTH); if (!CssConstants.AUTO.Equals(widthVal) && widthVal != null) { UnitValue width = CssUtils.ParseLengthValueToPt(widthVal, em, rem); element.SetProperty(Property.WIDTH, width); } String minWidthVal = cssProps.Get(CssConstants.MIN_WIDTH); if (!CssConstants.AUTO.Equals(minWidthVal) && minWidthVal != null) { UnitValue minWidth = CssUtils.ParseLengthValueToPt(minWidthVal, em, rem); element.SetProperty(Property.MIN_WIDTH, minWidth); } String maxWidthVal = cssProps.Get(CssConstants.MAX_WIDTH); if (!CssConstants.AUTO.Equals(maxWidthVal) && maxWidthVal != null) { UnitValue maxWidth = CssUtils.ParseLengthValueToPt(maxWidthVal, em, rem); element.SetProperty(Property.MAX_WIDTH, maxWidth); } // TODO consider display css property bool applyToTable = element is Table; bool applyToCell = element is Cell; UnitValue height = null; String heightVal = cssProps.Get(CssConstants.HEIGHT); if (heightVal != null) { if (!CssConstants.AUTO.Equals(heightVal)) { height = CssUtils.ParseLengthValueToPt(heightVal, em, rem); if (height != null) { // For tables, height does not have any effect. The height value will be used when // calculating effective min height value below if (!applyToTable && !applyToCell) { element.SetProperty(Property.HEIGHT, height); } } } } String maxHeightVal = cssProps.Get(CssConstants.MAX_HEIGHT); float maxHeightToApply = 0; UnitValue maxHeight = new UnitValue(UnitValue.POINT, 0); if (maxHeightVal != null) { maxHeight = CssUtils.ParseLengthValueToPt(maxHeightVal, em, rem); if (maxHeight != null) { // For tables and cells, max height does not have any effect. See also comments below when MIN_HEIGHT is applied. if (!applyToTable && !applyToCell) { maxHeightToApply = maxHeight.GetValue(); } } } if (maxHeightToApply > 0) { element.SetProperty(Property.MAX_HEIGHT, maxHeight); } String minHeightVal = cssProps.Get(CssConstants.MIN_HEIGHT); float minHeightToApply = 0; UnitValue minHeight = new UnitValue(UnitValue.POINT, 0); if (minHeightVal != null) { minHeight = CssUtils.ParseLengthValueToPt(minHeightVal, em, rem); if (minHeight != null) { // For cells, min height does not have any effect. See also comments below when MIN_HEIGHT is applied. if (!applyToCell) { minHeightToApply = minHeight.GetValue(); } } } // About tables: // The height of a table is given by the 'height' property for the 'table' or 'inline-table' element. // A value of 'auto' means that the height is the sum of the row heights plus any cell spacing or borders. // Any other value is treated as a minimum height. CSS 2.1 does not define how extra space is distributed when // the 'height' property causes the table to be taller than it otherwise would be. // About cells: // The height of a 'table-row' element's box is the maximum of the row's computed 'height', the computed 'height' of each cell in the row, // and the minimum height (MIN) required by the cells. MIN depends on cell box heights and cell box alignment. // In CSS 2.1, the height of a cell box is the minimum height required by the content. if ((applyToTable || applyToCell) && height != null && height.GetValue() > minHeightToApply) { minHeightToApply = height.GetValue(); if (minHeightToApply > 0) { element.SetProperty(Property.MIN_HEIGHT, height); } } else { if (minHeightToApply > 0) { element.SetProperty(Property.MIN_HEIGHT, minHeight); } } if (CssConstants.BORDER_BOX.Equals(cssProps.Get(CssConstants.BOX_SIZING))) { element.SetProperty(Property.BOX_SIZING, BoxSizingPropertyValue.BORDER_BOX); } }
/// <summary> /// Creates a /// <see cref="iText.Layout.Borders.Border"/> /// instance based on specific properties. /// </summary> /// <param name="outlineWidth">the outline width</param> /// <param name="outlineStyle">the outline style</param> /// <param name="outlineColor">the outline color</param> /// <param name="em">the em value</param> /// <param name="rem">the root em value</param> /// <returns>the border</returns> public static Border GetCertainBorder(String outlineWidth, String outlineStyle, String outlineColor, float em, float rem) { if (outlineStyle == null || CssConstants.NONE.Equals(outlineStyle)) { return(null); } if (outlineWidth == null) { outlineWidth = CssDefaults.GetDefaultValue(CssConstants.OUTLINE_WIDTH); } float outlineWidthValue; if (CssConstants.BORDER_WIDTH_VALUES.Contains(outlineWidth)) { if (CssConstants.THIN.Equals(outlineWidth)) { outlineWidth = "1px"; } else { if (CssConstants.MEDIUM.Equals(outlineWidth)) { outlineWidth = "2px"; } else { if (CssConstants.THICK.Equals(outlineWidth)) { outlineWidth = "3px"; } } } } UnitValue unitValue = CssUtils.ParseLengthValueToPt(outlineWidth, em, rem); if (unitValue == null) { return(null); } if (unitValue.IsPercentValue()) { LOGGER.Error("outline-width in percents is not supported"); return(null); } outlineWidthValue = unitValue.GetValue(); Border outline = null; if (outlineWidthValue > 0) { DeviceRgb color = (DeviceRgb)ColorConstants.BLACK; float opacity = 1f; if (outlineColor != null) { if (!CssConstants.TRANSPARENT.Equals(outlineColor)) { float[] rgbaColor = CssUtils.ParseRgbaColor(outlineColor); color = new DeviceRgb(rgbaColor[0], rgbaColor[1], rgbaColor[2]); opacity = rgbaColor[3]; } else { opacity = 0f; } } else { if (CssConstants.GROOVE.Equals(outlineStyle) || CssConstants.RIDGE.Equals(outlineStyle) || CssConstants.INSET .Equals(outlineStyle) || CssConstants.OUTSET.Equals(outlineStyle)) { color = new DeviceRgb(212, 208, 200); } } switch (outlineStyle) { case CssConstants.SOLID: case CssConstants.AUTO: { outline = new SolidBorder(color, outlineWidthValue, opacity); break; } case CssConstants.DASHED: { outline = new DashedBorder(color, outlineWidthValue, opacity); break; } case CssConstants.DOTTED: { outline = new DottedBorder(color, outlineWidthValue, opacity); break; } case CssConstants.DOUBLE: { outline = new DoubleBorder(color, outlineWidthValue, opacity); break; } case CssConstants.GROOVE: { outline = new GrooveBorder(color, outlineWidthValue, opacity); break; } case CssConstants.RIDGE: { outline = new RidgeBorder(color, outlineWidthValue, opacity); break; } case CssConstants.INSET: { outline = new InsetBorder(color, outlineWidthValue, opacity); break; } case CssConstants.OUTSET: { outline = new OutsetBorder(color, outlineWidthValue, opacity); break; } default: { outline = null; break; } } } return(outline); }
/// <summary>Applies paddings to an element.</summary> /// <param name="cssProps">the CSS properties</param> /// <param name="context">the processor context</param> /// <param name="element">the element</param> /// <param name="baseValueHorizontal">value used by default for horizontal dimension</param> /// <param name="baseValueVertical">value used by default for vertical dimension</param> public static void ApplyPaddings(IDictionary <String, String> cssProps, ProcessorContext context, IPropertyContainer element, float baseValueVertical, float baseValueHorizontal) { String paddingTop = cssProps.Get(CssConstants.PADDING_TOP); String paddingBottom = cssProps.Get(CssConstants.PADDING_BOTTOM); String paddingLeft = cssProps.Get(CssConstants.PADDING_LEFT); String paddingRight = cssProps.Get(CssConstants.PADDING_RIGHT); float em = CssUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); UnitValue paddingTopVal = CssUtils.ParseLengthValueToPt(paddingTop, em, rem); UnitValue paddingBottomVal = CssUtils.ParseLengthValueToPt(paddingBottom, em, rem); UnitValue paddingLeftVal = CssUtils.ParseLengthValueToPt(paddingLeft, em, rem); UnitValue paddingRightVal = CssUtils.ParseLengthValueToPt(paddingRight, em, rem); if (paddingTopVal != null) { if (paddingTopVal.IsPointValue()) { element.SetProperty(Property.PADDING_TOP, paddingTopVal); } else { if (baseValueVertical != 0.0f) { element.SetProperty(Property.PADDING_TOP, new UnitValue(UnitValue.POINT, baseValueVertical * paddingTopVal .GetValue() * 0.01f)); } else { logger.Error(iText.Html2pdf.LogMessageConstant.PADDING_VALUE_IN_PERCENT_NOT_SUPPORTED); } } } if (paddingBottomVal != null) { if (paddingBottomVal.IsPointValue()) { element.SetProperty(Property.PADDING_BOTTOM, paddingBottomVal); } else { if (baseValueVertical != 0.0f) { element.SetProperty(Property.PADDING_BOTTOM, new UnitValue(UnitValue.POINT, baseValueVertical * paddingBottomVal .GetValue() * 0.01f)); } else { logger.Error(iText.Html2pdf.LogMessageConstant.PADDING_VALUE_IN_PERCENT_NOT_SUPPORTED); } } } if (paddingLeftVal != null) { if (paddingLeftVal.IsPointValue()) { element.SetProperty(Property.PADDING_LEFT, paddingLeftVal); } else { if (baseValueHorizontal != 0.0f) { element.SetProperty(Property.PADDING_LEFT, new UnitValue(UnitValue.POINT, baseValueHorizontal * paddingLeftVal .GetValue() * 0.01f)); } else { logger.Error(iText.Html2pdf.LogMessageConstant.PADDING_VALUE_IN_PERCENT_NOT_SUPPORTED); } } } if (paddingRightVal != null) { if (paddingRightVal.IsPointValue()) { element.SetProperty(Property.PADDING_RIGHT, paddingRightVal); } else { if (baseValueHorizontal != 0.0f) { element.SetProperty(Property.PADDING_RIGHT, new UnitValue(UnitValue.POINT, baseValueHorizontal * paddingRightVal .GetValue() * 0.01f)); } else { logger.Error(iText.Html2pdf.LogMessageConstant.PADDING_VALUE_IN_PERCENT_NOT_SUPPORTED); } } } }