Deixando a disposição aqui.
No Harbour transformei pra classes e acrescentei algumas facilidades, mas não equivale a harupdf.
Por enquanto ainda atende, mas já que uso harupdf pra outras coisas, melhor usar pra isso também.
De qualquer jeito, é interessante pra ver a estrutura de um PDF.
Como o PDF é feito com objetos, a estrutura básica acaba continuando a mesma, só aparecendo novos objetos.
Peguei o fonte mais recente que eu tinha, antes de virar código Harbour.
// Procedure Main()
// Txt2Pdf("d:\temp\*.lst","teste.pdf")
// Return NIL
Function Txt2Pdf(cFileInput, cFileOutput)
Position := PageNo := LineNo := PageHeight := PageWidth := 0
Lines := Obj := TPages := Encoding := Resources := 0
PointSize := VertSpace := Rotate := Info := Root := 0
nPagex := nPagey := LIneLen := Rotation := 0
Author := Creator := KeyWords := Subject := Title := ""
BaseFont := cmdLine := ""
nHandle := 0
Declare Location[4000]
Afill(Location,0)
Declare PageObj[4000]
Afill(PageObj,0)
Pages := "" // Variant
aFileList := {}
cPath := ""
If "\" $ cFileInput
cPath := Substr(cFileInput,1,Rat("\",cFileInput))
Endif
mDirList := Directory(cFileInput)
For nCont = 1 To Len(mDirList)
Aadd(aFileList,cPath+mDirList[nCont,1])
Next
AppName := "JPA-Preview"
Author = "JPA-Preview"
Creator = "JPA-Preview"
Keywords = "None"
Subject = "Listagem JPA-Preview"
Title = "Listagem JPA-Preview"
nHandle := fCreate(cFileOutput)
PdfSetup()
PdfStart()
PdfHead()
WritePages(aFileList)
PdfEnd()
fClose(nHandle)
Return NIL
Function PdfSetup()
FontSize := PaperWidth := PaperHeight := Rotation := 0
FontName := ""
FontName = "Courier"
FontSize = 6
PaperWidth = 8.3 // 'A4=8.3
PaperHeight = 11.7 // 'A4=11.7
Rotation = 0
pageHeight = Round(72 * PaperHeight, 0)
pageWidth = Round(72 * PaperWidth, 0)
BaseFont = FontName // ' Courier, Times-Roman, Arial
pointSize = FontSize // ' Font Size; não altere
vertSpace = Round(FontSize * 1.7, 0) // ' Round(FontSize * 1.2, 0) ' Vertical spacing
rotate = Rotation // ' degrees to rotate; try setting 90,180,etc
lines = (pageHeight - 72) / vertSpace // ' no of lines on one page
// 'Select Case LCase(FontName)
// 'Case "courier":
// linelen = 1.5 * pageWidth / pointSize
// 'Case "arial": linelen = 2 * pageWidth / pointSize
// 'Case "Times-Roman": linelen = 2.2 * pageWidth / pointSize
// 'Case Else: linelen = 2.2 * pageWidth / pointSize
// 'End Select
obj = 0
npagex = pageWidth / 2
npagey = 25
pageNo = 0
Position = 0
Return NIL
Static Function PdfWrite(Stre)
Position := Position + Len(Stre)
fWrite(nHandle,Stre+Chr(13))
Return NIL
Static Function PdfStart()
PdfWrite("%PDF-1.2")
PdfWrite( Chr(37) + Chr(226) + Chr(227) + Chr(207) + Chr(211) ) // Confirmar porque isso e no VB
Return NIL
Static Function PdfHead()
CreationDate = ""
CreationDate = "D:" + Dtos(Date()) + Substr(Time(),1,2)+Substr(Time(),4,2)+Substr(Time(),7,2)
obj = obj + 1
location[obj] = Position
info = obj
PdfWrite(Ltrim(Str(obj)) + " 0 obj")
PdfWrite("<<")
PdfWrite("/Author (" + author + ")")
PdfWrite("/CreationDate (" + CreationDate + ")")
PdfWrite("/Creator (" + creator + ")")
PdfWrite("/Producer (" + AppName + ")")
PdfWrite("/Title (" + Title + ")")
PdfWrite("/Subject (" + subject + ")")
PdfWrite("/Keywords (" + keywords + ")")
PdfWrite(">>")
PdfWrite("endobj")
obj = obj + 1
root = obj
obj = obj + 1
Tpages = obj
encoding = obj + 2
resources = obj + 3
obj = obj + 1
location[obj] = Position
PdfWrite (Ltrim(Str(obj)) + " 0 obj")
PdfWrite("<<")
PdfWrite("/Type /Font")
PdfWrite("/Subtype /Type1")
PdfWrite("/Name /F1")
PdfWrite("/Encoding " + Ltrim(Str(encoding)) + " 0 R")
PdfWrite("/BaseFont /" + BaseFont)
PdfWrite(">>")
PdfWrite("endobj")
obj = obj + 1
location[obj] = Position
PdfWrite(Ltrim(Str(obj)) + " 0 obj")
PdfWrite("<<")
PdfWrite("/Type /Encoding")
PdfWrite("/BaseEncoding /WinAnsiEncoding")
PdfWrite(">>")
PdfWrite("endobj")
obj = obj + 1
location[obj] = Position
PdfWrite(Ltrim(Str(obj)) + " 0 obj")
PdfWrite("<<")
PdfWrite(" /Font << /F1 " + Ltrim(Str(obj - 2)) + " 0 R >>")
PdfWrite(" /ProcSet [ /PDF /Text ]")
PdfWrite(">>")
PdfWrite("endobj")
Return NIL
Static Function WritePages(aFileList)
I := 0
Line := TmpLine := BeginStream := ""
//' beginstream = PdfPageStart()
//' lineNo = -1
nCont := 0
For nCont = 1 To Len(aFileList)
cTexto := MemoRead(aFileList[nCont])
beginstream = PdfPageStart()
lineNo = -1
For nCont2 = 1 To MLCount(cTexto,255)
Line = MemoLine(cTexto,255,nCont2)
// 'quebra de página
// 'If lineNo >= lines Or InStr(line, Chr(12)) > 0 Then
// ' PdfWrite ("1 0 0 1 " & npagex & " " & npagey & " Tm")
// ' PdfWrite ("(" & pageNo & ") Tj")
// ' PdfWrite ("/F1 " & pointSize & " Tf")
// ' PdfPageEnd (beginstream)
// ' beginstream = PdfPageStart()
// 'End If
line = StrTran(line, "\", "\\")
line = StrTran(line, "(", "\(")
line = StrTran(line, ")", "\)")
//' line = Trim(line)
//' Acrescentado aqui ref PDF eliminar espaços em branco, mas não deu certo
// 'If Mid(line, 1, 1) = " " Then
// ' line = "\." & Mid(line, 2)
// 'End If
PdfWrite("T* (" + line + Chr(13) + Chr(10) + ") Tj")
lineNo = lineNo + 1
//' End If
Next
//' Acrescentado aqui
PdfWrite("1 0 0 1 " + Ltrim(Str(npagex)) + " " + Ltrim(Str(npagey)) + " Tm")
PdfWrite("(" + Ltrim(Str(pageNo)) + ") Tj")
PdfWrite("/F1 " + Ltrim(Str(pointSize)) + " Tf")
PdfPageEnd(beginstream)
Next
//' PdfWrite ("1 0 0 1 " & npagex & " " & npagey & " Tm")
//' PdfWrite ("(" & pageNo & ") Tj")
//' PdfWrite ("/F1 " & pointSize & " Tf")
//' PdfPageEnd (beginstream)
Return NIL
Static Function PdfPageStart()
Local StrmPos := 0
obj = obj + 1
location[obj] = Position
pageNo = pageNo + 1
pageObj[pageNo] = obj
PdfWrite(Ltrim(Str(obj)) + " 0 obj")
PdfWrite("<<")
PdfWrite("/Type /Page")
PdfWrite("/Parent " + Ltrim(Str(Tpages)) + " 0 R")
PdfWrite("/Resources " + Ltrim(Str(resources)) + " 0 R")
obj = obj + 1
PdfWrite("/Contents " + Ltrim(Str(obj)) + " 0 R")
PdfWrite("/Rotate " + Ltrim(Str(rotate)))
PdfWrite(">>")
PdfWrite("endobj")
location[obj] = Position
PdfWrite(Ltrim(Str(obj)) + " 0 obj")
PdfWrite("<<")
PdfWrite("/Length " + Ltrim(Str(obj + 1)) + " 0 R")
PdfWrite(">>")
PdfWrite("stream")
strmpos = Position
PdfWrite("BT")
PdfWrite("/F1 " + Ltrim(Str(pointSize)) + " Tf")
PdfWrite("1 0 0 1 50 " + Ltrim(Str(pageHeight - 40)) + " Tm")
PdfWrite(Ltrim(Str(vertSpace)) + " TL")
Return StrmPos
Static Function PdfPageEnd(streamstart)
StreamEnd := 0
PdfWrite ("ET")
streamEnd = Position
PdfWrite ("endstream")
PdfWrite ("endobj")
obj = obj + 1
location[obj] = Position
PdfWrite(Ltrim(Str(obj)) + " 0 obj")
PdfWrite(Ltrim(Str(streamEnd - streamstart)))
PdfWrite( "endobj")
lineNo = 0
Return NIL
Static Function PdfEnd()
Ty := ""
I := 0
xRef := ""
location[root] = Position
PdfWrite(Ltrim(Str(root)) + " 0 obj")
PdfWrite("<<")
PdfWrite("/Type /Catalog")
PdfWrite("/Pages " + Ltrim(Str(Tpages)) + " 0 R")
PdfWrite(">>")
PdfWrite("endobj")
location[Tpages] = Position
PdfWrite(Ltrim(Str(Tpages)) + " 0 obj")
PdfWrite("<<")
PdfWrite("/Type /Pages")
PdfWrite("/Count " + Ltrim(Str(pageNo)))
PdfWrite("/MediaBox [ 0 0 " + Ltrim(Str(pageWidth)) + " " + Ltrim(Str(pageHeight)) + " ]")
ty = ("/Kids [ ")
For i = 1 To pageNo
ty = ty + Ltrim(Str(pageObj[i])) + " 0 R "
Next i
ty = ty + "]"
PdfWrite(ty)
PdfWrite(">>")
PdfWrite("endobj")
xreF = Position
PdfWrite("0 " + Ltrim(Str(obj + 1)))
PdfWrite("0000000000 65535 f ")
For i = 1 To obj
PdfWrite(StrZero(location[i], 10) + " 00000 n ")
Next i
PdfWrite("trailer")
PdfWrite("<<")
PdfWrite("/Size " + Ltrim(Str(obj + 1)))
PdfWrite("/Root " + Ltrim(Str(root)) + " 0 R")
PdfWrite("/Info " + Ltrim(Str(info)) + " 0 R")
PdfWrite(">>")
PdfWrite("startxref")
PdfWrite(Ltrim(Str(xreF)))
PdfWrite("%%EOF")
Return NIL