历史上的今天

今天是:2024年10月23日(星期三)

正在发生

2018年10月23日 | LPC54608生成PDF文件

发布者:颐真阁 来源: eefocus关键字:LPC54608  PDF文件 手机看文章 扫描二维码
随时随地手机看文章

主机环境:Win10 64bit


开发环境:MDK5.23


目标板:LPC54608


之前在NXP论坛里得到了一块LPC54608开发板,最吸引人的地方是带了一块屏,如下图:

这也是第一次接触NXP的开发板,之前一直都是用的ST的MCU,NXP的库跟ST的还是差别蛮大的,自我感觉ST的开发入手要快一些,而NXP的相对慢一些,入手开发板之后就看了库里面自带的一些基本驱动例程,只熟悉了一下基本外设的开发,之前有次在群里看到有人询问单片机生成PDF的问题,突然觉得有些兴趣所以就有了前面的libHaru学习笔记,libHaru库是一个十分不错的库,对于PDF的实现来说也是相当齐全的,在PC上使用是完全没有问题的,但在资源紧张的MCU上,还是有些困难的,因此就想找一下适用于MCU的生成PDF的库,结果不太理想,都是一些需要实现动态内存管理的平台才行,而且这些库都是把生成的数据放在了内存中,直到保存文件时才写入到文件中,这对于一般只有几十或者几百KB级别的单片机来说更不可能了,于是乎,萌发了自己动手写一个基本的能用于MCU的生成PDF文件的库,我称之为libpdf,其中的接口参考了libHaru,如下所示:

当然有些接口还没有实现,但基本的操作还是可以的,等以后再逐渐完善吧,pdflib是生成pdf文件的,因此要基于Fatfs来实现文件的操作,pdflib库只有两个文件,也相应的参考了pdfgen库,该库在后面有链接,


头文件如下:



#ifndef __PDFLIB_H__

#define __PDFLIB_H__

 

#include "ff.h"

/*----- standard C library functions -----------------------------------------*/

 

#define LPDF_FOPEN                  f_open

#define LPDF_FCLOSE                 f_close

#define LPDF_FREAD                  f_read

#define LPDF_FWRITE                 f_write

#define LPDF_FFLUSH                 f_sync

#define LPDF_FSEEK                  f_seek

#define LPDF_FTELL                  f_tell

#define LPDF_FEOF                   f_eof

#define LPDF_FERROR                 f_error

#define LPDF_RENAME                 f_rename

#define LPDF_REMOVE                 f_unlink

#define LPDF_MALLOC                 malloc

#define LPDF_FREE                   free

#define LPDF_FILE                   FIL

#define LPDF_TIME                   time

#define LPDF_PRINTF                 printf

#define LPDF_SPRINTF                sprintf

#define LPDF_FPRINTF                f_printf

#define LPDF_VOID                   void

#define LPDF_SIN                    sin

#define LPDF_COS                    cos

 

/*  native OS integer types */

typedef  signed int          LPDF_INT;

typedef  unsigned int        LPDF_UINT;

 

 

/*  32bit integer types

 */

typedef  signed int          LPDF_INT32;

typedef  unsigned int        LPDF_UINT32;

 

 

/*  16bit integer types

 */

typedef  signed short        LPDF_INT16;

typedef  unsigned short      LPDF_UINT16;

 

 

/*  8bit integer types

 */

typedef  signed char         LPDF_INT8;

typedef  unsigned char       LPDF_UINT8;

 

 

/*  8bit binary types

 */

typedef  unsigned char       LPDF_BYTE;

 

 

/*  float type (32bit IEEE754)

 */

typedef  float               LPDF_REAL;

 

 

/*  double type (64bit IEEE754)

 */

typedef  double              LPDF_DOUBLE;

 

 

/*  boolean type (0: False, !0: True)

 */

typedef  signed int          LPDF_BOOL;

 

 

/*  error-no type (32bit unsigned integer)

 */

typedef  unsigned long       LPDF_STATUS;

 

#define LPDF_OK                     0

#define LPDF_FAILED                 1

 

/*----- font state -----------------------------------------------------------*/

