The system I am working on stamps PDF's with certain information. It does this by creating a lime green text box in the top right corner of the document. It then draws a certain string on top of the green space. This works for thousands of PDFs but for one the text is invisible even though the box is drawn. I can still select the text and copy it to something else, but it is invisible in the PDF.
Unfortunately, I cannot share the PDF but it is a PDF 1.4. What would cause this?
The code for stamping:
private static XGraphics drawString(XGraphics xgr, PdfPage page, string printString, int pageNumber = 0)
{
XFont font = new XFont("Verdana", 10, XFontStyle.BoldItalic);
var textSize = xgr.MeasureString(printString, font);
var width = textSize.Width;
var height = textSize.Height;
double xMin = 0;
double yMin = 0;
if (page.Rotate == 90)
{
xMin = page.Height - textSize.Width;
var state = xgr.Save();
xgr.DrawRectangle(XBrushes.LimeGreen, xMin, yMin, width, height);
xgr.Restore(state);
xgr.DrawString(printString, font, XBrushes.Black, new XRect(0, 0, page.Height, page.Width), topRight());
}
else
{
xMin = page.Width - textSize.Width;
var state = xgr.Save();
xgr.DrawRectangle(XBrushes.LimeGreen, xMin, yMin, width, height);
xgr.Restore(state);
xgr.DrawString(printString, font, XBrushes.Black, new XRect(0, 0, page.Width, page.Height), topRight());
}
return xgr;
}
private static XStringFormat topRight()
{
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Far;
format.LineAlignment = XLineAlignment.Near;
return format;
}
I have tried using Dipose() on xgr and reinitialising it before each of its draw actions. I have tried saving and restoring the state of xgr between draw actions as seen in the code. I have tried various fonts and font sizes with no luck either.
Let me know what metadata about the PDF is relevant and I will share that.
Using PdfSharp 1.5 GDI, I have been having this issue as well. Some pdfs would be ok, others would have 1 or 2 pages that were ok, and then others would have no pages that were ok. Text could be selected, but text could not be seen. Changing the renderMode fixes the issue.
In PdfGraphicsState.cs, there is a condition to check if _realizedRenderingMode != renderMode. However, _realizedRenderingMode and renderMode is 0 by default, so it never enters codeblock, nor does it look like there is a method for changing the renderMode unless you change the font to italic, bold, strikeout, or underline:
int _realizedRenderingMode; // Reference: TABLE 5.2 Text state operators / Page 398
public void RealizeFont(XFont font, XBrush brush, int renderingMode)
{
const string format = Config.SignificantFigures3;
// So far rendering mode 0 (fill text) and 2 (fill, then stroke text) only.
RealizeBrush(brush, _renderer._colorMode, renderingMode, font.Size); // _renderer.page.document.Options.ColorMode);
// Realize rendering mode.
if (_realizedRenderingMode != renderingMode)
{
_renderer.AppendFormatInt("{0} Tr\n", renderingMode);
_realizedRenderingMode = renderingMode;
}
Removing the condition would suffice in fixing the issue, but the renderingMode seems to only be needed 1 time for the BT (Begin Text) in XGraphicsPdfRenderer.cs.
internal void BeginTextMode()
{
if (_streamMode != StreamMode.Text)
{
_streamMode = StreamMode.Text;
_content.Append("BT\n");
// Text matrix is empty after BT
_gfxState.RealizedTextPosition = new XPoint();
_gfxState.ItalicSimulationOn = false;
}
}
So, I ended up modifying XGraphics to include XGraphicsPdfRendererOptions and passing the variable to the various methods so it can be changed regardless of location:
private XGraphicsPdfRendererOptions _renderOptions { get; set; }
public XGraphicsPdfRendererOptions RenderOptions
{
get
{
if (_renderOptions == null)
{
_renderOptions = new XGraphicsPdfRendererOptions();
}
return _renderOptions;
}
set
{
_renderOptions = value;
}
}
Keep in mind that the renderMode is originally based on whether the font is italic, bold, strikeout, or underline, which I don't really see how those relate to renderMode, in XGraphicsPdfRenderer.cs:
//bool bold = (font.Style & XFontStyle.Bold) != 0;
//bool italic = (font.Style & XFontStyle.Italic) != 0;
bool italicSimulation = (font.GlyphTypeface.StyleSimulations & XStyleSimulations.ItalicSimulation) != 0;
bool boldSimulation = (font.GlyphTypeface.StyleSimulations & XStyleSimulations.BoldSimulation) != 0;
bool strikeout = (font.Style & XFontStyle.Strikeout) != 0;
bool underline = (font.Style & XFontStyle.Underline) != 0;
Realize(font, brush, boldSimulation ? 2 : 0);
Class and enum:
public class XGraphicsPdfRendererOptions
{
public XGraphicsPdfRenderMode RenderMode { get; set; }
public bool IncludeRenderModeForPage { get; set; }
public bool IncludeRenderModeForObject { get; set; }
}
public enum XGraphicsPdfRenderMode
{
Text_Render_Mode_Fill = 0,
Text_Render_Mode_Stroke = 1,
Text_Render_Mode_Fill_Stroke = 2,
Text_Render_Mode_Invisible = 3
}
Usage:
gfx.RenderOptions = new XGraphicsPdfRendererOptions() { RenderMode = XGraphicsPdfRenderMode.Text_Render_Mode_Fill, IncludeRenderModeForPage = true };
https://github.com/zaryk/PDFsharp
I've happened across this issue a couple of times now on separate projects. I found that the simplest fix is to dispose of the XGraphics object and then simply re-instantiate it using your current PdfPage instance.
PdfSharp.Pdf.PdfPage Page = Document.AddPage();
PdfSharp.Drawing.XGraphics gfx = PdfSharp.Drawing.XGraphics.FromPdfPage(Page);
//Build your pdf here until transparency issue occurs
//Issue has occured so re-instantiate gfx object
gfx.Dispose();
gfx = PdfSharp.Drawing.XGraphics.FromPdfPage(Page);
//Continue as normal
Below is the code I use to hide something in document and edit the document and again save. Let me know if it helps you
private PdfDocument FormatPdfDocument(PdfDocument document, List<string> packingTypes, string carrierName)
{
XFont PackingTypeFont = new XFont("Calibri", 10, XFontStyle.Bold);
var i = 0;
foreach (PdfPage page in document.Pages)
{
using (var gfx = XGraphics.FromPdfPage(page))
{
var packingType = packingTypes.ElementAtOrDefault(i++) ?? "PackingType Not Found";
if (carrierName == "xxxx")
{
var packingTypeBounds = new XRect(64, 62, 200, 12);
gfx.DrawRectangle(XBrushes.White, packingTypeBounds);
gfx.DrawString(packingType, PackingTypeFont, XBrushes.Black, packingTypeBounds, XStringFormats.TopLeft);
var logoBounds = new XRect(0, 0, 130, 50);
gfx.DrawRectangle(XBrushes.White, logoBounds);
}
else if (carrierName == "yyyy")
{
var packingTypeBounds = new XRect(200, 0, 200, 12);
gfx.DrawString(packingType, PackingTypeFont, XBrushes.Black, packingTypeBounds, XStringFormats.TopLeft);
}
else if (carrierName == "zzzz")
{
var packingTypeBounds = new XRect(410, 20, 200, 12);
var state = gfx.Save();
gfx.RotateAtTransform(90, new XPoint { X = 410, Y = 20 });
gfx.DrawString(packingType, PackingTypeFont, XBrushes.Black, packingTypeBounds, XStringFormats.TopLeft);
gfx.Restore(state);
}
}
}
return document;
}
This works fine for me till date without any issues
Some possible causes to answer your question "What would cause this?":
Are you using the latest version PDFsharp 1.50 beta 3b?
IIRC there is a bug in 1.32 that can lead to unexpected behavior because some properties are not reset.
Since you see the rectangle this might be the cause.
Since you see the rectangle, this probably does not apply:
There are two ways of modifying existing pages: "append" and "prepend". Your code snippet does not show how you do it.
With "prepend" your lime rectangle could be hidden under a white filled rectangle. Watch the PDF in Adobe Reader with active Transparency Grid and check that you see the grid where the rectangle should be.
Since you see the rectangle, this probably does not apply:
Maybe your text goes to the wrong position. Check the MediaBox and CropBox settings of the PDF page you are modifying. Normally pages start at (0,0), but you cannot be sure.
Locate your text in the PDF file and compare the text position with MediaBox and CropBox.
It could be an unknown bug in PDFsharp. If you do not find a PDF that allows to replicate the issue which you can share then it will be very difficult to fix the bug. But maybe one of the options above leads to success.
So I managed to find a way to make it work. I ran the stamping process twice on the document and it worked as expected. Fortunately, stamping twice does not affect regular documents which actually work normally.
Still an issue in 1.50 for some PDF files...
As a workaround, I create a PNG file using System.Drawing.DrawString.
Bitmap bmp = new Bitmap((int)p.Width.Point, 30);
Graphics gra = Graphics.FromImage(bmp);
gra.DrawString("Hello world", new Font("Verdana", 20), Brushes.Red, new PointF(0, 0));
bmp.Save("test.png", System.Drawing.Imaging.ImageFormat.Png);
Then I use XGraphics.DrawImage from this PNG file.
XGraphics xg = XGraphics.FromPdfPage(p, XGraphicsPdfPageOptions.Append);
XImage xi = XImage.FromFile("test.png");
// Add it at the bottom of the page
xg.DrawImage(xi, 0, p.Height-32, p.Width, 30);
This always ends up on top.
Related
I have facing some problem in pdfbox.
I can't get particular words in inputted position(eg. x=20,y=30,height=100,width=100)
How I get words from particular area.
Finally I got the answer. Its working fine.
public static void ReadCooridinates(string sourceFilePath)
{
using (PDDocument pDDocument = PDDocument.load(sourceFilePath))
{
PDPage page = new PDPage();
java.util.List allPages = pDDocument.getDocumentCatalog().getAllPages();
page = (PDPage)allPages.get(0);
PDFTextStripperByArea stripper = new PDFTextStripperByArea();
stripper.setSortByPosition(true);
Rectangle rect = new Rectangle(10, 200, 100, 30);
stripper.addRegion("class1", rect);
stripper.extractRegions(page);//Assign the page to read the coordinates
Console.WriteLine("\nText in the area:" + rect + "\n");
Console.WriteLine(stripper.getTextForRegion("class1"));
}
}
I am writing a C# Direct2D application using SharpDX, however I can understand answers/examples that are provided in C++.
I want to render text and change the width of certain characters to look like the picture:
The letter B expanded to 200% and the letter D is reduced to 50%
In the code below I draw the geometry of the glyphs
And so it is possible to change the width of geometry
But that's not a good solution, because a geometry drawing comes out as blurred as you see in the picture.
In conclusion, there are two questions:
How I change the width of the characters?
How to draw geometries of letters without blurring. (it is possible to render geometry with ClearType?)
private void RenderGlyphRun1(FontFace1 fontFace)
{
var Offsets = new List<GlyphOffset>();
var fontEmSize_ = 12;
GlyphRun glyphRun = new GlyphRun();
glyphRun.FontFace = fontFace;
glyphRun.FontSize = fontEmSize_;
glyphRun.BidiLevel = 1;
var left = 650f;
var top = 50f;
var baseLine = (float)(fontFace.Metrics.LineGap + fontFace.Metrics.Ascent) /
fontFace.Metrics.DesignUnitsPerEm * glyphRun.FontSize;
string textToDraw = "ABCDE";
foreach (char letter in textToDraw)
{
Offsets.Add(new GlyphOffset());
}
var charArr = textToDraw.Select(x => (int)x).ToArray();
glyphRun.Indices = fontFace.GetGlyphIndices(charArr);
var metrics = fontFace.GetDesignGlyphMetrics(glyphRun.Indices, false);
glyphRun.Advances = metrics.Select(x => (float)x.AdvanceWidth /
fontFace.Metrics.DesignUnitsPerEm * glyphRun.FontSize).ToArray();
glyphRun.Offsets = Offsets.ToArray();
RenderTarget2D.BeginDraw();
RenderTarget2D.Clear(SharpDX.Color.White);
RenderTarget2D.DrawGlyphRun(new Vector2(left, top),
glyphRun, new SharpDX.Direct2D1.SolidColorBrush(RenderTarget2D, SharpDX.Color.Black),
MeasuringMode.Natural);
top += baseLine;
var pathGeometry = new PathGeometry(Factory2D);
var geometrySink = pathGeometry.Open();
fontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices,
glyphRun.Advances, glyphRun.Offsets, glyphRun.IsSideways,
glyphRun.BidiLevel % 2 != 0, geometrySink);
geometrySink.Close();
geometrySink.Dispose();
fontFace.Dispose();
var matrix = new Matrix3x2()
{
M11 = 1,
M12 = 0,
M21 = 0,
M22 = 1,
M31 = left,
M32 = top
};
var transformedGeometry = new TransformedGeometry(Factory2D, pathGeometry, matrix);
var brushColor = (Color4)SharpDX.Color.Black;
var brush = new SolidColorBrush(RenderTarget2D, brushColor);
RenderTarget2D.FillGeometry(transformedGeometry, brush);
pathGeometry.Dispose();
transformedGeometry.Dispose();
brush.Dispose();
RenderTarget2D.EndDraw();
}
Since some of the letters should be narrow and some are normal and some are wide, you can not use one GlyphRun, but must create 3 different GlyphRun.
To cause all letters of any GlyphRun to be wide or narrow:
Configure Transform to RenderTarget
Draw the GlyphRun
Return the original Transform
Wide transform: RenderTarget2D.Transform = new SharpDX.Mathematics.Interop.RawMatrix3x2(1.5f, 0, 0, 1, 0, 0);
Narrow transform: RenderTarget2D.Transform = new SharpDX.Mathematics.Interop.RawMatrix3x2(0.5f, 0, 0, 1, 0, 0);
After this solution you do not need to convert GlyphRun to geometry and get mixed up with blurred letters.
Direct2D text rendering functionality is offered in two parts:
1) DrawText and DrawTextLayout method, enables a caller to pass either a string and formatting parameters or a DWrite text layout object for multiple formats. This should be suitable for most callers.
2) The second way is to render text, exposed as the DrawGlyphRun method, provides rasterization for customers who already know the position of the glyphs they want to render. The following two general rules can help improve text performance when drawing in Direct2D.
I now see that you are using the second approach, but in the first one, you can set the rendering to ClearType :
RenderTarget2D.TextAntialiasMode = TextAntialiasMode.Cleartype;
I am not sure how to include it in you example, but the Sharp DX example looks like this:
using System;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.DirectWrite;
using SharpDX.Samples;
using TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode;
namespace TextRenderingApp
{
public class Program : Direct2D1DemoApp
{
public TextFormat TextFormat { get; private set; }
public TextLayout TextLayout { get; private set; }
protected override void Initialize(DemoConfiguration demoConfiguration)
{
base.Initialize(demoConfiguration);
// Initialize a TextFormat
TextFormat = new TextFormat(FactoryDWrite, "Calibri", 128) {TextAlignment = TextAlignment.Center, ParagraphAlignment = ParagraphAlignment.Center};
RenderTarget2D.TextAntialiasMode = TextAntialiasMode.Cleartype;
// Initialize a TextLayout
TextLayout = new TextLayout(FactoryDWrite, "SharpDX D2D1 - DWrite", TextFormat, demoConfiguration.Width, demoConfiguration.Height);
}
protected override void Draw(DemoTime time)
{
base.Draw(time);
// Draw the TextLayout
RenderTarget2D.DrawTextLayout(new Vector2(0,0), TextLayout, SceneColorBrush, DrawTextOptions.None );
}
[STAThread]
static void Main(string[] args)
{
Program program = new Program();
program.Run(new DemoConfiguration("SharpDX DirectWrite Text Rendering Demo"));
}
}
}
Sample taken from: https://github.com/sharpdx/SharpDX-Samples/blob/master/Desktop/Direct2D1/TextRenderingApp
I am making an application that creates a watermark on a PDF that the user selects and I can't seem to get the watermark to appear on the selected PDF but I also get no errors. Any help would be appreciated.
I am using PDFsharp version 1.50.4000
public void WaterMarkPDF(string sourceFileName)
{
try
{
string watermark = "watermark";
int emSize = 100;
string file ="test.pdf";
File.Copy(sourceFileName, file, true);
File.SetAttributes(file, File.GetAttributes(file) & ~FileAttributes.ReadOnly);
// Take in pdf from the form
PdfDocument document = PdfReader.Open(file);
// change the version cause sometimes newer versions break it
if (document.Version < 14)
document.Version = 14;
XFont font = new XFont("Times New Roman", emSize, XFontStyle.BoldItalic);
for (int idx = 0; idx < document.Pages.Count; idx++)
{
var page = document.Pages[idx];
// Get an XGraphics object for drawing beneath the existing content.
var gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
// Get the size (in points) of the text.
var size = gfx.MeasureString(watermark, font);
// Define a rotation transformation at the center of the page.
gfx.TranslateTransform(page.Width / 2, page.Height / 2);
gfx.RotateTransform(-Math.Atan(page.Height / page.Width) * 180 / Math.PI);
gfx.TranslateTransform(-page.Width / 2, -page.Height / 2);
// Create a string format.
var format = new XStringFormat();
format.Alignment = XStringAlignment.Near;
format.LineAlignment = XLineAlignment.Near;
// Create a dimmed red brush.
XBrush brush = new XSolidBrush(XColor.FromArgb(128, 255, 0, 0));
// Draw the string.
gfx.DrawString(watermark, font, brush,
new XPoint((page.Width - size.Width) / 2, (page.Height - size.Height) / 2),
format);
// Save the document...
document.Save(file);
// ...and start a viewer.
Process.Start(file);
}
}
catch (Exception e)
{
throw e;
}
}
Maybe try XGraphicsPdfPageOptions.Appendinstead of XGraphicsPdfPageOptions.Prepend.
Call document.Save and Process.Startoutside the for loop.
Update: Explanation: With XGraphicsPdfPageOptions.Prepend the watermark is drawn below the original PDF page. Most PDF files consist of black text on transparent background and the watermark will be visible there (you can check this by activating the Transparency Grid in Adobe Reader). For PDF pages with a solid background (e.g. images, tables with a background colour, ...) the watermark will not be visible.
The PDFsharp source code includes a Watermark sample:
http://pdfsharp.net/wiki/Watermark-sample.ashx
There are two variants that add a semi-transparent text on top of the existing PDF page. These variants also work for PDF pages without transparency.
I'm trying the create a multiple-page pdf using iTextSharp, but I'm having some issue creating a loop to have more than a single page.
My code below is working well for one page; however, my content will not fit into a single page. Thanks.
How can I write a loop to write contents on the first pdf page and the remaining to the second, third, etc...So far, I'm only seeing one page. Thank you.
int height = 600;
int totalPage = 1;
int oldPage = 1;
bool cons = false;
bool st = false;
foreach (string al in combo)
foreach (string al in combo) //my loop to write on the pdf but "combo" has 100 lines, which would fit into a single page.
{
string[] word = al.Split(',');
int strIndex = combo.IndexOf(al);
if (al.Length != 0)
{
if (word[0].ToString().ToUpper().Contains("(REV")==true && cons == false)
{
cb.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 11);
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "CONSTRUCTION PRINTS", 80, height, 0);
cb.EndText();
height = height - 20;
cons = true;
}
if (word[0].ToString().ToUpper().Contains("(REV")==false && st == false)
{
cb.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 11);
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "SAG & TENSION CHARTS", 80, height, 0);
cb.EndText();
height = height - 20;
st = true;
}
cb.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 11);
totalPage = totalPage + oldPage;
// write the text in the pdf content
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, word[0].ToString().ToUpper(), 80, height, 0);
cb.EndText();
// write the text in the pdf content
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "......................................................................................", 335, height, 0);
cb.EndText();
// write the text in the pdf content
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, totalPage.ToString(), 500, height, 0);
cb.EndText();
oldPage = Convert.ToInt32(word[1]);
}
height = height - 20;
}
//// create the new page and add it to the pdf
// reader = new PdfReader(oldFile);//old file
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
//// close the streams and voilá the file should be changed :)
document.Close();
reader.Close();
fs.Close();
writer.Close();
Please go to the official documentation and click Q&A to go to the most frequently asked questions. Pick the Getting started category. The first thing you'll see, is the most popular iText example (which I am porting to C# for your convenience):
// step 1
Document document = new Document();
// step 2
FileStream fs = new FileStream("hello.pdf", FileMode.Create);
PdfWriter.GetInstance(document, fs);
// step 3
document.Open();
// step 4
document.Add(new Paragraph("Hello World!"));
// step 5
document.Close();
In your code, you are adding text at absolute positions by introducing PDF syntax, such as BeginText() (BT) / EndText() (ET) / SetFontAndSize() (Tf). This is creating PDF the hard way. If is very easy to make mistakes, as shown in this question: What is causing syntax errors in a page created with iText?
If you don't know the PDF reference (ISO 32000-1) by heart, you should avoid code like this. Instead you can use objects such as Paragraph, List, PdfPTable... The beauty of adding these objects to a Document using the Add() method, is that a new page gets triggered automagically as soon as a page is full. You can also trigger a new page yourself using:
document.NewPage();
If you want to add text at absolute positions, iText offers convenience methods and objects such as ColumnText. See my answer to Adding footer to existing PDF
You can define a Rectangle and add objects such as Paragraph, List, PdfPTable... Take a look at the answer to the question How to continue an ordered list on a second page? for inspiration:
ColumnText ct = new ColumnText(cb);
ct.AddElement(list);
Rectangle rect = new Rectangle(36, 36, 559, 806);
ct.SetSimpleColumn(rect);
int status = ct.Go();
while (ColumnText.HasMoreText(status)) {
document.NewPage();
ct.SetSimpleColumn(rect);
ct.Go();
}
The while loop is the loop you are looking for.
I am using wkHTMLtoPDF and I want to change orientation on the PDF based on the length of the headers in the HTML, but I'm not sure if it's the right way to do this.
private const double A4Width = 2480; // A4 pixel width
Landscape detection method
private bool IsLandscape(string html)
{
int start = html.IndexOf("<th>");
int end = html.LastIndexOf("</th>") - start;
string tableHeadings = html.Substring(start, end).Replace("<th>", string.Empty).Replace("</th>", string.Empty);
FontFamily fontFamily = new FontFamily("Arial");
Font font = new Font(fontFamily, 13);
var size = MeasureString(tableHeadings, font);
if(size.Width > A4Width)
{
return true;
}
return false;
}
Method for font calculus
private SizeF MeasureString(string content, Font font)
{
SizeF result = SizeF.Empty;
using (var image = new Bitmap(1,1))
{
using (var g = Graphics.FromImage(image))
{
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
result = g.MeasureString(content, font, int.MaxValue, StringFormat.GenericTypographic);
}
}
return result;
}
Note: This code is in a library so that is the reason I have used this question to measure string.
Update
To be short:
I am looking for a best practice of implementing the problem.
The problem summary:
I am building from HTML a PDF that has a table inside.
I get the table columns (eg: Col1, Col2) and remove the tags (eg: Col1Col2).
Next I want to calculate the size (in px) of that string result (using a Font with a specified text size), and if that size excedes the A4 portrait size than rotate the PDF to the landscape orientation.
I have found that the best implementation of this problem is to add to wkHTMLtoPDF an attribute to force the PDF to be A4 size.
Attribute used : --page-size A4
Also I have changed the code that checks if the measured width size is grater than the A4 size.
if(size.Width > (A4Width / 4))
{
return true;
}