Ejemplo n.º 1
0
 /// <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);
 }
Ejemplo n.º 2
0
        /* (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);
                }
            }
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 7
0
        /// <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));
        }
Ejemplo n.º 8
0
        /// <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);
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
0
        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));
            }
        }
Ejemplo n.º 11
0
        /// <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);
                        }
                    }
                }
            }
        }
Ejemplo n.º 12
0
        /// <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);
        }
Ejemplo n.º 13
0
        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);
            }
        }
Ejemplo n.º 14
0
        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);
            }
        }
Ejemplo n.º 20
0
        /// <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());
        }
Ejemplo n.º 26
0
        /// <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);
                    }
                }
            }
        }
Ejemplo n.º 27
0
        /// <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;
                            }
                        }
                    }
                }
            }
        }