public static RenderFont GetRenderFont(StyleInfo styleInfo) { //face name RenderFont renderFont = new RenderFont(); renderFont.FaceName = getFontNameNormalized(styleInfo.FontFamily); //font style switch (renderFont.FaceName) { //this font only have one file with italic style case "Monotype Corsiva": if (styleInfo.IsFontBold()) renderFont.SimulateBold = true; break; //standard fonts default: if (styleInfo.IsFontBold() && styleInfo.FontStyle == FontStyleEnum.Italic) renderFont.Style = RenderFont.FontStyle.BoldItalic; else if (styleInfo.IsFontBold()) renderFont.Style = RenderFont.FontStyle.Bold; else if (styleInfo.FontStyle == FontStyleEnum.Italic) renderFont.Style = RenderFont.FontStyle.Italic; break; } return renderFont; }
public static RenderFont GetRenderFont(StyleInfo styleInfo) { //face name RenderFont renderFont = new RenderFont(); renderFont.FaceName = getFontNameNormalized(styleInfo.FontFamily); //font style switch (renderFont.FaceName) { //this font only have one file with italic style case "Monotype Corsiva": if (styleInfo.IsFontBold()) { renderFont.SimulateBold = true; } break; //standard fonts default: if (styleInfo.IsFontBold() && styleInfo.FontStyle == FontStyleEnum.Italic) { renderFont.Style = RenderFont.FontStyle.BoldItalic; } else if (styleInfo.IsFontBold()) { renderFont.Style = RenderFont.FontStyle.Bold; } else if (styleInfo.FontStyle == FontStyleEnum.Italic) { renderFont.Style = RenderFont.FontStyle.Italic; } break; } return(renderFont); }
/// <summary> /// Add text at the X Y position; multiple lines handled /// </summary> private void addText(float x, float y, float width, float height, string[] textLines, StyleInfo styleInfo, float[] textWidths, bool wrap, string url, bool noClip, string tooltip) { RenderFont renderFont = RenderUtility.GetRenderFont(styleInfo); BaseFont baseFont = null; //convert the render font type to iTextSharp type int fontType = 0; switch (renderFont.Style) { case RenderFont.FontStyle.Bold: fontType = iTextSharp.text.Font.BOLD; break; case RenderFont.FontStyle.Italic: fontType = iTextSharp.text.Font.ITALIC; break; case RenderFont.FontStyle.BoldItalic: fontType = iTextSharp.text.Font.BOLDITALIC; break; default: fontType = iTextSharp.text.Font.NORMAL; break; } //get the index of the font name in the list font name int indexBaseFont = BaseFontNames.FindIndex(delegate(string _fontname) { return(_fontname == renderFont.FaceName + "_" + fontType); }); //if not found then add the new BaseFont if (indexBaseFont == -1) { //create a new font or a with a new type baseFont = FontFactory.GetFont(renderFont.FaceName, BaseFont.IDENTITY_H, 0, fontType).BaseFont; //add the font face name and font to the lists BaseFontNames.Add(renderFont.FaceName + "_" + fontType); BaseFonts.Add(baseFont); } else { baseFont = BaseFonts[indexBaseFont]; } //text alignment int align = 0; //first position x and y and the leading (usefull for all kind of justified text) float firstStartX = -1; float firstStartY = -1; float leading = -1; //chunks of text List <Chunk> chunks = new List <Chunk>(); //loop thru the lines of text for (int i = 0; i < textLines.Length; i++) { string text = textLines[i]; float textwidth = textWidths[i]; float startX = x + styleInfo.PaddingLeft; // TODO: handle tb_rl float startY = y + styleInfo.PaddingTop + (i * styleInfo.FontSize); // TODO: handle tb_rl if (styleInfo.WritingMode == WritingModeEnum.lr_tb) { //calculate the x position switch (styleInfo.TextAlign) { case TextAlignEnum.Center: if (width > 0) { startX = x + styleInfo.PaddingLeft + (width - styleInfo.PaddingLeft - styleInfo.PaddingRight) / 2 - textwidth / 2; align = Element.ALIGN_CENTER; } break; case TextAlignEnum.Right: if (width > 0) { startX = x + width - textwidth - styleInfo.PaddingRight - 2; align = Element.ALIGN_RIGHT; } break; case TextAlignEnum.Justified: case TextAlignEnum.JustifiedLine: case TextAlignEnum.JustifiedDottedLine: if (width > 0) { startX += 2; align = Element.ALIGN_JUSTIFIED; } break; case TextAlignEnum.Left: default: if (width > 0) { startX += 2; } align = Element.ALIGN_LEFT; break; } //calculate the y position switch (styleInfo.VerticalAlign) { case VerticalAlignEnum.Middle: if (height <= 0) { break; } //calculate the middle of the region startY = y + styleInfo.PaddingTop + (height - styleInfo.PaddingTop - styleInfo.PaddingBottom) / 2 - styleInfo.FontSize / 2; //now go up or down depending on which line if (textLines.Length == 1) { break; } //even number if (textLines.Length % 2 == 0) { startY = startY - ((textLines.Length / 2 - i) * styleInfo.FontSize) + styleInfo.FontSize / 2; } else { startY = startY - ((textLines.Length / 2 - i) * styleInfo.FontSize); } break; case VerticalAlignEnum.Bottom: if (height <= 0) { break; } startY = y + height - styleInfo.PaddingBottom - (styleInfo.FontSize * (textLines.Length - i)); break; case VerticalAlignEnum.Top: default: break; } } else { //move x in a little - it draws to close to the edge of the rectangle (25% of the font size seems to work!) and Center or right align vertical text startX += styleInfo.FontSize / 4; switch (styleInfo.TextAlign) { case TextAlignEnum.Center: if (height > 0) { startY = y + styleInfo.PaddingLeft + (height - styleInfo.PaddingLeft - styleInfo.PaddingRight) / 2 - textwidth / 2; } break; case TextAlignEnum.Right: if (width > 0) { startY = y + height - textwidth - styleInfo.PaddingRight; } break; case TextAlignEnum.Left: default: break; } } //mark the first x position for justify text if (firstStartX == -1) { firstStartX = startX; } //mark the first y position for justify text if (firstStartY == -1) { firstStartY = startY; } //mark the first leading height for justify text else if (leading == -1) { leading = startY - firstStartY; } //draw background rectangle if needed (only put out on the first line, since we do whole rectangle) if (!styleInfo.BackgroundColor.IsEmpty && height > 0 && width > 0 && i == 0) { addFillRectangle(x, y, width, height, styleInfo.BackgroundColor); } //set the clipping path, (Itext have no clip) if (height > 0 && width > 0) { pdfContent.SetRGBColorFill(styleInfo.Color.R, styleInfo.Color.G, styleInfo.Color.B); if (align == Element.ALIGN_JUSTIFIED) { chunks.Add(new Chunk(text)); } else { if (styleInfo.WritingMode == WritingModeEnum.lr_tb) { //if textline after measure with word break can fit just simple show Text if (width >= textwidth) { pdfContent.SaveState(); pdfContent.BeginText(); pdfContent.SetFontAndSize(baseFont, styleInfo.FontSize); //same fonts dont have nativelly bold so we could simulate that if (renderFont.SimulateBold) { pdfContent.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE); pdfContent.SetLineWidth(0.2f); } pdfContent.SetTextMatrix(startX, pageHeight - startY - styleInfo.FontSize); pdfContent.ShowText(text); pdfContent.EndText(); pdfContent.RestoreState(); } else { //else use Column text to wrap or clip (wrap: for example a text like an URL so word break is not working here //itextsharp ColumnText do the work for us) ColumnText columnText = new ColumnText(pdfContent); columnText.SetSimpleColumn(new Phrase(text, new iTextSharp.text.Font(baseFont, styleInfo.FontSize)), x + styleInfo.PaddingLeft, pageHeight - startY, x + width - styleInfo.PaddingRight, pageHeight - y - styleInfo.PaddingBottom - height, 10f, align); columnText.Go(); } } else { //not checked double rads = -283.0 / 180.0; double radsCos = Math.Cos(rads); double radsSin = Math.Sin(rads); pdfContent.BeginText(); pdfContent.SetFontAndSize(baseFont, styleInfo.FontSize); pdfContent.SetTextMatrix((float)radsCos, (float)radsSin, (float)-radsSin, (float)radsCos, startX, pageHeight - startY); pdfContent.ShowText(text); pdfContent.EndText(); } } //add URL if (url != null) { document.Add(new Annotation(x, pageHeight - y, height, width, url)); } //add tooltip if (tooltip != null) { document.Add(new Annotation(x, pageHeight - y, height, width, tooltip)); } } //handle underlining etc ... float maxX; switch (styleInfo.TextDecoration) { case TextDecorationEnum.Underline: maxX = width > 0 ? Math.Min(x + width, startX + textwidth) : startX + textwidth; addLine(startX, startY + styleInfo.FontSize + 1, maxX, startY + styleInfo.FontSize + 1, 1, styleInfo.Color, BorderStyleEnum.Solid); break; case TextDecorationEnum.LineThrough: maxX = width > 0 ? Math.Min(x + width, startX + textwidth) : startX + textwidth; addLine(startX, startY + (styleInfo.FontSize / 2) + 1, maxX, startY + (styleInfo.FontSize / 2) + 1, 1, styleInfo.Color, BorderStyleEnum.Solid); break; case TextDecorationEnum.Overline: maxX = width > 0 ? Math.Min(x + width, startX + textwidth) : startX + textwidth; addLine(startX, startY + 1, maxX, startY + 1, 1, styleInfo.Color, BorderStyleEnum.Solid); break; case TextDecorationEnum.None: default: break; } } //add text to justify if (chunks.Count > 0) { Paragraph paragraph = new Paragraph(); paragraph.Alignment = align; paragraph.Leading = leading; paragraph.Font = new iTextSharp.text.Font(baseFont, styleInfo.FontSize); //join all text (is necessary to justify alignment) foreach (Chunk chunk in chunks) { paragraph.Add(chunk); } //add separator for kind of justified alignments if (styleInfo.TextAlign == TextAlignEnum.JustifiedLine) { iTextSharp.text.pdf.draw.LineSeparator lineSeparator = new iTextSharp.text.pdf.draw.LineSeparator(); lineSeparator.Offset = 3f; lineSeparator.LineColor = new BaseColor(styleInfo.Color); paragraph.Add(new Chunk(lineSeparator)); } else if (styleInfo.TextAlign == TextAlignEnum.JustifiedDottedLine) { iTextSharp.text.pdf.draw.DottedLineSeparator dottedLineSeparator = new iTextSharp.text.pdf.draw.DottedLineSeparator(); dottedLineSeparator.Offset = 3f; dottedLineSeparator.LineColor = new BaseColor(styleInfo.Color); paragraph.Add(new Chunk(dottedLineSeparator)); } ColumnText columnText = new ColumnText(pdfContent); //start from the top of the column columnText.UseAscender = true; //width, y position from the bottom page (compensate 2 units), x position, 0 columnText.SetSimpleColumn(firstStartX, pageHeight - firstStartY - 2, firstStartX + width - styleInfo.PaddingRight, 0); columnText.AddElement(paragraph); columnText.Go(); } //add any required border addBorder(styleInfo, x, y, width, height); }