#define   LPDF_FONT_INVALID                 0x00FF

#define   LPDF_FONT_COURIER                 0x0000

#define   LPDF_FONT_COURIER_B               0x0001

#define   LPDF_FONT_COURIER_O               0x0002

#define   LPDF_FONT_COURIER_OB              0x0003

#define   LPDF_FONT_HELVETICA               0x0004

#define   LPDF_FONT_HELVETICA_B             0x0005

#define   LPDF_FONT_HELVETICA_O             0x0006

#define   LPDF_FONT_HELVETICA_BO            0x0007

#define   LPDF_FONT_TIMES_R                 0x0008

#define   LPDF_FONT_TIMES_B                 0x0009

#define   LPDF_FONT_TIMES_I                 0x000A

#define   LPDF_FONT_TIMES_BI                0x000B

#define   LPDF_FONT_SYMBOL                  0x000C

#define   LPDF_FONT_ZAP                     0x000D

/*----- Graphis mode ---------------------------------------------------------*/

#define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001

#define   LPDF_GMODE_PATH_OBJECT            0x0002

#define   LPDF_GMODE_TEXT_OBJECT            0x0004

#define   LPDF_GMODE_CLIPPING_PATH          0x0008

#define   LPDF_GMODE_SHADING                0x0010

#define   LPDF_GMODE_INLINE_IMAGE           0x0020

#define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040

#define   LPDF_GMODE_INVALID                0x0080

#define   LPDF_GMODE_OVER                   0x0100

 

#define OBJ_MAX_NUM     256

 

/* Page的结构信息是否需要树形结构 */

typedef enum 

{

    OBJ_info,

    OBJ_stream,

    OBJ_font,

    OBJ_page,

    OBJ_catalog,

    OBJ_pages,

    OBJ_image,

}LPDF_ObjType;

 

typedef struct

{

    LPDF_ObjType objType;

    LPDF_UINT16 objIdx;

    LPDF_UINT16 height;

    LPDF_UINT16 width;

    LPDF_UINT16 length;

    LPDF_UINT gMode;

    LPDF_BYTE fontType;

    LPDF_BYTE fontSize;

    LPDF_BYTE pState;

    LPDF_VOID *doc;

}LPDF_Obj;

 

typedef struct

{

    LPDF_Obj obj[OBJ_MAX_NUM];

    LPDF_UINT32 offset;

    LPDF_UINT16 objNumber;

    LPDF_FILE file;

}LPDF_Doc_Rec;

 

typedef LPDF_Doc_Rec *LPDF_Doc;

typedef LPDF_Obj *LPDF_Page;

typedef LPDF_Obj *LPDF_Image;

extern const char *font_list[];

/*----- LPDF Interfaces-------------------------------------------------------*/

const char * LPDF_GetVersion(void);

LPDF_Doc LPDF_New(void);

LPDF_Page LPDF_AddPage(LPDF_Doc pdf);

LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);

LPDF_STATUS LPDF_Free(LPDF_Doc pdf);

LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);

LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,

                           const char *font_name, LPDF_UINT8 size);

LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);

LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);

LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);

LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);

LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);

LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);

LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);

LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);

LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);

LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,

                         LPDF_INT x, LPDF_INT y);

LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, 

                         LPDF_UINT16 x, LPDF_UINT16 y,

                         const char *text);

LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,

                         LPDF_REAL r,

                         LPDF_REAL g,

                         LPDF_REAL b);

LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,

                         LPDF_REAL r,

                         LPDF_REAL g,

                         LPDF_REAL b);

LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,

                         LPDF_UINT16 x,

                         LPDF_UINT16 y);

LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,

                         LPDF_UINT16 x,

                         LPDF_UINT16 y);

LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);

LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);

LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,

                      LPDF_Image image,

                      LPDF_UINT16 x,

                      LPDF_UINT16 y,

                      LPDF_UINT16 width,

                      LPDF_UINT16 height);

#endif

源文件如下:


#include

#include

#include

#include

#include "pdflib.h"

 

#define LPDF_INVALID_OBJECT                       0x1033

 

static char pdf_buf[512];

 

