I'm creating a PDF with images and text. Text can be of varying color. I convert the color from the HTML color code to get me a System.Drawing.Color object but the color turns out differently in the generated PDF. In one particular instance, the html code is 3C3C3C and it comes out as 3C403E. I check the color by using a color picker to get the color in the PDF.
var color = System.Drawing.ColorTranslator.FromHtml("#3C3C3C);
iTextSharp.text.Font font = font = FontFactory.GetFont(FontFactory.HELVETICA);
font.Color = new BaseColor(color);
// boxValue is a string
Phrase phrase = new Phrase(boxValue, font);
ColumnText columnText = new ColumnText(canvas);
columnText.SetSimpleColumn(boxRectangle);
columnText.Leading = lineHeight;
columnText.SetLeading(lineHeight, 0);
columnText.SetText(phrase);
columnText.Alignment = alignment;
columnText.Go();
It turns out that it does save the actual color in the PDF. I discovered this by using a PDF inspector and do see the correct values used.
public static BaseColor stringToBaseColor(string code)
{
Color color = ColorFromString(code);
BaseColor b = new BaseColor(color);
return ColorToBaseColor(color);
}
public static BaseColor ColorToBaseColor(Color color)
{
return new BaseColor(color);
}
public static Color ColorFromString(string code)
{
string[] colors = code.Split(',');
List<int> myInts = Array.ConvertAll(colors, s => int.Parse(s)).ToList();
return Color.FromArgb(myInts[0], myInts[1], myInts[2]);
}
Related
I'm developing an application that must create a PDF file with different font styles (sometimes bold, sometimes italic and sometimes regular). The Font that I must use is Eras Medium BT (True Type), and I load it using a local file named "erasm.TTF". My question is, how can I draw text in bold or italics using my Eras font file?
I've got a legacy code that uses iText to generate a similar PDF, and to get a bold Font I just need to call this function:
public Font getFontErasMDBTBold9(){
FontFactory.register(fontPath + "erasm.TTF", "ERASM");
fontErasMDBT9 = FontFactory.getFont("ERASM", 9, Font.BOLD, Color.BLACK);
return fontErasMDBT9;
}
Edit:
I've seen in other questions that it can be done using different font variants, or artificially by using raw commands. What I want is to use the original font and set some text to be bold, other text italics and the rest just regular.
Is it possible to open a Font in bold style or italic style like in iText?
Thanks for your comments and advices. Finally I used the setRenderingMode method of the PDFPageContentStream class to set the different styles of my text. Here's a private method to write some text with the desired render mode:
private void writeText(PDPageContentStream contentStream, String text, PDFont font,
int size, float xPos, float yPos, RenderingMode renderMode = RenderingMode.FILL) {
contentStream.beginText()
contentStream.setFont(font, size)
contentStream.newLineAtOffset(xPos, yPos)
contentStream.setRenderingMode(renderMode)
contentStream.showText(text)
contentStream.endText()
}
And here is the code to write regular text and bold text.
private void addFrontPage(PDDocument document) {
PDPage frontPage = newPage()
PDPageContentStream contentStream = new PDPageContentStream(document, frontPage)
// Write text
String text = "This is a bold text"
writeText(contentStream, text, eras, 18, 25, 500, RenderingMode.FILL_STROKE)
text = "and this is a regular text"
writeText(contentStream, text, eras, 9, 25, 480)
contentStream.close()
document.addPage(frontPage)
}
Note: The code is writen in Groovy language.
Here is a full example to explain how to render the used font to appear in Italic & bold:
String message = "This is a message in the page.";
PDDocument document = new PDDocument();
PDPage page = new PDPage();
PDPageContentStream contentStream = new PDPageContentStream( document, page, AppendMode.APPEND, true, true);
contentStream.beginText();
contentStream.setFont( font, fontSize ); // set font and font size.
contentStream.setNonStrokingColor( 1f, 0, 0 ); // set text color to red
// Modify font to appear in Italic:
Matrix matrix = new Matrix( 1, 0, .2f, 1, 7, 5 );
contentStream.setTextMatrix( matrix );
// Modify the font to appear in bold:
contentStream.setRenderingMode( RenderingMode.FILL_STROKE );
contentStream.setStrokingColor( 1f, 0, 0 );
// Write text:
contentStream.showText( message );
contentStream.endText();
contentStream.close();
document.addPage( page );
document.save( PDF_FILE_PATH );
document.close();
Using C# and Winforms, I want to display a PDF, select a rectangular region, and then extract that area of text from a number of PDFs. For displaying the PDF, I have a number of options...
Use an "Adobe PDF Reader" control to display the PDF - However, I cant use mouseover events and according to https://forums.adobe.com/thread/1640606 its just not possible to select a region.
Use a "WebBrowser" control to display the PDF, but it appears I have the same issue with mouseover events and cannot select a region.
Convert the PDF to an image (using ghostscript in my case) and displaying it in a picturebox. I'm finding the most success here, as I can now generate and record the coordinates of a rectangular region. When I take these coordinates and apply them to the PDF using Itext, I don't think my rectangular region translates correctly.
My question is, How do I render the GhostScripted image in a picture box maintaining the same ratios so that my coordinates will line up with the PDF?
Thank you in advance for the down votes!!
Here is the current state of my code... Everything works with the exception that my units are off in space somewhere. The action DOES return text, but it's never the text I selected. Im sure its a combination of the coordinate system / units and I will continue to try to understand this.
---- update
With a PDF at 0 deg rotation (portrait), I think the following holds true, or is at least working for me right now... User Units having not been changed, the coordinates taken from selecting in the picturebox need adjusting. The Y coordinates need to be subtracted from the overall height while the X coordinate remains the same.
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(first.X, 3024-first.Y, last.X, 3024-last.Y);
This is picking text up exactly as expected on 0 deg rotated PDFs. On 90 deg rotated PDFs, the X and Y coordinates just need to be swapped.I am updating the code snippet below to show my working example.
using System;
using System.Drawing;
using System.Windows.Forms;
using Ghostscript.NET.Rasterizer;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
namespace formPdf
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string fileName; // The filename of the pdf
float width; // The width of the PDF in pixels
float hight; // the Height of the PDF in pixels
float rotation; // the Rotation of the PDF 0 or 90
float llx = 0; // The Lower Left X value for applying to the PDF
float lly = 0; // the Lower Left Y value for applying to the PDF
float urx = 0; // the Upper Right X value for applying to the PDF
float ury = 0; // the Upper Right Y value for applying to the PDF
// OnCLick event to open the file browser and select a file... The Width, Height and rotation values are set and the program
// is directed to render the First page of the pdf by calling the setPicture function
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
fileName = openFileDialog1.FileName;
PdfReader reader = new PdfReader(fileName);
iTextSharp.text.Rectangle dim = reader.GetPageSizeWithRotation(1);
width = dim.Width;
hight = dim.Height;
rotation = dim.Rotation;
setPicture(openFileDialog1.FileName);
} catch
{
// do nothing for now
}
}
}
// Using Ghostscript, the image is rendered to a picturebox. DPIs are set assuming the PDF default value is used
private void setPicture(string fileName)
{
GhostscriptRasterizer rasterizer = new GhostscriptRasterizer();
rasterizer.Open(fileName);
Image img = rasterizer.GetPage(72, 72, 1);
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox1.Image = img;
}
// Declare point variables for the user defined rectangle indicating the locatoin of the PDF to be searched...
Point first = new Point();
Point last = new Point();
// The first point is collected on the MouseDown event
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
first = e.Location;
}
// The second point is collected on the mouse down event. Points to be applied to the PDF are adjusted based on the rotation of the PDF.
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
last = e.Location;
if (rotation == 0)
{
llx = first.X;
lly = hight - first.Y;
urx = last.X;
ury = hight - last.Y;
} else if(rotation == 90) {
llx = first.Y;
lly = first.X;
urx = last.Y;
ury = last.X;
}
gettext();
}
// the original PDF is opened with Itext and the text is extracted from t he defined location...
private void gettext()
{
PdfReader reader = new PdfReader(fileName);
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(llx, lly, urx, ury);
RenderFilter[] renderfilter = new RenderFilter[1];
renderfilter[0] = new RegionTextRenderFilter(rect);
ITextExtractionStrategy textExtractionStrategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), renderfilter);
string text = PdfTextExtractor.GetTextFromPage(reader, 1, textExtractionStrategy);
iTextSharp.text.Rectangle mediabox = reader.GetPageSizeWithRotation(1);
MessageBox.Show("", text+" "+mediabox+" "+first+" "+last);
}
// Image Controls....
}
}
I am using a Jface table viewer with OwnerDrawLabelProvider for multiline rows, how do I change the font style/size?
Basically you just need to get the font you want to use and set in the event GC in the measure and paint methods.
This might be something like:
private static final int TEXT_MARGIN = 3;
#Override
protected void measure(Event event, Object element)
{
String text = ... get the text
Font font = JFaceResources.getFont(JFaceResources.HEADER_FONT);
event.gc.setFont(font);
Point size = event.gc.textExtent(text);
event.width = size.x + 2 * TEXT_MARGIN;
event.height = Math.max(event.height, size.y + 2 * TEXT_MARGIN);
}
#Override
protected void paint(Event event, Object element)
{
String text = ... get the text
Font font = JFaceResources.getFont(JFaceResources.HEADER_FONT);
event.gc.setFont(font);
event.gc.drawText(text, event.x + TEXT_MARGIN, event.y + TEXT_MARGIN, true);
}
Here I am using JFaceResources.getFont to get one of the existing JFace fonts. You can also create your own font - but be sure to do this only once do not create it every time measure or paint is called.
I'm using iTextSharp to add a watermark to existing PDF files. When viewing these files on screen, the watermark and PDF appears correctly. However, when printing on certain printers (2 out of 3 that have been tested by the client), the watermark seems to interfere with the content that is above it causing it to appear malformed when printed.
The PDF's are of CAD drawings (i.e. electrical circuit drawings etc.)
The code being used to apply the watermark is below. The PdfContentByte is retrieved by a call to GetOverContent from the class PdfStamper
private void AddWaterMark(PdfContentByte dc, string text, BaseFont font, float fontSize, float angle, BaseColor color, Rectangle realPageSize, Rectangle rect = null)
{
var gstate = new PdfGState { FillOpacity = 0.1f, StrokeOpacity = 0.3f };
dc.SaveState();
dc.SetGState(gstate);
dc.SetColorFill(color);
dc.BeginText();
dc.SetFontAndSize(font, fontSize);
var ps = rect ?? realPageSize; /*dc.PdfDocument.PageSize is not always correct*/
var x = (ps.Right + ps.Left) / 2;
var y = (ps.Bottom + ps.Top) / 2;
dc.ShowTextAligned(Element.ALIGN_CENTER, text, x, y, angle);
dc.EndText();
dc.RestoreState();
}
Here is an example of what it looks like on screen:
Here is what it looks like when printed on some of the printers:
Can anyone give me any idea on why certain printers will not print the PDF correctly and if I can change the way I apply the watermarks to avoid this issue?
I'm dynamically parsing data and adding text as Run, Hyperlinks and images as InlineUIContainer into a Windows Phone 8.0 RichTextBox. Somehow I can't manage that the images vertically align centered with the text.
Images are added like this:
Paragraph paragraph = new Paragraph();
richTextBox.Blocks.Add(paragraph);
var img = new Image
{
Stretch = Stretch.Uniform,
Source = imageSource,
VerticalAlignment = VerticalAlignment.Center,
Height = inlineImageSize,
};
paragraph.Inlines.Add(new InlineUIContainer {Child = img});
And text like that:
Paragraph paragraph = new Paragraph();
richTextBox.Blocks.Add(paragraph);
paragraph.Inlines.Add(new Run { Text = text });
I tried to set a few values for alignment on the RichTextBox as well, but the text is never centered with the images. The text is always bottom aligned.
Any chance getting the inline images vertically centered with the inline text in the WP RichTextBox?
I think what you are looking for is the BaselineAlignment Property.
try the following :
Paragraph paragraph = new Paragraph();
richTextBox.Blocks.Add(paragraph);
var img = new Image
{
Stretch = Stretch.Uniform,
Source = imageSource,
BaselineAlignment = BaselineAlignment.Center,
Height = inlineImageSize,
};
paragraph.Inlines.Add(new InlineUIContainer {Child = img});
Sorry for late reply. Try to set Margin for your Inline Images:
Paragraph paragraph = new Paragraph();
richTextBox.Blocks.Add(paragraph);
var img = new Image
{
Stretch = Stretch.Uniform,
Source = imageSource,
Height = inlineImageSize,
Margin = new Thickness(0,0,0,-5);
};
paragraph.Inlines.Add(new InlineUIContainer {Child = img});