#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "pdflib.h"
static char pdf_buf[512];
#define LPDF_VERSIOIN_TEXT "0.0.4"
#define LPDF_FILE_HEADER_LEN 15
#define LPDF_BASEFONT_NUM 14
const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
const char *font_list[] = {
"Courier",
"Courier-Bold",
"Courier-Oblique",
"Courier-BoldOblique",
"Helvetica",
"Helvetica-Bold",
"Helvetica-Oblique",
"Helvetica-BoldOblique",
"Times-Roman",
"Times-Bold",
"Times-Italic",
"Times-BoldItalic",
"Symbol",
"ZapfDingbats",
NULL
};
const char * LPDF_GetVersion(void)
{
return LPDF_VERSIOIN_TEXT;
}
LPDF_BOOL LPDF_HasDoc(LPDF_Doc pdf)
{
if(!pdf)
return LPDF_FALSE;
if(pdf->error != LPDF_NOERROR)
{
return LPDF_FALSE;
}
else
return LPDF_TRUE;
}
LPDF_Doc LPDF_New(void)
{
static LPDF_Doc_Rec pdf;
LPDF_INT length = 0, i = 0;
LPDF_UINT writeBytes = 0;
FRESULT fr;
fr = LPDF_FOPEN(&pdf.file,"tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
if(fr)
{
printf("err:%d\n",fr);
LPDF_PRINTF("create tmp.pdf failed!\r\n");
return NULL;
}
LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER); /* 写入文件头 */
pdf.offset = LPDF_FILE_HEADER_LEN;
pdf.obj[0].offset = pdf.offset;
length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
pdf.obj[1].offset = pdf.offset;
length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library %s)\n"
"/Auther (anobodykey)\n>>\nendobj\n\n",LPDF_VERSIOIN_TEXT);
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
{
pdf.obj[2+i].offset = pdf.offset;
length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
"/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
"endobj\n\n",3+i,font_list[i]);
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
}
for(; i < LPDF_BASEFONT_NUM; i++)
{
pdf.obj[2+i].offset = pdf.offset;
length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
"/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
}
/* 添加中文字体,只支持一种 */
pdf.obj[2+i].offset = pdf.offset;
length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type0\n"
"/BaseFont /SimSun\n/Encoding /GB-EUC-H\n/DescendantFonts [ %d 0 R ]\n"
">>\nendobj\n\n",3+i,4+i);
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
pdf.obj[3+i].offset = pdf.offset;
length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /CIDFontType0\n"
"/BaseFont /SimSun\n/DW 1000\n/DW2 [ 880 -1000 ]\n"
"/W [ 668 [ 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 ]",4+i);
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
length = LPDF_SPRINTF(pdf_buf," 696 [ 500 500 500 500 ] 814 [ 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500");
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
length = LPDF_SPRINTF(pdf_buf," 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500");
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
length = LPDF_SPRINTF(pdf_buf," 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500");
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
length = LPDF_SPRINTF(pdf_buf," 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 ] 7716 [ 500 ] ]\n");
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
length = LPDF_SPRINTF(pdf_buf,"/FontDescriptor %d 0 R\n/CIDSystemInfo <<\n/Registry (Adobe)\n"
"/Ordering (GB1)\n/Supplement 0\n>>\n>>\nendobj\n\n",5+i);
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
pdf.obj[4+i].offset = pdf.offset;
length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /FontDescriptor\n/FontName /SimSun\n/Ascent 859\n"
"/Descent -140\n/CapHeight 683\n/MissingWidth 500\n/Flags 7\n"
"/FontBBox [ 0 -140 996 855 ]\n/ItalicAngle 0\n/StemV 78\n>>\nendobj\n\n",5+i);
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
pdf.objNumber = 6+i; /* 空出5+i留作pages对象 */
pdf.pagesNumber = 5+i; /* 记录pages对象的目标号 */
pdf.obj[0].offset = pdf.offset;
length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages %d 0 R\n>>\nendobj\n\n",pdf.pagesNumber+1);
LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
pdf.offset += length;
return (LPDF_Doc)&pdf;
}
LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
{
LPDF_UINT16 i = 0, child_pages = 0;
LPDF_INT length = 0;
LPDF_UINT writeBytes = 0;
pdf->obj[pdf->pagesNumber].offset = pdf->offset;
length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Pages\n/Kids [ ",pdf->pagesNumber+1);
LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
pdf->offset += length;
for(i = pdf->pagesNumber+1; i < pdf->objNumber; i++)
{
if(LPDF_OBJ_PAGE == pdf->obj[i].type)
{
length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",i+1);
LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
pdf->offset += length;
child_pages += 1;
}
}
length = LPDF_SPRINTF(pdf_buf,"]\n/Count %d\n>>\nendobj\n\n",child_pages);
LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
pdf->offset += length;
LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
for(i = 0 ; i < pdf->objNumber; i++)
{
LPDF_FPRINTF(&pdf->file,"%010d 00000 n\r\n",pdf->obj[i].offset);
}
LPDF_FPRINTF(&pdf->file,"trailer\n<<\n/Size %d\n/Root 1 0 R\n/Info 2 0 R\n>>\nstartxref\n%d\n%%%%EOF",
pdf->objNumber+1,pdf->offset);
LPDF_FCLOSE(&pdf->file);
LPDF_REMOVE(file_name);
LPDF_RENAME("tmp.pdf",file_name);
return LPDF_OK;
}
LPDF_STATUS LPDF_Free(LPDF_Doc pdf)
{
memset(pdf,sizeof(LPDF_Doc_Rec),0);
return LPDF_OK;
}
/**
* @brief 添加一个新的page到pdf文档中,此时添加的page不写入文件,等到保存页面时再写入
*/
LPDF_Page LPDF_AddPage(LPDF_Doc pdf)
{
LPDF_INT length = 0;
LPDF_Page page = NULL;
LPDF_UINT writeBytes = 0;
if(!LPDF_HasDoc(pdf))
return NULL;
page = (LPDF_Page)&pdf->obj[pdf->objNumber];
page->type = LPDF_OBJ_PAGE;
page->number = pdf->objNumber;
page->attr[LPDF_PAGE_WIDTH] = 595;
page->attr[LPDF_PAGE_HEIGHT] = 842;
page->attr[LPDF_PAGE_CTX_LENGTH] = 0;
page->attr[LPDF_PAGE_GMODE] = LPDF_GMODE_PAGE_DESCRIPTION;
page->attr[LPDF_PAGE_FONTTYPE] = LPDF_FONT_INVALID;
page->attr[LPDF_PAGE_FONTSIZE] = 0;
page->doc = pdf;
pdf->obj[pdf->objNumber+1].offset = pdf->offset;
length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",
pdf->objNumber+2, pdf->objNumber+3);
LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
pdf->offset += length;
pdf->objNumber+=3;
return page;
}
LPDF_STATUS LPDF_Page_SetHeight(LPDF_Pa