/// <summary> /// Creates a new /// <see cref="LiTagWorker"/> /// instance. /// </summary> /// <param name="element">the element</param> /// <param name="context">the context</param> public LiTagWorker(IElementNode element, ProcessorContext context) { listItem = new ListItem(); if (element.GetAttribute(AttributeConstants.VALUE) != null) { int?indexValue = (int?)CssDimensionParsingUtils.ParseInteger(element.GetAttribute(AttributeConstants.VALUE )); if (indexValue != null) { listItem.SetListSymbolOrdinalValue(indexValue.Value); } } if (!(context.GetState().Top() is UlOlTagWorker)) { listItem.SetProperty(Property.LIST_SYMBOL_POSITION, ListSymbolPosition.INSIDE); float em = CssDimensionParsingUtils.ParseAbsoluteLength(element.GetStyles().Get(CssConstants.FONT_SIZE)); if (TagConstants.LI.Equals(element.Name())) { ListStyleApplierUtil.SetDiscStyle(listItem, em); } else { listItem.SetProperty(Property.LIST_SYMBOL, null); } list = new List(); list.Add(listItem); } inlineHelper = new WaitingInlineElementsHelper(element.GetStyles().Get(CssConstants.WHITE_SPACE), element. GetStyles().Get(CssConstants.TEXT_TRANSFORM)); AccessiblePropHelper.TrySetLangAttribute(listItem, element); }
/* (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 worker) { base.Apply(context, stylesContainer, worker); IPropertyContainer cell = worker.GetElementResult(); if (cell != null) { IDictionary <String, String> cssProps = stylesContainer.GetStyles(); VerticalAlignmentApplierUtil.ApplyVerticalAlignmentForCells(cssProps, context, cell); float em = CssDimensionParsingUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); Border[] bordersArray = BorderStyleApplierUtil.GetBordersArray(cssProps, em, rem); if (bordersArray[0] == null) { cell.SetProperty(Property.BORDER_TOP, Border.NO_BORDER); } if (bordersArray[1] == null) { cell.SetProperty(Property.BORDER_RIGHT, Border.NO_BORDER); } if (bordersArray[2] == null) { cell.SetProperty(Property.BORDER_BOTTOM, Border.NO_BORDER); } if (bordersArray[3] == null) { cell.SetProperty(Property.BORDER_LEFT, Border.NO_BORDER); } } }
/// <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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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()); } } } } }
/* (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 = CssDimensionParsingUtils.ParseAbsoluteLength(css.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); UnitValue startPadding = CssDimensionParsingUtils.ParseLengthValueToPt(css.Get(CssConstants.PADDING_INLINE_START ), em, rem); list.SetProperty(isRtl ? Property.PADDING_RIGHT : Property.PADDING_LEFT, startPadding); } }
// element.setProperty(Property.POSITION, LayoutPosition.FIXED); // float em = CssUtils.parseAbsoluteLength(cssProps.get(CommonCssConstants.FONT_SIZE)); // applyLeftProperty(cssProps, element, em, Property.X); // applyTopProperty(cssProps, element, em, Property.Y); // TODO DEVSIX-4104 support "fixed" value of position property /// <summary>Applies left, right, top, and bottom properties.</summary> /// <param name="cssProps">the CSS properties</param> /// <param name="context">the processor context</param> /// <param name="element">the element</param> /// <param name="position">the position</param> private static void ApplyLeftRightTopBottom(IDictionary <String, String> cssProps, ProcessorContext context , IPropertyContainer element, String position) { float em = CssDimensionParsingUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); if (CssConstants.RELATIVE.Equals(position) && cssProps.ContainsKey(CssConstants.LEFT) && cssProps.ContainsKey (CssConstants.RIGHT)) { // When both the right CSS property and the left CSS property are defined, the position of the element is overspecified. // In that case, the left value has precedence when the container is left-to-right (that is that the right computed value is set to -left), // and the right value has precedence when the container is right-to-left (that is that the left computed value is set to -right). bool isRtl = CssConstants.RTL.Equals(cssProps.Get(CssConstants.DIRECTION)); if (isRtl) { ApplyRightProperty(cssProps, element, em, rem, Property.RIGHT); } else { ApplyLeftProperty(cssProps, element, em, rem, Property.LEFT); } } else { ApplyLeftProperty(cssProps, element, em, rem, Property.LEFT); ApplyRightProperty(cssProps, element, em, rem, Property.RIGHT); } ApplyTopProperty(cssProps, element, em, rem, Property.TOP); ApplyBottomProperty(cssProps, element, em, rem, Property.BOTTOM); }
/// <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 = CssDimensionParsingUtils.ParseAbsoluteLength(resolvedCssProps.Get(CssConstants.FONT_SIZE)); String width = resolvedCssProps.Get(CssConstants.WIDTH); return(width != null?CssDimensionParsingUtils.ParseLengthValueToPt(width, em, context.GetCssContext().GetRootFontSize ()) : null); }
/// <summary>Calculates text rise for percentage value text rise.</summary> /// <param name="stylesContainer">the styles container</param> /// <param name="rootFontSize">the root font size</param> /// <param name="vAlignVal">the vertical alignment value</param> /// <returns>the calculated text rise</returns> private static float CalcTextRiseForPercentageValue(IStylesContainer stylesContainer, float rootFontSize, String vAlignVal) { String ownFontSizeStr = stylesContainer.GetStyles().Get(CssConstants.FONT_SIZE); float fontSize = CssDimensionParsingUtils.ParseAbsoluteLength(ownFontSizeStr); String lineHeightStr = stylesContainer.GetStyles().Get(CssConstants.LINE_HEIGHT); float lineHeightActualValue = GetLineHeightActualValue(fontSize, rootFontSize, lineHeightStr); return(CssDimensionParsingUtils.ParseRelativeValue(vAlignVal, lineHeightActualValue)); }
/// <summary>Calculates the text rise for middle alignment.</summary> /// <param name="stylesContainer">the styles container</param> /// <returns>the calculated text rise</returns> private static float CalcTextRiseForMiddle(IStylesContainer stylesContainer) { String ownFontSizeStr = stylesContainer.GetStyles().Get(CssConstants.FONT_SIZE); float fontSize = CssDimensionParsingUtils.ParseAbsoluteLength(ownFontSizeStr); float parentFontSize = GetParentFontSize(stylesContainer); double fontMiddleCoefficient = 0.3; float elementMidPoint = (float)(fontSize * fontMiddleCoefficient); // shift to element mid point from the baseline float xHeight = parentFontSize / 4; return(xHeight - elementMidPoint); }
/// <summary>Calculates the text rise for top alignment.</summary> /// <param name="stylesContainer">the styles container</param> /// <param name="rootFontSize">the root font size</param> /// <returns>the calculated text rise</returns> private static float CalcTextRiseForTextTop(IStylesContainer stylesContainer, float rootFontSize) { String ownFontSizeStr = stylesContainer.GetStyles().Get(CssConstants.FONT_SIZE); float fontSize = CssDimensionParsingUtils.ParseAbsoluteLength(ownFontSizeStr); String lineHeightStr = stylesContainer.GetStyles().Get(CssConstants.LINE_HEIGHT); float lineHeightActualValue = GetLineHeightActualValue(fontSize, rootFontSize, lineHeightStr); float parentFontSize = GetParentFontSize(stylesContainer); float elementTopEdge = (float)(fontSize * ASCENDER_COEFFICIENT + (lineHeightActualValue - fontSize) / 2); float parentTextTop = (float)(parentFontSize * ASCENDER_COEFFICIENT); return(parentTextTop - elementTopEdge); }
protected override void ComparePdf(String outPath, String dest, String cmp) { CompareTool compareTool = new CompareTool(); for (int i = 0; i < PdfHtmlResponsiveDesign.pageSizes.Length; i++) { float width = CssDimensionParsingUtils.ParseAbsoluteLength(PdfHtmlResponsiveDesign.pageSizes[i].GetWidth().ToString()); String currentDest = dest.Replace("<filename>", "responsive_" + width.ToString("0.0", CultureInfo.InvariantCulture) + ".pdf"); String currentCmp = cmp.Replace("<filename>", "responsive_" + width.ToString("0.0", CultureInfo.InvariantCulture) + ".pdf"); AddError(compareTool.CompareByContent(currentDest, currentCmp, outPath, "diff_")); AddError(compareTool.CompareDocumentInfo(currentDest, currentCmp)); } }
/// <summary>Applies margins 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 ApplyMargins(IDictionary <String, String> cssProps, ProcessorContext context, IPropertyContainer element, float baseValueVertical, float baseValueHorizontal) { String marginTop = cssProps.Get(CssConstants.MARGIN_TOP); String marginBottom = cssProps.Get(CssConstants.MARGIN_BOTTOM); String marginLeft = cssProps.Get(CssConstants.MARGIN_LEFT); String marginRight = cssProps.Get(CssConstants.MARGIN_RIGHT); // The check for display is useful at least for images bool isBlock = element is IBlockElement || CssConstants.BLOCK.Equals(cssProps.Get(CssConstants.DISPLAY)); bool isImage = element is Image; float em = CssDimensionParsingUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); if (isBlock || isImage) { TrySetMarginIfNotAuto(Property.MARGIN_TOP, marginTop, element, em, rem, baseValueVertical); TrySetMarginIfNotAuto(Property.MARGIN_BOTTOM, marginBottom, element, em, rem, baseValueVertical); } bool isLeftAuto = !TrySetMarginIfNotAuto(Property.MARGIN_LEFT, marginLeft, element, em, rem, baseValueHorizontal ); bool isRightAuto = !TrySetMarginIfNotAuto(Property.MARGIN_RIGHT, marginRight, element, em, rem, baseValueHorizontal ); if (isBlock) { if (isLeftAuto && isRightAuto) { element.SetProperty(Property.HORIZONTAL_ALIGNMENT, HorizontalAlignment.CENTER); } else { if (isLeftAuto) { element.SetProperty(Property.HORIZONTAL_ALIGNMENT, HorizontalAlignment.RIGHT); } else { if (isRightAuto) { element.SetProperty(Property.HORIZONTAL_ALIGNMENT, HorizontalAlignment.LEFT); } } } } }
/// <summary>Gets the parent font size.</summary> /// <param name="stylesContainer">the styles container</param> /// <returns>the parent font size</returns> private static float GetParentFontSize(IStylesContainer stylesContainer) { float parentFontSize; if (stylesContainer is INode && ((IElementNode)stylesContainer).ParentNode() is IStylesContainer) { INode parent = ((IElementNode)stylesContainer).ParentNode(); String parentFontSizeStr = ((IStylesContainer)parent).GetStyles().Get(CssConstants.FONT_SIZE); parentFontSize = CssDimensionParsingUtils.ParseAbsoluteLength(parentFontSizeStr); } else { // let's take own font size for this unlikely case String ownFontSizeStr = stylesContainer.GetStyles().Get(CssConstants.FONT_SIZE); parentFontSize = CssDimensionParsingUtils.ParseAbsoluteLength(ownFontSizeStr); } return(parentFontSize); }
public static void Main(string[] args) { FileInfo file = new FileInfo(DEST.Replace("<filename>", "")); file.Directory.Create(); string htmlSource = SRC + "responsive.html"; PdfHtmlResponsiveDesign runner = new PdfHtmlResponsiveDesign(); // Create a pdf for each page size for (int i = 0; i < pageSizes.Length; i++) { float width = CssDimensionParsingUtils.ParseAbsoluteLength(pageSizes[i].GetWidth().ToString(CultureInfo.InvariantCulture)); string dest = DEST.Replace("<filename>", "responsive_" + width.ToString("0.0", CultureInfo.InvariantCulture) + ".pdf"); runner.ManipulatePdf(htmlSource, dest, SRC, pageSizes[i], width); } }
public virtual void ResponsiveIText() { PageSize[] pageSizes = new PageSize[] { null, new PageSize(PageSize.A3.GetHeight(), PageSize.A4.GetHeight( )), new PageSize(760, PageSize.A4.GetHeight()), new PageSize(PageSize.A5.GetWidth(), PageSize.A4.GetHeight ()) }; String htmlSource = sourceFolder + "responsiveIText.html"; foreach (PageSize pageSize in pageSizes) { float?pxWidth = null; if (pageSize != null) { pxWidth = CssDimensionParsingUtils.ParseAbsoluteLength(pageSize.GetWidth().ToString()); } String outName = "responsiveIText" + (pxWidth != null ? "_" + (int)(float)pxWidth : "") + ".pdf"; PdfWriter writer = new PdfWriter(destinationFolder + outName); PdfDocument pdfDoc = new PdfDocument(writer); ConverterProperties converterProperties = new ConverterProperties(); if (pageSize != null) { pdfDoc.SetDefaultPageSize(pageSize); MediaDeviceDescription mediaDescription = new MediaDeviceDescription(MediaType.SCREEN); mediaDescription.SetWidth((float)pxWidth); converterProperties.SetMediaDeviceDescription(mediaDescription); } using (FileStream fileInputStream = new FileStream(htmlSource, FileMode.Open, FileAccess.Read)) { HtmlConverter.ConvertToPdf(fileInputStream, pdfDoc, converterProperties); } pdfDoc.Close(); } foreach (PageSize pageSize in pageSizes) { float?pxWidth = null; if (pageSize != null) { pxWidth = CssDimensionParsingUtils.ParseAbsoluteLength(pageSize.GetWidth().ToString()); } String outName = "responsiveIText" + (pxWidth != null ? "_" + (int)(float)pxWidth : "") + ".pdf"; String cmpName = "cmp_" + outName; NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(destinationFolder + outName, sourceFolder + cmpName, destinationFolder, "diffResponsive_")); } }
/// <summary>Applies borders 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 ApplyBorders(IDictionary <String, String> cssProps, ProcessorContext context, IPropertyContainer element) { float em = CssDimensionParsingUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); Border[] bordersArray = GetBordersArray(cssProps, em, rem); if (bordersArray[0] != null) { element.SetProperty(Property.BORDER_TOP, bordersArray[0]); } if (bordersArray[1] != null) { element.SetProperty(Property.BORDER_RIGHT, bordersArray[1]); } if (bordersArray[2] != null) { element.SetProperty(Property.BORDER_BOTTOM, bordersArray[2]); } if (bordersArray[3] != null) { element.SetProperty(Property.BORDER_LEFT, bordersArray[3]); } BorderRadius[] borderRadii = GetBorderRadiiArray(cssProps, em, rem); if (borderRadii[0] != null) { element.SetProperty(Property.BORDER_TOP_LEFT_RADIUS, borderRadii[0]); } if (borderRadii[1] != null) { element.SetProperty(Property.BORDER_TOP_RIGHT_RADIUS, borderRadii[1]); } if (borderRadii[2] != null) { element.SetProperty(Property.BORDER_BOTTOM_RIGHT_RADIUS, borderRadii[2]); } if (borderRadii[3] != null) { element.SetProperty(Property.BORDER_BOTTOM_LEFT_RADIUS, borderRadii[3]); } }
/* (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 worker) { base.Apply(context, stylesContainer, worker); Table table = (Table)worker.GetElementResult(); if (table != null) { String tableLayout = stylesContainer.GetStyles().Get(CssConstants.TABLE_LAYOUT); if (tableLayout != null) { table.SetProperty(Property.TABLE_LAYOUT, tableLayout); } String borderCollapse = stylesContainer.GetStyles().Get(CssConstants.BORDER_COLLAPSE); // BorderCollapsePropertyValue.COLLAPSE is default in iText layout if (null == borderCollapse || CssConstants.SEPARATE.Equals(borderCollapse)) { table.SetBorderCollapse(BorderCollapsePropertyValue.SEPARATE); } String borderSpacing = stylesContainer.GetStyles().Get(CssConstants.BORDER_SPACING); if (null != borderSpacing) { String[] props = iText.IO.Util.StringUtil.Split(borderSpacing, "\\s+"); if (1 == props.Length) { table.SetHorizontalBorderSpacing(CssDimensionParsingUtils.ParseAbsoluteLength(props[0])); table.SetVerticalBorderSpacing(CssDimensionParsingUtils.ParseAbsoluteLength(props[0])); } else { if (2 == props.Length) { table.SetHorizontalBorderSpacing(CssDimensionParsingUtils.ParseAbsoluteLength(props[0])); table.SetVerticalBorderSpacing(CssDimensionParsingUtils.ParseAbsoluteLength(props[1])); } } } } }
private bool CompareFloatProperty(ICollection <String> expectedStyles, ICollection <String> actualStyles, String propertyName) { String containsExpected = null; foreach (String str in expectedStyles) { if (str.StartsWith(propertyName)) { containsExpected = str; } } String containsActual = null; foreach (String str in actualStyles) { if (str.StartsWith(propertyName)) { containsActual = str; } } if (containsActual == null && containsExpected == null) { return(true); } if (containsActual != null && containsExpected != null) { containsActual = containsActual.Substring(propertyName.Length + 1).Trim(); containsExpected = containsExpected.Substring(propertyName.Length + 1).Trim(); float actual = CssDimensionParsingUtils.ParseAbsoluteLength(containsActual, CssConstants.PT); float expected = CssDimensionParsingUtils.ParseAbsoluteLength(containsExpected, CssConstants.PT); return(Math.Abs(actual - expected) < 0.0001); } else { return(false); } }
/// <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 = CssDimensionParsingUtils.ParseAbsoluteLength(styles.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); pageSize = PageSizeParser.FetchPageSize(styles.Get(CssConstants.SIZE), em, rem, defaultPageSize); UnitValue bleedValue = CssDimensionParsingUtils.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); pageMarginBoxHelper = new PageMarginBoxBuilder(properties.GetResolvedPageMarginBoxes(), margins, pageSize); return(this); }
/// <summary>Applies background 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 ApplyBackground(IDictionary <String, String> cssProps, ProcessorContext context, IPropertyContainer element) { String backgroundColorStr = cssProps.Get(CssConstants.BACKGROUND_COLOR); String backgroundImagesStr = cssProps.Get(CssConstants.BACKGROUND_IMAGE); String backgroundRepeatStr = cssProps.Get(CssConstants.BACKGROUND_REPEAT); String backgroundSizeStr = cssProps.Get(CssConstants.BACKGROUND_SIZE); String backgroundPositionXStr = cssProps.Get(CssConstants.BACKGROUND_POSITION_X); String backgroundPositionYStr = cssProps.Get(CssConstants.BACKGROUND_POSITION_Y); String backgroundBlendModeStr = cssProps.Get(CssConstants.BACKGROUND_BLEND_MODE); String backgroundClipStr = cssProps.Get(CssConstants.BACKGROUND_CLIP); String backgroundOriginStr = cssProps.Get(CssConstants.BACKGROUND_ORIGIN); IList <String> backgroundImagesArray = CssUtils.SplitStringWithComma(backgroundImagesStr); IList <String> backgroundRepeatArray = CssUtils.SplitStringWithComma(backgroundRepeatStr); IList <IList <String> > backgroundSizeArray = backgroundSizeStr == null ? null : CssUtils.ExtractShorthandProperties (backgroundSizeStr); IList <String> backgroundPositionXArray = CssUtils.SplitStringWithComma(backgroundPositionXStr); IList <String> backgroundPositionYArray = CssUtils.SplitStringWithComma(backgroundPositionYStr); IList <String> backgroundBlendModeArray = CssUtils.SplitStringWithComma(backgroundBlendModeStr); String fontSize = cssProps.Get(CssConstants.FONT_SIZE); float em = fontSize == null ? 0 : CssDimensionParsingUtils.ParseAbsoluteLength(fontSize); float rem = context.GetCssContext().GetRootFontSize(); IList <String> backgroundClipArray = CssUtils.SplitStringWithComma(backgroundClipStr); IList <String> backgroundOriginArray = CssUtils.SplitStringWithComma(backgroundOriginStr); BackgroundBox clipForColor = GetBackgroundBoxProperty(backgroundClipArray, backgroundImagesArray.IsEmpty() ? 0 : (backgroundImagesArray.Count - 1), BackgroundBox.BORDER_BOX); ApplyBackgroundColor(backgroundColorStr, element, clipForColor); IList <BackgroundImage> backgroundImagesList = GetBackgroundImagesList(backgroundImagesArray, context, em, rem, backgroundPositionXArray, backgroundPositionYArray, backgroundSizeArray, backgroundBlendModeArray , backgroundRepeatArray, backgroundClipArray, backgroundOriginArray); if (!backgroundImagesList.IsEmpty()) { element.SetProperty(Property.BACKGROUND_IMAGE, backgroundImagesList); } }
/// <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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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); bool textWrappingDisabled = CssConstants.NOWRAP.Equals(whiteSpace) || CssConstants.PRE.Equals(whiteSpace); element.SetProperty(Property.NO_SOFT_WRAP_INLINE, textWrappingDisabled); if (!textWrappingDisabled) { String overflowWrap = cssProps.Get(CssConstants.OVERFLOW_WRAP); if (CssConstants.ANYWHERE.Equals(overflowWrap)) { element.SetProperty(Property.OVERFLOW_WRAP, OverflowWrapPropertyValue.ANYWHERE); } else { if (CssConstants.BREAK_WORD.Equals(overflowWrap)) { element.SetProperty(Property.OVERFLOW_WRAP, OverflowWrapPropertyValue.BREAK_WORD); } else { element.SetProperty(Property.OVERFLOW_WRAP, OverflowWrapPropertyValue.NORMAL); } } String wordBreak = cssProps.Get(CssConstants.WORD_BREAK); if (CssConstants.BREAK_ALL.Equals(wordBreak)) { element.SetProperty(Property.SPLIT_CHARACTERS, new BreakAllSplitCharacters()); } else { if (CssConstants.KEEP_ALL.Equals(wordBreak)) { element.SetProperty(Property.SPLIT_CHARACTERS, new KeepAllSplitCharacters()); } else { if (CssConstants.BREAK_WORD.Equals(wordBreak)) { // CSS specification cite that describes the reason for overflow-wrap overriding: // "For compatibility with legacy content, the word-break property also supports // a deprecated break-word keyword. When specified, this has the same effect // as word-break: normal and overflow-wrap: anywhere, regardless of the actual value // of the overflow-wrap property." element.SetProperty(Property.OVERFLOW_WRAP, OverflowWrapPropertyValue.BREAK_WORD); element.SetProperty(Property.SPLIT_CHARACTERS, new DefaultSplitCharacters()); } else { element.SetProperty(Property.SPLIT_CHARACTERS, new DefaultSplitCharacters()); } } } } 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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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); }
/* (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); }
/// <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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.ParseLengthValueToPt(maxWidthVal, em, rem); element.SetProperty(Property.MAX_WIDTH, maxWidth); } 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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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 = CssDimensionParsingUtils.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>Applies an image list style 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 ApplyListStyleImageProperty(IDictionary <String, String> cssProps, ProcessorContext context , IPropertyContainer element) { String listStyleImageStr = cssProps.Get(CssConstants.LIST_STYLE_IMAGE); PdfXObject imageXObject = null; if (listStyleImageStr != null && !CssConstants.NONE.Equals(listStyleImageStr)) { if (CssGradientUtil.IsCssLinearGradientValue(listStyleImageStr)) { float em = CssDimensionParsingUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); try { StrategyBasedLinearGradientBuilder gradientBuilder = CssGradientUtil.ParseCssLinearGradient(listStyleImageStr , em, rem); if (gradientBuilder != null) { Rectangle formBBox = new Rectangle(0, 0, em * LIST_ITEM_MARKER_SIZE_COEFFICIENT, em * LIST_ITEM_MARKER_SIZE_COEFFICIENT ); PdfDocument pdfDocument = context.GetPdfDocument(); Color gradientColor = gradientBuilder.BuildColor(formBBox, null, pdfDocument); if (gradientColor != null) { imageXObject = new PdfFormXObject(formBBox); new PdfCanvas((PdfFormXObject)imageXObject, context.GetPdfDocument()).SetColor(gradientColor, true).Rectangle (formBBox).Fill(); } } } catch (StyledXMLParserException) { LOGGER.Warn(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.INVALID_GRADIENT_DECLARATION, listStyleImageStr )); } } else { imageXObject = context.GetResourceResolver().RetrieveImageExtended(CssUtils.ExtractUrl(listStyleImageStr)); } if (imageXObject != null) { Image image = null; if (imageXObject is PdfImageXObject) { image = new Image((PdfImageXObject)imageXObject); } else { if (imageXObject is PdfFormXObject) { image = new Image((PdfFormXObject)imageXObject); } else { throw new InvalidOperationException(); } } element.SetProperty(Property.LIST_SYMBOL, image); element.SetProperty(Property.LIST_SYMBOL_INDENT, 5); } } }
/// <summary>Applies a list style to an element.</summary> /// <param name="stylesContainer">the styles container</param> /// <param name="cssProps">the CSS properties</param> /// <param name="context">the processor context</param> /// <param name="element">the element</param> public static void ApplyListStyleTypeProperty(IStylesContainer stylesContainer, IDictionary <String, String > cssProps, ProcessorContext context, IPropertyContainer element) { float em = CssDimensionParsingUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); String style = cssProps.Get(CssConstants.LIST_STYLE_TYPE); if (CssConstants.DISC.Equals(style)) { SetDiscStyle(element, em); } else { if (CssConstants.CIRCLE.Equals(style)) { SetCircleStyle(element, em); } else { if (CssConstants.SQUARE.Equals(style)) { SetSquareStyle(element, em); } else { if (CssConstants.DECIMAL.Equals(style)) { SetListSymbol(element, ListNumberingType.DECIMAL); } else { if (CssConstants.DECIMAL_LEADING_ZERO.Equals(style)) { SetListSymbol(element, ListNumberingType.DECIMAL_LEADING_ZERO); } else { if (CssConstants.UPPER_ALPHA.Equals(style) || CssConstants.UPPER_LATIN.Equals(style)) { SetListSymbol(element, ListNumberingType.ENGLISH_UPPER); } else { if (CssConstants.LOWER_ALPHA.Equals(style) || CssConstants.LOWER_LATIN.Equals(style)) { SetListSymbol(element, ListNumberingType.ENGLISH_LOWER); } else { if (CssConstants.UPPER_ROMAN.Equals(style)) { SetListSymbol(element, ListNumberingType.ROMAN_UPPER); } else { if (CssConstants.LOWER_ROMAN.Equals(style)) { SetListSymbol(element, ListNumberingType.ROMAN_LOWER); } else { if (CssConstants.LOWER_GREEK.Equals(style)) { element.SetProperty(Property.LIST_SYMBOL, new ListStyleApplierUtil.HtmlAlphabetSymbolFactory(GREEK_LOWERCASE )); } else { if (CssConstants.NONE.Equals(style)) { SetListSymbol(element, new Text("")); } else { if (style != null) { ILog logger = LogManager.GetLogger(typeof(iText.Html2pdf.Css.Apply.Util.ListStyleApplierUtil)); logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.NOT_SUPPORTED_LIST_STYLE_TYPE, style )); } // Fallback style if (stylesContainer is IElementNode) { String elementName = ((IElementNode)stylesContainer).Name(); if (TagConstants.UL.Equals(elementName)) { SetDiscStyle(element, em); } else { if (TagConstants.OL.Equals(elementName)) { SetListSymbol(element, ListNumberingType.DECIMAL); } } } } } } } } } } } } } } }
private static Transform.SingleTransform ParseSingleFunction(String transformationFunction) { String function; String args; if (!CssConstants.NONE.Equals(transformationFunction)) { function = transformationFunction.JSubstring(0, transformationFunction.IndexOf('(')).Trim(); args = transformationFunction.Substring(transformationFunction.IndexOf('(') + 1); } else { return(GetSingleTransform(1, 0, 0, 1, 0, 0)); } if (CssConstants.MATRIX.Equals(function)) { String[] arg = iText.IO.Util.StringUtil.Split(args, ","); if (arg.Length == 6) { float[] matrix = new float[6]; int i = 0; for (; i < 6; i++) { if (i == 4 || i == 5) { matrix[i] = CssDimensionParsingUtils.ParseAbsoluteLength(arg[i].Trim()); } else { matrix[i] = float.Parse(arg[i].Trim(), System.Globalization.CultureInfo.InvariantCulture); } if (i == 1 || i == 2 || i == 5) { matrix[i] *= -1; } } return(GetSingleTransform(matrix)); } } if (CssConstants.TRANSLATE.Equals(function)) { String[] arg = iText.IO.Util.StringUtil.Split(args, ","); bool xPoint; bool yPoint = true; float x; float y = 0; xPoint = arg[0].IndexOf('%') < 0; x = xPoint ? CssDimensionParsingUtils.ParseAbsoluteLength(arg[0].Trim()) : float.Parse(arg[0].Trim().JSubstring (0, arg[0].IndexOf('%')), System.Globalization.CultureInfo.InvariantCulture); if (arg.Length == 2) { yPoint = arg[1].IndexOf('%') < 0; y = -1 * (yPoint ? CssDimensionParsingUtils.ParseAbsoluteLength(arg[1].Trim()) : float.Parse(arg[1].Trim() .JSubstring(0, arg[1].IndexOf('%')), System.Globalization.CultureInfo.InvariantCulture)); } return(GetSingleTransformTranslate(1, 0, 0, 1, x, y, xPoint, yPoint)); } if (CssConstants.TRANSLATE_X.Equals(function)) { bool xPoint = args.IndexOf('%') < 0; float x = xPoint ? CssDimensionParsingUtils.ParseAbsoluteLength(args.Trim()) : float.Parse(args.Trim().JSubstring (0, args.IndexOf('%')), System.Globalization.CultureInfo.InvariantCulture); return(GetSingleTransformTranslate(1, 0, 0, 1, x, 0, xPoint, true)); } if (CssConstants.TRANSLATE_Y.Equals(function)) { bool yPoint = args.IndexOf('%') < 0; float y = -1 * (yPoint ? CssDimensionParsingUtils.ParseAbsoluteLength(args.Trim()) : float.Parse(args.Trim ().JSubstring(0, args.IndexOf('%')), System.Globalization.CultureInfo.InvariantCulture)); return(GetSingleTransformTranslate(1, 0, 0, 1, 0, y, true, yPoint)); } if (CssConstants.ROTATE.Equals(function)) { double angleInRad = ParseAngleToRadians(args); float cos = (float)Math.Cos(angleInRad); float sin = (float)Math.Sin(angleInRad); return(GetSingleTransform(cos, sin, -1 * sin, cos, 0, 0)); } if (CssConstants.SKEW.Equals(function)) { String[] arg = iText.IO.Util.StringUtil.Split(args, ","); double xAngleInRad = ParseAngleToRadians(arg[0]); double yAngleInRad = arg.Length == 2 ? ParseAngleToRadians(arg[1]) : 0.0; float tanX = (float)Math.Tan(xAngleInRad); float tanY = (float)Math.Tan(yAngleInRad); return(GetSingleTransform(1, tanY, tanX, 1, 0, 0)); } if (CssConstants.SKEW_X.Equals(function)) { float tanX = (float)Math.Tan(ParseAngleToRadians(args)); return(GetSingleTransform(1, 0, tanX, 1, 0, 0)); } if (CssConstants.SKEW_Y.Equals(function)) { float tanY = (float)Math.Tan(ParseAngleToRadians(args)); return(GetSingleTransform(1, tanY, 0, 1, 0, 0)); } if (CssConstants.SCALE.Equals(function)) { String[] arg = iText.IO.Util.StringUtil.Split(args, ","); float x; float y; if (arg.Length == 2) { x = float.Parse(arg[0].Trim(), System.Globalization.CultureInfo.InvariantCulture); y = float.Parse(arg[1].Trim(), System.Globalization.CultureInfo.InvariantCulture); } else { x = float.Parse(arg[0].Trim(), System.Globalization.CultureInfo.InvariantCulture); y = x; } return(GetSingleTransform(x, 0, 0, y, 0, 0)); } if (CssConstants.SCALE_X.Equals(function)) { float x = float.Parse(args.Trim(), System.Globalization.CultureInfo.InvariantCulture); return(GetSingleTransform(x, 0, 0, 1, 0, 0)); } if (CssConstants.SCALE_Y.Equals(function)) { float y = float.Parse(args.Trim(), System.Globalization.CultureInfo.InvariantCulture); return(GetSingleTransform(1, 0, 0, y, 0, 0)); } return(new Transform.SingleTransform()); }
/// <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 = CssDimensionParsingUtils.ParseAbsoluteLength(cssProps.Get(CssConstants.FONT_SIZE)); float rem = context.GetCssContext().GetRootFontSize(); UnitValue paddingTopVal = CssDimensionParsingUtils.ParseLengthValueToPt(paddingTop, em, rem); UnitValue paddingBottomVal = CssDimensionParsingUtils.ParseLengthValueToPt(paddingBottom, em, rem); UnitValue paddingLeftVal = CssDimensionParsingUtils.ParseLengthValueToPt(paddingLeft, em, rem); UnitValue paddingRightVal = CssDimensionParsingUtils.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); } } } }
/// <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; } } } } } }