Click here to Skip to main content
11,575,109 members (65,122 online)
Click here to Skip to main content

View PDF files in C# using the Xpdf and muPDF library, Print PostScript.

, 26 Nov 2010 GPL3 505.3K 244 228
Rate this:
Please Sign up or sign in to vote.
Wrapper C# class written in C++\CLI and a sample implementation in C# to render PDF files.

AFPDFLib

Introduction 

Xpdf is an Open Source library released under GPL license; they have an ActiveX with commercial license, but some time ago, before I knew about this commercial control, I wrote this wrapper library to render PDF files in C#. 

Background

The basic idea is create a preview of PDF files in C#. After looking at many places in the internet, I found this wonderful library; the only problem is that the library uses XLib, and there is no XLib available for Windows. Fortunately, Xpdf can render the generated PDF into a Win32 DC.

Writting the wrapper

C++\CLI can mix managed and unmanaged code thanks to the IJW technology, so I was thinking that maybe I could to link the xpdf lib to the wrapper. The problem is that xpdf has some classes that are also declared in .Net, the solution was compile a C++ project with a class that includes only the necessary files to do the interop.
This library (AFPDFLib) contains a simple class that works like a proxy between C++ and C++\CLI, keeping the xpdf objects into the unmanaged Heap.
The C# wrapper is linked to AFPDFLib statically, and this only includes:
AFPDFDocInterop.h
OutlineItemInterop.h
SearchResultInterop.h
The classes:
AFPDFDoc -> Implement the methods that needs xpdf.
AFPDFDocInterop -> Write the methods to wrap into C#
PDFWrapper -> Wrapped methods

Marshal Strings:
IntPtr ptr = Marshal::StringToCoTaskMemAnsi(fileName);
char *singleByte= (char*)ptr.ToPointer();
try{
}finally{
     Marshal::FreeCoTaskMem(ptr);
}   

For releasing resources is necessary implement IDisposable:

!PDFWrapper()
{
   _pdfDoc->Dispose();
} 

Using the code  

The file xpdfWin-Interop.sln includes all the necessary files, you can also download the last version from http://www.foolabs.com/xpdf/ and recompile without the files that requires XLib.

The Build Project Order is as follows: freetype,xpdf,AFPDFLib, PDFLibNet. Once compiled PDFLibNet, it can be used in C# code:    

OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "Portable Document Format (*.pdf)|*.pdf";
if (dlg.ShowDialog() == DialogResult.OK)
{
    _pdfDoc = new PDFLibNet.PDFWrapper();
    _pdfDoc.LoadPDF(dlg.FileName);
    _pdfDoc.CurrentPage = 1;

   PictureBox pic =new PictureBox();
   pic.Width=800;
   pic.Height=1024;
   _pdfDoc.FitToWidth(pic.Handle);
   pic.Height = _pdfDoc.PageHeight;
   _pdfDoc.RenderPage(pic.Handle);
   
   Bitmap _backbuffer = new Bitmap(_pdfDoc.PageWidth, _pdfDoc.PageHeight);
   using (Graphics g = Graphics.FromImage(_backbuffer))
   {
       _pdfDoc.RenderHDC(g.GetHdc);
       g.ReleaseHdc();
   }
   pic.Image = _backbuffer;
}   

It is necessary create a PictureBox because the class implements only a method that accepts an HWND, because in the first instance, I was trying to implement the scroll into the same control that the PDF is rendered. In the included sample, the scroll is controlled by a Panel container.

Xpdf can export the PDF to a PostScript file. For printing this is the best option if you have a PostScript Printer:       

PSOutputDev *psOut =new PSOutputDev((char *)fileName,m_PDFDoc->getXRef(),m_PDFDoc->getCatalog(),fromPage,toPage,psModePS);
if(psOut->isOk()){
    m_PDFDoc->displayPages(psOut,fromPage,toPage,PRINT_DPI,PRINT_DPI,0,gTrue,globalParams->getPSCrop(),gTrue);
}
delete psOut;  

