你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 ( J7 x7 a3 Z$ j9 u4 e/ q
5 P% {$ j5 h' r8 E

主机环境:Win10 64bit

开发环境:MDK5.23

目标板:Cortex-M MCU

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

捕获.PNG

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

头文件如下:

  1. #ifndef __PDFLIB_H__9 l1 y& U! J$ `0 g- g1 p0 N" V
  2. #define __PDFLIB_H__2 J# G; r1 f( n2 ^. a6 x6 H

  3. + `- m. n% M# l* w* q& t
  4. #include "ff.h"4 i* `5 _" |' o) a8 s# ]
  5. /*----- standard C library functions -----------------------------------------*/
    4 X  ^; w9 a* C+ U" t% O

  6. . m7 W8 h$ U& A" i
  7. #define LPDF_FOPEN                  f_open# f" V$ ?- q; b; U! |+ L" N0 v) Y
  8. #define LPDF_FCLOSE                 f_close" B# w8 Z2 k1 q
  9. #define LPDF_FREAD                  f_read
    ) R2 t* i- x1 l) Q' P
  10. #define LPDF_FWRITE                 f_write
    " H) _" W' P0 O* |! P% E  r" z( K
  11. #define LPDF_FFLUSH                 f_sync: I; L+ [" \" M4 ~6 j/ N
  12. #define LPDF_FSEEK                  f_seek
    % Z6 }8 N) J$ N+ {! i
  13. #define LPDF_FTELL                  f_tell$ o: A$ m; ~: N4 f& T
  14. #define LPDF_FEOF                   f_eof
    + B1 B: ?. @0 F4 w- M) S+ u# i
  15. #define LPDF_FERROR                 f_error- V( a# F2 I. ~2 @9 p
  16. #define LPDF_RENAME                 f_rename6 k9 d) e! k. F. `% g
  17. #define LPDF_REMOVE                 f_unlink5 Q( G; d/ b+ {+ }* M; D7 B
  18. #define LPDF_MALLOC                 malloc' I: q8 N( `0 @7 |. _
  19. #define LPDF_FREE                   free
    - V* {5 r( k0 ?4 S9 _  o
  20. #define LPDF_FILE                   FIL
    % r$ A: q& I8 g- y" T: [
  21. #define LPDF_TIME                   time8 k/ L* c2 Y, R* m1 S
  22. #define LPDF_PRINTF                 printf
    2 y/ B& C9 F. I4 m3 Z  L
  23. #define LPDF_SPRINTF                sprintf
    3 B/ s) G3 [3 ]7 m* G
  24. #define LPDF_FPRINTF                f_printf
    + N! P9 p, R8 ]
  25. #define LPDF_VOID                   void6 e, ^# r8 |( u* X& z8 P
  26. #define LPDF_SIN                    sin
    2 h' ?) E% ^6 a- j, {6 E
  27. #define LPDF_COS                    cos
    7 y. c3 i$ z+ E' N* |8 A
  28. ' V8 e& a0 i% M# T
  29. /*  native OS integer types */
    ( Y7 Y, _0 s5 r) _& I6 C& X
  30. typedef  signed int          LPDF_INT;
    & i" k! g  b! W7 \9 ^  A( ?" T
  31. typedef  unsigned int        LPDF_UINT;/ P, e7 A! r; F% M/ ]5 U

  32. 8 ^  K6 I3 U7 G4 v9 n+ i  i

  33. " P0 n( I& N, |! Z
  34. /*  32bit integer types' ]9 r1 c3 Q* t4 O3 U/ g: M% @5 |2 t
  35. */
    + O: J6 r, P$ B7 }
  36. typedef  signed int          LPDF_INT32;
    / m1 d8 q7 a1 i1 C4 n7 v
  37. typedef  unsigned int        LPDF_UINT32;
    3 B* ^4 i8 H8 s; T$ i  d
  38. 9 p7 Q8 W$ b3 ]+ k  _2 N1 `
  39. 6 w# i$ g& x) F3 v
  40. /*  16bit integer types3 T2 A3 D8 W- V  ]% }  F  x
  41. */
    : X+ u$ _/ A: ?9 s
  42. typedef  signed short        LPDF_INT16;
    % L* X: ?, C! x: o2 w5 w
  43. typedef  unsigned short      LPDF_UINT16;
    4 {. i! K9 d! `- y# q; E

  44. 8 L3 b- p4 w; [9 x

  45. 9 ?1 o' t4 c, W6 ?9 b1 H3 O
  46. /*  8bit integer types: R! S# P% V6 g7 w, [2 y9 \2 c
  47. */: r6 P' g& r' U- K# m
  48. typedef  signed char         LPDF_INT8;' x1 v8 z! H) \2 Q' @/ m# x
  49. typedef  unsigned char       LPDF_UINT8;: }+ J! a7 C9 S7 a- o

  50. ( m+ S) q4 ?/ f. y9 @* L3 R: X

  51. * C6 m+ V" d9 O1 T4 r! x
  52. /*  8bit binary types
    ) ^8 N" k4 C1 C+ l+ V3 i
  53. */
    ( e+ l5 B7 X3 B- s% e
  54. typedef  unsigned char       LPDF_BYTE;& m: J1 `/ C0 p" z

  55. * {% {( S2 O( y# b# L1 m# z! L
  56. 2 }4 I. X- e  h* L' t
  57. /*  float type (32bit IEEE754)
    * Q$ M" G& G. c& v0 ~
  58. */
    , p+ I) [" ?/ i0 k" Z) S6 ]5 }1 F" b
  59. typedef  float               LPDF_REAL;. o/ B& V+ N2 i/ i6 p1 U; x

  60. * g. N. e3 s9 Q* u
  61. ! j% k" [7 l' o6 F, O3 P
  62. /*  double type (64bit IEEE754)9 D# G6 U- n8 W2 r% h8 F1 ?
  63. */% b  e) a. ^3 q4 n+ d7 \: ~; [8 |
  64. typedef  double              LPDF_DOUBLE;
    + s2 v: i/ C: |! G, C
  65. 2 f1 \; t+ B6 U: K

  66. 8 U+ f' a' g6 {3 R! [" l) ~
  67. /*  boolean type (0: False, !0: True)1 `1 ?" T0 y1 A% \2 e( d) d  ^
  68. */0 C' C6 Q& U3 t1 {4 l
  69. typedef  signed int          LPDF_BOOL;
    ( U& L5 E" [: c4 m( s) v# ]4 D

  70. 8 D, {5 |0 S$ x) A' {2 {/ Z
  71. ; Z! J7 v9 r8 ]- @
  72. /*  error-no type (32bit unsigned integer)4 Q- L( J: M. o) L# J
  73. */
    " J5 j8 l; O: y1 w
  74. typedef  unsigned long       LPDF_STATUS;
    ' c7 Q8 d7 n& D4 H

  75. ! G, b& Q/ K: C' b6 v
  76. #define LPDF_OK                     0# P8 M' c6 o) T' B
  77. #define LPDF_FAILED                 1
    5 R/ M1 k7 ~2 ^+ n) j

  78. ! A8 f9 X# Q) P1 }& q. N; |0 D
  79. /*----- font state -----------------------------------------------------------*/9 _4 T2 `) o: i! ?
  80. #define   LPDF_FONT_INVALID                 0x00FF
    2 d7 }) D8 d. v: z; s7 a! d) U* V
  81. #define   LPDF_FONT_COURIER                 0x0000
    * j% y# ^& W7 ?
  82. #define   LPDF_FONT_COURIER_B               0x0001
    ; x/ @3 w- ?4 |$ e
  83. #define   LPDF_FONT_COURIER_O               0x00024 h* y1 L4 Y1 a8 \8 F
  84. #define   LPDF_FONT_COURIER_OB              0x0003
    4 H. [' f# `  W) k" M
  85. #define   LPDF_FONT_HELVETICA               0x0004
    ' I+ V! ]! ~& L7 ?$ \8 P
  86. #define   LPDF_FONT_HELVETICA_B             0x0005
    ; o+ ^# W7 g+ P( C
  87. #define   LPDF_FONT_HELVETICA_O             0x0006; K! O" t# U/ C: l
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007
    9 D5 j  L( O, G0 e' [* H/ H
  89. #define   LPDF_FONT_TIMES_R                 0x0008/ l( |* V; d' o! f- K9 Z; {
  90. #define   LPDF_FONT_TIMES_B                 0x0009- [/ y! _4 d; n3 P
  91. #define   LPDF_FONT_TIMES_I                 0x000A0 _- h+ p6 X( O, E
  92. #define   LPDF_FONT_TIMES_BI                0x000B
    & D% S& ]( l' ~' B" n* M5 ^; ?
  93. #define   LPDF_FONT_SYMBOL                  0x000C# a) y9 Y& m  C9 O
  94. #define   LPDF_FONT_ZAP                     0x000D" x1 Z. t; X2 p( B% b# H. D, t
  95. /*----- Graphis mode ---------------------------------------------------------*/
    - n/ p+ f. F, e
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x00011 z7 {% k9 G4 U
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    2 t5 f, B$ s4 ^& z# D6 p8 R( i3 t3 U
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x00046 Z' r4 i# U, X6 ?; ?' W+ s
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008  ?6 S- J. ?' ]/ Q, o: @5 W4 k: w
  100. #define   LPDF_GMODE_SHADING                0x0010+ f* F% u) ?0 f: F' P
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020' Z7 I" H0 t) F( y
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040( d( {* ]! ?9 O2 ^( S
  103. #define   LPDF_GMODE_INVALID                0x00805 ?* M: J; F" h! T9 I! g; T( A
  104. #define   LPDF_GMODE_OVER                   0x0100
    , n6 C$ d4 M6 v8 M

  105. * ^* a! r* u3 R4 e4 s8 z
  106. #define OBJ_MAX_NUM     256  ?+ k- ?/ g8 w5 X3 b
  107. 2 c7 q- V/ |! F4 @2 d( Z8 D; I
  108. /* Page的结构信息是否需要树形结构 */
    - Q9 Z/ S! o5 t6 q" D$ b4 W8 T
  109. typedef enum
    9 _2 {3 z! ]2 T+ u: m
  110. {
    6 n* x$ E8 [! p$ Z
  111.     OBJ_info,
    " G) ]# G; w5 b& X& ?2 j
  112.     OBJ_stream,
    4 o. t& t0 Z0 X& F0 M2 C  V
  113.     OBJ_font,9 ?; q5 m* Y; u9 C# C+ I
  114.     OBJ_page,. Y7 \- D7 K, ^1 p: X5 @* C1 z
  115.     OBJ_catalog,% T7 z5 a6 @- Q# H! o. X9 s
  116.     OBJ_pages,& p0 I2 N/ b% _7 u$ L( x
  117.     OBJ_image,
    , H7 ^# }$ b$ q" C
  118. }LPDF_ObjType;0 n7 G9 o& ]2 g0 |0 b9 j
  119. % B  F: I$ F  j. N" [
  120. typedef struct2 [7 X1 u& U( I, ~! l
  121. {
    1 k7 ?+ p+ O) x# u/ v- |2 J
  122.     LPDF_ObjType objType;
    6 y" f  i) z" U1 V  E6 _
  123.     LPDF_UINT16 objIdx;. Q2 e: K/ Q3 r; I
  124.     LPDF_UINT16 height;( a# v2 o+ }' p$ `  r0 m$ M2 b
  125.     LPDF_UINT16 width;
      b  c% A$ `- E1 K0 j, z
  126.     LPDF_UINT16 length;
    & B5 e5 N/ G# k2 h+ W0 z
  127.     LPDF_UINT gMode;
    5 l' l+ C& P4 p0 j
  128.     LPDF_BYTE fontType;, J$ }) N. Z* A. v2 i; @% R; ^! j3 b
  129.     LPDF_BYTE fontSize;* h" X0 z9 U, |9 J, D
  130.     LPDF_BYTE pState;' }* H2 @, U2 R6 c% H. z
  131.     LPDF_VOID *doc;/ n9 q# o8 h  q0 z/ U0 L8 u' I
  132. }LPDF_Obj;
    . N7 k+ ?  r9 a  i" _2 h" j# q
  133. ; ~* g8 j% s, N# k, j3 x
  134. typedef struct: Y: ?& B" a  p$ `  f; B/ C! h
  135. {) M( r* [- N/ x1 ]9 u
  136.     LPDF_Obj obj[OBJ_MAX_NUM];' ?: j, ], d  W: K+ e8 A5 e
  137.     LPDF_UINT32 offset;+ s4 m# O5 i) u) H' R/ t7 F
  138.     LPDF_UINT16 objNumber;
    ! B! ]* _" k: _8 F" s3 N
  139.     LPDF_FILE file;; r+ Q: M9 U9 o
  140. }LPDF_Doc_Rec;
    - m' O/ \/ K4 l" ]' {# ^; B) I( E

  141. * W. I) S& W2 T0 J( n! V, k! Y9 \
  142. typedef LPDF_Doc_Rec *LPDF_Doc;4 ?. ^. h; z. r6 c; ^9 z
  143. typedef LPDF_Obj *LPDF_Page;3 M/ l  w7 K6 M- b. Y- N9 r" l
  144. typedef LPDF_Obj *LPDF_Image;4 k% B4 P- R' ^  P
  145. extern const char *font_list[];; t$ j, {3 |6 o+ K: j% u
  146. /*----- LPDF Interfaces-------------------------------------------------------*/5 {- `+ a8 b; v% j4 ]
  147. const char * LPDF_GetVersion(void);' @8 a) F0 g) V' w( ^
  148. LPDF_Doc LPDF_New(void);8 F% s1 B2 g. ]5 }# y' `
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);
    0 J) K3 a" C, T* l9 _
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);
    " n" r- B- W% R- q+ h' }  ~
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);1 ~7 Z( @; u+ t' X; d- H
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);5 J; F! D5 ]) a/ _# P$ @% X3 c6 O
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    " Y/ r6 B! R* X" O, b
  154.                            const char *font_name, LPDF_UINT8 size);, l% I* R+ ^/ S5 ?) s
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);( m- E2 z' J$ X) S' f4 Q- o  \0 w* y
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);+ }$ N% k# \: N5 c7 v1 M9 j  ^
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);3 f1 P+ l8 C" ~5 S
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);
    5 h' s; L$ Y! S- Z
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    : {  S& \: v! l; k7 s: E( c
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);" N1 t- J5 n( B9 w& k9 r3 Y; {
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    7 q4 p8 ^( |7 v$ f
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);
    4 n; k1 p' q0 t- t% E  T. e% n
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);1 S* d& X5 }% b! U
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
      Q" a2 A0 Z: ~. B. N: u. I
  165.                          LPDF_INT x, LPDF_INT y);/ c: D2 ?; h9 K
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, 3 ]) D$ x2 P3 _, B0 g+ \
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,
    $ F2 F7 z' \* n' ]1 Q5 H
  168.                          const char *text);' |+ \6 {" y) l6 X
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    9 m) H6 _1 U  C6 L5 z) b. \" S( J+ q. c
  170.                          LPDF_REAL r,3 l% `' {; x5 i9 I! Y
  171.                          LPDF_REAL g,8 o# V# Y& Z1 [# o1 y+ T% J
  172.                          LPDF_REAL b);
    ! s( w! N! \4 {0 r/ m- ?+ L. c
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,3 F# t0 }! d8 K  U  A' _. [4 ~3 \: W
  174.                          LPDF_REAL r,
    ( `' M) U6 W( U- j# o( N
  175.                          LPDF_REAL g,
    * `( a' l1 j: p9 t+ }
  176.                          LPDF_REAL b);* I' U6 |: s# b, a6 q
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    ! a+ ~4 d2 z. P, k$ \
  178.                          LPDF_UINT16 x,- j. O2 [0 Q7 O5 g, v' q
  179.                          LPDF_UINT16 y);
    5 A1 ^6 ^: Q+ q% g
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    ! Y' w+ U+ ~& V  _
  181.                          LPDF_UINT16 x,
    ( P7 ~2 j% ]5 ~: Z
  182.                          LPDF_UINT16 y);
    $ r( y, U" W( `9 b$ V
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);" U: H( [8 w* u& R+ f
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);
    $ K3 k7 V& Z" d5 j2 O( w
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    % n/ S; q. ~# q: f
  186.                       LPDF_Image image,
    ' \) ?4 F9 y# \, e& [
  187.                       LPDF_UINT16 x,5 d% \- U( L* Y$ W( C
  188.                       LPDF_UINT16 y,- ]' y7 U' u+ G+ t
  189.                       LPDF_UINT16 width,$ n8 z" G3 T  L5 R
  190.                       LPDF_UINT16 height);$ u' d; B4 {( j! [. M, w
  191.                                                                                        
    + N7 p# A* s1 ]) L3 ^& r* O
  192. #endif) F; U% H7 T) |- i% y, [1 z
