/** * * @param c the Chunk to apply CSS to. * @param t the tag containing the chunk data * @return the styled chunk */ virtual public Chunk Apply(Chunk c, Tag t) { Font f = ApplyFontStyles(t); float size = f.Size; String value = null; IDictionary<String, String> rules = t.CSS; foreach (KeyValuePair<String, String> entry in rules) { String key = entry.Key; value = entry.Value; if (Util.EqualsIgnoreCase(CSS.Property.FONT_STYLE, key)) { if (Util.EqualsIgnoreCase(CSS.Value.OBLIQUE, value)) { c.SetSkew(0, 12); } } else if (Util.EqualsIgnoreCase(CSS.Property.LETTER_SPACING, key)) { String letterSpacing = entry.Value; float letterSpacingValue = 0f; if (utils.IsRelativeValue(value)) { letterSpacingValue = utils.ParseRelativeValue(letterSpacing, f.Size); } else if (utils.IsMetricValue(value)) { letterSpacingValue = utils.ParsePxInCmMmPcToPt(letterSpacing); } c.SetCharacterSpacing(letterSpacingValue); } else if (Util.EqualsIgnoreCase(CSS.Property.XFA_FONT_HORIZONTAL_SCALE, key)) { // only % allowed; need a catch block NumberFormatExc? c.SetHorizontalScaling( float.Parse(value.Replace("%", ""))/100); } } // following styles are separate from the for each loop, because they are based on font settings like size. if (rules.TryGetValue(CSS.Property.VERTICAL_ALIGN, out value)) { if (Util.EqualsIgnoreCase(CSS.Value.SUPER, value) || Util.EqualsIgnoreCase(CSS.Value.TOP, value) || Util.EqualsIgnoreCase(CSS.Value.TEXT_TOP, value)) { c.SetTextRise((float) (size/2 + 0.5)); } else if (Util.EqualsIgnoreCase(CSS.Value.SUB, value) || Util.EqualsIgnoreCase(CSS.Value.BOTTOM, value) || Util.EqualsIgnoreCase(CSS.Value.TEXT_BOTTOM, value)) { c.SetTextRise(-size/2); } else { c.SetTextRise(utils.ParsePxInCmMmPcToPt(value)); } } String xfaVertScale; if (rules.TryGetValue(CSS.Property.XFA_FONT_VERTICAL_SCALE, out xfaVertScale)) { if (xfaVertScale.Contains("%")) { size *= float.Parse(xfaVertScale.Replace("%", ""))/100; c.SetHorizontalScaling(100/float.Parse(xfaVertScale.Replace("%", ""))); } } if (rules.TryGetValue(CSS.Property.TEXT_DECORATION, out value)) { String[] splitValues = new Regex(@"\s+").Split(value); foreach (String curValue in splitValues) { if (Util.EqualsIgnoreCase(CSS.Value.UNDERLINE, curValue)) { c.SetUnderline(0.75f, -size/8f); } if (Util.EqualsIgnoreCase(CSS.Value.LINE_THROUGH, curValue)) { c.SetUnderline(0.75f, size/4f); } } } if (rules.TryGetValue(CSS.Property.BACKGROUND_COLOR, out value)) { c.SetBackground(HtmlUtilities.DecodeColor(value)); } f.Size = size; c.Font = f; float? leading = null; value = null; if (rules.TryGetValue(CSS.Property.LINE_HEIGHT, out value)) { if (utils.IsNumericValue(value)) { leading = float.Parse(value) * c.Font.Size; } else if (utils.IsRelativeValue(value)) { leading = utils.ParseRelativeValue(value, c.Font.Size); } else if (utils.IsMetricValue(value)) { leading = utils.ParsePxInCmMmPcToPt(value); } } if (leading != null) { c.setLineHeight((float)leading); } return c; }
/** * Method used for copying styles from one chunk to another. Could be deprecated if the content of a chunk can be overwritten. * * @param source chunk which contains the required styles. * @param target chunk which needs the required styles. */ virtual public void CopyChunkStyles(Chunk source, Chunk target) { target.Font = source.Font; target.Attributes = source.Attributes; target.SetCharacterSpacing(source.GetCharacterSpacing()); target.SetHorizontalScaling(source.HorizontalScaling); target.SetHorizontalScaling(source.HorizontalScaling); }
/* * (non-Javadoc) * * @see * com.itextpdf.tool.xml.css.CssApplier#apply(com.itextpdf.text.Element, * com.itextpdf.tool.xml.Tag) */ public Chunk Apply(Chunk c, Tag t) { String fontName = null; String encoding = BaseFont.CP1252; float size = new FontSizeTranslator().GetFontSize(t); int style = Font.UNDEFINED; BaseColor color = null; IDictionary<String, String> rules = t.CSS; foreach (KeyValuePair<String, String> entry in rules) { String key = entry.Key; String value = entry.Value; if (Util.EqualsIgnoreCase(CSS.Property.FONT_WEIGHT, key)) { if (CSS.Value.BOLD.Contains(value)) { if (style == Font.ITALIC) { style = Font.BOLDITALIC; } else { style = Font.BOLD; } } else { if (style == Font.BOLDITALIC) { style = Font.ITALIC; } else { style = Font.NORMAL; } } } else if (Util.EqualsIgnoreCase(CSS.Property.FONT_STYLE, key)) { if (Util.EqualsIgnoreCase(value, CSS.Value.ITALIC)) { if (style == Font.BOLD) style = Font.BOLDITALIC; else style = Font.ITALIC; } if (Util.EqualsIgnoreCase(value, CSS.Value.OBLIQUE)) { c.SetSkew(0, 12); } } else if (Util.EqualsIgnoreCase(CSS.Property.FONT_FAMILY, key)) { if (value.Contains(",")){ String[] fonts = value.Split(','); foreach (String s in fonts) { string s2 = s.Trim(); if (!Util.EqualsIgnoreCase(FontFactory.GetFont(s2).Familyname, "unknown")){ fontName = s2; break; } } } else { fontName = value; } } else if (Util.EqualsIgnoreCase(CSS.Property.COLOR, key)) { color = HtmlUtilities.DecodeColor(value); } else if (Util.EqualsIgnoreCase(CSS.Property.LETTER_SPACING, key)) { c.SetCharacterSpacing(utils.ParsePxInCmMmPcToPt(value)); } else if (rules.ContainsKey(CSS.Property.XFA_FONT_HORIZONTAL_SCALE)) { // only % allowed; need a catch block NumberFormatExc? c.SetHorizontalScaling(float.Parse(rules[CSS.Property.XFA_FONT_HORIZONTAL_SCALE].Replace("%", ""), CultureInfo.InvariantCulture)/100f); } } // following styles are separate from the for each loop, because they are based on font settings like size. if (rules.ContainsKey(CSS.Property.VERTICAL_ALIGN)) { String value = rules[CSS.Property.VERTICAL_ALIGN]; if (Util.EqualsIgnoreCase(value, CSS.Value.SUPER)||Util.EqualsIgnoreCase(value, CSS.Value.TOP)||Util.EqualsIgnoreCase(value, CSS.Value.TEXT_TOP)) { c.SetTextRise((float) (size / 2 + 0.5)); } else if (Util.EqualsIgnoreCase(value, CSS.Value.SUB)||Util.EqualsIgnoreCase(value, CSS.Value.BOTTOM)||Util.EqualsIgnoreCase(value, CSS.Value.TEXT_BOTTOM)) { c.SetTextRise(-size / 2); } else { c.SetTextRise(utils.ParsePxInCmMmPcToPt(value)); } } String xfaVertScale; rules.TryGetValue(CSS.Property.XFA_FONT_VERTICAL_SCALE, out xfaVertScale); if (null != xfaVertScale) { // only % allowed; need a catch block NumberFormatExc? if (xfaVertScale.Contains("%")) { size *= float.Parse(xfaVertScale.Replace("%", ""), CultureInfo.InvariantCulture)/100; c.SetHorizontalScaling(100/float.Parse(xfaVertScale.Replace("%", ""), CultureInfo.InvariantCulture)); } } if (rules.ContainsKey(CSS.Property.TEXT_DECORATION)) { // Restriction? In html a underline and a line-through is possible on one piece of text. A Chunk can set an underline only once. String value = rules[CSS.Property.TEXT_DECORATION]; if (Util.EqualsIgnoreCase(CSS.Value.UNDERLINE, value)) { c.SetUnderline(0.75f, -size/8f); } if (Util.EqualsIgnoreCase(CSS.Value.LINE_THROUGH, value)) { c.SetUnderline(0.75f, size/4f); } } if (rules.ContainsKey(CSS.Property.BACKGROUND_COLOR)) { c.SetBackground(HtmlUtilities.DecodeColor(rules[CSS.Property.BACKGROUND_COLOR])); } Font f = FontFactory.GetFont(fontName, encoding, BaseFont.EMBEDDED, size, style, color); c.Font = f; return c; }
/** * * @param c the Chunk to apply CSS to. * @param t the tag containing the chunk data * @return the styled chunk */ public Chunk Apply(Chunk c, Tag t) { Font f = ApplyFontStyles(t); float size = f.Size; String value = null; IDictionary<String, String> rules = t.CSS; foreach (KeyValuePair<String, String> entry in rules) { String key = entry.Key; value = entry.Value; if (Util.EqualsIgnoreCase(CSS.Property.FONT_STYLE, key)) { if (Util.EqualsIgnoreCase(CSS.Value.OBLIQUE, value)) { c.SetSkew(0, 12); } } else if (Util.EqualsIgnoreCase(CSS.Property.LETTER_SPACING, key)) { c.SetCharacterSpacing(utils.ParsePxInCmMmPcToPt(value)); } else if (Util.EqualsIgnoreCase(CSS.Property.XFA_FONT_HORIZONTAL_SCALE, key)) { // only % allowed; need a catch block NumberFormatExc? c.SetHorizontalScaling( float.Parse(value.Replace("%", ""))/100); } } // following styles are separate from the for each loop, because they are based on font settings like size. if (rules.TryGetValue(CSS.Property.VERTICAL_ALIGN, out value)) { if (Util.EqualsIgnoreCase(CSS.Value.SUPER, value) || Util.EqualsIgnoreCase(CSS.Value.TOP, value) || Util.EqualsIgnoreCase(CSS.Value.TEXT_TOP, value)) { c.SetTextRise((float) (size/2 + 0.5)); } else if (Util.EqualsIgnoreCase(CSS.Value.SUB, value) || Util.EqualsIgnoreCase(CSS.Value.BOTTOM, value) || Util.EqualsIgnoreCase(CSS.Value.TEXT_BOTTOM, value)) { c.SetTextRise(-size/2); } else { c.SetTextRise(utils.ParsePxInCmMmPcToPt(value)); } } String xfaVertScale; if (rules.TryGetValue(CSS.Property.XFA_FONT_VERTICAL_SCALE, out xfaVertScale)) { if (xfaVertScale.Contains("%")) { size *= float.Parse(xfaVertScale.Replace("%", ""))/100; c.SetHorizontalScaling(100/float.Parse(xfaVertScale.Replace("%", ""))); } } if (rules.TryGetValue(CSS.Property.TEXT_DECORATION, out value)) { // Restriction? In html a underline and a line-through is possible on one piece of text. A Chunk can set an underline only once. if (Util.EqualsIgnoreCase(CSS.Value.UNDERLINE, value)) { c.SetUnderline(0.75f, -size/8f); } if (Util.EqualsIgnoreCase(CSS.Value.LINE_THROUGH, value)) { c.SetUnderline(0.75f, size/4f); } } if (rules.TryGetValue(CSS.Property.BACKGROUND_COLOR, out value)) { c.SetBackground(HtmlUtilities.DecodeColor(value)); } f.Size = size; c.Font = f; return c; }
// =========================================================================== public void Write(Stream stream) { string RESOURCE = Utility.ResourcePosters; // step 1 using (Document document = new Document()) { // step 2 PdfWriter writer = PdfWriter.GetInstance(document, stream); // step 3 document.Open(); // step 4 Chunk c; String foobar = "Foobar Film Festival"; // Measuring a String in Helvetica Font helvetica = new Font(Font.FontFamily.HELVETICA, 12); BaseFont bf_helv = helvetica.GetCalculatedBaseFont(false); float width_helv = bf_helv.GetWidthPoint(foobar, 12); c = new Chunk(foobar + ": " + width_helv, helvetica); document.Add(new Paragraph(c)); document.Add(new Paragraph(string.Format( "Chunk width: {0}", c.GetWidthPoint() ))); // Measuring a String in Times BaseFont bf_times = BaseFont.CreateFont( "c:/windows/fonts/times.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED ); Font times = new Font(bf_times, 12); float width_times = bf_times.GetWidthPoint(foobar, 12); c = new Chunk(foobar + ": " + width_times, times); document.Add(new Paragraph(c)); document.Add(new Paragraph(String.Format( "Chunk width: {0}", c.GetWidthPoint() ))); document.Add(Chunk.NEWLINE); // Ascent and descent of the String document.Add(new Paragraph( "Ascent Helvetica: " + bf_helv.GetAscentPoint(foobar, 12) )); document.Add(new Paragraph( "Ascent Times: " + bf_times.GetAscentPoint(foobar, 12) )); document.Add(new Paragraph( "Descent Helvetica: " + bf_helv.GetDescentPoint(foobar, 12) )); document.Add(new Paragraph( "Descent Times: " + bf_times.GetDescentPoint(foobar, 12) )); document.Add(Chunk.NEWLINE); // Kerned text width_helv = bf_helv.GetWidthPointKerned(foobar, 12); c = new Chunk(foobar + ": " + width_helv, helvetica); document.Add(new Paragraph(c)); // Drawing lines to see where the text is added PdfContentByte canvas = writer.DirectContent; canvas.SaveState(); canvas.SetLineWidth(0.05f); canvas.MoveTo(400, 806); canvas.LineTo(400, 626); canvas.MoveTo(508.7f, 806); canvas.LineTo(508.7f, 626); canvas.MoveTo(280, 788); canvas.LineTo(520, 788); canvas.MoveTo(280, 752); canvas.LineTo(520, 752); canvas.MoveTo(280, 716); canvas.LineTo(520, 716); canvas.MoveTo(280, 680); canvas.LineTo(520, 680); canvas.MoveTo(280, 644); canvas.LineTo(520, 644); canvas.Stroke(); canvas.RestoreState(); // Adding text with PdfContentByte.ShowTextAligned() canvas.BeginText(); canvas.SetFontAndSize(bf_helv, 12); canvas.ShowTextAligned(Element.ALIGN_LEFT, foobar, 400, 788, 0); canvas.ShowTextAligned(Element.ALIGN_RIGHT, foobar, 400, 752, 0); canvas.ShowTextAligned(Element.ALIGN_CENTER, foobar, 400, 716, 0); canvas.ShowTextAligned(Element.ALIGN_CENTER, foobar, 400, 680, 30); canvas.ShowTextAlignedKerned(Element.ALIGN_LEFT, foobar, 400, 644, 0); canvas.EndText(); // More lines to see where the text is added canvas.SaveState(); canvas.SetLineWidth(0.05f); canvas.MoveTo(200, 590); canvas.LineTo(200, 410); canvas.MoveTo(400, 590); canvas.LineTo(400, 410); canvas.MoveTo(80, 572); canvas.LineTo(520, 572); canvas.MoveTo(80, 536); canvas.LineTo(520, 536); canvas.MoveTo(80, 500); canvas.LineTo(520, 500); canvas.MoveTo(80, 464); canvas.LineTo(520, 464); canvas.MoveTo(80, 428); canvas.LineTo(520, 428); canvas.Stroke(); canvas.RestoreState(); // Adding text with ColumnText.ShowTextAligned() Phrase phrase = new Phrase(foobar, times); ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 200, 572, 0); ColumnText.ShowTextAligned(canvas, Element.ALIGN_RIGHT, phrase, 200, 536, 0); ColumnText.ShowTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 500, 0); ColumnText.ShowTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 464, 30); ColumnText.ShowTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 428, -30); // Chunk attributes c = new Chunk(foobar, times); c.SetHorizontalScaling(0.5f); phrase = new Phrase(c); ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 572, 0); c = new Chunk(foobar, times); c.SetSkew(15, 15); phrase = new Phrase(c); ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 536, 0); c = new Chunk(foobar, times); c.SetSkew(0, 25); phrase = new Phrase(c); ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 500, 0); c = new Chunk(foobar, times); c.SetTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_STROKE, 0.1f, BaseColor.RED); phrase = new Phrase(c); ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 464, 0); c = new Chunk(foobar, times); c.SetTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, 1, null); phrase = new Phrase(c); ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 428, -0); } }