#define LPDF_VERSIOIN_TEXT          "0.0.1"

#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_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)

{

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].objIdx = 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].objIdx = pdf.offset;

    length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"

                    "/Auther (anobodykey)\n>>\nendobj\n\n");

    LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);

    pdf.offset += length;

    

    for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)

    {

        pdf.obj[2+i].objIdx = 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].objIdx = 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.objNumber = 3+i;

  

    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[16].objIdx = pdf->offset;

    child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;

    length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    for(i = 0; i < child_pages; i++)

    {

        length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);

        LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

        pdf->offset += length;

    }

    length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");

    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,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);

    }

    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;

}

 

LPDF_Page LPDF_AddPage(LPDF_Doc pdf)

{

    LPDF_INT length = 0,i = 0;

    LPDF_Page page = NULL;

LPDF_UINT writeBytes = 0;

    

    pdf->obj[pdf->objNumber].objIdx = pdf->offset;

    length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"

                    "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"

                    "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    while(font_list[i])

    {

        length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);

        LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

        pdf->offset += length;

        i+=1;

    }

    LPDF_FPRINTF(&pdf->file,">>\n>>\n");

    pdf->offset += 4;

    page = (LPDF_Page)&pdf->obj[pdf->objNumber];

    page->width = 595;

    page->height = 842;

    page->gMode = LPDF_GMODE_INVALID;

    page->fontType = LPDF_FONT_INVALID;

    page->doc = pdf;

    return page;

}

 

LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)

{

    page->height = value;

    return LPDF_OK;

}

LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)

{

    page->width = value;

    return LPDF_OK;

}

 

LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)

{

    if(page)

    {

        return page->height;

    }

    

    return LPDF_OK;

}

 

LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)

{

    if(page)

    {

        return page->width;

    }

    

    return LPDF_OK;

}

 

LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)

{

    if(!page)

        return LPDF_INVALID_OBJECT;

    if(!(page->gMode&mode))

        return LPDF_FAILED;

 

    return LPDF_OK;

}

 

LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,

                           const char *font_name, LPDF_UINT8 size)

{

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_INT i = 0,length = 0;

LPDF_UINT writeBytes = 0;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);

    if(LPDF_OK != ret)

        return ret;

 

    while(font_list[i])

    {

        if(0 == strcmp(font_list[i],font_name))

        {

            page->fontType = i;

            page->fontSize = size;

            length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);

            LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

            pdf->offset += length;

            page->length += length;

            return LPDF_OK;

        }

        i+=1;

    }

    

    return LPDF_OK;

}

 

LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)

{

    LPDF_INT length;

LPDF_UINT writeBytes = 0;

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);

    if(LPDF_OK != ret)

        return ret;

    

    /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */

    length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",

                        page->width, page->height);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;

    length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<>\nstream\n",

                        pdf->objNumber+2, pdf->objNumber+3);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    page->length = 0;

    page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;

    return LPDF_OK;

}

 

LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)

{

    LPDF_INT length;

LPDF_UINT writeBytes = 0;

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);

    if(LPDF_OK != ret)

        return ret;

     /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */

    length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes); 

    pdf->offset += length;

    pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;

    length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",

                        pdf->objNumber+3,page->length);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    pdf->objNumber += 3;

    page->gMode = LPDF_GMODE_OVER;

    return LPDF_OK;

}

 

LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)

{

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);

    if(LPDF_OK != ret)

        return ret;

    LPDF_FPRINTF(&pdf->file,"BT\n");

    pdf->offset += 3;

    page->length += 3;

    page->gMode = LPDF_GMODE_TEXT_OBJECT;

    return LPDF_OK;

}

LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)

{

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);

    if(LPDF_OK != ret)

        return ret;

    LPDF_FPRINTF(&pdf->file,"ET\n");

    pdf->offset += 3;

    page->length += 3;

    page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;

    return LPDF_OK;

}

 

LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)

{

    LPDF_INT length = 0;

LPDF_UINT writeBytes = 0;

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);

    if(LPDF_OK != ret)

        return ret;

    if(LPDF_FONT_INVALID == page->fontType)

        return LPDF_OK;

    length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    page->length += length;

    return LPDF_OK;

    

}

LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,

                        LPDF_INT x, LPDF_INT y)

{

    LPDF_INT length = 0;

LPDF_UINT writeBytes = 0;

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);

    if(LPDF_OK != ret)

        return ret;

    length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    page->length += length;

 

    return LPDF_OK;

}

LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, 

                        LPDF_UINT16 x, LPDF_UINT16 y,

                        const char *text)

{

    return LPDF_OK;

}

 

LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,

                         LPDF_REAL r,

                         LPDF_REAL g,

                         LPDF_REAL b)

{

    LPDF_INT length = 0;

LPDF_UINT writeBytes = 0;

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);

    if(LPDF_OK != ret)

        return ret;

 

    length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    page->length += length;

    return LPDF_OK;

}

 

LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,

                         LPDF_REAL r,

                         LPDF_REAL g,

                         LPDF_REAL b)

{

    LPDF_INT length = 0;

LPDF_UINT writeBytes = 0;

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);

    if(LPDF_OK != ret)

        return ret;

 

    length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    page->length += length;

    return LPDF_OK;

}

LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,

                         LPDF_UINT16 x,

                         LPDF_UINT16 y)

{

    LPDF_INT length = 0;

LPDF_UINT writeBytes = 0;

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);

    if(LPDF_OK != ret)

        return ret;

    length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    page->length += length;

    page->gMode = LPDF_GMODE_PATH_OBJECT;

    return LPDF_OK;

}

LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,

                         LPDF_UINT16 x,

                         LPDF_UINT16 y)

{

    LPDF_INT length = 0;

LPDF_UINT writeBytes = 0;

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);

    if(LPDF_OK != ret)

        return ret;

    length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);

    LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);

    pdf->offset += length;

    page->length += length;

    return LPDF_OK;

}

LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)

{

    LPDF_Doc pdf = (LPDF_Doc)page->doc;

    LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);

    if(LPDF_OK != ret)

        return ret;

    LPDF_FPRINTF(&pdf->file,"S\n");

    pdf->offset += 2;

    page->length += 2;

    page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;

    return LPDF_OK;

}

LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,

                      LPDF_Image image,

                      LPDF_UINT16 x,

                      LPDF_UINT16 y,

                      LPDF_UINT16 width,

                      LPDF_UINT16 height)

{

return LPDF_OK;

}

对于pdf文件结构可以去查看pdf参考手册,这里我看的是pdf-1.4参考手册,该库的测试代码我是在基于LPC54608库中的sdcard_fatfs示例改编的,关键代码如下:

测试代码很简单,生成了一个含有两个page的pdf文件,在第一页中用了不同的字体来显示同一个字符串,可以参考libHaru中的font_demo示例,第二页中是画了一个立方体图,下载代码到目标板,并运行该示例,串口终端输出如下:

拔下板上的SD卡,插入到PC上,可以看到red.pdf文件

使用pdf阅读器打开该文件,截图如下:

pdflib库目前来说还是比较简单的,需慢慢完善,


pdfgen库链接如下:https://github.com/AndreRenaud/PDFGen


pdflib下载链接:上传了半天没反应,有需要的可以去我的资源里面找下,这里就不放链接了。


关键字:LPC54608  PDF文件 引用地址:LPC54608生成PDF文件

上一篇:STM32学习笔记之USB工程目录文件分析
下一篇:最后一页

推荐阅读

