/* (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) { // Trim semicolons at the end because they seem to not affect the value in browsers String cssEquivalent = iText.IO.Util.StringUtil.ReplaceAll(value, ";+$", ""); if (!CssTypesValidationUtils.IsMetricValue(cssEquivalent) && !cssEquivalent.EndsWith(CssConstants.PERCENTAGE )) { cssEquivalent += CssConstants.PX; } return(JavaUtil.ArraysAsList(new CssDeclaration(CssConstants.HEIGHT, cssEquivalent))); }
private static void SetLineHeight(IPropertyContainer elementToSet, String lineHeight, float em, float rem) { if (lineHeight != null && !CssConstants.NORMAL.Equals(lineHeight) && !CssConstants.AUTO.Equals(lineHeight) ) { if (CssTypesValidationUtils.IsNumericValue(lineHeight)) { float?number = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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 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 (CssTypesValidationUtils.IsNumericValue(lineHeight)) { float?mult = CssDimensionParsingUtils.ParseFloat(lineHeight); if (mult != null) { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, (float)mult)); } } else { UnitValue lineHeightValue = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.ParseLengthValueToPt(lineHeightStr, fontSize, rootFontSize ); if (CssTypesValidationUtils.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); }
/// <summary>Apply vertical alignment to inline elements.</summary> /// <param name="cssProps">the CSS properties</param> /// <param name="context">the processor context</param> /// <param name="stylesContainer">the styles container</param> /// <param name="childElements">the child elements</param> public static void ApplyVerticalAlignmentForInlines(IDictionary <String, String> cssProps, ProcessorContext context, IStylesContainer stylesContainer, IList <IPropertyContainer> childElements) { String vAlignVal = cssProps.Get(CssConstants.VERTICAL_ALIGN); if (vAlignVal != null) { // TODO DEVSIX-1750 for inline images and tables (inline-blocks) v-align is not supported float textRise = 0; // TODO DEVSIX-3757 'top' and 'bottom' values are not supported; // 'top' and 'bottom' require information of actual line height, therefore should be applied at layout level; // 'sub', 'super' calculations are based on the behaviour of the common browsers (+33% and -20% shift accordingly from the parent's font size); // 'middle', 'text-top', 'text-bottom' calculations are based on the approximate assumptions that x-height is 0.5 of the font size // and descender and ascender heights are 0.2 and 0.8 of the font size accordingly. if (CssConstants.SUB.Equals(vAlignVal) || CssConstants.SUPER.Equals(vAlignVal)) { textRise = CalcTextRiseForSupSub(stylesContainer, vAlignVal); } else { if (CssConstants.MIDDLE.Equals(vAlignVal)) { textRise = CalcTextRiseForMiddle(stylesContainer); } else { if (CssConstants.TEXT_TOP.Equals(vAlignVal)) { textRise = CalcTextRiseForTextTop(stylesContainer, context.GetCssContext().GetRootFontSize()); } else { if (CssConstants.TEXT_BOTTOM.Equals(vAlignVal)) { textRise = CalcTextRiseForTextBottom(stylesContainer, context.GetCssContext().GetRootFontSize()); } else { if (CssTypesValidationUtils.IsMetricValue(vAlignVal)) { textRise = CssDimensionParsingUtils.ParseAbsoluteLength(vAlignVal); } else { if (vAlignVal.EndsWith(CssConstants.PERCENTAGE)) { textRise = CalcTextRiseForPercentageValue(stylesContainer, context.GetCssContext().GetRootFontSize(), vAlignVal ); } } } } } } if (textRise != 0) { foreach (IPropertyContainer element in childElements) { if (element is Text) { float?effectiveTr = element.GetProperty <float?>(Property.TEXT_RISE); if (effectiveTr != null) { effectiveTr += textRise; } else { effectiveTr = textRise; } element.SetProperty(Property.TEXT_RISE, effectiveTr); } else { if (element is IBlockElement) { break; } } } } } }
/// <summary>Checks if a string represents length value.</summary> /// <param name="pageSizeChunk">the string that possibly represents a length value</param> /// <returns>true, if the string represents a length value</returns> private static bool IsLengthValue(String pageSizeChunk) { return(CssTypesValidationUtils.IsMetricValue(pageSizeChunk) || CssTypesValidationUtils.IsRelativeValue(pageSizeChunk )); }
/* (non-Javadoc) * @see com.itextpdf.html2pdf.css.resolve.ICssResolver#resolveStyles(com.itextpdf.html2pdf.html.node.INode, com.itextpdf.html2pdf.css.resolve.CssContext) */ private IDictionary <String, String> ResolveStyles(INode element, CssContext context) { IDictionary <String, String> elementStyles = ResolveElementsStyles(element); if (CssConstants.CURRENTCOLOR.Equals(elementStyles.Get(CssConstants.COLOR))) { // css-color-3/#currentcolor: // If the ‘currentColor’ keyword is set on the ‘color’ property itself, it is treated as ‘color: inherit’. elementStyles.Put(CssConstants.COLOR, CssConstants.INHERIT); } String parentFontSizeStr = null; if (element.ParentNode() is IStylesContainer) { IStylesContainer parentNode = (IStylesContainer)element.ParentNode(); IDictionary <String, String> parentStyles = parentNode.GetStyles(); if (parentStyles == null && !(element.ParentNode() is IDocumentNode)) { ILog logger = LogManager.GetLogger(typeof(iText.Html2pdf.Css.Resolve.DefaultCssResolver)); logger.Error(iText.Html2pdf.LogMessageConstant.ERROR_RESOLVING_PARENT_STYLES); } if (parentStyles != null) { ICollection <IStyleInheritance> inheritanceRules = new HashSet <IStyleInheritance>(); inheritanceRules.Add(cssInheritance); foreach (KeyValuePair <String, String> entry in parentStyles) { elementStyles = StyleUtil.MergeParentStyleDeclaration(elementStyles, entry.Key, entry.Value, parentStyles. Get(CommonCssConstants.FONT_SIZE), inheritanceRules); } parentFontSizeStr = parentStyles.Get(CssConstants.FONT_SIZE); } } String elementFontSize = elementStyles.Get(CssConstants.FONT_SIZE); if (CssTypesValidationUtils.IsRelativeValue(elementFontSize) || CssConstants.LARGER.Equals(elementFontSize ) || CssConstants.SMALLER.Equals(elementFontSize)) { float baseFontSize; if (CssTypesValidationUtils.IsRemValue(elementFontSize)) { baseFontSize = context.GetRootFontSize(); } else { if (parentFontSizeStr == null) { baseFontSize = CssDimensionParsingUtils.ParseAbsoluteFontSize(CssDefaults.GetDefaultValue(CssConstants.FONT_SIZE )); } else { baseFontSize = CssDimensionParsingUtils.ParseAbsoluteLength(parentFontSizeStr); } } float absoluteFontSize = CssDimensionParsingUtils.ParseRelativeFontSize(elementFontSize, baseFontSize); // Format to 4 decimal places to prevent differences between Java and C# elementStyles.Put(CssConstants.FONT_SIZE, DecimalFormatUtil.FormatNumber(absoluteFontSize, "0.####") + CssConstants .PT); } else { elementStyles.Put(CssConstants.FONT_SIZE, Convert.ToString(CssDimensionParsingUtils.ParseAbsoluteFontSize( elementFontSize), System.Globalization.CultureInfo.InvariantCulture) + CssConstants.PT); } // Update root font size if (element is IElementNode && TagConstants.HTML.Equals(((IElementNode)element).Name())) { context.SetRootFontSize(elementStyles.Get(CssConstants.FONT_SIZE)); } ICollection <String> keys = new HashSet <String>(); foreach (KeyValuePair <String, String> entry in elementStyles) { if (CssConstants.INITIAL.Equals(entry.Value) || CssConstants.INHERIT.Equals(entry.Value)) { // if "inherit" is not resolved till now, parents don't have it keys.Add(entry.Key); } } foreach (String key in keys) { elementStyles.Put(key, CssDefaults.GetDefaultValue(key)); } // This is needed for correct resolving of content property, so doing it right here CounterProcessorUtil.ProcessCounters(elementStyles, context); ResolveContentProperty(elementStyles, element, context); return(elementStyles); }