/** * Calculates the margin top or spacingBefore based on the given value and the last margin bottom. * <br /><br /> * In HTML the margin-bottom of a tag overlaps with the margin-top of a following tag. * This method simulates this behavior by subtracting the margin-top value of the given tag from the margin-bottom of the previous tag. The remaining value is returned or if the margin-bottom value is the largest, 0 is returned * @param value float containing the margin-top value. * @param configuration XmlWorkerConfig containing the last margin bottom. * @return an offset */ public float CalculateMarginTop(float value, HtmlPipelineContext configuration) { float marginTop = value; IDictionary <String, Object> memory = configuration.GetMemory(); Object mb; memory.TryGetValue(HtmlPipelineContext.LAST_MARGIN_BOTTOM, out mb); if (mb != null) { float marginBottom = (float)mb; marginTop = (marginTop > marginBottom)?marginTop - marginBottom:0; } return(marginTop); }
public override void Write(PdfWriter writer, Document doc) { PdfDestination destination = new PdfDestination(PdfDestination.XYZ, 20, writer.GetVerticalPosition(false), 0); IDictionary <String, Object> memory = context.GetMemory(); HeaderNode tree = null; if (memory.ContainsKey(HtmlPipelineContext.BOOKMARK_TREE)) { tree = (HeaderNode)memory[HtmlPipelineContext.BOOKMARK_TREE]; } int level = header.GetLevel(tag); if (null == tree) { // first h tag encounter tree = new HeaderNode(0, writer.RootOutline, null); } else { // calculate parent int lastLevel = tree.Level; if (lastLevel == level) { tree = tree.Parent; } else if (lastLevel > level) { while (lastLevel >= level) { lastLevel = tree.Parent.Level; tree = tree.Parent; } } } if (LOGGER.IsLogging(Level.TRACE)) { LOGGER.Trace(String.Format(LocaleMessages.GetInstance().GetMessage(LocaleMessages.ADD_HEADER), title.ToString())); } HeaderNode node = new HeaderNode(level, new PdfOutline(tree.Outline, destination, title), tree); memory[HtmlPipelineContext.BOOKMARK_TREE] = node; }
/** * Calculates top or bottom spacing of the list. In HTML following possibilities exist: * <ul> * <li><b>padding-top of the ul/ol tag == 0.</b><br /> * The margin-top values of the ul/ol tag and its <b>first</b> li tag are <b>compared</b>. The total spacing before is the largest margin value and the first li's padding-top.</li> * <li><b>padding-top of the ul/ol tag != 0.</b><br /> * The margin-top or bottom values of the ul/ol tag and its first li tag are <b>accumulated</b>, along with padding-top values of both tags.</li> * <li><b>padding-bottom of the ul/ol tag == 0.</b><br /> * The margin-bottom values of the ul/ol tag and its <b>last</b> li tag are <b>compared</b>. The total spacing after is the largest margin value and the first li's padding-bottom.</li> * <li><b>padding-bottom of the ul/ol tag != 0.</b><br /> * The margin-bottom or bottom values of the ul/ol tag and its last li tag are <b>accumulated</b>, along with padding-bottom values of both tags.</li> * </ul> * @param isTop bool, if true the top spacing is calculated, if false the bottom spacing is calculated. * @param storeMarginBottom if true the calculated margin bottom value is stored for later comparison with the top margin value of the next tag. * @param tag the ul/ol tag. * @param child first or last li tag of this list. * @return float containing the spacing before or after. */ private float CalculateTopOrBottomSpacing(bool isTop, bool storeMarginBottom, Tag tag, Tag child, IWorkerContext ctx) { float totalSpacing = 0; try { HtmlPipelineContext context = GetHtmlPipelineContext(ctx); String end = isTop?"-top":"-bottom"; float ownFontSize = fst.GetFontSize(tag); float ownMargin = 0; String marginValue; tag.CSS.TryGetValue(CSS.Property.MARGIN + end, out marginValue); if (marginValue == null) { if (null != tag.Parent && GetHtmlPipelineContext(ctx).GetRootTags().Contains(tag.Parent.Name)) { ownMargin = ownFontSize; } } else { ownMargin = utils.ParseValueToPt(marginValue, ownFontSize); } float ownPadding = 0; if (tag.CSS.ContainsKey(CSS.Property.PADDING + end)) { ownPadding = utils.ParseValueToPt(tag.CSS[CSS.Property.PADDING + end], ownFontSize); } float childFontSize = fst.GetFontSize(child); float childMargin = 0; if (child.CSS.ContainsKey(CSS.Property.MARGIN + end)) { childMargin = utils.ParseValueToPt(child.CSS[CSS.Property.MARGIN + end], childFontSize); } //Margin values of this tag and its first child need to be compared if paddingTop or bottom = 0. if (ownPadding == 0) { float margin = 0; if (ownMargin != 0 && childMargin != 0) { margin = ownMargin >= childMargin?ownMargin:childMargin; } else if (ownMargin != 0) { margin = ownMargin; } else if (childMargin != 0) { margin = childMargin; } if (!isTop && storeMarginBottom) { context.GetMemory()[HtmlPipelineContext.LAST_MARGIN_BOTTOM] = margin; } totalSpacing = margin; } else // ownpadding != 0 and all margins and paddings need to be accumulated. { totalSpacing = ownMargin + ownPadding + childMargin; if (!isTop && storeMarginBottom) { context.GetMemory()[HtmlPipelineContext.LAST_MARGIN_BOTTOM] = ownMargin; } } } catch (NoCustomContextException e) { throw new RuntimeWorkerException(LocaleMessages.GetInstance().GetMessage(LocaleMessages.NO_CUSTOM_CONTEXT), e); } return(totalSpacing); }
virtual public void VerifyNewMemory() { Assert.AreNotSame(ctx.GetMemory(), clone.GetMemory()); }
virtual public void VerifyMemory() { Assert.NotNull(ctx.GetMemory()); }
/* (non-Javadoc) * @see com.itextpdf.tool.xml.css.CssApplier#apply(com.itextpdf.text.Element, com.itextpdf.tool.xml.Tag) */ public NoNewLineParagraph Apply(NoNewLineParagraph p, Tag t) { if (this.configuration.GetRootTags().Contains(t.Name)) { m.SetLeading(t); } else { m.SetVariablesBasedOnChildren(t); } float fontSize = FontSizeTranslator.GetInstance().GetFontSize(t); 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); } 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)) { if (Util.EqualsIgnoreCase(CSS.Value.RIGHT, value)) { p.Alignment = Element.ALIGN_RIGHT; } else if (Util.EqualsIgnoreCase(CSS.Value.CENTER, value)) { p.Alignment = Element.ALIGN_CENTER; } else if (Util.EqualsIgnoreCase(CSS.Value.LEFT, value)) { p.Alignment = Element.ALIGN_LEFT; } else if (Util.EqualsIgnoreCase(CSS.Value.JUSTIFY, value)) { p.Alignment = Element.ALIGN_JUSTIFIED; } } else if (Util.EqualsIgnoreCase(CSS.Property.TEXT_INDENT, key)) { p.FirstLineIndent = utils.ParseValueToPt(value, fontSize); } } // setDefaultMargin to largestFont if no margin-top is set and p-tag is child of the root tag. if (null != t.Parent) { String parent = t.Parent.Name; if (!css.ContainsKey(CSS.Property.MARGIN_TOP) && configuration.GetRootTags().Contains(parent)) { p.SpacingBefore = p.SpacingBefore + utils.CalculateMarginTop(fontSize.ToString(CultureInfo.InvariantCulture) + "pt", 0, configuration); } if (!css.ContainsKey(CSS.Property.MARGIN_BOTTOM) && configuration.GetRootTags().Contains(parent)) { p.SpacingAfter = p.SpacingAfter + fontSize; css[CSS.Property.MARGIN_BOTTOM] = fontSize.ToString(CultureInfo.InvariantCulture) + "pt"; lmb = fontSize; hasLMB = true; } p.Leading = m.GetLargestLeading(); if (p.Alignment == -1) { p.Alignment = Element.ALIGN_LEFT; } } if (hasLMB) { configuration.GetMemory()[HtmlPipelineContext.LAST_MARGIN_BOTTOM] = lmb; } return(p); }