How to get Pdfium to work (done)

Just starting out? Need help? Post your questions and find answers here.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: How to get Pdfium to work

Post by IdeasVacuum »

Hi, I did actually try that before too, no joy at the time.

In fact this works:

Code: Select all

dc = GetDC_(GadgetID(#MyCanvas))
... but only if I do not re-size the Canvas before applying RenderPage. If the Canvas is re-sized, the PDF page render appears and disappears within milliseconds. Also, with a successful render, the render is lost if the ScrollArea is scrolled.

It also works if rendering directly on the ScrollArea, but again the render is lost if the ScrollArea is scrolled.

So, based on this knowledge, I went back to rendering directly on the Window (as a test, most times that would not be enough). However, if the Window is re-sized after the render (mouse drag edge), the render is lost....

Code: Select all

Global sgPDF.s = "C:\EGG COOKER user guide.pdf"

Prototype protoInitLibrary()
Prototype protoLoadDocument(documentpath.p-utf8,password.p-utf8)
Prototype protoGetPageCount(document)
Prototype protoRenderPage(hDC, page, start_x, start_y, size_x, size_y, rotate, flags);As "_FPDF_RenderPage@32
Prototype protoLoadPage(document, page_index) ;"_FPDF_LoadPage@8"

Procedure Main(*win)
 
  Protected pdf_dll =OpenLibrary(#PB_Any, "pdfium.dll")
 
  Protected InitLibrary.protoInitLibrary = GetFunction(pdf_dll,"_FPDF_InitLibrary@0")
  Protected GetPageCount.protoGetPageCount = GetFunction(pdf_dll,"_FPDF_GetPageCount@4")
  Protected LoadDocument.protoLoadDocument = GetFunction(pdf_dll,"_FPDF_LoadDocument@8")
  Protected RenderPage.protoRenderPage = GetFunction(pdf_dll,"_FPDF_RenderPage@32")
  Protected LoadPage.protoLoadPage = GetFunction(pdf_dll,"_FPDF_LoadPage@8")
 
  InitLibrary()
 
  Protected pdf_doc = LoadDocument(sgPDF, "")
 
  Protected pdf_page = LoadPage(pdf_doc, 0)

   RenderPage(GetDC_(WindowID(*win)), pdf_page, 0, 0, 794, 1123, 0, $100);

   Repeat
   
   Until WaitWindowEvent() = #PB_Event_CloseWindow
   
   CloseLibrary(pdf_dll)
 
EndProcedure

Define iFlags.i = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_SizeGadget
Main(OpenWindow(#PB_Any, 0, 0, 800, 640, "Pdfium", iFlags))
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
acreis
Enthusiast
Enthusiast
Posts: 204
Joined: Fri Jun 01, 2012 12:20 am

Re: How to get Pdfium to work

Post by acreis »

I think we need draw the pdf page to an image then set this image to canvas.
Hadrianus
User
User
Posts: 34
Joined: Wed Mar 27, 2013 11:31 pm

Re: How to get Pdfium to work

Post by Hadrianus »

This works nice. You can put the image inside canvasgadget or imagegadget. No need for windows-api, only PB and Pdfium.

Code: Select all

Enumeration
  #PdfLibrary
  #PdfImage
EndEnumeration

Prototype protoInitPdfLibrary()
Prototype protoLoadDocument(documentpath.p-utf8,password.p-utf8)
Prototype protoLoadPage(document,pagenumber)
Prototype protoGetMediaBox(page,left,bottom,right,top)
Prototype protoRenderPageDC(hDC,page,startx,starty,width,height,rotation,flags)

Procedure CreatePdfBitmap()

  OpenLibrary(#PdfLibrary,"pdfium.dll")
    
  Protected left.f      
  Protected bottom.f
  Protected right.f
  Protected top.f
  Protected pdfpagewidth.f  ; Unit: points.
  Protected pdfpageheight.f ; Unit: points
  Protected hImage          ; Handle image.

  Protected InitPdfLibrary.protoInitPdfLibrary = GetFunction(#PdfLibrary,"_FPDF_InitLibrary@0")
  Protected LoadDocument.protoLoadDocument     = GetFunction(#PdfLibrary,"_FPDF_LoadDocument@8")
  Protected LoadPage.protoLoadPage             = GetFunction(#PdfLibrary,"_FPDF_LoadPage@8")
  Protected GetMediaBox.protoGetMediaBox       = GetFunction(#PdfLibrary,"_FPDFPage_GetMediaBox@20")
  Protected RenderPageDC.protoRenderPageDC     = GetFunction(#PdfLibrary,"_FPDF_RenderPage@32")

  InitPdfLibrary()
      
  Protected hdocument.i   = LoadDocument("example.pdf","")  ; Handle document.
  Protected hpagenumber.i = LoadPage(hdocument,0)           ; Handle page
      
  GetMediaBox(hpagenumber,@left,@bottom,@right,@top)
  
  pdfpagewidth  = Abs(right-left)
  pdfpageheight = Abs(top-bottom)
  
  ; Here below, I make pdfpagewidth and pdfpageheidght equal to pixel, but you
  ; can make it also bigger of smaller. The more bigger, the more smooth pdf
  ; output you will get.

  If CreateImage(#PdfImage,pdfpagewidth,pdfpageheight,24,RGB(255,255,255)) 
        
    hImage = StartDrawing(ImageOutput(#PdfImage))
    RenderPageDC(hImage,hpagenumber,0,0,pdfpagewidth,pdfpageheight,0,$100)
    StopDrawing()

  EndIf
      
  SaveImage(#PdfImage,"testpdf_rendering_on_bitmap.bmp")
  FreeImage(#PdfImage)
  
  CloseLibrary(#PdfLibrary)
  
EndProcedure

CreatePdfBitmap()
End


You can extent this easily with the functions for getting total pagenumber, for get the rotation and change the rotation if necessary.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: How to get Pdfium to work (done)

Post by IdeasVacuum »

This must be the best approach, thanks guys.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
T4r4ntul4
Enthusiast
Enthusiast
Posts: 119
Joined: Tue Mar 04, 2014 4:15 pm
Location: Netherlands

Re: How to get Pdfium to work (done)

Post by T4r4ntul4 »

Hey guys,

Sorry to bump this topic, but i had a question.
When the PDF is converted to an image the PDF gets loaded in the software. And the PDF stays loaded, even when the image is done.
I found a command to close the PDF document with FFDF_CloseDocument (i think thats closing the PDF)
link: https://pdfium.patagames.com/help/html/ ... ec5b02.htm

But since iam completely lost with prototypes and such, i have no clue how to implement this in the procedure, so can someone be that kind to implement this in?

I would be very thankful!
acreis
Enthusiast
Enthusiast
Posts: 204
Joined: Fri Jun 01, 2012 12:20 am

Re: How to get Pdfium to work (done)

Post by acreis »

Maybe this helps:

Code: Select all

Prototype protoCloseDocument(document)
Prototype protoClosePage(page) 

CloseDocument.protoCloseDocument = GetFunction(pdf_dll,"_FPDF_CloseDocument@4")
ClosePage.protoClosePage               = GetFunction(pdf_dll,"_FPDF_ClosePage@4")
T4r4ntul4
Enthusiast
Enthusiast
Posts: 119
Joined: Tue Mar 04, 2014 4:15 pm
Location: Netherlands

Re: How to get Pdfium to work (done)

Post by T4r4ntul4 »

Thanks! Works perfect now!
coder14
Enthusiast
Enthusiast
Posts: 327
Joined: Tue Jun 21, 2011 10:39 am

Re: How to get Pdfium to work (done)

Post by coder14 »

First of all, thank you acreis for bringing this library to the forum. IdeasVacuum pointed it out to me in another thread. :D

You examples work well but I am trying to implement FPDFImageObj_LoadJpegFile and FPDFFormContent_InsertObject. I am stuck with this param in the load jpeg function: FPDF_FILEACCESS :?:

It is not a normal type but a class type. Is there any way to call this in PB?
acreis
Enthusiast
Enthusiast
Posts: 204
Joined: Fri Jun 01, 2012 12:20 am

Re: How to get Pdfium to work (done)

Post by acreis »

Post some code and we'll try fix it!
coder14
Enthusiast
Enthusiast
Posts: 327
Joined: Tue Jun 21, 2011 10:39 am

Re: How to get Pdfium to work (done)

Post by coder14 »

acreis wrote:Post some code and we'll try fix it!
The VB syntax for the function is:

Code: Select all

Public Shared Function FPDFImageObj_LoadJpegFile ( 
	pages As IntPtr,
	nCount As Integer,
	image_object As IntPtr,
	fileAccess As FPDF_FILEACCESS
) As IntPtr
When declaring the prototype the first three are integers but how to prototype the 4th:

Code: Select all

Prototype protoLoadJPG(pages, count, image, FILEACCESS)
Protected LoadJpegFile.protoLoadJPG = GetFunction(#lib, "FPDFImageObj_LoadJpegFile@16")
What TYPE should FILEACCESS be and how to pass the filename to it?
acreis
Enthusiast
Enthusiast
Posts: 204
Joined: Fri Jun 01, 2012 12:20 am

Re: How to get Pdfium to work (done)

Post by acreis »

Edited again- Maybe this is the start of an answer:

Code: Select all

Prototype protoGetBlock( param,  position, *buf, size)

Structure FPDF_FILEACCESS
  FileLen.i
  *GetBlock.protoGetBlock
  param.i
  pdf_file$
EndStructure

Procedure GetBlockCallback( *param.FPDF_FILEACCESS,  position, *buf, size)
  
  ;code to read the file from position, for given size, result tobe put in *buf
  
EndProcedure  

Procedure Create_FPDF_FILEACCESS(pdf_file$) 
  
  Protected *this.FPDF_FILEACCESS= AllocateStructure(FPDF_FILEACCESS)
  
  *this\FileLen = FileSize(pdf_file$)
  *this\GetBlock = @GetBlockCallback()
  *this\param = *this
   *this\pdf_file$ = pdf_file$
  
  ProcedureReturn *this
  
EndProcedure

Global *FPDF_FILEACCESS.FPDF_FILEACCESS= Create_FPDF_FILEACCESS("MYPDF.PDF")

;now you can use *FPDF_FILEACCESS as parameter
;note that you have to implement the procedure GetBlockCallback

Last edited by acreis on Fri Jan 06, 2017 8:48 pm, edited 1 time in total.
coder14
Enthusiast
Enthusiast
Posts: 327
Joined: Tue Jun 21, 2011 10:39 am

Re: How to get Pdfium to work (done)

Post by coder14 »

acreis wrote:Edited - Maybe this is the start of an answer:

Code: Select all

Prototype protoGetBlock( param,  position, *buf, size)

Structure FPDF_FILEACCESS
  FileLen.i
  *GetBlock.protoGetBlock
  param.i
  pdf_file$
EndStructure

Procedure GetBlockCallback( *param.FPDF_FILEACCESS,  position, *buf, size)
  
  ;code to read the file from position, for given size, result tobe put in *buf
  
EndProcedure  

Procedure Create_FPDF_FILEACCESS(pdf_file$) 
  
  Protected *this.FPDF_PAGEOBJECT = AllocateStructure(FPDF_PAGEOBJECT)
  
  *this\FileLen = FileSize(pdf_file$)
  *this\GetBlock = @GetBlockCallback()
  *this\param = *this
   *this\pdf_file$ = pdf_file$
  
  ProcedureReturn *this
  
EndProcedure

Global *FPDF_FILEACCESS.FPDF_FILEACCESS= Create_FPDF_FILEACCESS("MYPDF.PDF")

;now you can use *FPDF_FILEACCESS as parameter
;note that you have to implement the procedure GetBlockCallback

Thank you but it is a non-starter for me. :cry:

The FPDF_PAGEOBJECT structure is not defined and is even more confusing than FPDF_FILEACCESS. The callback will assign the file name but to which of the 4 params? And what is position supposed to be ("byte offset from beginning of the file")?

Are all the methods in such structures required just to pass a file name? :x
acreis
Enthusiast
Enthusiast
Posts: 204
Joined: Fri Jun 01, 2012 12:20 am

Re: How to get Pdfium to work (done)

Post by acreis »

Sorry - edited again - no FPFF_PAGEOBJECT, my mistake.

This is a very interesting subject.

I'm going to investigate, but I'm sure you can do it too.

If you find anything that can help me be faster, post here!

As you can see, the code above is based on

https://pdfium.patagames.com/help/html/ ... 68e586.htm
Are all the methods in such structures required just to pass a file name? :x
Of course not! These members are needed to pass the filesize, what file is and what function must be called to read the file. And dont ask me why. Ask to pdfium programmers!

By the way, ehat are you trying to do? What that function do? Is that really necessary?
coder14
Enthusiast
Enthusiast
Posts: 327
Joined: Tue Jun 21, 2011 10:39 am

Re: How to get Pdfium to work (done)

Post by coder14 »

acreis wrote:Sorry - edited again - no FPFF_PAGEOBJECT, my mistake.

This is a very interesting subject.

I'm going to investigate, but I'm sure you can do it too.

If you find anything that can help me be faster, post here!

As you can see, the code above is based on

https://pdfium.patagames.com/help/html/ ... 68e586.htm
Are all the methods in such structures required just to pass a file name? :x
Of course not! These members are needed to pass the filesize, what file is and what function must be called to read the file. And dont ask me why. Ask to pdfium programmers!

By the way, ehat are you trying to do? What that function do? Is that really necessary?
Okay. I will work on it again. I am trying load a JPEG as an object so that it can be inserted into a new or existing PDF file using the function FPDFFormContent_InsertObject. It is very useful for PDF applications.

Thanks again. :)
coder14
Enthusiast
Enthusiast
Posts: 327
Joined: Tue Jun 21, 2011 10:39 am

Re: How to get Pdfium to work (done)

Post by coder14 »

My code so far which is KAPUT! :lol:

Code: Select all

Global sgPDF.s = "form.pdf"
Global sgJPG.s = "image.jpg"

Prototype protoGetBlock(param, position, *buf, size)

Structure FPDF_FILEACCESS
  FileLen.i
  *GetBlock.protoGetBlock
  param.i
  pdf_file$
EndStructure

Procedure GetBlockCallback(*param.FPDF_FILEACCESS,  position, *buf, size)
  
  *param\FileLen = FileSize(sgJPG)
  *param\pdf_file$ = sgJPG
  ProcedureReturn #True
  
EndProcedure  

Procedure Create_FPDF_FILEACCESS(file$) 
  
  Protected *this.FPDF_FILEACCESS = AllocateStructure(FPDF_FILEACCESS)
  
  *this\FileLen = FileSize(file$)
  *this\GetBlock = @GetBlockCallback()
  *this\param = *this
  *this\pdf_file$ = file$
  
  ProcedureReturn *this
  
EndProcedure

Global *FPDF_FILEACCESS.FPDF_FILEACCESS= Create_FPDF_FILEACCESS(sgJPG)


Prototype protoInitLibrary()
Prototype protoLoadDocument(documentpath.p-utf8, password.p-utf8)
Prototype jpgObject(pages, count, imgObject, fileObject)
Prototype protoGetPageCount(document)
Prototype protoRenderPage(hDC, page, start_x, start_y, size_x, size_y, rotate, flags)
Prototype protoLoadPage(document, page_index)                                        
Prototype protoGetMediaBox(page, left, bottom, right, top)
Prototype protoInsertObject(pdfObject, newObject, insertAfter)
Prototype protoCloseDocument(document)
Prototype protoClosePage(page) 

Procedure Main(*win)
  
  CanvasGadget(0, 0, 0, 800, 600)
  
  Protected pdf_dll =OpenLibrary(#PB_Any, "pdfium.dll")
  
  Protected InitLibrary.protoInitLibrary = GetFunction(pdf_dll,"_FPDF_InitLibrary@0")
  Protected GetPageCount.protoGetPageCount = GetFunction(pdf_dll,"_FPDF_GetPageCount@4")
  Protected LoadDocument.protoLoadDocument = GetFunction(pdf_dll,"_FPDF_LoadDocument@8")
  Protected insertObject.protoInsertObject = GetFunction(pdf_dll,"_FPDFFormContent_InsertObject@12")
  Protected RenderPage.protoRenderPage = GetFunction(pdf_dll,"_FPDF_RenderPage@32")
  Protected LoadPage.protoLoadPage = GetFunction(pdf_dll,"_FPDF_LoadPage@8")
  Protected GetMediaBox.protoGetMediaBox = GetFunction(pdf_dll,"_FPDFPage_GetMediaBox@20")
  Protected CloseDocument.protoCloseDocument = GetFunction(pdf_dll,"_FPDF_CloseDocument@4")
  Protected ClosePage.protoClosePage = GetFunction(pdf_dll,"_FPDF_ClosePage@4")
  
  Protected LoadJPG.jpgObject = GetFunction(pdf_dll,"FPDFImageObj_LoadJpegFile@16")
  
  InitLibrary()
  Protected pdf_doc = LoadDocument(sgPDF, "")
  Protected pdf_page = LoadPage(pdf_doc, 0)
  Protected hJPG = LoadJPG(0, 0, *newObject, *FPDF_FILEACCESS)
  insertObject(pdf_doc, hJPG, 0)
  
  hDC = StartDrawing(CanvasOutput(0))
    RenderPage(hDC, pdf_page, 0, 0, 800, 600, 0, $100);
  StopDrawing()  

  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
  
  ClosePage(pdf_page)
  CloseDocument(pdf_doc)   
  CloseLibrary(pdf_dll)
  
EndProcedure

Define iFlags.i = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_SizeGadget
Main(OpenWindow(#PB_Any, 0, 0, 800, 600, "Pdfium", iFlags))
I get an IMA on the LoadJPG function. Obviously. :oops:
Post Reply