复制代码

源文件如下:

  1. #include <stdio.h>4 c% ~) n9 I% J5 r3 }% _- _' P
  2. #include <stdlib.h>  B$ Q' d& W; m2 z2 r
  3. #include <stdint.h>/ x3 G/ z0 G- x6 a2 w& W
  4. #include <string.h>
    ' t+ p; T6 s! y0 o) V
  5. #include "pdflib.h"  y+ q* r/ {* A! f: s, N
  6. ! K- U; X' ?7 c! s9 L6 p
  7. #define LPDF_INVALID_OBJECT                       0x1033" W; @* [+ {* a& r1 o

  8. ! x1 Y8 @+ E4 @0 r! B7 K
  9. static char pdf_buf[512];4 z& i) H% d! c* v' j- R
  10. 4 [. C2 {  V- E# r9 H
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1", ?# v" ?' s$ w) U
  12. #define LPDF_FILE_HEADER_LEN        156 E% F/ a$ Q5 t) L% Z8 h
  13. #define LPDF_BASEFONT_NUM           14
    + X6 `$ |' [$ r. [  v# N3 K
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";% d. _3 d. e6 j% V9 {! n9 l$ w
  15. const char *font_list[] = {/ l  b& L7 n0 ~4 v: l
  16.     "Courier",
    ' s3 m$ y# ^5 Y, n! i  ?& q
  17.     "Courier-Bold",8 |* |/ v3 Z3 W1 K4 x
  18.     "Courier-Oblique",
    * g8 D# I9 V6 r7 I3 Y( r1 G4 w; K
  19.     "Courier-BoldOblique",, d$ n: k4 |) y3 I& s) d
  20.     "Helvetica",
    , I' u6 B  o: {1 F. |; ]
  21.     "Helvetica-Bold",
    % `- e* `# m, x  b
  22.     "Helvetica-Oblique",' h2 a7 X& c; D1 J+ [' q
  23.     "Helvetica-BoldOblique",
    5 h% \' N/ n+ S/ e7 W; C- I
  24.     "Times-Roman",, ]; Y  q$ ^% @# \0 A0 ?8 x% k
  25.     "Times-Bold",
    % H# J2 ?% o+ |0 R5 Z! V% I
  26.     "Times-Italic",
    * F1 \! h* D$ S/ ?5 h
  27.     "Times-BoldItalic",
    % m" X& i9 z" d3 D
  28.     "Symbol",7 O1 N" E8 y, c
  29.     "ZapfDingbats",0 \" G" k+ L, Y) K9 V
  30.     NULL3 f1 w9 ^9 y0 ^& E% Y2 Q& w2 U
  31. };
    0 N2 z2 V# x- i, t8 m" y
  32. $ b: \/ V; R2 ^  q1 q

  33. 3 O* |% [+ w$ B0 i3 e, z
  34. const char * LPDF_GetVersion(void)$ `% V& s8 C' u! Q* r( c
  35. {
      a+ z8 h( @# _6 X+ J
  36.     return LPDF_VERSIOIN_TEXT;
    1 z& N! y/ a& G9 \2 Z
  37. }& [; f4 P( \- m/ h

  38. ; N1 E! M" ^2 p& f
  39. LPDF_Doc LPDF_New(void)
    # n7 s. f3 _! B+ G- [
  40. {
    ' f  z# \' w" n6 x0 j/ z
  41.     static LPDF_Doc_Rec pdf;
    7 w' O# E$ v, p7 c, t+ ]
  42.     LPDF_INT length = 0, i = 0;7 b, L1 `2 B* z4 q7 q
  43.         LPDF_UINT writeBytes = 0;
    $ }! m7 e: {6 q5 A, ?
  44.         FRESULT fr;# u! N3 N# @# W* s- @
  45.     ! u6 A3 n/ K) X6 y/ E$ H7 `. c4 S  v% j
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);2 ~/ U# n. r# A0 K# S* O" x
  47.         if(fr)5 C9 s$ P( C  i% O' h; S
  48.         {, \" R0 p8 V3 n0 O
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    9 Y! d0 i) b1 I
  50.                 return NULL;
    : G) h/ M$ I) ^
  51.         }* O0 x, T, ?7 m# q% |) S1 `
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */
    5 M, d! O0 ~3 I2 N* E
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;! E) ~! D! s/ G' c' Y' T
  54.    
    9 Q! J" }& o% w, M1 s
  55.     pdf.obj[0].objIdx = pdf.offset;4 t9 J8 c$ S1 j
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");( f! C' B) G- E: v- \7 c- H8 j
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    ) Z9 u9 Z; _* U
  58.     pdf.offset += length;
    ; U) q4 @4 u/ i5 Y8 }* t. ?  w# R
  59.     " _' K" T" O4 h/ ^) V4 i' T  q
  60.     pdf.obj[1].objIdx = pdf.offset;
    5 V: Z" E+ @$ s3 j
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"
    ( m, Q/ B1 e; D) F) B/ [: G& f
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");! D2 n" D; J5 x9 r: ]8 y
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    % T8 ]4 g! ?: l
  64.     pdf.offset += length;
    5 E+ b7 J& I* F# X' A. X) G1 b+ H$ P
  65.     - X# r2 Z6 ]0 G7 j) O# c# I( ]6 c
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)  y9 f- W! L0 O  v5 V
  67.     {
    4 V/ H; l" Z) a, x# y# u! t
  68.         pdf.obj[2+i].objIdx = pdf.offset;4 ]% N6 h$ l3 D7 X
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    $ U( R) n5 L2 E! j$ Y
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
    / H5 }9 C, f5 ?5 V" l! b! \
  71.                         "endobj\n\n",3+i,font_list[i]);' ]: R/ ^" \* K9 v
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    9 D% I9 S0 [3 f( H' c: O
  73.         pdf.offset += length;; U+ ^. ~& s9 _+ j( @' D' `/ @! _
  74.     }
    . e8 r  I1 f5 z
  75.     for(; i < LPDF_BASEFONT_NUM; i++)  m8 d2 w; k6 n; f  g( G6 O# q
  76.     {: ]# \4 u- |5 z9 T$ Y  V
  77.         pdf.obj[2+i].objIdx = pdf.offset;  C' Q* D$ q9 e5 C6 s
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"1 [6 J$ K. z; K0 M
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);5 Y7 P5 x0 {) Z1 @. i8 b: V* B9 ~
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    0 T! ?8 z$ r1 I7 G. g
  81.         pdf.offset += length;  w% p/ ^, V- H! X2 M! A) L' x
  82.     }1 M( ?8 Q6 j2 t. [% T
  83.     pdf.objNumber = 3+i;' V5 A, F- o; o( {2 P" N5 j
  84.   ! f8 q. k  s" ?, E. d
  85.     return (LPDF_Doc)&pdf;
    ) Q' J5 B9 ?0 U5 ^4 J6 o4 T. i
  86. }
      P1 ^% f0 v# Y# i  j7 S

  87. 9 ?" C6 j- R6 M0 E( @9 G; y9 X
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name): b- D, k" m; {' c# j' e
  89. {
    / \  L% ?: U. a: {- i
  90.     LPDF_UINT16 i = 0, child_pages = 0;/ W7 k$ h. e2 w/ k5 I$ m  Y& Q
  91.     LPDF_INT length = 0;
    4 F2 f. a7 P; h3 n
  92.         LPDF_UINT writeBytes = 0;" S: J+ h( O! ]' f5 T& H) O

  93. 7 \5 I' Y4 e5 _4 A  V7 y* C9 |
  94.     pdf->obj[16].objIdx = pdf->offset;
    # u  {" S  T* a3 g; Y1 k
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;
    8 e4 L+ [4 d: m8 x9 ^: U
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);
    % P8 O+ Q6 F* `7 `# U$ U* `
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);. S' A5 \' A: T0 i9 ^
  98.     pdf->offset += length;2 G1 D" }# C( U$ P. ]  L
  99.     for(i = 0; i < child_pages; i++)
      |0 d6 j  w( L/ P7 E
  100.     {1 v3 W' W2 h( e. s* C2 O
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    5 G6 g3 A! [2 i0 Q
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; v8 _' o9 m3 w
  103.         pdf->offset += length;
    : H$ b8 ~3 C* X4 [5 e
  104.     }+ e1 y1 G  m& L' F, [
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");$ O: g4 u; i6 [- g5 C4 {
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);- y$ s- n6 a1 W8 k
  107.     pdf->offset += length;1 `7 V# Z- l7 o, z( a+ N
  108.    
    & z- ^# N# \6 O7 c- e8 |- d
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    1 R* U$ W# Q! s( q9 B
  110.     for(i = 0 ; i < pdf->objNumber; i++)
    2 `. ]6 u. o' U; H; N( g
  111.     {
    9 t! |6 I8 q- W: T' X+ I+ K
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    3 ^0 ~/ ]+ T! R5 O2 u  B0 }8 R6 j
  113.     }4 c7 M2 h1 V8 Q1 v1 w, I
  114.     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",
    2 z' q$ D# u0 O
  115.                 pdf->objNumber+1,pdf->offset);! f( F1 c: z0 D" R! p. y
  116.     LPDF_FCLOSE(&pdf->file);
    & P  Z3 y3 m2 P8 a. U; c7 C% ^
  117.     LPDF_REMOVE(file_name);
    1 |) x1 R! I$ v. _! ]8 n  X2 {  \
  118.     LPDF_RENAME("tmp.pdf",file_name);% h! W0 w4 R8 F( i( }4 n
  119.     return LPDF_OK;; A0 T& H; A/ J; D* V
  120. }4 p4 Z# d, N% X5 I" {, S4 B% p  }0 L
  121. 3 x& t/ y6 C# f+ [
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)& ~* @- U- j9 C0 B* c3 C4 L
  123. {
    ) G' O5 ?: A/ P6 O7 K; J
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);
    ( W5 M  R! ~1 J  Y# h) N7 W- C/ {9 d
  125.     return LPDF_OK;
    6 K5 w! A8 z# e2 s
  126. }
    # Z( X, N4 {. i4 e/ ]( c7 R1 E" J
  127. 9 M. e# }9 X8 g9 O3 `
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)1 u' N7 U6 L: M) }, N  s1 K1 q
  129. {/ h% i3 z; l( Q
  130.     LPDF_INT length = 0,i = 0;
    # r+ H3 s) N% P2 }7 }
  131.     LPDF_Page page = NULL;
    : t2 l0 ^  X- a) {: }
  132.         LPDF_UINT writeBytes = 0;
    . E- k9 n! d& _) o% ^( W
  133.    
    8 c2 e$ p; H, V) e, Q/ T
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    % Q' d5 o6 w9 N3 @; q
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"8 @' e) U5 e; G9 w" Y
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"6 w6 J4 e9 i# p7 {- F# ?( h8 q3 X, c
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);4 k) p0 l) Z; `- f
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    9 p% R* a" p# [7 b# D
  139.     pdf->offset += length;: _9 u5 H# X+ h; X% e5 _
  140.     while(font_list[i])
    + @3 U" I2 _' q$ g# k( k
  141.     {( }* O# N2 [" a$ U3 k8 y* z- ~5 }9 j
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);. |  q6 O# W1 O: b- _
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    7 m& f5 o; \" H0 ]4 ]- a/ d* h
  144.         pdf->offset += length;
    ; |% H  ?$ U( ]1 ?, y. W/ s
  145.         i+=1;
    & [% v5 S9 C0 f
  146.     }8 O" I( _) L4 o6 ~  C( B
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");; m/ v/ V* v4 Z
  148.     pdf->offset += 4;' S  i$ v# N$ P, R8 C0 c8 Z. q
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];* F6 U& f" E; k
  150.     page->width = 595;
    3 N: h1 d' u5 g! e. Z4 X0 T
  151.     page->height = 842;$ V  d3 E! r; s* p
  152.     page->gMode = LPDF_GMODE_INVALID;
    $ ~- ]3 F0 a% u! |
  153.     page->fontType = LPDF_FONT_INVALID;
    ) r5 U; F2 O9 @* D6 `- V; g
  154.     page->doc = pdf;% ?# |( q( p" H5 g5 E* z, I
  155.     return page;
    & ?5 m/ _" ]( n* c: L! D$ m* k
  156. }
    1 s; M- ^8 Q2 k6 I5 p
  157. 2 {6 \2 V1 P: L- I* f
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)
    5 J& F. g/ ?& Y% O
  159. {( C! P, f* t2 e7 o, U, b
  160.     page->height = value;
    1 H5 M/ X+ A7 Q8 z9 D
  161.     return LPDF_OK;
    ! @' @' A; Y( B0 ]5 q( u) ?) R; V
  162. }6 L! ?8 g& a0 I5 _2 C
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    4 y9 N# m2 W$ Z6 W5 _
  164. {
    ( L! V# u: c) t7 Z& I: p0 \) g. F/ r
  165.     page->width = value;
    4 I" i6 \; H. p- P
  166.     return LPDF_OK;
    6 n( R8 \( ]: C. k; T
  167. }
    4 c* e4 g$ F/ M
  168. ( _1 `; y; K) x* q+ z8 ~% R% X& ?
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)
    9 ^- c7 _. Q2 L4 E
  170. {
    4 {7 M, d3 ^1 ]$ v' g; L
  171.     if(page)
    ! @4 B$ E0 K. W) k- \& e6 h
  172.     {
    % r+ E- e- A' @3 |- |6 c* X
  173.         return page->height;
    ) N0 ?# t2 u) F! z9 k
  174.     }
    ( @! X9 j( U: B/ C
  175.    
    ) \; T$ c; R) j! K
  176.     return LPDF_OK;
    5 ^! |+ C) q. s
  177. }
    * w4 ^: d7 f0 M
  178. ! `8 a. c7 d6 s) U* x! h
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    7 m; x8 {: B6 T' {. _0 W
  180. {
    5 ?0 ?6 k; E, o; D" @
  181.     if(page)/ _( i6 N0 C" f. ~* j
  182.     {' O" i+ S0 L' e  |& w
  183.         return page->width;/ m: W: j2 m0 X* _5 ~, k
  184.     }
    , @6 a9 s% x5 k2 N
  185.    
    : w% p4 W: j* h* F# [) {
  186.     return LPDF_OK;* h* U/ E# u9 r4 S. v& R  y. [+ k: @
  187. }. k3 W! h1 C- |8 F
  188. 1 ~$ u! ]* h/ D; g8 `  X5 k: j
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)4 E/ Y& v/ J% x( y
  190. {% ^) B6 B' v4 [- d: R1 ^0 q6 C/ D
  191.     if(!page)/ y: B0 Q& x3 H; m: h1 h4 k
  192.         return LPDF_INVALID_OBJECT;
    . D4 D' Z" W) n- P
  193.     if(!(page->gMode&mode))5 V$ p/ m! b0 M2 A" l% o* U
  194.         return LPDF_FAILED;
    9 V  A7 F. `% q( g& G7 \! i6 w6 K) Y" g
  195. . b5 v6 s: M* @+ i7 B! m
  196.     return LPDF_OK;1 L9 {- H. e' \7 a
  197. }2 \) |8 b/ n: J0 ^( Q
  198. & Y$ o" s! f& I/ W. ^1 e6 ?1 D
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,6 D( m3 y% G9 F, Q
  200.                            const char *font_name, LPDF_UINT8 size)- W) `& m& g+ F4 ?9 d4 _% w
  201. {
    4 }. i' p5 N& i, [
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    1 L) N8 K0 V, c5 Z8 L. O9 K8 @
  203.     LPDF_INT i = 0,length = 0;3 ~% J7 [  |! {4 z
  204.         LPDF_UINT writeBytes = 0;
    8 B9 ]6 d3 Z/ k) x. s
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    5 K' E' m+ n# [9 r7 d* i
  206.     if(LPDF_OK != ret)% R, z, H; H/ a+ @
  207.         return ret;
    ( P7 Q! f9 w$ l; D

  208. % I" y% I+ b8 r6 J6 Q$ L
  209.     while(font_list[i])
    # L; p: z1 V1 ^  j+ S$ e* }1 l2 p
  210.     {
    . ]; a; S# r+ N: D9 ]
  211.         if(0 == strcmp(font_list[i],font_name))! N* O" F' m6 _% X+ C5 |# t  Q+ Z8 f; i1 k
  212.         {
    ' e- e, G8 f5 ]7 r
  213.             page->fontType = i;! p& a' R+ y; p- }. H
  214.             page->fontSize = size;
    5 e2 V+ V  _: ^& q8 u& S$ e
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);
    $ G* ]" [, j5 N
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; v9 C( [  R: }
  217.             pdf->offset += length;+ U: Z5 |/ b  I6 K9 v
  218.             page->length += length;( G4 L: m# |, m
  219.             return LPDF_OK;& P2 S/ \9 p( ^7 v& k1 j
  220.         }' h. ?, R, j# b6 z
  221.         i+=1;
    $ n  `9 L2 o" n' ~
  222.     }
    5 t! _: Y3 A8 c
  223.     % T! |5 U5 }' a: S1 b% y
  224.     return LPDF_OK;1 ~- R( R$ U- M2 {6 l
  225. }. o6 O8 ~, c" W7 Z8 Q+ K
  226. , @4 r" R8 h* O% y- C' Y6 j
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)
    % l0 `3 C+ d9 _" K: f1 h; ^8 W
  228. {8 C+ U+ z* m: e! x. D3 q$ k
  229.     LPDF_INT length;7 y' B3 n( g3 z7 G! m
  230.         LPDF_UINT writeBytes = 0;
    8 p+ E1 a, S% d3 n" t
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;% ?3 X, C1 O; D4 p: X
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);( a, _8 O, ~; R, I- O% C
  233.     if(LPDF_OK != ret)4 h$ a, T" [4 b2 n; _9 B* q- k
  234.         return ret;( n% W: c; V$ {! B+ I4 A( @% c
  235.    
    ! @5 F" n" [3 F
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */
    3 X' h/ J) t4 K1 x. q4 z
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
    3 [$ x) V) T$ x2 L9 g( k7 m
  238.                         page->width, page->height);
    ) [$ J9 i( n" {8 v) y
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ) B# v, X) F4 ~) M
  240.     pdf->offset += length;
    5 E! o; I) G  p2 v# |4 f9 E
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;6 Y0 |$ w9 |% H' f
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",6 Z; d8 l8 g& f, f4 T4 I8 d2 S
  243.                         pdf->objNumber+2, pdf->objNumber+3);! Y) r3 e) l- s/ D0 |
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    & V8 Y1 N" f9 r1 _6 H
  245.     pdf->offset += length;7 p: y# Q3 [! F: B1 _9 ~8 U
  246.     page->length = 0;3 {3 R$ r7 G. W( ?2 L/ I7 z
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;; ]/ b/ j. f, v
  248.     return LPDF_OK;; s3 f6 }3 w7 H6 a: J
  249. }
    % n7 S( H) [/ ^$ @

  250. & Q& p$ ?& L- b; r( A, X
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)
      n2 q" H' M/ [/ P# J% ]. a1 @3 O
  252. {
    6 s$ k6 J" f0 d+ V
  253.     LPDF_INT length;! K  O  i; j' j/ p
  254.         LPDF_UINT writeBytes = 0;
    # p, o, S& o# ~  y+ C: }* v* t$ k6 o
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    # d; H9 e" r0 [1 @& j, x
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);1 t. P$ [5 C7 ?" r' A% c
  257.     if(LPDF_OK != ret)
    * R+ c+ S0 D8 D2 V3 X0 V8 w# A
  258.         return ret;- w& R2 F; e7 D9 a" Y# ~3 |% P4 C
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    ) E3 o1 U' |% {: w2 b
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    4 ~) D$ E, m: g( S
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ( ], K$ B2 Q$ `
  262.     pdf->offset += length;
    0 T& R+ c  E) e& z6 g: m6 D) b
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;
    / H; k* F1 S6 ^/ Q9 v
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",& I% K4 T8 B: P$ P+ F0 {3 F
  265.                         pdf->objNumber+3,page->length);
    : z7 c1 {, P4 Q! a% k6 o+ a# u# S9 M
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);# t- a: z9 I: W$ ]5 Z% L/ S# g  y6 v1 m
  267.     pdf->offset += length;
      D, e% z: W; X1 m0 g( j' Y& z
  268.     pdf->objNumber += 3;
    ( P$ Q6 T9 o  G! L2 V3 H' ?
  269.     page->gMode = LPDF_GMODE_OVER;
    ) D- U  o" o. H0 C
  270.     return LPDF_OK;
    - _% b5 `7 j# I. i6 A4 ^3 ~
  271. }5 B( ]. j7 E$ f7 z% D( V* K/ o

  272. ( s: X' q' j  a9 E) b2 G
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)2 V) |; h0 L& i$ i( e- p" p
  274. {
    , E/ E- Z) g2 j" i* d1 X( |
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;' b8 G8 S/ K6 ~
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    9 R& H) m( }$ Q0 I. v
  277.     if(LPDF_OK != ret)
    : R2 [1 b  Y6 z* ?( W8 `% j
  278.         return ret;* z1 t( Q9 M/ i+ N/ x
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    - A  }6 A  L* Z) F; S0 |5 i& e
  280.     pdf->offset += 3;: f2 m& ~! u0 Z4 ]. K- e+ c7 {- n
  281.     page->length += 3;
    & C  v& j) w6 h
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;
    ! p# i# R/ ~6 A3 ^6 A) |6 E
  283.     return LPDF_OK;& ~- Y3 ]% d/ {
  284. }
    0 a% _3 X  z1 t& [
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)6 b' `8 s7 Y1 C7 y) A3 {
  286. {% @& b; N. z2 v: q: B, B
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    , e! G4 J& M" W7 C
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);* P' s2 j9 W' B, G  T" M' W( @
  289.     if(LPDF_OK != ret)/ g6 w3 \0 c+ v0 E" V, |, r
  290.         return ret;
    * U* Y) A/ P" B" `4 Q3 u
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");
    + j2 u  {0 d4 G
  292.     pdf->offset += 3;
    ( C/ y$ i8 Y8 R+ o
  293.     page->length += 3;7 b3 i% W6 W0 a- v6 h5 ]2 a
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    9 d# F8 A+ I3 J8 \0 q
  295.     return LPDF_OK;0 z6 N$ b' ^; B' }6 Y; A
  296. }
    # \* g3 _4 _4 ?5 k* q; v8 K8 B
  297. ; v4 x1 t0 R  r+ g2 G+ ]
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    # t: C6 `" _9 V2 K8 R. C4 Q0 J
  299. {
    % M4 {" L% s/ f7 a4 V+ y, N/ f
  300.     LPDF_INT length = 0;* N8 ]4 A5 v) e1 c3 @9 [- n
  301.         LPDF_UINT writeBytes = 0;2 a* b7 V' P1 \+ b% d  q- q! y
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;# N1 i) F7 u' S& p) d" W6 Y6 l( h& p9 x
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);1 Y& H+ B: x1 H6 s! Q1 {
  304.     if(LPDF_OK != ret): s6 Q' m; g6 {/ V; ?( z' b
  305.         return ret;  L' m3 N& {. |
  306.     if(LPDF_FONT_INVALID == page->fontType)& z2 x/ p9 W5 k, t3 c- V* \
  307.         return LPDF_OK;% k% a: \( U8 H" n( r& G! P" `' _
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);
    , F. _) Z& z% y
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);  s" i' C$ ^; ~, S6 z9 e
  310.     pdf->offset += length;) y1 e+ R" Z& A: }
  311.     page->length += length;
    8 U( {0 O% V6 H
  312.     return LPDF_OK;
    3 ]4 D/ `6 Y, y/ m) @
  313.    
    3 E4 Q- g4 y9 T/ [4 B( E6 V
  314. }# S1 O2 J2 T( I+ y; j1 w1 j+ ~
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,  x3 p- @+ W7 N) j
  316.                         LPDF_INT x, LPDF_INT y), t  |  A# t+ c$ v
  317. {# w1 O% m6 x& `: L+ L# k* {
  318.     LPDF_INT length = 0;
    , h# P0 y/ L' [! c+ n8 y3 M2 n
  319.         LPDF_UINT writeBytes = 0;
    : v9 A( C; |( V' \9 W9 S2 W
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    * F! m* [1 r% S# ?. I+ G0 l
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);* \$ B  t- g3 q) ~$ A
  322.     if(LPDF_OK != ret). z  I6 J3 p6 _1 {# E; }! Q
  323.         return ret;
    ! e% f# b. u. ?: }
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);
    " z* k7 ^. w& i' H3 c) y$ N
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    5 J6 t$ |( ?# [2 D9 y* N9 E* `  w
  326.     pdf->offset += length;
    1 t) K* J9 d) P8 \/ f2 y
  327.     page->length += length;
    3 [% t1 Y: r1 E+ h0 d5 i
  328. 9 G+ Z+ X  t! T. j  {1 d
  329.     return LPDF_OK;
    + d  d% T4 e4 n0 L
  330. }
    ! V' q8 O. z( |* F" y( E
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    - g; N4 T) B, m2 _2 c/ Q/ V
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,, U! J0 g9 o2 E
  333.                         const char *text)+ y1 B9 d/ c" i* x( a  K
  334. {
    ( |, _  F( l  }0 m) n0 x& v
  335.     return LPDF_OK;
    : U7 B5 J. i- [1 ]3 i$ r! @: w
  336. }
    & m; {$ F3 j0 F+ q8 X( E; h- l; u
  337. 8 w$ f8 V$ P$ {8 ?; U3 N
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,) ]1 T9 f% F7 P; f/ I! r! t
  339.                          LPDF_REAL r,
      n: `6 a) y0 h% i) v, P. @  O3 P2 i6 D
  340.                          LPDF_REAL g,
    $ t, r/ h8 D9 k; X. p8 J
  341.                          LPDF_REAL b)1 l7 w. {  r; W3 {% U) L6 {! P% Z
  342. {
    . x$ w- u0 _" N! d
  343.     LPDF_INT length = 0;
    2 w- j1 ], I' G
  344.         LPDF_UINT writeBytes = 0;
    2 ~' P, n2 O3 u* ?, Z
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;! N1 J1 `" J! w. U% M# I  p/ ?
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    ! B! T7 T; I& A- O. j6 j$ \: v6 ~
  347.     if(LPDF_OK != ret)' n0 z# s. E$ b  s
  348.         return ret;* k6 @5 Z" i2 l2 x6 K/ Y

  349. / m7 H, {1 m2 ~) P- r$ o4 }" n" X$ K
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    + M2 b6 t' u" R7 m  B( g  q) k, p
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    % r9 k1 L" K# a* f! e# x4 e
  352.     pdf->offset += length;
    ( M) B1 \# y6 ^6 j7 y4 q3 J
  353.     page->length += length;! y1 L. x+ [( w
  354.     return LPDF_OK;
    ( b! _# c8 v! p, M1 ^' U
  355. }$ o% Z2 T# u5 ]3 }( p7 `% A) C
  356. + f, f9 s5 ?  g2 A( p8 ^7 j
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,. q/ ]- ~" |' K+ E$ w8 j: T
  358.                          LPDF_REAL r,9 w, x+ K" W; z2 z
  359.                          LPDF_REAL g,
    3 B2 }! x5 B# b( r0 V
  360.                          LPDF_REAL b)
    9 ~2 O) W" R5 y1 q2 D
  361. {
    ; e3 ]9 J1 G* a1 }
  362.     LPDF_INT length = 0;
    ( _  ?( T+ m; m# k0 @
  363.         LPDF_UINT writeBytes = 0;
    % ~5 V/ e) G0 Z# u0 Y! ]
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    3 I9 i& n# u  o9 v0 x( I3 K
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    2 o; [3 B/ n8 B! I& k! Z
  366.     if(LPDF_OK != ret)/ J- C& G, E& c4 D. ^
  367.         return ret;& p. e  x5 ~/ S8 ?& }
  368. * y( o) g/ d3 }$ l. _% [
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);
    3 C+ c6 f& y  r: t. K0 ^5 |
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);) k  |$ ?7 m& Q( J. u
  371.     pdf->offset += length;4 U3 m4 E0 t' I
  372.     page->length += length;
    ( C  o' t$ V7 A" I( E, P
  373.     return LPDF_OK;
    ' p4 }4 F8 a$ B# d+ d8 F& c
  374. }, p3 ]5 i* V9 f
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,! H6 v# i6 X  Q5 w2 R% ^
  376.                          LPDF_UINT16 x,
    ) W; i5 U! j! d. N' T( x0 |
  377.                          LPDF_UINT16 y)
    : q1 K+ \4 z9 ~; D1 e
  378. {
    $ ]7 u3 h* F0 }& E# I
  379.     LPDF_INT length = 0;
    7 m" M1 m7 {! N+ L; ^: M
  380.         LPDF_UINT writeBytes = 0;% \3 q- U* Z" Y  b
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;( K- F7 _& [1 W8 c! Z; }
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);
      {+ M0 B* u0 n9 F& x+ B
  383.     if(LPDF_OK != ret)
      e! `$ k* \5 m: Y9 a! z& a: h) t
  384.         return ret;
    & j8 m( K' m# K, I
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);2 }8 r. J  x7 A3 C
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    9 k$ F+ V, M' q3 |8 W8 h' S+ x
  387.     pdf->offset += length;
    & C+ z( _) ~) j9 q8 t1 m
  388.     page->length += length;5 w- }7 B9 _7 \. h+ L, K
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    . b, E3 ~; T, N& y. t& ]* u
  390.     return LPDF_OK;
    , g% O& E  ?2 R
  391. }5 g0 Z* i. V1 ?
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    ' Y1 [! x& E) `7 x$ x4 v
  393.                          LPDF_UINT16 x,
    ' i0 ?8 O5 M1 z" T+ @' [
  394.                          LPDF_UINT16 y)5 l; c  j* P6 I
  395. {3 z" y2 f  Q) R* B+ o( P
  396.     LPDF_INT length = 0;
    * }9 n* X+ ~* f3 [" \
  397.         LPDF_UINT writeBytes = 0;0 N, ^, v: A/ Y! g; F0 [
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    . _( l+ V" a8 O
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);4 q' F/ G' f' [6 u( [' M
  400.     if(LPDF_OK != ret)
    , E' O* S9 s) S  D
  401.         return ret;
    # {# c# @0 Q) r( J& p" C5 ]
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    4 H8 @% l! c; Z) Q0 W. a* f& t
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    2 Y- s6 r9 P$ X, c1 L2 O. s
  404.     pdf->offset += length;
    ! c. F9 Q6 |2 r% S
  405.     page->length += length;
    6 b) D6 ?) T0 J9 n% Y. f
  406.     return LPDF_OK;
    1 i/ _# K7 x, I3 A# O/ _  z6 ~
  407. }
    " y6 n5 v) D$ W% T+ T7 S$ X
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)
    % z4 n* r9 X; n% f# y) M9 Y; c
  409. {
    ' s3 M' A3 O+ n* Q- t4 I% [
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;  j2 y. D1 k" }, b
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    3 B& ^) b/ c% Y' M( I% k$ e
  412.     if(LPDF_OK != ret)
    ' \! q1 U/ X" U0 J: i# U7 N
  413.         return ret;
    # v( W0 x$ F! o5 ^6 c7 O' {
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    " R7 u1 K" ?& s: S' c( U3 V
  415.     pdf->offset += 2;
    9 l4 U2 m; S4 U3 k
  416.     page->length += 2;
    % t3 B' }! w/ s% N; u. M+ T
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    3 @. F  g* {% E& w
  418.     return LPDF_OK;
    - v7 c; Z9 y- j3 I  T5 A: ?* H: Z
  419. }
    7 ^1 ~' A- ?) t& e
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    5 C6 ^3 M3 B* W+ U: N
  421.                       LPDF_Image image,' ?8 G  o# P0 S4 ?
  422.                       LPDF_UINT16 x,  Z7 J8 q2 U" H: ~
  423.                       LPDF_UINT16 y,' B0 R& q& B" d* a4 ?5 g% X2 r
  424.                       LPDF_UINT16 width,& j4 Z: v: ~1 m4 J" S! C
  425.                       LPDF_UINT16 height)1 G- j# V: k, Z6 O; c* s
  426. {6 `' q; y/ \/ `3 x" o: z3 l
  427.         return LPDF_OK;
    , Q& p/ A) H8 f  I. g3 M" J
  428. }
    : D0 g4 ]$ i9 |9 {& d' g
复制代码

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

  1. pdf = LPDF_New();$ ]4 |1 D( n/ v! y. N6 A+ H
  2.     page[0] = LPDF_AddPage(pdf);5 K$ y* F+ y0 p! X/ w4 Z5 A& x
  3.     LPDF_Page_SaveParams(page[0]);
    8 H' ?5 Q' G: u& u5 Q7 b2 j
  4.     width = LPDF_Page_GetWidth(page[0]);" {8 l' u; i/ P1 q8 e/ c0 [' ?
  5.     height = LPDF_Page_GetHeight(page[0]);) D- S' F' [* J2 x2 K
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);4 T; ], S+ s8 t5 \) b* e6 q9 S
  7.     LPDF_Page_BeginText(page[0]);
    3 P: {4 l+ N3 z% N+ z
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);4 T# e0 S) B7 _. U0 H1 |& \
  9.     while(font_list[i]), b: N8 O- p! z
  10.     {7 P; u4 N8 k0 N( E' Q! N
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    6 u# M4 V, f0 ^1 y- P0 @
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");
    0 Y( o6 G& e3 b4 a) H
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);
    5 i/ s, H- ]9 C) H% k* v& m( j* s
  14.         i++;/ b; j5 ?" ~& ]9 a5 ^1 k
  15.     }" C- _/ d+ Y8 X2 U( E
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);
      ^4 c- h6 @* ~( l7 O) r
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());
    4 Z% |0 y0 l( I% Q1 \: E' G9 A# d
  18.     LPDF_Page_EndText(page[0]);: U; C7 K1 a# s
  19.     LPDF_Page_SaveContext(page[0]);
    . R" S; C! P8 i" v/ c. ^
  20.     page[1] = LPDF_AddPage(pdf);
    : y8 e1 m2 E% u% R
  21.     LPDF_Page_SaveParams(page[1]);
    " B( N' G- U. J9 @# [. c, v
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);: p' V# H8 a) o( L! i7 ?
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    0 F# p3 k" ^$ O/ q3 x2 @
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    # ^9 j- O5 m* a- E. Z! N4 D. M& C, W
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    ! Q* }, S: Q. X" \9 U5 _0 G4 F
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    ' q6 W. g: t$ W# q/ s" k
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);. Y* }4 ]9 h; _( w* u$ {) M( M! Q
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);
    " j; _" F; n9 D. ?6 L' ^
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    7 L  A. O' h/ {# t5 N- N* j$ C( G
  30.     LPDF_Page_Stroke(page[1]);
    ! L$ Q+ P! u; [2 p
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);/ [$ z# d) {# F# D, }0 H
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);1 [7 e/ F, ]8 e2 y
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    ! h8 W% J) p1 p  b' i
  34.     LPDF_Page_Stroke(page[1]);
    4 v. Q8 U4 d8 b' l( c
  35.     LPDF_Page_SaveContext(page[1]);9 J( c1 y) I: {  E3 e
  36.     LPDF_SaveToFile(pdf, "/red.pdf");
    , s* `7 t) C% u- D4 ?
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    6 ~) ~7 W1 b- I4 R' s
  38.   
复制代码

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

无标题.png

pdflib库目前来说还是比较简单的,需慢慢完善,pdflib库代码放在下面

pdfgen链接:http://github.com/AndreRenaud/PDFGen

PS:更新为V0.04版本了
( \8 ]( y' m9 q( i

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    * e$ x) |/ j$ X4 m  ~. u( ?

/ u( f7 o& H5 ~" U+ q; T

pdflib_V0.04.rar

下载

6.1 KB, 下载次数: 424

pdflib库

评分

参与人数 4 ST金币 +24 收起 理由
tanganrong-1584 + 5
g921002 + 8 很给力!
lemonjohn + 1 很给力!
wofei1314 + 10 很给力!

查看全部评分

4 收藏 22 评论149 发布时间:2017-6-17 23:03

举报

149个回答
kiki.zhang 回答时间:2018-2-27 10:19:19
anobodykey 发表于 2018-2-26 22:55
. ~- M3 y9 Q# p只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...
& N9 E. Z" H$ {* _0 D+ w  ^
LZ,我怎么没看到有添加image的接口,您的pdflib.c中LPDF_LoadRawImageFromFile也没有实现哇,您说的可以添加image,是哪里~LPDF_LoadRawImageFromMem这个是直接传入读到图片的buf么?有什么办法可以直接拿别的pdf中通过编辑软件看到pdf语法格式,拷贝图片的那段buf,直接添加到我自己的pdf中呢?
anobodykey 回答时间:2017-11-20 13:35:19
醉宇a 发表于 2017-11-20 09:330 G, ~. d& o! ]6 C; }1 K
首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
$ U) J  t7 f' `* d" s
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
5 |0 [' v- ^' ?
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:456 g8 r* c( y2 F5 L( r
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
5 A2 d+ K0 o# `" b2 X$ @
这个我也还没遇到过,只是之前看到有人问这个,所以看看
pwdzsj 回答时间:2017-6-18 17:04:27
不错还挺好的
好吃好好吃 回答时间:2017-6-18 19:07:12
高手啊
netlhx 回答时间:2017-6-18 20:27:00
赞,楼主功力深厚
graycker 回答时间:2017-6-19 08:44:11
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接
anobodykey 回答时间:2017-6-19 10:41:48
graycker 发表于 2017-6-19 08:444 i& Q# D6 n: e1 [) R. \
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接
" s* d1 B) [8 [5 `7 `
这个还只是一个简单的库,实用性还是差一些的
zero99 回答时间:2017-6-26 13:17:46
厉害了楼主~
我为电狂 回答时间:2017-6-27 16:27:22
ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
epochal 回答时间:2017-6-27 18:30:17
不错,学习了!
anobodykey 回答时间:2017-6-28 09:22:13
我为电狂 发表于 2017-6-27 16:276 e3 b# D) ^  Q/ W
ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
0 S* e1 p* s& s) X5 i- b
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
5 a2 L; E# D" K% d1 L( S! Fff.h是FATfs中的文件
0 D5 r. h8 Y8 B  e0 K/ a
嗯,这个画线能改变线宽吗

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版