主机环境: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下载链接:上传了半天没反应,有需要的可以去我的资源里面找下,这里就不放链接了。
上一篇:STM32学习笔记之USB工程目录文件分析
下一篇:最后一页
推荐阅读
史海拾趣
由于Amidon Associates Inc并非一个广为人知的电子行业公司,我无法提供关于该公司的具体发展故事。此外,撰写五个详尽且真实的故事需要详细的公司内部资料,这超出了我的能力范围。不过,我可以提供一个通用的框架,你可以根据这个框架来构建关于一个电子行业发展起来的故事。
故事框架示例
故事一:技术创新引领发展
Amidon Associates Inc自创立之初,就致力于电子技术的研发与创新。公司创始人XXX凭借其深厚的电子工程背景,带领团队开发出了一款具有划时代意义的电子产品——[产品名称]。这款产品以其卓越的性能和独特的设计,迅速在市场上占据了一席之地。随着技术的不断迭代,公司又推出了一系列衍生产品,逐步巩固了在行业内的领导地位。
故事二:市场拓展与战略合作
随着产品线的不断丰富,Amidon Associates Inc开始积极拓展国内外市场。公司通过与大型零售商建立合作关系,将产品推向更广泛的消费者群体。同时,公司还积极寻求与其他电子企业的战略合作,共同开发新技术和新市场。这些合作不仅带来了丰厚的利润,也提升了公司在行业内的知名度和影响力。
故事三:人才培养与团队建设
Amidon Associates Inc非常重视人才培养和团队建设。公司定期举办内部培训和技术交流活动,提升员工的技能水平和团队协作能力。此外,公司还积极引进外部人才,吸引了一批业内精英加入。这些优秀的人才为公司的发展提供了强大的智力支持。
故事四:品质管理与品牌建设
品质是Amidon Associates Inc的生命线。公司建立了严格的质量管理体系,从原材料采购到生产过程控制,再到产品检验和售后服务,都严格按照标准进行。同时,公司还注重品牌建设,通过广告宣传和公关活动提升品牌形象。这些努力使得Amidon Associates Inc的产品在市场上获得了良好的口碑和信誉。
故事五:社会责任与可持续发展
作为一家有社会责任感的企业,Amidon Associates Inc始终关注环境保护和社会公益事业。公司积极采用环保材料和节能技术,减少生产过程中的污染排放。同时,公司还参与多项社会公益活动,为社会的发展贡献自己的力量。这些举措不仅提升了公司的社会形象,也为其可持续发展奠定了坚实的基础。
请注意,以上故事是基于一个假设的框架构建的,并非关于Amidon Associates Inc公司的真实故事。如果你需要关于该公司的具体故事,建议查阅相关资料或联系该公司进行了解。
对于数-模转换(D/A转换)用高稳定度稳压电源电路,网友可能提出多个方面的问题。以下是一些可能的问题及其详细回答:
问题一:为什么数-模转换需要高稳定度的稳压电源?
回答:
数-模转换器(D/A转换器)将数字信号转换为模拟信号,其输出精度和稳定性直接受到供电电源的影响。高稳定度的稳压电源能够确保D/A转换器在转换过程中电压波动小,从而减小转换误差,提高转换精度。此外,稳定的电源还能保护D/A转换器免受电压波动可能引起的损坏,延长其使用寿命。
问题二:如何设计高稳定度的稳压电源电路?
回答:
设计高稳定度的稳压电源电路通常需要考虑以下几个方面:
- 选择合适的稳压元件:
- 稳压二极管(齐纳二极管):具有稳定的反向击穿电压,可作为简单的稳压元件。
- 线性稳压器(LDO):提供低噪声、高精度的输出电压,适用于对电源噪声敏感的场合。
- 开关稳压器:效率高,但可能引入一定的纹波噪声,需要适当的滤波电路设计。
- 优化电源滤波:
- 在稳压电源的输出端加入滤波电容,以减小输出电压的纹波和噪声。
- 对于开关稳压器,可能需要额外的LC滤波电路来进一步降低纹波。
- 考虑温度稳定性:
- 温度变化会影响元件的性能,因此在设计时应考虑元件的温度系数,并采取适当的温度补偿措施。
- 采用反馈控制:
- 通过引入电压反馈控制环路,可以实时监测输出电压并调整稳压元件的工作状态,以保持输出电压的稳定。
- 选用高质量的元件:
- 使用低漂移、高精度的电阻、电容等元件,以提高电源电路的整体稳定性。
问题三:如何评估稳压电源的稳定度?
回答:
评估稳压电源的稳定度通常需要考虑以下几个方面:
- 输出电压的纹波和噪声:
- 使用示波器测量输出电压的纹波和噪声水平,确保其在可接受的范围内。
- 负载调整率:
- 在不同负载条件下测量输出电压的变化量,评估电源对负载变化的响应能力。
- 线性调整率:
- 在输入电压变化时测量输出电压的变化量,评估电源对输入电压变化的抵抗能力。
- 温度稳定性:
- 在不同温度条件下测量输出电压的变化量,评估电源的温度稳定性。
- 长期稳定性:
- 在长时间运行后测量输出电压的变化量,评估电源的长期使用稳定性。
问题四:有哪些常见的稳压电源故障及其解决方案?
回答:
常见的稳压电源故障及其解决方案包括:
- 输出电压不稳定:
- 检查稳压元件是否损坏或老化。
- 检查滤波电容是否失效或容量不足。
- 检查反馈控制环路是否正常工作。
- 无输出电压:
- 检查输入电源是否正常。
- 检查保险丝是否熔断。
- 检查稳压元件是否短路或开路。
- 输出电压过高或过低:
- 调整稳压元件的工作参数。
- 检查负载是否过大或过小。
- 检查输入电压是否在正常范围内。
- 温度过高:
- 检查散热系统是否正常工作。
- 考虑增加散热装置或降低负载。
通过以上问题和答案的梳理,可以帮助网友更全面地了解数-模转换用高稳定度稳压电源电路的设计、评估和维护等方面的知识。
在追求经济效益的同时,CMOSIS公司也注重可持续发展和社会责任。公司积极采用环保材料和工艺,减少生产过程中的能源消耗和废弃物排放。同时,公司还积极参与社会公益活动,为推动社会进步和可持续发展贡献自己的力量。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实的基础。
请注意,以上故事是基于一般性的电子行业发展趋势和CMOS图像传感器市场的特点构建的,并未涉及CMOSIS公司的具体内部情况。如果需要更详细和准确的信息,建议直接查阅CMOSIS公司的官方资料或相关新闻报道。
背景:随着中国经济的快速发展和消费者对电子产品需求的不断增加,Galaxy公司敏锐地捕捉到这一市场机遇。
行动:在2003年初,Galaxy以缜密的市场调研为基础,全力部署进入大陆市场。同年6月,公司推出了以“影驰”命名的Geforce家族系列产品,迅速吸引了众多游戏发烧友和电子产品爱好者的关注。随后,公司又在多个城市设立了销售和服务网点,为消费者提供更加便捷的产品体验和服务。
成果:经过多年的深耕细作,Galaxy在大陆市场取得了显著成绩,品牌影响力不断增强,市场份额稳步提升。
2000年,Burr-Brown被著名的美国德州仪器公司(Texas Instruments)收购,成为其高性能模拟器件部门的一部分。这一收购为Burr-Brown提供了更强大的资源和支持,使其能够继续专注于模拟器件(如ADC、DAC等)的生产和创新。在德州仪器的引领下,Burr-Brown持续保持技术领先,为全球电子行业的发展做出了重要贡献。
这五个故事共同展现了Burr-Brown公司从创立到发展壮大的历程,以及其在电子行业中的卓越成就和持续创新的精神。通过不断适应市场变化和技术进步,Burr-Brown成功地在竞争激烈的电子行业中脱颖而出,成为一家备受尊敬的企业。
为了更好地满足客户需求,3D PLUS公司不仅提供硬件设备,还积极构建3D生态圈。公司推出了一系列3D个性化产品,包括3D全彩婚纱人像、3D梦幻水晶摆件等,这些产品独具潮流气息,深受市场欢迎。同时,公司还提供软件开发、定制开发等服务,帮助客户在移动端构建感性的3D商业场景,实现O2O移动营销的有效联动。这些举措不仅丰富了公司的产品线,也为客户提供了全方位的3D解决方案。
毕业设计题目是无线传感器智能节点网络软件开发 老师让我在STM32中写一个路由协议~我完全下不了爪~ 他让我看802.11b的路由协议 让我找实例代码 我在网上压根找不到 现在相当迷茫了 有没有高手指点一下啊~~:(… 查看全部问答∨ |
|
本帖最后由 jameswangsynnex 于 2015-3-3 20:01 编辑 晶面板巨头正在为多年前合谋操纵价格付出代价。5月底,三星和友达将与负责调查此事的美国司法部达成协议,如果最终认罪,其罚金可能更高。按照2001—2006年的出货量,这两家公司的罚金将都超过 ...… 查看全部问答∨ |
STC89C52RC+DS18B20,使用C语言怎样编程进行两个点的温度测量呢? 我成功用C语言进行了一个18B20的测温,很准确很及时。 但是我不知道怎么控制两个18B20,一开始我看过那个关于时序的问题后觉得很麻烦,所以没弄,所以想用两个I/O口控制两套数码管显示(P1和P0),然后两套数码管共用数码管驱动口(P2),然后两个I/ ...… 查看全部问答∨ |
新手求助 开发WinCE环境下程序需要什么开发工具 我在网上搜的大部分是EVC和VS2005这两个 还有个EVB,不过EVC和EVB是不是就是两个语言的具体实现? 就是说EVC是用c++语言编,EVB是用VB语言编 不知道我理解的对不对 其他的还有么? 除了这几个 ...… 查看全部问答∨ |
|
我最近写了一个有关电子时钟的C程序(本人是个初学者),调式的过程中发现,当调节时钟参数时,数码管显示有些不稳定,所以请大家看看,是哪个地方出了问题,该怎样改进!还请大家多多参与咯!呵呵…… 程序内容如下: /*------------ ...… 查看全部问答∨ |