/// <summary> /// Instantiates a new /// <see cref="PageCountElement"/>. /// </summary> public PageCountElement() : base( // Workaround to match correct font containing number glyphs "1234567890") { digitsGlyphStyle = CounterDigitsGlyphStyle.DEFAULT; }
/// <summary> /// Instantiates a new /// <see cref="PageCountElement"/>. /// </summary> /// <param name="digitsGlyphStyle">digits glyph style</param> public PageCountElement(CounterDigitsGlyphStyle digitsGlyphStyle) : base(HtmlUtils // Workaround to match correct font containing number glyphs .GetAllNumberGlyphsForStyle(digitsGlyphStyle)) { this.digitsGlyphStyle = digitsGlyphStyle; }
/// <summary>Gets target-counter value for specified ID and counterName.</summary> /// <remarks>Gets target-counter value for specified ID and counterName. Value is converted according to listSymbolType. /// </remarks> /// <param name="id"> /// ID of the element. The first call adds ID to the Map, which means we require its value. /// The second call returns corresponding value if we already encountered corresponding element /// </param> /// <param name="counterName"> /// name of the counter. The first call adds counterName to the Map, /// which means we require its value. /// The second call returns corresponding value if we already encountered corresponding element /// </param> /// <param name="listSymbolType">the list symbol type to convert counter's value. null if conversion is not required. /// </param> /// <returns>target-counter value.</returns> public virtual String ResolveTargetCounter(String id, String counterName, CounterDigitsGlyphStyle listSymbolType ) { int?counterValue = null; if (targetCounterMap.ContainsKey(id)) { IDictionary <String, int?> countersForThisId = targetCounterMap.Get(id); if (countersForThisId.ContainsKey(counterName)) { counterValue = countersForThisId.Get(counterName); } else { countersForThisId.Put(counterName, null); } } else { targetCounterMap.Put(id, new Dictionary <String, int?>()); targetCounterMap.Get(id).Put(counterName, null); } return(counterValue == null ? null : HtmlUtils.ConvertNumberAccordingToGlyphStyle(listSymbolType, (int)counterValue )); }
//TODO /// <summary>Gets a string which contains all glyphs which can be used in number according to given glyph style. /// </summary> /// <param name="glyphStyle">style of the glyphs</param> /// <returns>string of all number glyphs</returns> public static String GetAllNumberGlyphsForStyle(CounterDigitsGlyphStyle glyphStyle) { if (glyphStyle == null) { return(DEFAULT_NUMERALS); } switch (glyphStyle) { case CounterDigitsGlyphStyle.NONE: { return(""); } case CounterDigitsGlyphStyle.DISC: { return(DISC_SYMBOL); } case CounterDigitsGlyphStyle.SQUARE: { return(SQUARE_SYMBOL); } case CounterDigitsGlyphStyle.CIRCLE: { return(CIRCLE_SYMBOL); } case CounterDigitsGlyphStyle.UPPER_ALPHA_AND_LATIN: { return(LATIN_NUMERALS.ToUpperInvariant()); } case CounterDigitsGlyphStyle.LOWER_ALPHA_AND_LATIN: { return(LATIN_NUMERALS); } case CounterDigitsGlyphStyle.LOWER_GREEK: { return(GREEK_NUMERALS); } case CounterDigitsGlyphStyle.LOWER_ROMAN: { return(ROMAN_NUMERALS); } case CounterDigitsGlyphStyle.UPPER_ROMAN: { return(ROMAN_NUMERALS.ToUpperInvariant()); } case CounterDigitsGlyphStyle.GEORGIAN: { return(GEORGIAN_NUMERALS); } case CounterDigitsGlyphStyle.ARMENIAN: { return(ARMENIAN_NUMERALS); } default: { return(DEFAULT_NUMERALS); } } }
/// <summary>Resolves a counter.</summary> /// <param name="counterName">the counter name</param> /// <param name="listSymbolType">the list symbol type</param> /// <returns> /// the counter value as a /// <see cref="System.String"/> /// </returns> public virtual String ResolveCounter(String counterName, CounterDigitsGlyphStyle listSymbolType) { int?result = counterValues.Get(counterName); if (result == null) { if (!counters.ContainsKey(counterName) || counters.Get(counterName).IsEmpty()) { result = 0; } else { result = counters.Get(counterName).JGetLast(); } } return(HtmlUtils.ConvertNumberAccordingToGlyphStyle(listSymbolType, (int)result)); }
/// <summary> /// Creates a new /// <see cref="PageCountWorker"/> /// instance. /// </summary> /// <param name="element">the element</param> /// <param name="context">the context</param> public PageCountWorker(IElementNode element, ProcessorContext context) : base(element, context) { if (element is PageCountElementNode) { CounterDigitsGlyphStyle digitsStyle = ((PageCountElementNode)element).GetDigitsGlyphStyle(); if (element is PageTargetCountElementNode) { pageCountElement = new PageTargetCountElement(((PageTargetCountElementNode)element).GetTarget(), digitsStyle ); } else { bool totalPageCount = ((PageCountElementNode)element).IsTotalPageCount(); pageCountElement = new PageCountElement(digitsStyle); pageCountElement.SetProperty(Html2PdfProperty.PAGE_COUNT_TYPE, totalPageCount ? PageCountType.TOTAL_PAGE_COUNT : PageCountType.CURRENT_PAGE_NUMBER); } } }
/// <summary> /// Instantiates a new /// <see cref="PageTargetCountElement"/>. /// </summary> /// <param name="target">name of the corresponding target</param> /// <param name="digitsGlyphStyle">digits glyph style</param> public PageTargetCountElement(String target, CounterDigitsGlyphStyle digitsGlyphStyle) : base(HtmlUtils.GetAllNumberGlyphsForStyle(digitsGlyphStyle)) { this.target = target.Replace("'", "").Replace("#", ""); this.digitsGlyphStyle = digitsGlyphStyle; }
/// <summary> /// Instantiates a new /// <see cref="PageTargetCountElement"/>. /// </summary> /// <param name="target">name of the corresponding target</param> public PageTargetCountElement(String target) : base("1234567890") { this.target = target.Replace("'", "").Replace("#", ""); this.digitsGlyphStyle = CounterDigitsGlyphStyle.DEFAULT; }
/// <summary> /// Instantiates a new /// <see cref="PageTargetCountRenderer"/>. /// </summary> /// <param name="textElement">the text element</param> internal PageTargetCountRenderer(PageTargetCountElement textElement) : base(textElement) { digitsGlyphStyle = textElement.GetDigitsGlyphStyle(); target = textElement.GetTarget(); }
/// <summary>Sets glyph style for digits.</summary> /// <param name="digitsGlyphStyle">name of the glyph style</param> /// <returns> /// this /// <see cref="PageCountElementNode"/> /// instance /// </returns> public virtual iText.Html2pdf.Css.Resolve.Func.Counter.PageCountElementNode SetDigitsGlyphStyle(CounterDigitsGlyphStyle digitsGlyphStyle) { this.digitsGlyphStyle = digitsGlyphStyle; return(this); }
/// <summary>Converts number according to given glyph style.</summary> /// <param name="glyphStyle">style of the glyphs</param> /// <param name="number">number to be converted</param> /// <returns>converted number</returns> public static String ConvertNumberAccordingToGlyphStyle(CounterDigitsGlyphStyle glyphStyle, int number) { if (glyphStyle == null) { return(number.ToString()); } switch (glyphStyle) { case CounterDigitsGlyphStyle.NONE: { return(""); } case CounterDigitsGlyphStyle.DISC: { return(DISC_SYMBOL); } case CounterDigitsGlyphStyle.SQUARE: { return(SQUARE_SYMBOL); } case CounterDigitsGlyphStyle.CIRCLE: { return(CIRCLE_SYMBOL); } case CounterDigitsGlyphStyle.UPPER_ALPHA_AND_LATIN: { return(number > 0 ? EnglishAlphabetNumbering.ToLatinAlphabetNumberUpperCase(number) : number.ToString()); } case CounterDigitsGlyphStyle.LOWER_ALPHA_AND_LATIN: { return(number > 0 ? EnglishAlphabetNumbering.ToLatinAlphabetNumberLowerCase(number) : number.ToString()); } case CounterDigitsGlyphStyle.LOWER_GREEK: { return(number > 0 ? GreekAlphabetNumbering.ToGreekAlphabetNumberLowerCase(number) : number.ToString()); } case CounterDigitsGlyphStyle.LOWER_ROMAN: { return(number <= MAX_ROMAN_NUMBER?RomanNumbering.ToRomanLowerCase(number) : number.ToString()); } case CounterDigitsGlyphStyle.UPPER_ROMAN: { return(number <= MAX_ROMAN_NUMBER?RomanNumbering.ToRomanUpperCase(number) : number.ToString()); } case CounterDigitsGlyphStyle.DECIMAL_LEADING_ZERO: { return((number < 10 ? "0" : "") + number.ToString()); } case CounterDigitsGlyphStyle.GEORGIAN: { return(GeorgianNumbering.ToGeorgian(number)); } case CounterDigitsGlyphStyle.ARMENIAN: { return(ArmenianNumbering.ToArmenian(number)); } default: { return(number.ToString()); } } }
/// <summary>Resolves counters.</summary> /// <param name="counterName">the counter name</param> /// <param name="counterSeparatorStr">the counter separator</param> /// <param name="listSymbolType">the list symbol type</param> /// <returns> /// the counters as a /// <see cref="System.String"/> /// </returns> public virtual String ResolveCounters(String counterName, String counterSeparatorStr, CounterDigitsGlyphStyle listSymbolType) { IList <String> resolvedCounters = new List <String>(); if (counters.ContainsKey(counterName)) { foreach (int?value in counters.Get(counterName)) { resolvedCounters.Add(HtmlUtils.ConvertNumberAccordingToGlyphStyle(listSymbolType, (int)value)); } } int?currentValue = counterValues.Get(counterName); if (currentValue != null) { resolvedCounters.Add(HtmlUtils.ConvertNumberAccordingToGlyphStyle(listSymbolType, (int)currentValue)); } if (resolvedCounters.IsEmpty()) { return(HtmlUtils.ConvertNumberAccordingToGlyphStyle(listSymbolType, 0)); } else { return(BuildCountersStringFromList(resolvedCounters, counterSeparatorStr)); } }
/// <summary>Gets target-counter value for specified ID and counterName.</summary> /// <remarks>Gets target-counter value for specified ID and counterName. Value is converted according to listSymbolType. /// </remarks> /// <param name="id"> /// ID of the element. The first call adds ID at the Map, /// which means we require its value. The second call returns corresponding value /// if we already encountered this element /// </param> /// <param name="counterName"> /// name of the counter. The first call adds name at the Map, /// which means we require its value. The second call returns corresponding value /// if we already encountered this element /// </param> /// <param name="counterSeparatorStr">separator to separate counters values.</param> /// <param name="listSymbolType">the list symbol type to convert counter's value. null if conversion is not required. /// </param> /// <returns>target-counter value.</returns> public virtual String ResolveTargetCounters(String id, String counterName, String counterSeparatorStr, CounterDigitsGlyphStyle listSymbolType) { String countersStr = null; if (targetCountersMap.ContainsKey(id)) { IDictionary <String, String> countersForThisId = targetCountersMap.Get(id); if (countersForThisId.ContainsKey(counterName)) { countersStr = countersForThisId.Get(counterName); } else { countersForThisId.Put(counterName, null); } } else { targetCountersMap.Put(id, new Dictionary <String, String>()); targetCountersMap.Get(id).Put(counterName, null); } if (countersStr == null) { return(null); } else { String[] resolvedCounters = iText.IO.Util.StringUtil.Split(countersStr, "\\."); IList <String> convertedCounters = new List <String>(); foreach (String counter in resolvedCounters) { convertedCounters.Add(HtmlUtils.ConvertNumberAccordingToGlyphStyle(listSymbolType, Convert.ToInt32(counter , System.Globalization.CultureInfo.InvariantCulture))); } return(BuildCountersStringFromList(convertedCounters, counterSeparatorStr)); } }
/// <summary>Resolves content.</summary> /// <param name="styles">the styles map</param> /// <param name="contentContainer">the content container</param> /// <param name="context">the CSS context</param> /// <returns> /// a list of /// <see cref="iText.StyledXmlParser.Node.INode"/> /// instances /// </returns> internal static IList <INode> ResolveContent(IDictionary <String, String> styles, INode contentContainer, CssContext context) { String contentStr = styles.Get(CssConstants.CONTENT); IList <INode> result = new List <INode>(); if (contentStr == null || CssConstants.NONE.Equals(contentStr) || CssConstants.NORMAL.Equals(contentStr)) { return(null); } CssDeclarationValueTokenizer tokenizer = new CssDeclarationValueTokenizer(contentStr); CssDeclarationValueTokenizer.Token token; CssQuotes quotes = null; while ((token = tokenizer.GetNextValidToken()) != null) { if (token.IsString()) { result.Add(new CssContentPropertyResolver.ContentTextNode(contentContainer, token.GetValue())); continue; } if (token.GetValue().StartsWith(CssConstants.COUNTERS + "(")) { String paramsStr = token.GetValue().JSubstring(CssConstants.COUNTERS.Length + 1, token.GetValue().Length - 1); IList <String> @params = CssUtils.SplitString(paramsStr, ',', ALLOWED_ESCAPE_CHARACTERS); if (@params.Count < COUNTERS_MIN_PARAMS_SIZE) { return(ErrorFallback(contentStr)); } // Counters are denoted by case-sensitive identifiers String counterName = @params[0].Trim(); String counterSeparationStr = @params[1].Trim(); counterSeparationStr = counterSeparationStr.JSubstring(1, counterSeparationStr.Length - 1); CounterDigitsGlyphStyle listStyleType = HtmlUtils.ConvertStringCounterGlyphStyleToEnum(@params.Count > COUNTERS_MIN_PARAMS_SIZE ? @params[COUNTERS_MIN_PARAMS_SIZE].Trim() : null); CssCounterManager counterManager = context.GetCounterManager(); INode scope = contentContainer; if (CssConstants.PAGE.Equals(counterName)) { result.Add(new PageCountElementNode(false, contentContainer).SetDigitsGlyphStyle(listStyleType)); } else { if (CssConstants.PAGES.Equals(counterName)) { result.Add(new PageCountElementNode(true, contentContainer).SetDigitsGlyphStyle(listStyleType)); } else { String resolvedCounter = counterManager.ResolveCounters(counterName, counterSeparationStr, listStyleType); result.Add(new CssContentPropertyResolver.ContentTextNode(scope, resolvedCounter)); } } } else { if (token.GetValue().StartsWith(CssConstants.COUNTER + "(")) { String paramsStr = token.GetValue().JSubstring(CssConstants.COUNTER.Length + 1, token.GetValue().Length - 1); IList <String> @params = CssUtils.SplitString(paramsStr, ',', ALLOWED_ESCAPE_CHARACTERS); if (@params.Count < COUNTER_MIN_PARAMS_SIZE) { return(ErrorFallback(contentStr)); } // Counters are denoted by case-sensitive identifiers String counterName = @params[0].Trim(); CounterDigitsGlyphStyle listStyleType = HtmlUtils.ConvertStringCounterGlyphStyleToEnum(@params.Count > COUNTER_MIN_PARAMS_SIZE ? @params[COUNTER_MIN_PARAMS_SIZE].Trim() : null); CssCounterManager counterManager = context.GetCounterManager(); INode scope = contentContainer; if (CssConstants.PAGE.Equals(counterName)) { result.Add(new PageCountElementNode(false, contentContainer).SetDigitsGlyphStyle(listStyleType)); } else { if (CssConstants.PAGES.Equals(counterName)) { result.Add(new PageCountElementNode(true, contentContainer).SetDigitsGlyphStyle(listStyleType)); } else { String resolvedCounter = counterManager.ResolveCounter(counterName, listStyleType); result.Add(new CssContentPropertyResolver.ContentTextNode(scope, resolvedCounter)); } } } else { if (token.GetValue().StartsWith(CssConstants.TARGET_COUNTER + "(")) { String paramsStr = token.GetValue().JSubstring(CssConstants.TARGET_COUNTER.Length + 1, token.GetValue().Length - 1); IList <String> @params = CssUtils.SplitString(paramsStr, ',', ALLOWED_ESCAPE_CHARACTERS); if (@params.Count < TARGET_COUNTER_MIN_PARAMS_SIZE) { return(ErrorFallback(contentStr)); } String target = CssUtils.ExtractUrl(@params[0]); String counterName = @params[1].Trim(); CounterDigitsGlyphStyle listStyleType = HtmlUtils.ConvertStringCounterGlyphStyleToEnum(@params.Count > TARGET_COUNTER_MIN_PARAMS_SIZE ? @params[TARGET_COUNTER_MIN_PARAMS_SIZE].Trim() : null); if (CssConstants.PAGE.Equals(counterName)) { result.Add(new PageTargetCountElementNode(contentContainer, target).SetDigitsGlyphStyle(listStyleType)); } else { if (CssConstants.PAGES.Equals(counterName)) { result.Add(new PageCountElementNode(true, contentContainer).SetDigitsGlyphStyle(listStyleType)); } else { String counter = context.GetCounterManager().ResolveTargetCounter(target.Replace("'", "").Replace("#", "") , counterName, listStyleType); CssContentPropertyResolver.ContentTextNode node = new CssContentPropertyResolver.ContentTextNode(contentContainer , counter == null ? "0" : counter); result.Add(node); } } } else { if (token.GetValue().StartsWith(CssConstants.TARGET_COUNTERS + "(")) { String paramsStr = token.GetValue().JSubstring(CssConstants.TARGET_COUNTERS.Length + 1, token.GetValue().Length - 1); IList <String> @params = CssUtils.SplitString(paramsStr, ',', ALLOWED_ESCAPE_CHARACTERS); if (@params.Count < TARGET_COUNTERS_MIN_PARAMS_SIZE) { return(ErrorFallback(contentStr)); } String target = CssUtils.ExtractUrl(@params[0]); String counterName = @params[1].Trim(); String counterSeparator = @params[2].Trim(); counterSeparator = counterSeparator.JSubstring(1, counterSeparator.Length - 1); CounterDigitsGlyphStyle listStyleType = HtmlUtils.ConvertStringCounterGlyphStyleToEnum(@params.Count > TARGET_COUNTERS_MIN_PARAMS_SIZE ? @params[TARGET_COUNTERS_MIN_PARAMS_SIZE].Trim() : null); if (CssConstants.PAGE.Equals(counterName)) { result.Add(new PageTargetCountElementNode(contentContainer, target).SetDigitsGlyphStyle(listStyleType)); } else { if (CssConstants.PAGES.Equals(counterName)) { result.Add(new PageCountElementNode(true, contentContainer).SetDigitsGlyphStyle(listStyleType)); } else { String counters = context.GetCounterManager().ResolveTargetCounters(target.Replace(",", "").Replace("#", "" ), counterName, counterSeparator, listStyleType); CssContentPropertyResolver.ContentTextNode node = new CssContentPropertyResolver.ContentTextNode(contentContainer , counters == null ? "0" : counters); result.Add(node); } } } else { if (token.GetValue().StartsWith("url(")) { IDictionary <String, String> attributes = new Dictionary <String, String>(); attributes.Put(AttributeConstants.SRC, CssUtils.ExtractUrl(token.GetValue())); //TODO: probably should add user agent styles on CssContentElementNode creation, not here. attributes.Put(AttributeConstants.STYLE, CssConstants.DISPLAY + ":" + CssConstants.INLINE_BLOCK); result.Add(new CssContentElementNode(contentContainer, TagConstants.IMG, attributes)); } else { if (CssGradientUtil.IsCssLinearGradientValue(token.GetValue())) { IDictionary <String, String> attributes = new Dictionary <String, String>(); attributes.Put(AttributeConstants.STYLE, CssConstants.BACKGROUND_IMAGE + ":" + token.GetValue() + ";" + CssConstants .HEIGHT + ":" + CssConstants.INHERIT + ";" + CssConstants.WIDTH + ":" + CssConstants.INHERIT + ";"); result.Add(new CssContentElementNode(contentContainer, TagConstants.DIV, attributes)); } else { if (token.GetValue().StartsWith("attr(") && contentContainer is CssPseudoElementNode) { int endBracket = token.GetValue().IndexOf(')'); if (endBracket > 5) { String attrName = token.GetValue().JSubstring(5, endBracket); if (attrName.Contains("(") || attrName.Contains(" ") || attrName.Contains("'") || attrName.Contains("\"")) { return(ErrorFallback(contentStr)); } IElementNode element = (IElementNode)contentContainer.ParentNode(); String value = element.GetAttribute(attrName); result.Add(new CssContentPropertyResolver.ContentTextNode(contentContainer, value == null ? "" : value)); } } else { if (token.GetValue().EndsWith("quote") && contentContainer is IStylesContainer) { if (quotes == null) { quotes = CssQuotes.CreateQuotes(styles.Get(CssConstants.QUOTES), true); } String value = quotes.ResolveQuote(token.GetValue(), context); if (value == null) { return(ErrorFallback(contentStr)); } result.Add(new CssContentPropertyResolver.ContentTextNode(contentContainer, value)); } else { if (token.GetValue().StartsWith(CssConstants.ELEMENT + "(") && contentContainer is PageMarginBoxContextNode ) { String paramsStr = token.GetValue().JSubstring(CssConstants.ELEMENT.Length + 1, token.GetValue().Length - 1); String[] @params = iText.IO.Util.StringUtil.Split(paramsStr, ","); if (@params.Length == 0) { return(ErrorFallback(contentStr)); } String name = @params[0].Trim(); String runningElementOccurrence = null; if (@params.Length > 1) { runningElementOccurrence = @params[1].Trim(); } result.Add(new PageMarginRunningElementNode(name, runningElementOccurrence)); } else { return(ErrorFallback(contentStr)); } } } } } } } } } } return(result); }