/// <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); } }
/* (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); } } } } }