/// <summary>Resolves content and counter(s) styles of a node given the passed context.</summary>
        /// <param name="node">the node</param>
        /// <param name="context">the CSS context (RootFontSize, etc.)</param>
        public virtual void ResolveContentAndCountersStyles(INode node, CssContext context)
        {
            IDictionary <String, String> elementStyles = ResolveElementsStyles(node);

            CounterProcessorUtil.ProcessCounters(elementStyles, context);
            ResolveContentProperty(elementStyles, node, context);
        }
 /// <summary>Recursively processes a node to preprocess target-counters.</summary>
 /// <param name="node">the node</param>
 private void VisitToProcessCounters(INode node)
 {
     if (node is IElementNode)
     {
         IElementNode element = (IElementNode)node;
         if (cssResolver is DefaultCssResolver)
         {
             ((DefaultCssResolver)cssResolver).ResolveContentAndCountersStyles(node, context.GetCssContext());
         }
         CounterProcessorUtil.StartProcessingCounters(context.GetCssContext(), element);
         VisitToProcessCounters(CreatePseudoElement(element, null, CssConstants.BEFORE));
         foreach (INode childNode in element.ChildNodes())
         {
             if (!context.IsProcessingInlineSvg())
             {
                 VisitToProcessCounters(childNode);
             }
         }
         VisitToProcessCounters(CreatePseudoElement(element, null, CssConstants.AFTER));
         CounterProcessorUtil.EndProcessingCounters(context.GetCssContext(), element);
     }
 }
Пример #3
0
        /* (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)
        {
            IList <CssRuleSet> ruleSets = new List <CssRuleSet>();

            ruleSets.Add(new CssRuleSet(null, UserAgentCss.GetStyles(element)));
            if (element is IElementNode)
            {
                ruleSets.Add(new CssRuleSet(null, HtmlStylesToCssConverter.Convert((IElementNode)element)));
            }
            ruleSets.AddAll(cssStyleSheet.GetCssRuleSets(element, deviceDescription));
            if (element is IElementNode)
            {
                String styleAttribute = ((IElementNode)element).GetAttribute(AttributeConstants.STYLE);
                if (styleAttribute != null)
                {
                    ruleSets.Add(new CssRuleSet(null, CssRuleSetParser.ParsePropertyDeclarations(styleAttribute)));
                }
            }
            IDictionary <String, String> elementStyles = CssStyleSheet.ExtractStylesFromRuleSets(ruleSets);

            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 (CssUtils.IsRelativeValue(elementFontSize) || CssConstants.LARGER.Equals(elementFontSize) || CssConstants
                .SMALLER.Equals(elementFontSize))
            {
                float baseFontSize;
                if (CssUtils.IsRemValue(elementFontSize))
                {
                    baseFontSize = context.GetRootFontSize();
                }
                else
                {
                    if (parentFontSizeStr == null)
                    {
                        baseFontSize = CssUtils.ParseAbsoluteFontSize(CssDefaults.GetDefaultValue(CssConstants.FONT_SIZE));
                    }
                    else
                    {
                        baseFontSize = CssUtils.ParseAbsoluteLength(parentFontSizeStr);
                    }
                }
                float absoluteFontSize = CssUtils.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(CssUtils.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, element);
            ResolveContentProperty(elementStyles, element, context);
            return(elementStyles);
        }
 /// <summary>Recursively processes a node converting HTML into PDF using tag workers.</summary>
 /// <param name="node">the node</param>
 private void Visit(INode node)
 {
     if (node is IElementNode)
     {
         IElementNode element = (IElementNode)node;
         element.SetStyles(cssResolver.ResolveStyles(element, context.GetCssContext()));
         if (!IsDisplayable(element))
         {
             return;
         }
         ITagWorker tagWorker = context.GetTagWorkerFactory().GetTagWorker(element, context);
         if (tagWorker == null)
         {
             if (!ignoredTags.Contains(element.Name()))
             {
                 logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.NO_WORKER_FOUND_FOR_TAG, (element)
                                                       .Name()));
             }
         }
         else
         {
             context.GetState().Push(tagWorker);
         }
         if (tagWorker is HtmlTagWorker)
         {
             ((HtmlTagWorker)tagWorker).ProcessPageRules(node, cssResolver, context);
         }
         if (TagConstants.BODY.Equals(element.Name()) || TagConstants.HTML.Equals(element.Name()))
         {
             RunApplier(element, tagWorker);
         }
         context.GetOutlineHandler().AddOutlineAndDestToDocument(tagWorker, element, context);
         CounterProcessorUtil.StartProcessingCounters(context.GetCssContext(), element);
         Visit(CreatePseudoElement(element, tagWorker, CssConstants.BEFORE));
         Visit(CreatePseudoElement(element, tagWorker, CssConstants.PLACEHOLDER));
         foreach (INode childNode in element.ChildNodes())
         {
             if (!context.IsProcessingInlineSvg())
             {
                 Visit(childNode);
             }
         }
         Visit(CreatePseudoElement(element, tagWorker, CssConstants.AFTER));
         CounterProcessorUtil.EndProcessingCounters(context.GetCssContext(), element);
         if (tagWorker != null)
         {
             tagWorker.ProcessEnd(element, context);
             LinkHelper.CreateDestination(tagWorker, element, context);
             context.GetOutlineHandler().SetDestinationToElement(tagWorker, element);
             context.GetState().Pop();
             if (!TagConstants.BODY.Equals(element.Name()) && !TagConstants.HTML.Equals(element.Name()))
             {
                 RunApplier(element, tagWorker);
             }
             if (!context.GetState().Empty())
             {
                 PageBreakApplierUtil.AddPageBreakElementBefore(context, context.GetState().Top(), element, tagWorker);
                 tagWorker = ProcessRunningElement(tagWorker, element, context);
                 bool childProcessed = context.GetState().Top().ProcessTagChild(tagWorker, context);
                 PageBreakApplierUtil.AddPageBreakElementAfter(context, context.GetState().Top(), element, tagWorker);
                 if (!childProcessed && !ignoredChildTags.Contains(element.Name()))
                 {
                     logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.WORKER_UNABLE_TO_PROCESS_OTHER_WORKER
                                                           , context.GetState().Top().GetType().FullName, tagWorker.GetType().FullName));
                 }
             }
             else
             {
                 if (tagWorker.GetElementResult() != null)
                 {
                     roots.Add(tagWorker.GetElementResult());
                 }
             }
         }
         element.SetStyles(null);
     }
     else
     {
         if (node is ITextNode)
         {
             String content = ((ITextNode)node).WholeText();
             if (content != null)
             {
                 if (!context.GetState().Empty())
                 {
                     bool contentProcessed = context.GetState().Top().ProcessContent(content, context);
                     if (!contentProcessed)
                     {
                         logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.WORKER_UNABLE_TO_PROCESS_IT_S_TEXT_CONTENT
                                                               , context.GetState().Top().GetType().FullName));
                     }
                 }
                 else
                 {
                     logger.Error(iText.Html2pdf.LogMessageConstant.NO_CONSUMER_FOUND_FOR_CONTENT);
                 }
             }
         }
     }
 }