datasheet

LPC54608生成PDF文件

2018-10-23来源: 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文件

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/2018/ic-news102341971.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32学习笔记之USB工程目录文件分析
下一篇:ARM处理器工作模式及寄存器结构

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

LPC17xx管脚复用之Uart部分

管脚复用,即一个管脚可以用作多种用途,通过寄存器的设置来选取相应的功能,这在微处理器中很常见。之前用过LPC2xxx系列芯片就有很多管脚复用,但不同管脚的复用功能不会重复。最近再调试LPC17xx时候发现复用的新情况:不同管脚可以有同一种复用功能,如Uart1的可以有三组管脚来实现:(P0.15,P0.16),(P2.0,P2.1)和(P3.16,P3.17),根据需要设计电路。在编程中就要注意实际使用了哪对管脚,我就是没看仔细,把之前的程序移植过来出了问题。
发表于 2019-02-15

LPC1788外部中断的例子,基于Keil MDK

网上LPC1700外部中断的例子都是ADS的,我来贡献个Keil MDK的吧以外部中断0(EINT0)为例,低电平触发中断关键代码如下://头文件为MDK 4.23带的"LPC177x_8x.h",代码中所用宏均在其中可以找到定义 #include "LPC177x_8x.h"  LPC_IOCON->P2_10 = (LPC_IOCON->P2_10 & ~0x07) | 1;  //把P2.10设为EINT0 LPC_SC->EXTMODE &= ~0x01;  //中断为电平触发 
发表于 2019-02-15

LPC2387 RS485通信

最近一款基于LPC2387方案的产品要用到RS485通信,查了下datasheet,LPC2387的Uart没有内置RS485功能,故只能采用电平转化了。最后选择了MAX485和英联的UM3085,两款芯片管脚兼容,都能进行TTL和RS485转化。因为采用半双工通信,所以用一个GPIO口同时控制DE和RE,某一刻只能是接收或发送。LPC2387的TXD1和RXD1分别和485的DI和RO连接。//RS-485收发控制示意代码,和普通串口通信相比多了485芯片的发送/接收使能设置 #define RS485_DE_RE (0x01<<9)  //GPIO P0.9控制DE,RE 
发表于 2019-02-15

LPC1788实现10ms单位的计数器

利用LPC1788的定时器0实现10ms单位的计数器,即每10ms计数增加1.初始化定时器0 init_timer(1,599990); //10ms为单位 599990=10(60000000/1000-1),LPC1788工作在120MHZ,经PLL分频后的外设时钟PeripheralClock为60MHZ函数原型:uint32_t init_timer ( uint8_t timer_num, uint32_t TimerInterval ) {  timer0_counter = 0; LPC_SC->PCONP |= (0x01<<1); LPC_TIM0->MR0
发表于 2019-02-15

LPC2387看门狗功能

最近一个基于LPC2387的方案遇到了棘手的死机问题,板子的网口在客户那运行了十天左右会无法连通。这种现象很难复制,也没有规律。只能祭出大招看门狗,死机时候Ping不通那肯定网络线程Down掉了,那就在网络线程中喂狗吧。看门狗驱动://初始化watchdogvoid InitWDT(unsigned long t){ WDCLKSEL = 0; //use IRC as watchdog clock WDTC = t*1000000; // t*4/4MHZ WDMOD = 0x03;}  void FeedWDT(){    Disable_Int();  //禁止中断,以免喂狗
发表于 2019-02-15

LPC17xx使用内部晶体(Internal RC Oscillator)作为时钟源

在一般应用场合(不使用USB,对精度要求不高)LPC17xx系列除了使用外部晶体外,还可以使用内部的12MHZ晶体作为振荡源。其实在运行初始化程序,进入用户程序前(main函数),LPC17xx是使用了内部晶体,这样设计是为了让引导代码(俗称bootloader)运行在一个已知的频率上。最近在开发板上做了个使用内部晶体的小实验,把原来使用外部12MHZ的程序修改成了使用内部晶体。这个修改其实很简单,只要修改时钟源选择寄存器(CLKSRCSEL)和锁相环0配置寄存器(PLL0CFG)。在Keil下system_LPC177x_8x.c下甚至能可视化修改。具体如下图:为了确定实验效果,把外部晶体使能关闭了(Main
发表于 2019-02-15
LPC17xx使用内部晶体(Internal RC Oscillator)作为时钟源

小广播

何立民专栏

单片机及嵌入式宝典

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

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