LPC54608 generates PDF files

Publisher:颐真阁Latest update time:2018-10-23 Source: eefocusKeywords:LPC54608 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Host environment: Win10 64bit


Development environment: MDK5.23


Target board: LPC54608


I got an LPC54608 development board from the NXP forum before. The most attractive thing about it is that it comes with a screen, as shown below:

This is also the first time I have come into contact with NXP's development board. I have always used ST's MCU before. The NXP library is quite different from ST's. I feel that ST's development is faster, while NXP's is relatively slower. After getting the development board, I looked at some basic driver routines that come with the library and only became familiar with the development of basic peripherals. I once saw someone in the group asking about the problem of generating PDF with a single-chip microcomputer. I suddenly felt interested, so I had the previous libHaru study notes. The libHaru library is a very good library, and it is also quite complete for the implementation of PDF. It is used on the PC. There is absolutely no problem in using it, but it is still a bit difficult on MCU with limited resources. Therefore, I want to find a library for generating PDF files suitable for MCU. The result is not ideal. They are all platforms that need to implement dynamic memory management. Moreover, these libraries put the generated data in the memory and write it to the file until the file is saved. This is even more impossible for microcontrollers with only tens or hundreds of KB. So, I have the idea of ​​writing a basic library that can be used for MCU to generate PDF files. I call it libpdf, and its interface refers to libHaru, as shown below:

Of course, some interfaces have not been implemented yet, but the basic operations are still possible, and they will be gradually improved in the future. pdflib generates pdf files, so it is necessary to implement file operations based on Fatfs. The pdflib library has only two files, and the pdfgen library is also referenced accordingly. The library has a link at the back.


The header file is as follows:



#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;

 

 

/* 32-bit integer types

 */

typedef signed int LPDF_INT32;

typedef unsigned int LPDF_UINT32;

 

 

/* 16-bit integer types

 */

typedef signed short LPDF_INT16;

typedef unsigned short LPDF_UINT16;

 

 

/* 8-bit integer types

 */

typedef signed char LPDF_INT8;

typedef unsigned char LPDF_UINT8;

 

 

/* 8-bit 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

 

/* Does the structure information of the Page need a tree structure?*/

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

The source files are as follows:


#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); /* Write 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;

    

    /* For each page, this interface can only be called once, that is, when GMODE is 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;

     /* For each page, this interface can only be called once, that is, when GMODE is PAGE_DESCRIPTION mode*/

    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 %dm\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 %dl\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;

}

For the PDF file structure, you can check the PDF reference manual. Here I am looking at the PDF-1.4 reference manual. The test code of this library is adapted from the sdcard_fatfs example in the LPC54608 library. The key code is as follows:

The test code is very simple. It generates a PDF file with two pages. Different fonts are used to display the same string in the first page. You can refer to the font_demo example in libHaru. The second page draws a cube. Download the code to the target board and run the example. The serial terminal output is as follows:

Unplug the SD card from the board and insert it into the PC, you can see the red.pdf file

Use a PDF reader to open the file, and the screenshot is as follows:

The pdflib library is still relatively simple at present and needs to be gradually improved.


The pdfgen library link is as follows: https://github.com/AndreRenaud/PDFGen


pdflib download link: There was no response after uploading it for a long time. If you need it, you can find it in my resources. I won’t put the link here.


Keywords:LPC54608 Reference address:LPC54608 generates PDF files

Previous article:STM32 study notes USB project directory file analysis
Next article:ARM processor working mode and register structure

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

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