The file must be sended in RAW format (http://support.microsoft.com/kb/322091)

JPG Export 

For async export: 

 _doc.ExportJpg(filename, 
1,        //From page
1,        //To page
150,      //Resolution in DPI
90,       //Jpg quality 
if you need a sync operation its posible especify a wait time:
 _doc.ExportJpg(filename, 
1,        //From page
1,        //To page
150,      //Resolution in DPI
90,       //Jpg quality
-1);      //Time to wait, -1 to infinite.
 If the file name does not contains a %d token (for the page number), then the procedure replaces .jpg with -page%d.jpg.  PDFWrapper exposes two events ExportJpgProgress and ExportJpgFinished. Both events are called from the exporting Thread, so it is necesary to make a security call using Invoke, check frmExportJpg for a sample.  

History:    

06\July\2009:
  • Full deployed solution.
  • Updated to xpdf 3.0.2 version.
  • FreeType updated to 2.3.1
  • When click in a bookmark and search, the page scroll to the correct position.
  • PostScript implemented. 
  • Now gets the Title, Author.  
08\July\2009
  • Some memory leaks corrected 
  • Prerender next page in new thread 
  • Cache of pages  
  • Mouse Scrolling 
  • Mouse Navigation 
  • Load links from page (LinkURI, LinkGoTo) 
11\July\2009 
  • Using DIB Sections,  fixes the problem with the zoom.
  • Added control PageViewer, now render only the viewable area
  • Open password protected files.
  • Export to txt
  • Export to jpg
12\July\2009
  • Added support for Unicode in Bookmarks, title, subject, keywords...
  • Added support for named destinations
13\July\2009
  • Fixed some bugs.
  • Added support for unicode search
20\July\2009  
  • Multithread jpg export
  • Fixed others bugs
07\Nov\2009 
  • Added MuPDF as second renderer. 
 26\NOV\2010 Know issues:     MuPDF has some problems with transparency, but is faster than xpdf.  A couple of memory leaks.

IMPORTANT:         

MuPDF uses recursion for analyze the tree document, so is necessary increment the Stack Size to at least 4mb to avoid problems with some complex files (editbin for C#, VB.Net exe's). Soon or later the recursion causes an stack overflow if the tree is so big, so while it is fixed that is the most important issue.

To Do:        

- Apply last xpdf patche - Show multiple pages in the viewer. - Improve user interface. - Implement LoadFromStream for MuPDF. There is missing some functionality that can be extracted from xpdf: - Enable selection, image extraction and instant snapshot. - Print in non PostScript printers.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Antonio Sandoval
Engineer HidraQuim SA de CV
Mexico Mexico
I'm a Chemical Engineering that loves the programming.
2003 - Graduated from Technical Programmer UNIVA México.
2009 - Graduated from Chemical Engineering Universidad de Guadalajara, Mexico.
Programmer by Hobby since 6 years ago.

You may also be interested in...

Comments and Discussions

 
QuestionHow to search text while using mupdf Pin
miralireza27-May-13 19:36
membermiralireza27-May-13 19:36 
AnswerRe: How to search text while using mupdf Pin
Member 105864714-Aug-14 23:16
memberMember 105864714-Aug-14 23:16 
QuestionLinks? Pin
tntblow26-Mar-13 10:03
membertntblow26-Mar-13 10:03 
QuestionHelp!!! I need .net 1.1 version Pin
xiaoheibai18-Nov-12 22:15
memberxiaoheibai18-Nov-12 22:15 
QuestionWhere can I get .sln project file?? Pin
Phiru3-Apr-12 14:05
memberPhiru3-Apr-12 14:05 
QuestionIs that easy to do a whole document search and list all results? Pin
Mayaya6520-Feb-12 19:18
memberMayaya6520-Feb-12 19:18 
QuestionIs this Compatible with .Net FrameWork 4.0? Pin
Sankaroo72-Feb-12 1:48
memberSankaroo72-Feb-12 1:48 
AnswerRe: Is this Compatible with .Net FrameWork 4.0? Pin
Barbara Post1-Jun-12 1:58
memberBarbara Post1-Jun-12 1:58 
Questioncan I used PDFLibNet.dll in commercial applications on the CPOL license?? Pin
kikimart.japan25-Dec-11 17:59
memberkikimart.japan25-Dec-11 17:59 
QuestionPDFLibNet.dll for VS2003 Pin
lianganton6-Dec-11 18:38
memberlianganton6-Dec-11 18:38 
Help:Has a "PDFLibNet.dll" for VS2003 to add reference?if had,where is download?

modified 7-Dec-11 19:35pm.

QuestionText Position Pin
davfeu29-Nov-11 21:23
memberdavfeu29-Nov-11 21:23 
QuestionHola antonio, sin embargo cuando levanto una version en visual basic Pin
GL_Terminator11-Oct-11 7:17
memberGL_Terminator11-Oct-11 7:17 
AnswerRe: Hola antonio, sin embargo cuando levanto una version en visual basic Pin
Antonio Sandoval11-Oct-11 9:03
memberAntonio Sandoval11-Oct-11 9:03 
QuestionHelp... System.AccessViolationException Pin
Gabriel_7524-Aug-11 16:26
memberGabriel_7524-Aug-11 16:26 
AnswerRe: Help... System.AccessViolationException Pin
Antonio Sandoval11-Oct-11 9:04
memberAntonio Sandoval11-Oct-11 9:04 
QuestionSearch function crashes Pin
cricrides3-Aug-11 2:38
membercricrides3-Aug-11 2:38 
QuestionHow can i get this dll CJK(chinese Japanise Koreal )supported? Pin
zhuoml2-Aug-11 16:47
memberzhuoml2-Aug-11 16:47 
Question.net 2.0. Pin
Josip Habjan19-Jul-11 0:11
memberJosip Habjan19-Jul-11 0:11 
QuestionHow can I merge the code with the latest mupdf? Pin
wmjordan4-Jul-11 23:46
memberwmjordan4-Jul-11 23:46 
GeneralI have the fix for the muPDF rendering memory leak [modified] Pin
Ron Schuler29-May-11 15:57
memberRon Schuler29-May-11 15:57 
AnswerRe: I have the fix for the muPDF rendering memory leak Pin
Antonio Sandoval30-May-11 5:54
memberAntonio Sandoval30-May-11 5:54 
GeneralRe: I have the fix for the muPDF rendering memory leak Pin
Ron Schuler30-May-11 6:08
memberRon Schuler30-May-11 6:08 
GeneralRe: I have the fix for the muPDF rendering memory leak Pin
Ron Schuler30-May-11 6:20
memberRon Schuler30-May-11 6:20 
GeneralRe: I have the fix for the muPDF rendering memory leak Pin
Pizzamaka32122-Nov-11 1:29
memberPizzamaka32122-Nov-11 1:29 
GeneralRenderNotifyFinished handler not being removed Pin
Ron Schuler25-May-11 16:48
memberRon Schuler25-May-11 16:48 
GeneralRe: RenderNotifyFinished handler not being removed [modified] Pin
Ron Schuler28-May-11 4:41
memberRon Schuler28-May-11 4:41 
GeneralRe: RenderNotifyFinished handler not being removed Pin
Antonio Sandoval28-May-11 7:33
memberAntonio Sandoval28-May-11 7:33 
GeneralRe: RenderNotifyFinished handler not being removed Pin
Ron Schuler28-May-11 6:25
memberRon Schuler28-May-11 6:25 
GeneralRe: RenderNotifyFinished handler not being removed Pin
Antonio Sandoval28-May-11 7:38
memberAntonio Sandoval28-May-11 7:38 
GeneralSaveAs in PDFWrapper without loseless color on Render [modified] Pin
pioner198711-May-11 23:53
memberpioner198711-May-11 23:53 
GeneralRe: SaveAs in PDFWrapper without loseless color on Render Pin
Antonio Sandoval20-May-11 17:42
memberAntonio Sandoval20-May-11 17:42 
GeneralPlease help! Pin
wsmwlh11-Apr-11 15:43
memberwsmwlh11-Apr-11 15:43 
AnswerRe: Please help! Pin
Antonio Sandoval16-May-11 9:54
memberAntonio Sandoval16-May-11 9:54 
QuestionRe: Please help! Pin
wsmwlh18-May-11 22:25
memberwsmwlh18-May-11 22:25 
AnswerRe: Please help! Pin
Antonio Sandoval19-May-11 5:03
memberAntonio Sandoval19-May-11 5:03 
QuestionRe: Please help! [modified] Pin
wsmwlh19-May-11 22:07
memberwsmwlh19-May-11 22:07 
AnswerRe: Please help! Pin
Antonio Sandoval20-May-11 17:40
memberAntonio Sandoval20-May-11 17:40 
QuestionRe: Please help! Pin
wsmwlh25-May-11 16:48
memberwsmwlh25-May-11 16:48 
General"An attempt was made to load a program with an incorrect format." Pin
martinrousev7-Apr-11 3:55
membermartinrousev7-Apr-11 3:55 
GeneralRe: "An attempt was made to load a program with an incorrect format." Pin
dantrech10-May-11 11:14
memberdantrech10-May-11 11:14 
GeneralRe: "An attempt was made to load a program with an incorrect format." Pin
Antonio Sandoval10-May-11 13:07
memberAntonio Sandoval10-May-11 13:07 
GeneralRe: "An attempt was made to load a program with an incorrect format." Pin
Antonio Sandoval16-May-11 9:53
memberAntonio Sandoval16-May-11 9:53 
GeneralMy vote of 5 Pin
cjan198523-Mar-11 22:51
membercjan198523-Mar-11 22:51 
QuestionCan it be used with c++? Pin
cjan198523-Mar-11 22:50
membercjan198523-Mar-11 22:50 
QuestionCannot compile in VS2010 Pin
Marco Giacinti15-Feb-11 22:19
memberMarco Giacinti15-Feb-11 22:19 
NewsRe: Cannot compile in VS2010 Pin
Antonio Sandoval16-May-11 9:53
memberAntonio Sandoval16-May-11 9:53 
GeneralMy vote of 4 Pin
Slarti421-Feb-11 22:40
memberSlarti421-Feb-11 22:40 
GeneralPrinting direcly without GUI Pin
Slarti421-Feb-11 22:38
memberSlarti421-Feb-11 22:38 
GeneralRe: Printing direcly without GUI Pin
Antonio Sandoval2-Feb-11 11:32
memberAntonio Sandoval2-Feb-11 11:32 
GeneralMy vote of 4 Pin
Mauro Gagna26-Jan-11 4:31
memberMauro Gagna26-Jan-11 4:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150624.2 | Last Updated 26 Nov 2010
Article Copyright 2009 by Antonio Sandoval
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid