5

I'm using C# and the PDFium library to print a PDF to a particular label printer. When I print this PDF via Chrome, Edge, or my application, the quality is questionable. When I print through Adobe Reader or Foxit Reader, the quality is exactly what I want.

Here is an image on imgur of the differences: https://i.stack.imgur.com/twhPD.jpg

My application is the one labeled "Network Print". As you can see in the image, its quality matches what browsers are doing. In particular, the small text on the right is my concern.

So what are the desktop PDF readers doing differently when printing from them?

Here's the bit of code that actually prints the PDF in C#:

public static Boolean Print(PrintQueue printer, byte[] content, Boolean landscape)
{
    using (MemoryStream stream = new MemoryStream(content))
    {
        PdfDocument doc = PdfDocument.Load(stream);
        PrintDocument pd = GetPrintDocumentAsPDF(printer.Name, doc, landscape);
        pd.Print();
        return true;
    }
}

private static PrintDocument GetPrintDocumentAsPDF(String printerName, PdfDocument doc, Boolean landscape)
{
    PdfPrintMultiplePages multiPages = new PdfPrintMultiplePages(1, 1, landscape ? System.Windows.Forms.Orientation.Horizontal : System.Windows.Forms.Orientation.Vertical, 0);
    PdfPrintSettings settings = new PdfPrintSettings(PdfPrintMode.CutMargin, multiPages);

    PrintDocument pd = doc.CreatePrintDocument(settings);
    pd.PrinterSettings.PrinterName = printerName;

    Rectangle firstPage = GetSizeForDoc(doc, 0);

    pd.DefaultPageSettings.Landscape = landscape;

    // Find the closest matching media profile based on the size of the first page
    PaperSize bestFit = GetBestFitMediaProfile(firstPage.Width, firstPage.Height, landscape, pd.PrinterSettings.PaperSizes);

    if (bestFit != null)
    {
        pd.DefaultPageSettings.PaperSize = bestFit;
    }
    else
    {
        Util.RestLog("!!! No matching media profile. Using default !!!");
    }

    return pd;
}

/// <summary>
/// Calculates the size of a page from a document
/// </summary>
/// <param name="doc">the document to get the page from</param>
/// <param name="page">the page number to get the size for</param>
/// <returns>a rectangle with the width and height of the page</returns>
private static Rectangle GetSizeForDoc(PdfDocument doc, int page)
{
    // Calculate the actual size of the document
    SizeF docSize = doc.PageSizes[page];
    Rectangle docBounds = new Rectangle(0, 0, (int)Math.Floor(docSize.Width / DOT_PER_INCH * 100),
        (int)Math.Floor(docSize.Height / DOT_PER_INCH * 100));

    return docBounds;
}

/// <summary>
/// For a given width and height (of a document page), determines the smallest available media profile
/// that can be printed to while still encompassing the entire page
/// </summary>
/// <param name="width">width of the page to print</param>
/// <param name="height">height of the page to print</param>
/// <param name="mediaProfiles">the media profiles available on the print being printed to</param>
/// <returns></returns>
private static PaperSize GetBestFitMediaProfile(int width, int height, bool landscape, PrinterSettings.PaperSizeCollection mediaProfiles)
{
    PaperSize mediaProfile = null;
    double docLong = Math.Round((landscape ? width : height) * 1f, 2);
    double docShort = Math.Round((landscape ? height : width) * 1f, 2);

    double profileLong;
    double profileShort;

    foreach (PaperSize profile in mediaProfiles)
    {
        Util.RestLog("Found media profile: " + profile.Width + " x " + profile.Height);

        double profileWidth = Math.Round(profile.Width * 1f, 2);
        double profileHeight = Math.Round(profile.Height * 1f, 2);

        profileLong = landscape ? profileWidth : profileHeight;
        profileShort = landscape ? profileHeight : profileWidth;

        if (mediaProfile == null)
        {
            // Grab the first media profile that is larger than the document in both width and height
            if (profileLong >= docLong && profileShort >= docShort)
            {
                mediaProfile = profile;
            }
        }
        else
        {
            // If this profile is closer to the document size than the current one
            if (profileLong >= docLong && profileShort >= docShort &&
                GetArea(profileWidth, profileHeight) < GetArea(mediaProfile.Width, mediaProfile.Height))
            {
                mediaProfile = profile;
            }
        }
    }

    return mediaProfile;
}

/// <summary>
/// Calculates an area give a width and a height
/// </summary>
/// <param name="width">the width</param>
/// <param name="height">the height</param>
/// <returns>the area of the width and height</returns>
private static double GetArea(double width, double height)
{
    return width * height;
}

Essentially, the main thing this does is selects the correct media profile for the size of the PDF document being printed. I don't believe anyone will need to see the methods that have to do with finding the correct size (GetSizeForDoc and GetBestFitMediaProfile), but I can post them if someone needs.

Troncoso
  • 2,343
  • 3
  • 33
  • 52
  • 1
    could you please post the GetSizeForDoc and GetBestFitMediaProfile methods, thanks! –  Jun 14 '18 at 00:05
  • Hey, thanks for taking the time to read my question! I have posted the additional code you requested. – Troncoso Jun 14 '18 at 15:30
  • Hi, We are having same issue. We use pdfium viewver to print and the fonts, speceally the small ones are a little blurry. We are desperated with this problem. Did you finally solved it? – Pila 77 Jan 28 '21 at 10:14
  • Hi there! I can't recall specific details, but what I ended up doing was using the Adobe/Foxit reader CLI tool directly from my C# application. That obviously has the downside of requiring the relevant program to be installed. – Troncoso Jan 28 '21 at 14:10
  • Thanks for answer!!. In our propject can´t depend of have installed Adobe/foxit so I hope find something for this really entrage problem. – Pila 77 Jan 29 '21 at 15:22
  • @Pila77 Having the same issue, what did you end up doing? – JMK Jul 01 '21 at 11:16
  • @KJ By 'having the same issue', I mean I'm having the *exact* same issue, to be clear! – JMK Jul 06 '21 at 20:23
  • 1
    I don't know if this helps you guys, but the printer in question was a Zebra GK420T, so it had a DPI of 203. – Troncoso Jul 07 '21 at 18:17
  • At the time I believe I was using Zebra's drivers from the disk. – Troncoso Jul 09 '21 at 16:23
  • Thanks guys, I'm using a ZD420 but same DPI, I'll try the bartender drivers! – JMK Jul 11 '21 at 07:12
  • @JMK Sorry for late answer... We are still with the problem :( Its frustrating – Pila 77 Aug 31 '21 at 09:13

0 Answers0