历史上的今天
返回首页

历史上的今天

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

正在发生

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

2018-10-23 来源:eefocus

主机环境: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下载链接:上传了半天没反应,有需要的可以去我的资源里面找下,这里就不放链接了。


推荐阅读

史海拾趣

Freeport Resources Enterprises Corp公司的发展小趣事

为了提升在电子材料领域的竞争力,Freeport Resources积极寻求国际合作,与多家国际知名电子材料生产商和研究机构建立了战略伙伴关系。通过技术引进和联合研发,公司成功掌握了先进的电子材料提纯和加工技术,大幅提高了产品的质量和性能。同时,国际合作也帮助Freeport Resources打开了国际市场,其产品远销全球多个国家和地区,进一步巩固了其在电子材料市场的地位。

明微公司的发展小趣事

随着全球半导体行业向中国市场的转移,明微公司意识到拓展海外市场的重要性。为了加快海外市场拓展步伐,公司积极加强与国际知名企业的合作与交流,引进先进的技术和管理经验。同时,公司还积极参加国际展会和论坛等活动,提升品牌影响力。这些举措使明微公司在国际市场上逐渐树立起良好的口碑和形象。

艾华集团(AISHI)公司的发展小趣事

随着市场的不断变化和竞争的加剧,艾华集团意识到,要想在行业中立足并取得长远发展,必须走科技创新之路。于是,公司成立了多个研究院,专注于基础材料、产品、工业装备以及产品应用的研究。通过不断的科技创新和产品升级,艾华集团成功研发出了耐超高纹波和耐超强冲击电流的铝电容器技术,这一技术在市场上获得了广泛认可,赢得了飞利浦、欧司朗、GE等世界知名照明客户的青睐。

ETC2公司的发展小趣事

为了拓展全球市场,ETC2公司制定了国际化战略。他们积极参加国际展览和交流活动,与国际同行建立了广泛的合作关系。同时,ETC2公司还针对不同国家和地区的市场特点,推出了定制化的ETC产品和服务。这些举措不仅帮助ETC2公司成功打入国际市场,也为其未来的发展奠定了坚实的基础。

明波通信(BWAVE)公司的发展小趣事

经过多年的发展,明波通信在技术和市场上都取得了显著成绩。为了进一步推动公司的发展,明波通信成功在新三版上市。这一举措不仅为公司筹集了更多的发展资金,也提升了公司的品牌影响力和市场竞争力。上市后的明波通信,在资本市场上展现出了强劲的发展势头。

Good Will Instrument Co., Ltd.公司的发展小趣事

经过多年的发展,明波通信在技术和市场上都取得了显著成绩。为了进一步推动公司的发展,明波通信成功在新三版上市。这一举措不仅为公司筹集了更多的发展资金,也提升了公司的品牌影响力和市场竞争力。上市后的明波通信,在资本市场上展现出了强劲的发展势头。

问答坊 | AI 解惑

初学PIC单片机

想知道学PIC单片机需要什么软件? 在网上查的是需要: 1、MPLABV8.43(从microchip网站下的) 2、PICC编译器(C语言编译器) 3、PIC单片机单片机烧写器(具体软件暂时没查到)    有精通PIC单片机的高手请给予一下指点,其中第二,第 ...…

查看全部问答>

gogogo

[url=http://www.artgoin.com][/url]爱艺购,艺术的天堂,艺术的宝库,爱好艺术的人都该去看看,获取能找到一件稀世珍宝欧…

查看全部问答>

关于加速计和陀螺仪的测试

各位高手有没有测试过加速计和陀螺仪这两颗的功能阿,三轴加速计有X,Y,Z三个电压输出,都是经过其内部的AD转换后输出的,不知道这三个方向上的电压是怎么变化的,是有加速度的时候变化呢,还是位置改变了变化啊? 陀螺仪有X,Y两个电压输出,也是 ...…

查看全部问答>

关于MTD驱动的问题

很多MTD驱动都有调用simple_map_init()函数来初始化read,write等函数,不知道这个函数的用法,请大虾帮忙讲一讲啊,如果我需要改变这些read,write函数,该怎么办啦?…

查看全部问答>

求职: 请问有没有人需要高级WINCE工程师--限深圳地区!

求职: 请问有没有人需要高级WINCE驱动工程师--限深圳地区! 如有,请如下EMAIL联系 lumit_hu@126.com…

查看全部问答>

英蓓特STM32ARM开发板的初级改造(有图)

上周在研讨会上买了英蓓特的开发板,试了下,感觉有几个地方不爽,所以就自己动手DIY了:1)USB供电问题,必须插2条USB线,可怜我的本本一共才3个,鼠标用了一个,被他全占了,其它USB-232就没法用了;2)板子附带的1602没有接背光,而实际这 ...…

查看全部问答>

關於LMF232H5QD的UART問題

各位高手大家好,小妹我用此板子的UART出了一點問題,大家可以幫幫我嗎? 感激不盡 問題是這樣的,我開啟了八個UART,為了使輸入資料可以做辨識,個別在UART4跟UART5的地方 加了三個#字號跟一個通道編號 例如:UART4是  ###Edata 這樣 ...…

查看全部问答>

今年会出功率放大类的吗?

本帖最后由 paulhyde 于 2014-9-15 03:16 编辑 今年会出功率放大类的吗    …

查看全部问答>

这几天学习SimpliciTI协议栈的小总结合小纠结

SimpliciTI简介: SimpliciTI是TI开发的专门针对其CCxxxx系列无线通信芯片的网络协议。 它支持两种网络拓扑结构:严格的点对点通信和基于星型的网络拓扑结构,在星型连接中Hub点在SimplciTI被称为Access Point,简称AP.(AP就是常说的网关,数据中 ...…

查看全部问答>

TM4C 1294XL

老师给了一块tm4c 1294的launchpad,说让我们自己玩,但之前没接触过arm这些东西,接触过单片机;所以完全不知道怎么开始??这块板子能干嘛我都不知道,该怎么学习??完全处于迷茫状态??望大神相助,指点一二,让我有个方向!!非常感谢! …

查看全部问答>