Page 29 of 32

Re: PurePDF Version 2.0

Posted: Wed Apr 08, 2015 11:52 pm
by normeus
[EDIT 10/11/2016]
Last edit on this one. I had a chance to work on this so it should now work Unicode, ASCII
and string replacement is functional (i.e. using {nb} ) I didn't change this post so that the chain of posts after it makes sense. For code see post:
http://www.purebasic.fr/english/viewtop ... 65#p495665

[EDIT 10/10/2016]
1. use Chr(14) instead of Chr(16)
2. I also changed the code on the HACK please download it again.
(This will work with Unicode ASCII Unicode font and ASCII font )
( I don't have the time to fix Unicode string compare and that's why a single char replacement string
is currently the workaround )
see edit 9/25/2016

[EDIT 9/25/2016]
For the footer to be displayed with any font you'll have to change the replacement string to a single char.

Add this to your pdf create page: ( I am using chr(14) as the replacement string

Code: Select all

pdf_AliasNbPages(Chr(14))
and the Footer procedure should be also changed to the same single char string:

Code: Select all

Procedure Footer()
  Protected ftext.s="Page "+Str(pdf_GetPageNo())+"/"+Chr(14)
  pdf_SetY(-15);
  pdf_SetFont("MS Sans Serif","I",10)
  pdf_Cell(0,10,ftext,0,0,#PDF_ALIGN_CENTER);
EndProcedure
@Lord's code works in mysterious ways.

[EDIT]
After reading all 28 pages of messages, I saw that unicode works.
You have to use a font which contains the characters you are going to use.
here is a fix ( more like a hack ) for footer numbers not printing right in unicode. Replace this procedure in "PurePDF.pb" which forces footer numbers to be ascii:
[EDIT CODE FROM 10/10/2016]

Code: Select all

Procedure MEM_DataReplace(*aData.MEM_DataStructure, aSource.s, aDest.s)
  Protected vSourceLen,vDestLen,vCurSize,vMaxSize,vCount,vFind,*tmp,vReturn,i,j,*vaSource
  Protected vLen,*vaDest,vaDestString ; Needed to HACK unicode to ASCII
  
  vSourceLen   = StringByteLength(aSource); changed to StringByteLength for unicode
  *vaSource    = AllocateMemory(vSourceLen); created a temp buffer for unicode
  PokeS(*vaSource,aSource,vSourceLen,#PB_String_NoZero|#PB_Ascii);saved string to mem to compare mem not string ; HACK - copy string to buffer IN ASCII because MEM_DataStructure is ASCII
  vLen = SizeOf(Character)   ; find out if unicode or ASCII to HACK code
  vSourceLen=vSourceLen/vlen ; HACK - if unicode cutdown size to ascii
                 
                 
  vDestLen     = StringByteLength(aDest) ; changed to StringByteLength
  *vaDest=AllocateMemory(vDestLen)     ; HACK - needed to change number to ASCII
  PokeS(*vaDest,aDest,vDestLen)

  vCurSize     = *aData\lCursize  
  vMaxSize     = *aData\lMaxsize  
  vFind        = 0
  vReturn      = #True


  If (vDestLen > vSourceLen)
    For i = vCurSize To 0 Step -1
      vCount= 0
      For j = 0 To vSourceLen-1
        If PeekB(*aData\pData + i - vSourceLen + j ) = PeekB(*vaSource+j)
          vCount = vCount + 1
        EndIf
      Next 
      If vCount = vSourceLen   
         vFind = vFind + 1   
      EndIf
    Next
    If (vFind > 0)
      vReturn = MEM_DataInit(*aData, vMaxSize + (vFind*(vDestLen - vSourceLen))) ; = #False
    EndIf  
  EndIf
  
  If vReturn = #True
    *tmp = AllocateMemory((vDestLen + vCurSize) - vSourceLen)
    If *tmp
      For i = vCurSize To 0 Step -1
        vCount= 0
        For j = 0 To vSourceLen-1
          If PeekB(*aData\pData + i - vSourceLen + j ) = PeekB(*vaSource+j)
            vCount = vCount + 1
          EndIf
        Next

        If vCount = vSourceLen
          CopyMemory(*aData\pData + i, *tmp, *aData\lCurSize - i)
          ; CopyMemory(@aDest, *aData\pData + i - vSourceLen , vDestLen) ; this one will work when the unicode issue gets solved
          CopyMemory(*vaDest, *aData\pData + i - vSourceLen , vDestLen ) ; HACK - using new ASCII sized location
          CopyMemory(*tmp, *aData\pData + (i-(vLen-1)) - vSourceLen + vDestLen, *aData\lCurSize - i) ; COPY according to ASCII or UNICODE
          *aData\lCurSize = *aData\lCurSize + (vDestLen-vSourceLen)
        EndIf
      Next
      FreeMemory(*tmp)
    Else
      vReturn = #False
    EndIf
  EndIf
  FreeMemory(*vaSource) ; used to search as memory and not string
  FreeMemory(*vaDest) ; HACK to change to ASCII
  ProcedureReturn vReturn
EndProcedure
Norm.

Re: PurePDF Version 2.0

Posted: Tue Apr 14, 2015 7:50 pm
by normeus
Tutorial07 Images.pdf which creates two links to same spot does not work because the link is kept in a LIST so there is only one link for each set link; anyway here is a fix until ABBKlaus comes back and takes care of this.
Replace this procedure which will allow you to have multiple links pointed to same spot. ( like a link which goes back to a line on the first page of a multiple page document and you use it like a back button)

Code: Select all

Procedure ipdf_Link(X.f, Y.f, W.f, H.f, Link.l)
  Protected PLType,PLDestPage,PLy,PL1$
  If Link>0
    SelectElement(PageLinks(), Link-1)
    ;If this link was used before copy data and create a new link
    ;This will work with pages and URLS only 
    If PageLinks()\Page>0
      PLType=PageLinks()\Type
      PLDestPage=PageLinks()\DestPage
      PLy=PageLinks()\y
      PL1$=PageLinks()\Option1$
      AddElement(pagelinks())
      PageLinks()\Type = PLType
      PageLinks()\DestPage = PLDestPage
      PageLinks()\Y = PLy
      PageLinks()\Option1$ = PL1$
    EndIf
    If pdfCurOrientation$="P"
      PageLinks()\fA0 = x*pdfK
      PageLinks()\fA1 = pdfFhPt - y*pdfK
      PageLinks()\fA2 = w*pdfK
      PageLinks()\fA3 = h*pdfK
      PageLinks()\Page = pdfPage
    Else
      PageLinks()\fA0 = x*pdfK
      PageLinks()\fA1 = pdfFwPt - y*pdfK
      PageLinks()\fA2 = w*pdfK
      PageLinks()\fA3 = h*pdfK
      PageLinks()\Page = pdfPage
    EndIf
  EndIf
EndProcedure
and this is a sample of linking back to top page which will work after you replace the previous procedure in "PurePDF.pb":

Code: Select all

#PurePDF_Include=1
XIncludeFile "PurePDF.pb"


pdf_Create()
pdf_AddPage()
pdf_SetFont("Arial","",20)
Define linkr = pdf_Addlink()
pdf_SetLink(linkr,-1,-1)

pdf_Write(5,"COME BACK HERE ",linkr)



Define file$="Tutorial07A Images links.pdf"
pdf_AddPage()
pdf_Image("PurePDFLogo.png",10,10,30,0,linkr)
pdf_AddPage()
pdf_Image("PurePDFLogo.jpg",10,10,190,0,linkr)
pdf_addpage()
pdf_Write(5,"BACK to top ",linkr)

pdf_Save(file$)
RunProgram(file$)
Thank you.
Norm

Re: PurePDF Version 2.0

Posted: Fri Aug 28, 2015 7:30 pm
by collectordave
Hi all just joined.

Is purepdf.pb still available with an example?

Gratefull for any help

Re: PurePDF Version 2.0

Posted: Fri Aug 28, 2015 7:52 pm
by ts-soft
collectordave wrote:Is purepdf.pb still available with an example?
http://www.purebasicpower.de/?PurePDF

Re: PurePDF Version 2.0

Posted: Sat Aug 29, 2015 5:35 am
by collectordave
Brilliant

Thanks

Re: PurePDF Version 2.0

Posted: Fri Sep 25, 2015 5:11 pm
by infratec

Re: PurePDF Version 2.0

Posted: Thu Jan 28, 2016 1:27 am
by normeus
error codes in the help file should read:

Code: Select all

Possible values are:
- 1 = 16-bit depth PNG not supported.
- 2 = Alpha channel PNG not supported.
- 3 = Unknown compression PNG method.
- 4 = Unknown filter PNG method.
- 5 = Interlacing PNG not supported.
- 6 = Missing palette in PNG.
- 7 = This JPEG file is not supported
- 8 = Can't open image file
- 9 = Problem reading image file in memory
-10 = JFIF marker is missing
-11 = Not a JPEG file.
-12 = Incorrect PNG file.
-13 = Incorrect WMF file
-14 = Not a JPEG or PNG file.
-15 = Filename is not correct.
-16 = Can't create the file. 
-17 = File open error.
-18 = Out of memory. 
-19 = Bookmark Error
Currently if you save a pdf and there is an error, memory gets cleared and you have to generate the pdf in memory again.
it would be nice to be notified of the error and be able to save the pdf you have in memory.

This is a 3 step hack but you can get away with just doing the 1st step

step 1. change the save procedure, it is around line 4300 of purePDF.pb

Code: Select all

Procedure ipdf_Save(FileName$)
  Protected File,cbBytes
  ipdf_Close()
  pdfState=3
  If Len(FileName$)>0 And pdfError<>#PDF_ERROR_OUT_OF_MEMORY
    If CheckFilename(GetFilePart(Filename$)) = 1
      File=CreateFile(#PB_Any, FileName$)
      If File
        WriteData(File,pdfBuffer\pData, pdfBuffer\lCurSize)
        CloseFile(File)
      Else
        pdfError = #PDF_ERROR_ERROR_CREATING_FILE
        ProcedureReturn #False
      EndIf      
    Else
      pdfError = #PDF_ERROR_FILENAME_IS_NOT_CORRECT
      ProcedureReturn #False 
    EndIf
  EndIf
  If pdfBuffer\pData
    FreeMemory(pdfBuffer\pData)
  EndIf
  pdfBuffer\pData=0
  pdfState=0
  pdferror=0
  ProcedureReturn #True
EndProcedure
This will avoid deleting the pdf in memory so all you have to do is check pdf_GetErrorCode() Thus:

Code: Select all

pdf_Save(file$)
if pdf_GetErrorCode() = 15 or pdf_GetErrorCode() =16   ;error codes I got from help file
   ;file couldn't be created. request a new file and do pdf_Save() with new file name. Disco
   File$ = SaveFileRequester("Please choose file to save", file$, "*.pdf", 0)
   pdf_Save(file$) ; test for error codes again etc...
endif
Step 2. lets clean up a bit, again; this is not needed if you are careful checking pdf_GetErrorCode() every time you
save a pdf. This is for people like me who would open an new pdf assuming the last one worked fine.

search for ipdf_Create and add an "if" statement testing to see if there is a pdf that failed to save and if so dont create
a new pdf

Code: Select all

Procedure ipdf_Create(Orientation$="", Unit$="", Format$="")
  Protected lfMargin.f,mode,vBias
  If pdfState=3
    ProcedureReturn #False
  EndIf
now when you create a new pdf make sure it was created

Code: Select all

if pdf_Create()
   ; add fonts and other stuff to your new pdf
else
   ; get the code from pdf_GetErrorCode()  and fix the problem 
endif
Ok so you want to see what step 3 is like ?
step 3. on step 1 we modified pdf_save() so it wouldn't delete our pdf in memory if there was an error. We also added code to return #True or #False, however; for this procedureReturn to work we need to do a few changes.
( not difficult ). search for pdf_Save in purePDF.pb and you'll change each procedure to return the results like so:

Code: Select all

Procedure pdf_Save(FileName$) ;Output PDF to filename.
   ProcedureReturn ipdf_Save(FileName$)
  EndProcedure
and

Code: Select all

  ProcedureDLL pdf_Save(FileName$) ;Output PDF to filename.
    ProcedureReturn ipdf_Save(FileName$)
  EndProcedure
so now we can test with #True or #False the result of pdf_Save

Code: Select all

While  Not(pdf_Save(file$))
  Debug pdf_GetErrorMessage()
  File$ = SaveFileRequester("Please choose file to save", file$, "*.pdf", 0)
Wend


Again, this is code that is useful to me so I figure it might be useful to someone else.
Not really needed but handy to have.

Norm.

Re: PurePDF Version 2.0

Posted: Wed Apr 20, 2016 9:26 am
by oakvalley
In PurePDF 2.25, the file "PurePDF.pb", there is an error creating "page 0 of x" visible in the Document Properties/Initial View, causing the "Description" view to fail with "there is no page numbered 0 in this document" with a Acrobat PDF reader.

The code in:
Procedure ipdf_PutCatalog()

where "/OpenAction [1 0 " exists, replace 0 with 1

I tried it myself (4 places within the Procedure) and it works now.

Re: PurePDF Version 2.0

Posted: Wed Apr 20, 2016 11:58 pm
by DoubleDutch
Your fix kills bookmarks.

Re: PurePDF Version 2.0

Posted: Thu Jun 09, 2016 4:18 pm
by loulou2522
DoubleDutch wrote:Your fix kills bookmarks.
With PureBasic 5.50 PurePDF crash when saving file with a footer Procedure
Can someone Help me ?
Function PDF_SAVE

Re: PurePDF Version 2.0

Posted: Thu Jun 09, 2016 8:43 pm
by IdeasVacuum
loulou2522, post a snippet we can test.

Re: PurePDF Version 2.0

Posted: Fri Jun 10, 2016 7:06 am
by loulou2522
IdeasVacuum wrote:loulou2522, post a snippet we can test.

Code: Select all

#PurePDF_Include=0
;XIncludeFile "PurePDF.pb"

Define file$="Tutorial01 Hello World.pdf"

pdf_Create()
pdf_AddPage()
pdf_SetFont("Arial","B",16)
pdf_Cell(40,10,"Hello World!",1)
pdf_Save(file$)
RunProgram(file$)
Error Message with Purebasic 550 Beta1
Accés mémoire invalide erreur de lecture àl'adresse 843002431
Instruction ----> pdf_save(files$)

Re: PurePDF Version 2.0

Posted: Fri Jun 10, 2016 8:10 am
by Marc56us

Code: Select all

#PurePDF_Include=0
;XIncludeFile "PurePDF.pb"

Define file$="Tutorial01 Hello World.pdf"

pdf_Create()
pdf_AddPage()
pdf_SetFont("Arial","B",16)
pdf_Cell(40,10,"Hello World!",1)
pdf_Save(file$)
RunProgram(file$)
Error Message with Purebasic 550 Beta1
Accés mémoire invalide erreur de lecture àl'adresse 843002431
Instruction ----> pdf_save(files$)
With your snipet code as is, this does not work :|
Line 6: pdf_Create() is not a function, array, list, map or macro.

Without comment for XInclude, and
- Programm saved in a folder where it can write
- good path to acces to PurePDF.pb
- good path to acces to PurePDF_res.pb

It works :) PDF is generated and displayed.

My configuration: Windows 10 x64 / PB 5.50 B1 / PurePDF V2.25 (uncompress un PB install dir)

:!: work for PB x86 but not for PB x64 Message: 'Compressed libraries are not supported (PurePDF).' (when open PB 5.50 x64)

:wink:

Re: PurePDF Version 2.0

Posted: Fri Jun 10, 2016 8:45 am
by loulou2522
Hi all,
I solve my problem recompiling PurePDF V. 2.25 with Tailbite
After PurePDF works well in PB 5.50
Thanks

Re: PurePDF Version 2.0

Posted: Fri Aug 12, 2016 5:16 pm
by IdeasVacuum
Hmm, just noticed that, somehow, a metric (mm) PDF containing a png image is created slightly oversized.

Whilst checking this, I found a clue (or a red-herring). The margins default to 10mm. If a PDF is created without specifying the margins, they do indeed verify as 10mm. However, if margins are specified, they verify oversize. For example

Code: Select all

pdf_Create("P","mm",PDF_PAGE_FORMAT_A3)
pdf_SetMargins(10.00,10.00,10.00)
.....results in margins of 11.5mm

Images on the other hand are rendered approx 4% oversize.

When the image is a screen grab (e.g. a web page) this issue matters a lot, because the text is rendered slightly fuzzy compared to the original pixel-sharp image.

Edit:
Image
My memory needs replacing! Adobe Reader is not 'Screen DPI aware', but it does render an accurate printed page.
Reader can of course display the page scaled, so is it possible to set the display scale via RunProgram()?