韩国国内排名第一的工业机器人企业现代重工公司将参加韩国“2018世界机器人大会”并在展会展示协作机器人。现代重工虽然没有公开将展示的产品,据观测,可能是自主研发的协作机器人概念产品。 这次展会以协作机器人为切入点将是现代重工展示技术力的舞台。 这次韩国机器人大会将吸引国内外协作机器人专门企业会参展,业界排名第一的UR机器人,现代重...
用到了数码管显示,矩阵键盘,蜂鸣器,适合新接触51的朋友们,只是程序,一看就明白 c语言程序单片机源程序如下:/*********************************************************************************************程序名:    8键电子琴C程序编写人:    杜洋 编写时间:  2009年5月18日硬件支持:  STC系列单片机 12MHz接口说明:   ...
台积电持续推动高阶制程,带动相关的半导体设备及测试设备需求,半导体测试设备大厂爱德万(Advantest)表示,明年设备产业续受惠半导体先进制程和5G应用带动系统单晶片测试,预期明年整体半导体相关的测试及设备需求可望持稳。 爱德万测试台湾ATE业务销售事业处资深副总经理吴万锟指出,台积电积极布局3纳米及以下晶圆先进制程,且台积电资本支出也呼应整...
红米 Redmi Note 11 系列手机将于 10 月 28 日 19:00 正式发布,同时到来的还会有 Redmi Watch 2 智能手表。  官方此前已官宣了“迷雾森林”配色,采用 AG 玻璃后盖,整体设计有棱有角。该机采用 1.75mm 超窄边 2.96mm 针孔 AMOLED 屏,支持 120Hz 高刷和 360Hz 高触控。  今日,官方公布了系列的第二款配色“时...

史海拾趣

问答坊 | AI 解惑

求助啊~STM内嵌路由协议~

毕业设计题目是无线传感器智能节点网络软件开发 老师让我在STM32中写一个路由协议~我完全下不了爪~ 他让我看802.11b的路由协议 让我找实例代码 我在网上压根找不到 现在相当迷茫了 有没有高手指点一下啊~~:(…

查看全部问答∨

国际液晶面板巨头操纵价格或被罚15亿

本帖最后由 jameswangsynnex 于 2015-3-3 20:01 编辑 晶面板巨头正在为多年前合谋操纵价格付出代价。5月底,三星和友达将与负责调查此事的美国司法部达成协议,如果最终认罪,其罚金可能更高。按照2001—2006年的出货量,这两家公司的罚金将都超过 ...…

查看全部问答∨

STC89C52RC+DS18B20,使用C语言怎样编程进行两个点的温度测量呢?

我成功用C语言进行了一个18B20的测温,很准确很及时。 但是我不知道怎么控制两个18B20,一开始我看过那个关于时序的问题后觉得很麻烦,所以没弄,所以想用两个I/O口控制两套数码管显示(P1和P0),然后两套数码管共用数码管驱动口(P2),然后两个I/ ...…

查看全部问答∨

[求助]开发WinCE环境下程序需要什么开发工具

新手求助 开发WinCE环境下程序需要什么开发工具 我在网上搜的大部分是EVC和VS2005这两个 还有个EVB,不过EVC和EVB是不是就是两个语言的具体实现? 就是说EVC是用c++语言编,EVB是用VB语言编 不知道我理解的对不对 其他的还有么? 除了这几个 ...…

查看全部问答∨

关于GPS的选择

最近要做一个项目,要用到gps,我们不需要图形界面,只需要他传的时间和方位信息,想使用串口,不知道有没有合适的模块,请路过的朋友介绍一下,请别介绍车载用的,那是对您和我智慧的侮辱。…

查看全部问答∨

有人帮帮我吗?发现新硬件

有人能写个启动发现新硬件的DLL或者VBS给我吗?…

查看全部问答∨

精智6410

本款6410开发板做工精良,价格公道,童叟无欺,功能强大,并将配套《QT6410专用视频教材》,由韦东山直接倾力讲解和诠释,以及宋宝华的配套LINUX驱动详解第二版。 淘宝店铺:280605881.taobao.com …

查看全部问答∨

STC单片机电子时钟

我最近写了一个有关电子时钟的C程序(本人是个初学者),调式的过程中发现,当调节时钟参数时,数码管显示有些不稳定,所以请大家看看,是哪个地方出了问题,该怎样改进!还请大家多多参与咯!呵呵……   程序内容如下: /*------------ ...…

查看全部问答∨

我表示很伤心啊

哎,今天艾睿合众达的一个电话,让我很伤心啊。本来四月份参加了由TI和艾睿合众达联合举办的研讨会,说好可以申请一套MCU应用开发板的,结果我就申请了cortex-M4内核的开发板,然后一直盼望着盼望着,结果,今天艾睿合众达的一位工作人员说什么没货 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved