/** * @param file the CssFile * */ public CssStateController(ICssFile file) { this.css = file; utils = CssUtils.GetInstance(); buffer = new StringBuilder(); commentStart = new CommentStart(this); commentEnd = new CommentEnd(this); commentInside = new CommentInside(this); unknown = new Unknown(this); properties = new Properties(this); rule = new Rule(this); current = unknown; }
/// <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())); } else { if (token.GetValue().StartsWith(CssConstants.COUNTERS + "(")) { String paramsStr = token.GetValue().JSubstring(CssConstants.COUNTERS.Length + 1, token.GetValue().Length - 1); String[] @params = iText.IO.Util.StringUtil.Split(paramsStr, ","); if (@params.Length == 0) { 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); String listStyleType = @params.Length > 2 ? @params[2].Trim() : null; CssCounterManager counterManager = context.GetCounterManager(); INode scope = contentContainer; if (CssConstants.PAGE.Equals(counterName)) { result.Add(new PageCountElementNode(false, contentContainer)); } else { if (CssConstants.PAGES.Equals(counterName)) { result.Add(new PageCountElementNode(true, contentContainer)); } else { String resolvedCounter = counterManager.ResolveCounters(counterName, counterSeparationStr, listStyleType, scope); if (resolvedCounter == null) { logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.UNABLE_TO_RESOLVE_COUNTER, counterName )); } else { 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); String[] @params = iText.IO.Util.StringUtil.Split(paramsStr, ","); if (@params.Length == 0) { return(ErrorFallback(contentStr)); } // Counters are denoted by case-sensitive identifiers String counterName = @params[0].Trim(); String listStyleType = @params.Length > 1 ? @params[1].Trim() : null; CssCounterManager counterManager = context.GetCounterManager(); INode scope = contentContainer; if (CssConstants.PAGE.Equals(counterName)) { result.Add(new PageCountElementNode(false, contentContainer)); } else { if (CssConstants.PAGES.Equals(counterName)) { result.Add(new PageCountElementNode(true, contentContainer)); } else { String resolvedCounter = counterManager.ResolveCounter(counterName, listStyleType, scope); if (resolvedCounter == null) { logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.UNABLE_TO_RESOLVE_COUNTER, counterName )); } else { result.Add(new CssContentPropertyResolver.ContentTextNode(scope, resolvedCounter)); } } } } 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 (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); }
/// <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 = CssUtils.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 = CssUtils.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 = CssUtils.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 = CssUtils.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 = CssUtils.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 = CssUtils.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 = CssUtils.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> /// Creates a /// <see cref="iText.Layout.Borders.Border"/> /// instance based on specific properties. /// </summary> /// <param name="outlineWidth">the outline width</param> /// <param name="outlineStyle">the outline style</param> /// <param name="outlineColor">the outline color</param> /// <param name="em">the em value</param> /// <param name="rem">the root em value</param> /// <returns>the border</returns> public static Border GetCertainBorder(String outlineWidth, String outlineStyle, String outlineColor, float em, float rem) { if (outlineStyle == null || CssConstants.NONE.Equals(outlineStyle)) { return(null); } if (outlineWidth == null) { outlineWidth = CssDefaults.GetDefaultValue(CssConstants.OUTLINE_WIDTH); } float outlineWidthValue; if (CssConstants.BORDER_WIDTH_VALUES.Contains(outlineWidth)) { if (CssConstants.THIN.Equals(outlineWidth)) { outlineWidth = "1px"; } else { if (CssConstants.MEDIUM.Equals(outlineWidth)) { outlineWidth = "2px"; } else { if (CssConstants.THICK.Equals(outlineWidth)) { outlineWidth = "3px"; } } } } UnitValue unitValue = CssUtils.ParseLengthValueToPt(outlineWidth, em, rem); if (unitValue == null) { return(null); } if (unitValue.IsPercentValue()) { LOGGER.Error("outline-width in percents is not supported"); return(null); } outlineWidthValue = unitValue.GetValue(); Border outline = null; if (outlineWidthValue > 0) { DeviceRgb color = (DeviceRgb)ColorConstants.BLACK; float opacity = 1f; if (outlineColor != null) { if (!CssConstants.TRANSPARENT.Equals(outlineColor)) { float[] rgbaColor = CssUtils.ParseRgbaColor(outlineColor); color = new DeviceRgb(rgbaColor[0], rgbaColor[1], rgbaColor[2]); opacity = rgbaColor[3]; } else { opacity = 0f; } } else { if (CssConstants.GROOVE.Equals(outlineStyle) || CssConstants.RIDGE.Equals(outlineStyle) || CssConstants.INSET .Equals(outlineStyle) || CssConstants.OUTSET.Equals(outlineStyle)) { color = new DeviceRgb(212, 208, 200); } } switch (outlineStyle) { case CssConstants.SOLID: case CssConstants.AUTO: { outline = new SolidBorder(color, outlineWidthValue, opacity); break; } case CssConstants.DASHED: { outline = new DashedBorder(color, outlineWidthValue, opacity); break; } case CssConstants.DOTTED: { outline = new DottedBorder(color, outlineWidthValue, opacity); break; } case CssConstants.DOUBLE: { outline = new DoubleBorder(color, outlineWidthValue, opacity); break; } case CssConstants.GROOVE: { outline = new GrooveBorder(color, outlineWidthValue, opacity); break; } case CssConstants.RIDGE: { outline = new RidgeBorder(color, outlineWidthValue, opacity); break; } case CssConstants.INSET: { outline = new InsetBorder(color, outlineWidthValue, opacity); break; } case CssConstants.OUTSET: { outline = new OutsetBorder(color, outlineWidthValue, opacity); break; } default: { outline = null; break; } } } return(outline); }
/// <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 = CssUtils.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 = CssUtils.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); element.SetProperty(Property.NO_SOFT_WRAP_INLINE, CssConstants.NOWRAP.Equals(whiteSpace) || CssConstants.PRE .Equals(whiteSpace)); String textDecorationProp = cssProps.Get(CssConstants.TEXT_DECORATION); if (textDecorationProp != null) { String[] textDecorations = iText.IO.Util.StringUtil.Split(textDecorationProp, "\\s+"); IList <Underline> underlineList = new List <Underline>(); foreach (String textDecoration in textDecorations) { if (CssConstants.BLINK.Equals(textDecoration)) { logger.Error(iText.Html2pdf.LogMessageConstant.TEXT_DECORATION_BLINK_NOT_SUPPORTED); } else { if (CssConstants.LINE_THROUGH.Equals(textDecoration)) { underlineList.Add(new Underline(null, .75f, 0, 0, 1 / 4f, PdfCanvasConstants.LineCapStyle.BUTT)); } else { if (CssConstants.OVERLINE.Equals(textDecoration)) { underlineList.Add(new Underline(null, .75f, 0, 0, 9 / 10f, PdfCanvasConstants.LineCapStyle.BUTT)); } else { if (CssConstants.UNDERLINE.Equals(textDecoration)) { underlineList.Add(new Underline(null, .75f, 0, 0, -1 / 10f, PdfCanvasConstants.LineCapStyle.BUTT)); } else { if (CssConstants.NONE.Equals(textDecoration)) { 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 = CssUtils.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 = CssUtils.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 = CssUtils.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); // specification does not give auto as a possible lineHeight value // nevertheless some browsers compute it as normal so we apply the same behaviour. // What's more, it's basically the same thing as if lineHeight is not set in the first place if (lineHeight != null && !CssConstants.NORMAL.Equals(lineHeight) && !CssConstants.AUTO.Equals(lineHeight) ) { if (CssUtils.IsNumericValue(lineHeight)) { float?mult = CssUtils.ParseFloat(lineHeight); if (mult != null) { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, (float)mult)); } } else { UnitValue lineHeightValue = CssUtils.ParseLengthValueToPt(lineHeight, em, rem); if (lineHeightValue != null && lineHeightValue.IsPointValue()) { element.SetProperty(Property.LEADING, new Leading(Leading.FIXED, lineHeightValue.GetValue())); } else { if (lineHeightValue != null) { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, lineHeightValue.GetValue() / 100)); } } } } else { element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, 1.2f)); } }
/// <summary> /// Creates a new /// <see cref="InputTagWorker"/> /// instance. /// </summary> /// <param name="element">the element</param> /// <param name="context">the context</param> public InputTagWorker(IElementNode element, ProcessorContext context) { String inputType = element.GetAttribute(AttributeConstants.TYPE); if (!AttributeConstants.INPUT_TYPE_VALUES.Contains(inputType)) { if (null != inputType && 0 != inputType.Length) { ILog logger = LogManager.GetLogger(typeof(iText.Html2pdf.Attach.Impl.Tags.InputTagWorker)); logger.Warn(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.INPUT_TYPE_IS_INVALID, inputType)); } inputType = AttributeConstants.TEXT; } String value = element.GetAttribute(AttributeConstants.VALUE); String name = context.GetFormFieldNameResolver().ResolveFormName(element.GetAttribute(AttributeConstants.NAME )); // Default input type is text if (inputType == null || AttributeConstants.TEXT.Equals(inputType) || AttributeConstants.EMAIL.Equals(inputType ) || AttributeConstants.PASSWORD.Equals(inputType) || AttributeConstants.NUMBER.Equals(inputType)) { int?size = CssUtils.ParseInteger(element.GetAttribute(AttributeConstants.SIZE)); formElement = new InputField(name); value = PreprocessInputValue(value, inputType); // process placeholder instead String placeholder = element.GetAttribute(AttributeConstants.PLACEHOLDER); if (null != placeholder) { Paragraph paragraph; if (String.IsNullOrEmpty(placeholder)) { paragraph = new Paragraph(); } else { if (String.IsNullOrEmpty(placeholder.Trim())) { paragraph = new Paragraph("\u00A0"); } else { paragraph = new Paragraph(placeholder); } } ((InputField)formElement).SetPlaceholder(paragraph.SetMargin(0)); } formElement.SetProperty(Html2PdfProperty.FORM_FIELD_VALUE, value); formElement.SetProperty(Html2PdfProperty.FORM_FIELD_SIZE, size); if (AttributeConstants.PASSWORD.Equals(inputType)) { formElement.SetProperty(Html2PdfProperty.FORM_FIELD_PASSWORD_FLAG, true); } } else { if (AttributeConstants.SUBMIT.Equals(inputType) || AttributeConstants.BUTTON.Equals(inputType)) { formElement = new Button(name); formElement.SetProperty(Html2PdfProperty.FORM_FIELD_VALUE, value); } else { if (AttributeConstants.CHECKBOX.Equals(inputType)) { formElement = new CheckBox(name); String @checked = element.GetAttribute(AttributeConstants.CHECKED); if (null != @checked) { formElement.SetProperty(Html2PdfProperty.FORM_FIELD_CHECKED, @checked); } } else { // has attribute == is checked if (AttributeConstants.RADIO.Equals(inputType)) { formElement = new Radio(name); String radioGroupName = element.GetAttribute(AttributeConstants.NAME); formElement.SetProperty(Html2PdfProperty.FORM_FIELD_VALUE, radioGroupName); String @checked = element.GetAttribute(AttributeConstants.CHECKED); if (null != @checked) { context.GetRadioCheckResolver().CheckField(radioGroupName, (Radio)formElement); formElement.SetProperty(Html2PdfProperty.FORM_FIELD_CHECKED, @checked); } } else { // has attribute == is checked ILog logger = LogManager.GetLogger(typeof(iText.Html2pdf.Attach.Impl.Tags.InputTagWorker)); logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.INPUT_TYPE_IS_NOT_SUPPORTED, inputType )); } } } } if (formElement != null) { formElement.SetProperty(Html2PdfProperty.FORM_FIELD_FLATTEN, !context.IsCreateAcroForm()); } display = element.GetStyles() != null?element.GetStyles().Get(CssConstants.DISPLAY) : null; }
// NOTE: If src property is written in incorrect format // (for example, contains token url(<url_content>)<some_nonsense>), // then browser ignores it altogether and doesn't load font at all, even if there are valid tokens. // iText will still process all split tokens and can possibly load this font in case it contains some correct urls. /// <summary>Processes and splits a string sequence containing a url/uri.</summary> /// <param name="src">a string representing css src attribute</param> /// <returns> /// an array of /// <see cref="System.String"/> /// urls for font loading /// </returns> public static String[] SplitSourcesSequence(String src) { IList <String> list = new List <String>(); int indexToStart = 0; while (indexToStart < src.Length) { int indexToCut; int indexUnescapedOpeningQuoteMark = Math.Min(CssUtils.FindNextUnescapedChar(src, '\'', indexToStart) >= 0 ? CssUtils.FindNextUnescapedChar(src, '\'', indexToStart) : int.MaxValue, CssUtils.FindNextUnescapedChar (src, '"', indexToStart) >= 0 ? CssUtils.FindNextUnescapedChar(src, '"', indexToStart) : int.MaxValue); int indexUnescapedBracket = CssUtils.FindNextUnescapedChar(src, ')', indexToStart); if (indexUnescapedOpeningQuoteMark < indexUnescapedBracket) { indexToCut = CssUtils.FindNextUnescapedChar(src, src[indexUnescapedOpeningQuoteMark], indexUnescapedOpeningQuoteMark + 1); if (indexToCut == -1) { indexToCut = src.Length; } } else { indexToCut = indexUnescapedBracket; } while (indexToCut < src.Length && src[indexToCut] != ',') { indexToCut++; } list.Add(src.JSubstring(indexToStart, indexToCut).Trim()); indexToStart = ++indexToCut; } String[] result = new String[list.Count]; list.ToArray(result); return(result); }
/// <summary> /// Gets the height of the font in the specified units /// </summary> /// <returns></returns> public float GetEmHeight() { return(CssUtils.GetFontHeight(ActualFont)); }
public override Paragraph Apply(Paragraph p, Tag t, IMarginMemory configuration, IPageSizeContainable psc, HtmlPipelineContext ctx) { /*MaxLeadingAndSize m = new MaxLeadingAndSize(); * if (configuration.GetRootTags().Contains(t.GetName())) { * m.SetLeading(t); * } else { * m.SetVariablesBasedOnChildren(t); * }*/ CssUtils utils = CssUtils.GetInstance(); float fontSize = FontSizeTranslator.GetInstance().GetFontSize(t); if (fontSize == Font.UNDEFINED) { fontSize = 0; } float lmb = 0; bool hasLMB = false; IDictionary <String, String> css = t.CSS; foreach (KeyValuePair <String, String> entry in css) { String key = entry.Key; String value = entry.Value; if (Util.EqualsIgnoreCase(CSS.Property.MARGIN_TOP, key)) { p.SpacingBefore = p.SpacingBefore + utils.CalculateMarginTop(value, fontSize, configuration); } else if (Util.EqualsIgnoreCase(CSS.Property.PADDING_TOP, key)) { p.SpacingBefore = p.SpacingBefore + utils.ParseValueToPt(value, fontSize); p.PaddingTop = utils.ParseValueToPt(value, fontSize); } else if (Util.EqualsIgnoreCase(CSS.Property.MARGIN_BOTTOM, key)) { float after = utils.ParseValueToPt(value, fontSize); p.SpacingAfter = p.SpacingAfter + after; lmb = after; hasLMB = true; } else if (Util.EqualsIgnoreCase(CSS.Property.PADDING_BOTTOM, key)) { p.SpacingAfter = p.SpacingAfter + utils.ParseValueToPt(value, fontSize); } else if (Util.EqualsIgnoreCase(CSS.Property.MARGIN_LEFT, key)) { p.IndentationLeft = p.IndentationLeft + utils.ParseValueToPt(value, fontSize); } else if (Util.EqualsIgnoreCase(CSS.Property.MARGIN_RIGHT, key)) { p.IndentationRight = p.IndentationRight + utils.ParseValueToPt(value, fontSize); } else if (Util.EqualsIgnoreCase(CSS.Property.PADDING_LEFT, key)) { p.IndentationLeft = p.IndentationLeft + utils.ParseValueToPt(value, fontSize); } else if (Util.EqualsIgnoreCase(CSS.Property.PADDING_RIGHT, key)) { p.IndentationRight = p.IndentationRight + utils.ParseValueToPt(value, fontSize); } else if (Util.EqualsIgnoreCase(CSS.Property.TEXT_ALIGN, key)) { p.Alignment = CSS.GetElementAlignment(value); } else if (Util.EqualsIgnoreCase(CSS.Property.TEXT_INDENT, key)) { p.FirstLineIndent = utils.ParseValueToPt(value, fontSize); } else if (Util.EqualsIgnoreCase(CSS.Property.LINE_HEIGHT, key)) { if (utils.IsNumericValue(value)) { p.Leading = float.Parse(value, CultureInfo.InvariantCulture) * fontSize; } else if (utils.IsRelativeValue(value)) { p.Leading = utils.ParseRelativeValue(value, fontSize); } else if (utils.IsMetricValue(value)) { p.Leading = utils.ParsePxInCmMmPcToPt(value); } } } if (t.Attributes.ContainsKey(HTML.Attribute.ALIGN)) { String value = t.Attributes[HTML.Attribute.ALIGN]; if (value != null) { p.Alignment = CSS.GetElementAlignment(value); } } // setDefaultMargin to largestFont if no margin-bottom is set and p-tag is child of the root tag. /*if (null != t.GetParent()) { * String parent = t.GetParent().GetName(); * if (css[CSS.Property.MARGIN_TOP] == null && configuration.GetRootTags().Contains(parent)) { * p.SetSpacingBefore(p.GetSpacingBefore() + utils.CalculateMarginTop(fontSize + "pt", 0, configuration)); * } * if (css[CSS.Property.MARGIN_BOTTOM] == null && configuration.GetRootTags().Contains(parent)) { * p.SetSpacingAfter(p.GetSpacingAfter() + fontSize); * css.Put(CSS.Property.MARGIN_BOTTOM, fontSize + "pt"); * lmb = fontSize; * hasLMB = true; * } * //p.SetLeading(m.GetLargestLeading()); We need possibility to detect that line-height undefined; * if (p.GetAlignment() == -1) { * p.SetAlignment(Element.ALIGN_LEFT); * } * }*/ if (hasLMB) { configuration.LastMarginBottom = lmb; } Font font = appliers.ChunkCssAplier.ApplyFontStyles(t); p.Font = font; // TODO reactive for positioning and implement more return(p); }
virtual public void SetUp() { LoggerFactory.GetInstance().SetLogger(new SysoLogger(3)); css = CssUtils.GetInstance(); str = " een twee drie vier een twee drie vier"; }