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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑
  W. M# [& K! ?' y3 W
$ M- O6 X  o9 @8 ]

主机环境: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__
    5 v' J/ u/ |4 h1 g' ]1 x
  2. #define __PDFLIB_H__7 \6 }1 j' j) Y3 x& X/ g  r
  3. , V5 S( l" O+ v: J' g$ |% p
  4. #include "ff.h"" T- N! ?- e# W5 s$ Z7 M
  5. /*----- standard C library functions -----------------------------------------*/8 c% r5 c  o0 E, Z0 `7 k
  6. . \. H& N/ B% k1 ?, v) S
  7. #define LPDF_FOPEN                  f_open
    # \: v% D" k5 r8 n
  8. #define LPDF_FCLOSE                 f_close$ {2 ^/ U  a* R7 u/ b: N/ M. S$ r& k* B
  9. #define LPDF_FREAD                  f_read2 t6 h9 n9 t% `& c) `
  10. #define LPDF_FWRITE                 f_write
    . X3 h" a  M9 H
  11. #define LPDF_FFLUSH                 f_sync
    + W, u6 ^' \" D/ n3 v, O4 F4 V. v  B0 Z
  12. #define LPDF_FSEEK                  f_seek
    3 q- \! p, Q8 R9 b3 w6 j3 E1 ]8 d
  13. #define LPDF_FTELL                  f_tell
    ) {8 Y  k4 f5 q0 y7 E) V
  14. #define LPDF_FEOF                   f_eof
    $ j. T7 X. R, p
  15. #define LPDF_FERROR                 f_error
    # }- a* F6 U9 K( g+ _
  16. #define LPDF_RENAME                 f_rename9 w' L; Y9 q7 k& b# x# j8 ^
  17. #define LPDF_REMOVE                 f_unlink- V: a! O. ^; {% \  {/ ?4 x
  18. #define LPDF_MALLOC                 malloc
    . @+ n% x6 s* T/ c0 k1 n$ D
  19. #define LPDF_FREE                   free
    $ a0 T. j/ r+ {5 ^: U3 e# f) s
  20. #define LPDF_FILE                   FIL, i+ `7 Y- a/ ?
  21. #define LPDF_TIME                   time
    " Y. c  {- w0 [( s0 G  F6 o
  22. #define LPDF_PRINTF                 printf
    9 D2 l7 s+ K  ?) G# `% a, ]
  23. #define LPDF_SPRINTF                sprintf1 q! P' l, k6 W. W; n) i
  24. #define LPDF_FPRINTF                f_printf# O% P$ B, V( N. o/ q' [% Z, o, i  ^
  25. #define LPDF_VOID                   void( J, l* |5 ~- T- D# p
  26. #define LPDF_SIN                    sin
    3 D# I2 o. U8 G; B8 F0 J2 t
  27. #define LPDF_COS                    cos: g; m/ E6 X" B

  28. , F+ O2 I9 I; o0 t
  29. /*  native OS integer types */% u; j9 _$ M$ Z2 X- K5 g
  30. typedef  signed int          LPDF_INT;9 N+ b% {( B5 A9 u
  31. typedef  unsigned int        LPDF_UINT;
    & ~4 g  Z) H# _6 Y! W' s: n/ ^

  32. ' k; l2 z, B/ s/ ~1 X/ H
  33. $ J9 x, c7 j0 B* A# w
  34. /*  32bit integer types/ L6 i* t' M( W# {. C6 @6 y2 V; K3 D
  35. */- |+ @; t% j% H2 i8 D' J& U
  36. typedef  signed int          LPDF_INT32;
    % x) T! F, G& T1 f) b* f+ |
  37. typedef  unsigned int        LPDF_UINT32;
    4 |  M  t: ]' g6 w
  38. 4 g' Y2 G% X  E( F$ f4 M3 j
  39. 4 p6 s# o2 }5 O) x( R" M
  40. /*  16bit integer types
    6 F4 u" n- _( K8 z% r
  41. */& i. X1 [$ a0 V5 u- ^/ s0 E
  42. typedef  signed short        LPDF_INT16;
      M- ]9 N( T/ R5 o9 k/ U! Q2 x
  43. typedef  unsigned short      LPDF_UINT16;, Z% {/ l. ?( ^) ], o$ F
  44.   X8 M/ ^) }! w4 N+ D5 F9 A

  45. 0 J# ]3 S7 K( R
  46. /*  8bit integer types
    ) k. m5 F  V! ~; q0 R) V* k; H
  47. */
    * ]% [' j; ^' q: y. p4 F7 y- S
  48. typedef  signed char         LPDF_INT8;
    " b0 `# Y3 p  ~5 E! L
  49. typedef  unsigned char       LPDF_UINT8;
      H5 C6 f. H( p* V& f

  50. 6 M0 x0 X  e7 \; D# Q, \7 b( J
  51.   d& g$ w6 r2 s0 M, C
  52. /*  8bit binary types3 Z9 H& C  C' r: N3 b
  53. */# N! r: [( ^1 Z( B) `, k
  54. typedef  unsigned char       LPDF_BYTE;
    # v2 W- ~0 ^. b" [
  55. 8 E" s( [$ p- Q2 f2 o2 G
  56. 0 Z) N1 F, }( O0 A) L
  57. /*  float type (32bit IEEE754)$ {6 K+ t' \$ i# G. b/ U& c3 x
  58. */
    7 P3 I; @( e# A) u& Y) h
  59. typedef  float               LPDF_REAL;$ g% _# w: K' f1 V1 v

  60. $ I4 X! ?& e- s! {/ t8 H2 ?
  61. $ Z: ^8 Q6 |4 P+ {! y
  62. /*  double type (64bit IEEE754)  @8 ^7 s; w% G& U$ G4 l% ~
  63. */
    7 b, f3 G! b% L
  64. typedef  double              LPDF_DOUBLE;
      v* P9 E! l' X! C0 {
  65. 8 i7 s( |( ]. g/ R+ @3 |' s# @+ \

  66. / e% V7 m' I% I8 T8 d
  67. /*  boolean type (0: False, !0: True)
    ! f4 R4 t, `% X  g: S9 D
  68. */, r1 ~8 E' H, Q, ]$ J; h
  69. typedef  signed int          LPDF_BOOL;3 u7 D: n' [7 f/ i4 }
  70. 1 l3 @8 _3 U/ F, _
  71. 3 S9 M4 i- F7 O/ }0 G* o
  72. /*  error-no type (32bit unsigned integer)
    : S! E& `8 |: l# J8 y
  73. */) U! P- z4 e/ J6 o
  74. typedef  unsigned long       LPDF_STATUS;  E% y& u4 f& p! f
  75. % P% u" `& d/ {% w
  76. #define LPDF_OK                     0
    3 t* a$ Z; l7 J0 y; x
  77. #define LPDF_FAILED                 1# T5 n( s! U1 b; F, s# J$ P

  78. ! g" v6 Y0 A# X! }: Z" `0 v& e8 O( J
  79. /*----- font state -----------------------------------------------------------*/! `* [5 X3 ]: f
  80. #define   LPDF_FONT_INVALID                 0x00FF9 F* T/ Z* R8 t+ K5 z" C4 x
  81. #define   LPDF_FONT_COURIER                 0x0000
    ' j5 t. R4 l/ f* O" ]1 L
  82. #define   LPDF_FONT_COURIER_B               0x0001
    9 _7 Q5 o4 k6 v" e
  83. #define   LPDF_FONT_COURIER_O               0x00026 Z7 s& ^( i1 y' f0 z$ c
  84. #define   LPDF_FONT_COURIER_OB              0x0003
    + x' }9 C' b+ q: t7 E- a; ~7 b% a
  85. #define   LPDF_FONT_HELVETICA               0x00047 ~, M5 _* G1 k0 U  j
  86. #define   LPDF_FONT_HELVETICA_B             0x0005, l4 E3 u; V& o# O# t! |
  87. #define   LPDF_FONT_HELVETICA_O             0x0006& Y) I) c! g4 o$ E2 L$ A9 Z, W6 \( g
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007' V8 {5 }0 `; C) M& Q* ]
  89. #define   LPDF_FONT_TIMES_R                 0x0008
    $ O+ c7 R1 T1 S6 Y+ S( f
  90. #define   LPDF_FONT_TIMES_B                 0x0009; p! b2 c$ K- J5 |$ A
  91. #define   LPDF_FONT_TIMES_I                 0x000A0 N2 r& Z5 d- D( v. @
  92. #define   LPDF_FONT_TIMES_BI                0x000B: t; z0 A. d" S6 }6 K
  93. #define   LPDF_FONT_SYMBOL                  0x000C
    0 n, R8 O$ w6 d& ~
  94. #define   LPDF_FONT_ZAP                     0x000D
    - q+ z% ^+ V2 g/ c. _. W
  95. /*----- Graphis mode ---------------------------------------------------------*/4 Y6 _9 X) Y, b. ]
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    % Q$ k8 D) T: r9 C4 D% `
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    " {4 m# J* ?. _) I$ }
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    - K  E: ]; w7 t; i% `
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008
    ; L7 q) K( V: m/ K
  100. #define   LPDF_GMODE_SHADING                0x00104 H% |; i. Y& L2 l. P5 I3 p2 k1 S) B
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020
    ( v' F7 x; Z0 Q/ _' n9 l6 x* q
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
    2 w0 r' N& q4 V. e* S
  103. #define   LPDF_GMODE_INVALID                0x0080
    $ I1 v' J6 d, s" `' y0 C4 t
  104. #define   LPDF_GMODE_OVER                   0x0100
    # G' T8 D( P! J( O) r8 e7 B
  105. ( E5 z/ m$ D3 A+ q
  106. #define OBJ_MAX_NUM     2565 y; `; n0 P/ W! m

  107. 5 F* }7 y, B( p% T; L2 P0 _& y4 |
  108. /* Page的结构信息是否需要树形结构 *// u, r, T- I% u1 E# a/ e4 \8 x8 h
  109. typedef enum 9 c% f" P+ h. S( W' D
  110. {
    " G  @3 x3 y0 v0 L8 {
  111.     OBJ_info,) z( t) c0 F% {+ p" U
  112.     OBJ_stream,
    : V4 m. r1 `$ `* H3 K1 v
  113.     OBJ_font,
    . F* r, T: P- V# F
  114.     OBJ_page,
    , |: Z9 j- |& r
  115.     OBJ_catalog,' q, ~. d* j2 z* w
  116.     OBJ_pages,
    1 z6 \& e0 b; x
  117.     OBJ_image,
    $ a/ O; `3 r* r/ g9 c
  118. }LPDF_ObjType;
    " Y! j' e; s1 ~7 Q  _; l% y
  119. & E2 f# {8 ]5 x8 |2 N/ a6 ~
  120. typedef struct9 m6 D* j; S4 ]# x( ?2 x
  121. {7 Z, l" a9 ^3 h. J: U% f
  122.     LPDF_ObjType objType;
    8 R- _, _- E6 X" M1 p0 v1 l" k
  123.     LPDF_UINT16 objIdx;7 [* |  U0 m( ^7 F2 n2 C5 o/ ~% O
  124.     LPDF_UINT16 height;
    / O$ F+ Q. Q+ A
  125.     LPDF_UINT16 width;
    ! U9 W2 w5 W, f; @
  126.     LPDF_UINT16 length;
    ' q1 Y3 O8 e, x+ f; p6 W
  127.     LPDF_UINT gMode;% q, x1 P3 W2 w% s) I+ A
  128.     LPDF_BYTE fontType;6 r; d- k& b2 i7 P' K6 {
  129.     LPDF_BYTE fontSize;& |: W4 a) c% v/ K- S) ~7 y
  130.     LPDF_BYTE pState;
    , w8 ~/ r+ i- o: `. k$ m
  131.     LPDF_VOID *doc;
    * a" a0 W) A: }4 D) x7 w, b
  132. }LPDF_Obj;) I2 E  V( q" z

  133. ! t( M* i0 @8 x' o
  134. typedef struct
    4 u/ l$ P5 _: M( {1 }
  135. {6 `% f, ]' A/ {; B
  136.     LPDF_Obj obj[OBJ_MAX_NUM];
    " l+ d* f2 `  m) A; V
  137.     LPDF_UINT32 offset;1 T  e1 X5 N# o+ t& @  P
  138.     LPDF_UINT16 objNumber;, N- ^3 J8 O% r& j
  139.     LPDF_FILE file;
    3 o- H2 {( A9 t9 W7 W2 G
  140. }LPDF_Doc_Rec;
    % H6 s2 d8 \; Z6 U

  141.   o5 T+ n  t( j) |- W) v( U+ `2 y' q
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    ' M/ G2 B$ E- y9 Q  Q
  143. typedef LPDF_Obj *LPDF_Page;" V6 B; {% G! h7 r" L
  144. typedef LPDF_Obj *LPDF_Image;$ ]7 i* x3 z, j- I1 r) X
  145. extern const char *font_list[];' I+ `0 x2 F9 Q4 O7 a
  146. /*----- LPDF Interfaces-------------------------------------------------------*/0 _3 j" k$ f' z+ c9 ?/ e0 w
  147. const char * LPDF_GetVersion(void);2 S& v, x9 ]  u
  148. LPDF_Doc LPDF_New(void);
    * y4 k/ k: S: e$ M3 j/ u# l$ [
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);
    * h0 s$ W/ @* N6 W; y( w2 q* t
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);
    # q- N) J2 M4 w( {
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);
    $ c' N6 a7 R* L' R# {! k& Y
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);# \( c  E& s! ^1 t% P
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    / D; O- l. ^6 P: p2 m
  154.                            const char *font_name, LPDF_UINT8 size);
    ( K7 S8 ]3 A% u
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);; ~5 B% h4 u4 @- X4 O6 C) Z
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);
    + i* f) F, j( ^6 F& N/ Y7 r0 W% y
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);
    " |6 g8 i  ]3 V" x4 W3 |1 y
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);2 N6 D- H8 S4 U. `7 c3 d
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);: j4 K- b; I# D
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);
    , e- K& ~7 O! p+ c. W
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    0 X. H  Q& R# l& j8 |
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);
    " v# ?$ N0 m( G/ X! f7 m
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);4 M6 S5 Y+ K  {) e8 t
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,! |+ {9 n& X' b9 ]1 m  f
  165.                          LPDF_INT x, LPDF_INT y);' y5 Z3 F' j" R( N4 S: l, @2 y" H
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    , C; l( }- L. F; l% w; B
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,
    1 s3 r4 O) H' k( \+ z8 b1 ~
  168.                          const char *text);
      S7 k4 J- Q+ m: J$ M( @
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    : q; Q8 ^( t4 U8 I5 ?( t1 ]) ?
  170.                          LPDF_REAL r,
    8 q, K8 _* \. K/ h
  171.                          LPDF_REAL g,
    2 A. Q2 U2 ?5 b2 u5 p' m
  172.                          LPDF_REAL b);$ t' s" H4 W! i/ R5 O
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,$ C9 b  V* j$ |* H3 G; x
  174.                          LPDF_REAL r,
    * d) x' g) A. C" u5 ]
  175.                          LPDF_REAL g,5 y8 j0 b! \2 B; R
  176.                          LPDF_REAL b);
    ' `$ G* `% E0 p- ?5 G; A8 }
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,& @( m  G) ~5 \4 L5 h. W
  178.                          LPDF_UINT16 x,
    4 c( |3 ?' l1 v+ m% P. w' p
  179.                          LPDF_UINT16 y);
    2 R0 E& `6 Z& X# m& @4 Q
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    % s+ z0 B2 ]( c1 I2 a4 E
  181.                          LPDF_UINT16 x,, T# T9 b. m% U- y2 U0 @% L
  182.                          LPDF_UINT16 y);) f0 G% ]4 D5 Q6 p( @" Y
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);3 l! r2 V8 F2 L' @% ~- I
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);5 _: t5 |* G1 H* K
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    . {* y- L+ O4 @5 D5 [
  186.                       LPDF_Image image,* I  q6 r) r/ q1 r
  187.                       LPDF_UINT16 x,; ^2 E7 M4 e& t  _
  188.                       LPDF_UINT16 y,5 g7 L$ _3 A  l
  189.                       LPDF_UINT16 width,
    / p) ^8 ?. K) U5 ?- g
  190.                       LPDF_UINT16 height);: Y; Q; N. v7 ]' U+ ]
  191.                                                                                         $ P. ^. n/ S. I( M; s! [
  192. #endif
    ( H9 a1 g9 c' V# F& I
复制代码

源文件如下:

  1. #include <stdio.h>, H' e% k4 Q" T0 ^4 L
  2. #include <stdlib.h>
    , |; {, ~: ~5 x, O/ C
  3. #include <stdint.h>
    : M' s$ T. K# o
  4. #include <string.h>
    ! d( x5 g! B" i% X/ |
  5. #include "pdflib.h", Q3 w9 I$ T- D. t" W  }# q

  6. 0 e) w( N* Z' L4 ]! z" h  c& P
  7. #define LPDF_INVALID_OBJECT                       0x1033
    # l6 J0 z8 q$ M& O$ z( e

  8. 6 V& i& w* ?: Y  d  V3 c+ i) H
  9. static char pdf_buf[512];
    ; K* A1 b3 b, w& t0 u4 k
  10. : t9 ]* Z- o$ @8 Z- F# s
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"
    1 h+ B# S0 Z' R1 K# [. X) y
  12. #define LPDF_FILE_HEADER_LEN        15
    ( K+ |: l5 S6 Q9 o
  13. #define LPDF_BASEFONT_NUM           14- A2 u# g3 h0 q' n" c% }
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    ; X! Z- b3 d  L1 b! ?
  15. const char *font_list[] = {" u$ \2 @# c; t; [
  16.     "Courier",1 U$ x* c0 r# X6 d, U. M  F/ W
  17.     "Courier-Bold",
    * I: F1 x& P, @
  18.     "Courier-Oblique",
    0 Q/ A# ^! T6 _  }4 ?; \* D
  19.     "Courier-BoldOblique",
    4 a+ R' p3 [& u+ g6 a8 y: Q9 H6 Q
  20.     "Helvetica",
    % ~: G: D' M/ Z
  21.     "Helvetica-Bold",
    & i/ y( m$ s. O7 S: U7 |1 c2 ^
  22.     "Helvetica-Oblique",0 C) b' |1 T' E* G
  23.     "Helvetica-BoldOblique",
    ! N0 u, G/ G/ Y/ x. @- i
  24.     "Times-Roman",
    8 b' X% ~  |' D% C( J% l
  25.     "Times-Bold",; `9 f+ P  \  `5 V1 h2 m4 n
  26.     "Times-Italic",, a! ]  D2 ]3 v" |8 [
  27.     "Times-BoldItalic",
    , w5 {* B( A: K
  28.     "Symbol",1 R1 v! r* ?+ s5 s- A9 I! V
  29.     "ZapfDingbats",; F1 P1 L) j% n4 A: ^6 {
  30.     NULL
    6 R. Y9 ~. t9 [. H' ~5 B9 N
  31. };
    3 ?7 |  S: ~+ e
  32. ! w9 a) q+ D/ i8 K0 ^0 j9 b

  33. . T! z! I: \+ ~( q3 Z
  34. const char * LPDF_GetVersion(void)) M' {4 H- ~" V( f7 C2 ^- D2 ?8 t( @
  35. {
    : [0 i3 u' f4 q7 q
  36.     return LPDF_VERSIOIN_TEXT;
    6 T6 g( n0 H! k) v
  37. }
    # E6 D6 _+ U- B! c2 r
  38. 1 k0 r, @# ~4 P, L+ u+ E
  39. LPDF_Doc LPDF_New(void)$ L/ T1 s3 T* d  l" U  c* E
  40. {4 A: I" ?' @+ d2 k3 r. S* E
  41.     static LPDF_Doc_Rec pdf;3 S* l6 I7 i) h6 q; G
  42.     LPDF_INT length = 0, i = 0;7 I3 J- t: E* X; R5 k. `
  43.         LPDF_UINT writeBytes = 0;
    / x1 O7 n1 o7 ^. h' R4 t
  44.         FRESULT fr;- J+ B, q; q& q) K
  45.    
    # R+ r! s" r  t
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
    ! L7 j, E% n' P! y2 f. {
  47.         if(fr)
    $ n: A& b/ U- q0 O2 e
  48.         {% O" J5 W/ H* C6 a" x' z
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");3 o& |* }$ u8 t2 O
  50.                 return NULL;* Y( q( v6 ^0 u: t$ I; m1 |. ~
  51.         }
    * I6 n+ R. D0 ~
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */# z/ F) j: o! f; J: V
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;: N8 W8 _8 H9 m" [
  54.    
    ! F4 C0 B- v# i8 ]  T
  55.     pdf.obj[0].objIdx = pdf.offset;
      Y$ i* Y+ j0 ]
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
    * D" A- {2 j0 f" ]+ E  F) q" t
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    7 R+ F, {) z1 u8 T, Q+ N' f! t
  58.     pdf.offset += length;* o' e  s' k4 P! M# }  S6 X
  59.    
    ; C: g. H9 x" n. [
  60.     pdf.obj[1].objIdx = pdf.offset;1 N2 R) S# w3 @! B+ d
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"
    7 n1 k) e+ R& e) A& M
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");
    5 w  n0 w( |7 ?* V8 M4 k- O7 a
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);6 t8 Z- s4 i- y
  64.     pdf.offset += length;- G3 x3 y+ X/ S: [
  65.     4 m" Y4 A+ n4 G& b
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    $ Y9 Z: {+ j! t5 Y, E& g
  67.     {
    - C; b; P" I& {1 W, o7 z
  68.         pdf.obj[2+i].objIdx = pdf.offset;( Z& q5 l6 G( j2 a' Q' f
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"/ s" u! I, p- A! n1 g. b
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
    1 Y4 `( m+ T! ?& @3 O0 }; m4 O: m5 N
  71.                         "endobj\n\n",3+i,font_list[i]);
    0 @* e  f9 @2 c
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    $ m0 w6 o  ?8 ]' w
  73.         pdf.offset += length;" K+ N( m. k, v9 L$ {
  74.     }$ h9 t3 ^" l$ ^* R2 p! B
  75.     for(; i < LPDF_BASEFONT_NUM; i++). y5 g8 C! |# s4 `
  76.     {% W9 u4 F7 e$ Q' n3 P$ P& X
  77.         pdf.obj[2+i].objIdx = pdf.offset;- a2 H0 \7 W8 |3 F
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    9 ?) {: ?/ M* H: D+ z) c, ?% w( d2 W8 q
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);0 |0 o# ^$ a: p: ~$ D# j
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    * ?5 M' E$ Y3 Q/ T3 l
  81.         pdf.offset += length;
    7 S0 I7 d9 q# j* ^
  82.     }( A" C4 B2 H/ `3 u' z0 ~' Q
  83.     pdf.objNumber = 3+i;% y. c& a% |0 \0 g. l- N$ N- q
  84.   ; n5 }; R% C) X
  85.     return (LPDF_Doc)&pdf;
    # Q) E4 J% d! l5 V$ L% R/ p1 Y
  86. }! y* x1 [  r8 u3 z
  87. & j) N5 Q( q6 s; p2 n6 Q
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)0 [" l5 U) _4 n, D
  89. {4 J' I4 B5 h1 b3 E. F5 ~
  90.     LPDF_UINT16 i = 0, child_pages = 0;
    3 Y2 {3 I8 p" G; P2 G
  91.     LPDF_INT length = 0;/ B% X, x. i' ?
  92.         LPDF_UINT writeBytes = 0;; A" F& v8 O7 ?1 U" _+ y
  93. 7 O2 n% D& ^  f/ [6 J
  94.     pdf->obj[16].objIdx = pdf->offset;' A2 Q" q2 L; l2 q! z8 m$ q
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;7 v. i: t6 }; k7 x) q' e
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);8 c0 ]/ L+ n+ g# w, ?$ ~* |: b
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ; [/ M7 {  l; m$ X( m
  98.     pdf->offset += length;
    7 K! i7 Z+ I/ c& f2 d
  99.     for(i = 0; i < child_pages; i++)
    , K* e: l% g( \
  100.     {" E" \: ~4 h3 _% o7 n* K& H
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    9 Y* F) j) _* ^" ]. X
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);$ p- U9 k7 X6 x* D+ W
  103.         pdf->offset += length;0 {2 _/ ]6 E  D: J, W; @2 S) O
  104.     }
    " s  }! Q8 ~  C/ y' y
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");* f/ `) \& Y, p6 N# a
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    / O0 ]6 G, B% W  e' K" p0 F
  107.     pdf->offset += length;. {. ]6 L! F) n; k
  108.     / y& W8 T# H& o# w! @
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    . s8 E, H2 J' T3 n
  110.     for(i = 0 ; i < pdf->objNumber; i++)
    . k* r, w% G7 |( D* w* z
  111.     {# V3 F; v2 ?! `+ s5 n! ?% X) r
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);0 D2 \, t. R/ o5 ~4 Z4 E/ a5 ?: @
  113.     }
    4 N; |8 s$ f: C5 D/ f
  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",& ~* G. z0 G, ~  |
  115.                 pdf->objNumber+1,pdf->offset);
      l5 q9 J6 ^: |4 s6 k  F
  116.     LPDF_FCLOSE(&pdf->file);; U, o( c9 R8 W8 x* ?0 ]
  117.     LPDF_REMOVE(file_name);9 r; V( V) k$ s2 C6 j* p! X
  118.     LPDF_RENAME("tmp.pdf",file_name);- k0 Q3 c% @, A3 ]9 m' E. b6 R3 [# ?  @% w
  119.     return LPDF_OK;) e  \) P2 ?$ S/ G
  120. }! _! h4 i1 ~! D1 {
  121. : @  O/ a9 |+ J7 u1 k
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)/ b# k2 t5 w7 C* E- P% F
  123. {
    : B1 o$ \7 I/ D' n  X$ s$ E
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);" u6 h) t3 E! u/ L0 Y" f
  125.     return LPDF_OK;" Q; {* a" y2 b
  126. }
    9 ?6 M$ ~7 u0 Y  t
  127. - K2 e9 s5 n: y9 s3 h
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)
    3 k9 u/ H6 Y9 h1 w- M" g) A
  129. {
    " p  i, n0 t! x8 x) @1 b' g% y
  130.     LPDF_INT length = 0,i = 0;
    % O" n! D. h1 T7 B
  131.     LPDF_Page page = NULL;
    ! ^5 b# j$ B# L5 Q: m0 Z' U
  132.         LPDF_UINT writeBytes = 0;
    2 V4 [1 d/ d3 E( |1 {9 R
  133.     & R8 _) J$ U2 _$ Z# `
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    6 a7 i" _2 d' @& ]3 n
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n", `& R" H" G5 t' y5 T5 q
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    9 q! s. m) M2 e* l' M
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);/ O6 h' Y  T- N& Q
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    3 }& Z5 W* T' g! C4 {
  139.     pdf->offset += length;
    3 S( a" |( M6 q4 z1 v$ V
  140.     while(font_list[i])
    / s8 `( Z6 T" W! y) k' T3 @
  141.     {
    # D( |( h3 i3 h
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);
    # q8 [% t+ b( A* a; ?9 o
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);0 K8 D/ b  V% K& I
  144.         pdf->offset += length;& P! d, ?4 U9 I9 f7 n) _2 m
  145.         i+=1;
    8 g9 c& b, @2 D+ s6 @+ B
  146.     }
    " S( B- r+ `; C- ^" ~
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");
    + L+ z6 ?# d9 ~9 s  t6 v1 r7 B
  148.     pdf->offset += 4;
    " X( b- Z( U8 A5 T% W7 ?
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];
    # J% }9 B$ U' R5 H- I# B1 _
  150.     page->width = 595;4 {& \! j- z- V5 s  @6 h
  151.     page->height = 842;
    / @! u+ ?* G  f* o
  152.     page->gMode = LPDF_GMODE_INVALID;
    * h# E  }5 o2 U/ f# W
  153.     page->fontType = LPDF_FONT_INVALID;
    7 B! F4 {3 Q+ _1 a) O+ b" o& j
  154.     page->doc = pdf;
    $ R( N, n/ \* w6 g$ [
  155.     return page;+ w+ j& v8 ]/ ?7 d6 x% L8 X- G2 {
  156. }* E. V, S) m) M6 z. A- j8 {

  157. * z! V4 f+ `8 d6 |( l% u
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)* c: T0 D: J1 _1 \+ E4 j
  159. {8 }6 A4 ?* Y% U, B: j( ?6 e
  160.     page->height = value;. |3 D+ B& U  D6 j
  161.     return LPDF_OK;
    ) u; M) g$ p+ i/ O4 v% Z1 o
  162. }
    + B3 R& T4 }$ o" j  G3 R( @+ M9 N( \( e
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    , T  ]: ^/ Z' h1 \1 M
  164. {7 I1 t9 w( B2 Y' B
  165.     page->width = value;
    % O5 A. [% y  x* h1 Q3 e
  166.     return LPDF_OK;
      |4 P9 G7 K; Y: B
  167. }
    # m, s* M. m1 M9 b% I0 n

  168. * O, I. \" s* ^! X
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)9 O6 B7 O, j$ ^2 h8 P
  170. {
    * ?. a5 r% Y* t' ]0 E1 _$ ?4 L
  171.     if(page)
      q6 h$ V3 h, t
  172.     {
    3 d( U" _7 n7 r1 v0 |5 i9 ~7 e
  173.         return page->height;
    : G* i# ~1 l2 g0 \( `
  174.     }( f* p: @, X! C% ~& [0 |. E$ A
  175.     " K$ ]1 C+ U) t- y# }
  176.     return LPDF_OK;' J2 O& W* m  A' h6 i4 U& X- W- p
  177. }
    2 P0 @. L7 u* v9 [
  178. ) V2 X& E7 H) z/ j6 z% G
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)  d" {* J/ z' a
  180. {
    ! _. F- u) b2 A3 h; e- ]# B
  181.     if(page)
    4 m% p: g2 _9 t# A; `( _
  182.     {& n& V: {4 {* d0 ]1 R: [# J, L
  183.         return page->width;& M+ V+ U0 Z  V; g6 l7 Z
  184.     }/ _) A  v$ n2 n7 v9 P! w# t* }3 M
  185.     3 H; \9 ?8 q4 u% z' ^, _. ~# X
  186.     return LPDF_OK;
    : ]; B; H+ Q9 T% E; Q: t+ i
  187. }
    2 T. o, H" G- y# D- `& }

  188. & |! w4 d) \1 M$ Z) M
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)
    8 v: V, ?" ]. i3 E
  190. {
    . X1 W3 ]1 N1 J1 N& I
  191.     if(!page)5 @6 I8 y4 _% X* [0 u8 h
  192.         return LPDF_INVALID_OBJECT;# @5 H. Z/ S9 l3 R* c# ^
  193.     if(!(page->gMode&mode))1 _# w7 P4 a; q5 a) h8 r
  194.         return LPDF_FAILED;& F/ D# c+ l1 A4 y3 u' y- I

  195. 6 t7 Y9 D) w# P) e" t3 o
  196.     return LPDF_OK;) S  K4 g# A3 S. }' L* g* o) G
  197. }% k+ K1 f$ o# I. W

  198. 5 h+ x6 k& o3 t, l/ Y1 z: i. h+ N
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,3 r" ^- Q; j' t& E) h8 Q6 F
  200.                            const char *font_name, LPDF_UINT8 size)* O. b- S5 E+ i  a3 N1 ]# k
  201. {, M, [6 G$ d! X- B; c
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
      S  Q. M) @" A' s. s- K0 c4 H: w
  203.     LPDF_INT i = 0,length = 0;
      r4 d& A) \  F+ T, K+ T5 Q
  204.         LPDF_UINT writeBytes = 0;
    9 f+ |. t9 g0 D* @  e
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    + v. i: x/ L- Q/ s5 A* u) V" y3 k
  206.     if(LPDF_OK != ret)
    & X7 {* q8 W; `2 j% G
  207.         return ret;$ s1 \" l; u1 S8 y

  208. * P8 f5 A8 g* a9 \3 W2 ]- Q: k# R
  209.     while(font_list[i])$ u9 y# [# I4 s4 s8 z. h( B
  210.     {
    2 e6 r0 ]! ?  R4 M- d
  211.         if(0 == strcmp(font_list[i],font_name))3 h1 q- `0 T, U4 j
  212.         {
    $ f2 l& c2 X- W4 L
  213.             page->fontType = i;. I- h7 n; E5 d3 z
  214.             page->fontSize = size;
    * j& s* l4 y8 a% }
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);3 H! j1 C: c% n7 C% p9 w1 z4 y
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    % ]  s' g& \6 `0 v" m0 s
  217.             pdf->offset += length;
    - ]/ B3 b9 j6 l, f/ U0 H) S  H2 }# @
  218.             page->length += length;" a$ a# C4 x0 S
  219.             return LPDF_OK;
    ) v+ G/ m; z3 C" b, w
  220.         }( A" G. `; V! @; f/ Y: T. i
  221.         i+=1;2 w/ p. b# i9 [, `1 b7 x
  222.     }( c: i$ o( c' T7 x
  223.     * }1 h9 B; n7 t( `" ~+ w* T
  224.     return LPDF_OK;, ?3 ~) G1 U) b/ r
  225. }$ r* i- W4 x/ B- `
  226. 6 o  z+ \* c: X: q
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)" g$ K9 ]9 v0 C
  228. {
    3 J1 M8 a* D- e
  229.     LPDF_INT length;* z5 G2 L( l; }% q. i' t" x% m
  230.         LPDF_UINT writeBytes = 0;3 y/ s; S- x) M
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    $ P* f; x# c" C3 M
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    # W2 b8 X5 M4 b; M: O, j1 M8 o  U4 ]
  233.     if(LPDF_OK != ret)
    4 n( o2 A! U7 u' R% W- G3 H8 X
  234.         return ret;/ N  T" @, c% n8 r7 T
  235.     , w, H: c* T* v! o+ n0 t0 s
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */0 C5 q  D2 D2 C( L: A) h
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",( d& _/ z' R3 r9 d+ F% M- o
  238.                         page->width, page->height);% [6 j  s" {  V; X
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ; L! A4 b3 \, I6 s
  240.     pdf->offset += length;8 {( u) n, H6 Y, _! ^
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    5 c* g% D& D' |
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",& Z2 i0 Z) K: o7 ^) r
  243.                         pdf->objNumber+2, pdf->objNumber+3);5 J! m# D1 Z4 T7 g" R, z, C3 o7 @
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);8 \  b& v" o# Z0 Z1 p& w
  245.     pdf->offset += length;  A! U5 G5 B# O+ d
  246.     page->length = 0;$ `4 r/ z: ^8 u0 N8 {* M
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    9 W! H9 p" S/ z. T/ ]; {- N
  248.     return LPDF_OK;( l% X1 W1 y  p; h( r
  249. }$ }+ i5 z. K$ ]2 I

  250. 2 D; w& z) x4 ^3 v
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)2 l( v# P* F; K8 H
  252. {. m: ~0 V! K: Q
  253.     LPDF_INT length;
    8 o& W9 A) `2 K5 M
  254.         LPDF_UINT writeBytes = 0;2 {- H: g! V; C& B/ Y& m
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    6 g; Z0 z, T2 o* P
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
      D2 h! {7 Y8 c" B6 u& `8 c9 Q
  257.     if(LPDF_OK != ret)! c& B) s( c* |3 [4 `
  258.         return ret;! E5 K4 q! P  Y8 j  F
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */, R4 m: O* a, z1 _1 b) }9 E
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");' X$ \, C. f+ C7 u8 ]9 g) Y6 z
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes); 9 n2 M$ A% r2 E
  262.     pdf->offset += length;
    " q9 T- I7 _% S$ a" `
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;
    0 s+ [# W6 n. }, C! b
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",- [  Y% }4 S# \. z1 x$ ?3 z
  265.                         pdf->objNumber+3,page->length);
    4 F, Z( t( ~4 f; Z# |! u
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    * P& _: z4 ?% X! J6 e( |8 X: j
  267.     pdf->offset += length;
    . v" n6 R  @6 `3 ]
  268.     pdf->objNumber += 3;
    + Q" I* c# T/ I
  269.     page->gMode = LPDF_GMODE_OVER;
    : T8 z. C& H; {2 d6 f8 v/ Z: W
  270.     return LPDF_OK;
    0 ]6 T) T7 ?- ~4 _4 S
  271. }
    ! q  A; }( w; r2 y0 J/ l

  272. 5 U7 J6 B/ s0 q: t3 y# E. `
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    3 s: `2 I1 L4 l/ D" h" O& u
  274. {
    3 |" Q8 Z! K' u5 _5 ~9 s
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    9 B  b2 ]' c( X  E
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    3 ~5 h! g6 _2 g% ]& E, V* ~, p
  277.     if(LPDF_OK != ret)
    " e; T9 n; e) p7 R' g: v. Q
  278.         return ret;
      }7 F4 a# {" p& z6 f* B
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    8 @1 x. K  F* y; k
  280.     pdf->offset += 3;
    & t% N8 ]! A+ f# {
  281.     page->length += 3;1 P9 z5 H* C) k) |" G% X3 P4 R$ x" [
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;  O7 C. k  H. Q* {' @
  283.     return LPDF_OK;, k; S' g4 O% }
  284. }
    3 J% Y# v  W8 v; `' m7 c' \, D3 o
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)6 }6 C  s9 @. ?6 y5 {' X1 o! j- |8 @. x
  286. {
    4 _" O& E/ b3 O+ E+ j
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;, q$ a! r7 ?/ z- G
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);8 J* i9 _& H1 ?  g9 Q
  289.     if(LPDF_OK != ret)7 ^4 H* _( q  t0 @: Q* R' _, ~3 I
  290.         return ret;- ?+ E( N4 O" b1 i' B+ b
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");) L( o; W8 n9 r: K' y& F+ i% }/ ?
  292.     pdf->offset += 3;. i& L6 f$ P) B" X$ U6 C( E
  293.     page->length += 3;# ]+ h1 a% a6 A
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;; d4 T6 _* k- w' @
  295.     return LPDF_OK;( E9 C7 f# @* g* M$ x0 x' V4 x
  296. }6 _) ~- E4 `4 t
  297. * B, M- j/ C( J5 ~4 ?
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text): c4 Q3 }3 E6 C" O6 K
  299. {
    1 ~- M2 R8 |' {7 W) k% B
  300.     LPDF_INT length = 0;/ l5 A* m6 D) @, t3 t. m
  301.         LPDF_UINT writeBytes = 0;. I8 G& f0 w# B' m# Y8 j/ f) f
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    0 q0 ~4 R4 h' s* d9 _5 j" n: _. R
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    7 U' O5 E. v( {# d" c
  304.     if(LPDF_OK != ret)& [8 Y( [7 R7 R3 Z) p+ \. X
  305.         return ret;
    & m4 U/ i4 R2 l8 Y$ l4 @* F* J# E# Y7 [
  306.     if(LPDF_FONT_INVALID == page->fontType)9 ]9 B- ]" T+ Y+ M
  307.         return LPDF_OK;
    * v( {- s9 E* f1 l! e
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);$ Z" ^7 ^9 Q) Q5 ?% d/ H; s$ r
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    % G5 t* ~$ G2 E5 J
  310.     pdf->offset += length;
    ; p( Q7 h% ^. ~
  311.     page->length += length;7 `# T; Y+ N8 x' i
  312.     return LPDF_OK;- }/ s: k$ W8 k9 c. X  j
  313.    
    ' Y) c- K4 T) h- J* L7 a
  314. }
    % o( a- k& f2 u
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,. P7 C6 H5 W! J9 H  B$ t) n
  316.                         LPDF_INT x, LPDF_INT y)" C5 I& V3 H- l' `
  317. {1 v4 I8 ?- Z" m
  318.     LPDF_INT length = 0;1 _6 K4 V3 {; O3 U( b  ^
  319.         LPDF_UINT writeBytes = 0;* @+ v9 l+ I: H9 l6 V4 n
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    4 l( d; W% H9 O
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    * l: R* G3 v( p  O/ V7 r
  322.     if(LPDF_OK != ret)3 h/ M0 }3 R" b4 d! U' Q
  323.         return ret;
    . T. s4 {5 G; _- N( _' X  V
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);9 B( w; u; Z. k8 F0 P  x
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);- v, X3 I! ]& B: I3 |
  326.     pdf->offset += length;
    + r$ f* j' K; z; ^6 |
  327.     page->length += length;
    8 l9 ^7 h8 L9 Q+ c+ Q; e- \; y
  328. : I7 j5 y6 _( x
  329.     return LPDF_OK;' x+ f( w1 g6 A1 O/ e) @6 y- {
  330. }- C$ X7 y% R8 O4 ^& i1 [
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    - B9 d; S/ V" o5 i3 d3 |/ f
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,
    2 A$ R3 _# C7 h: `# D
  333.                         const char *text)& b& m+ p0 t! p# p$ U
  334. {; I( p+ }8 W$ G/ ^9 w6 Q6 U' `
  335.     return LPDF_OK;
    4 a! i6 o' F, ^# P4 M! W* Q  h0 y( ~
  336. }
    - T) E, m6 @  Q- p% W* ]5 q* ^
  337. 7 n* l4 o3 o9 j, q# c+ t, F; b) f
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    * ]( H6 D* k0 u( P2 C0 {
  339.                          LPDF_REAL r,2 J/ K2 ]7 m& V5 I, m
  340.                          LPDF_REAL g,: }1 @  Z  _: T" r
  341.                          LPDF_REAL b)9 J  c9 V, i: Q
  342. {5 G  X6 s9 S+ w: e, A! ?  @
  343.     LPDF_INT length = 0;
    . r7 n, J/ f1 r! e  H
  344.         LPDF_UINT writeBytes = 0;( e: a! G$ P1 v+ d
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    1 n: H+ S+ d& ^8 P7 w+ [4 {
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);+ M( m8 n0 i8 Z+ j2 ^
  347.     if(LPDF_OK != ret)0 V  s2 O+ w  [% ^  k# k
  348.         return ret;% o5 Q1 c9 I8 s1 V# P

  349. ' ~# ^2 u* p: ~9 [: J
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    0 ]3 _' S% j# w! B0 K( U
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    0 z& x1 V9 Y1 q9 V# s
  352.     pdf->offset += length;5 x1 ?/ B3 }% v, u
  353.     page->length += length;
    7 e% U1 P7 v. U2 N# N
  354.     return LPDF_OK;/ e# P, ~' I. G3 z' l
  355. }+ j1 A* r/ L7 O, O

  356. 2 E; E% z+ U% G+ W: I- j/ ?0 v
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    4 r4 \3 ?# T* g6 J
  358.                          LPDF_REAL r,
    . ~- L+ d6 x/ J  p
  359.                          LPDF_REAL g,
    * y7 o" v+ u6 B* ^
  360.                          LPDF_REAL b)
    ; \, B2 Z/ o/ O8 y1 Y3 I) F7 B
  361. {" ~$ R% v# h% `3 y, N% n
  362.     LPDF_INT length = 0;% B& l6 F8 \/ S5 Z$ r( H8 e
  363.         LPDF_UINT writeBytes = 0;9 m- O) c! ]# h5 i0 g. D) j8 O" @
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    * V) l# h+ ^9 b& e9 y. p! M
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    6 j- W" V+ C0 K, B  `
  366.     if(LPDF_OK != ret)1 d/ A; ]% }4 t" P& Q# ]9 E  W/ U
  367.         return ret;3 a4 Y5 h: m: Q9 J3 O- u
  368. # u4 M: |& M) F' ]& Q& w  `
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);. N7 k- g7 R  h8 K9 G
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    7 I, g/ M) A' ~, o1 m/ A# p& N
  371.     pdf->offset += length;. t8 e6 S% r7 a$ t6 r( F9 ^6 N. k4 c
  372.     page->length += length;
    - D6 }3 V% T& J2 v8 J2 O* q
  373.     return LPDF_OK;
    - [9 |+ c  h7 F; z% _; d
  374. }
    ) O! a/ y% r5 H$ D0 T* Z- F# E
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,2 a+ b1 ^5 R, Y0 H8 I* b
  376.                          LPDF_UINT16 x,
    4 V  _8 Q: u. {
  377.                          LPDF_UINT16 y)
    - [+ n# f3 O4 z7 _- D
  378. {5 g$ i) L6 J$ D0 S* v% E0 s& w( j2 K
  379.     LPDF_INT length = 0;
    1 J* u, m" v3 Q  y' D. V* l, R/ M
  380.         LPDF_UINT writeBytes = 0;2 ^3 C) h+ h- v, v5 Y
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;  K) q6 H) m" N& X- f: V
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);
    1 S! R4 F6 k0 u  b
  383.     if(LPDF_OK != ret)+ k$ ]# N  H; C! r2 p' S
  384.         return ret;/ U! j$ o& S& \: \  K. h  K
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    , i  c! z) @# i4 a
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    * t  b: z6 F# i8 ]; ?# e
  387.     pdf->offset += length;
    ! s$ c* e" [* ?) k7 |
  388.     page->length += length;
    9 L9 ^0 n" n! a
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;" o( ?& d/ R3 T; |" O
  390.     return LPDF_OK;$ I" y& i  b; c: j$ R+ f9 u- K* m9 w
  391. }
    ; S* l# T# D: e8 c" s
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    0 i. m! e9 K4 `& D+ P; @9 M4 n
  393.                          LPDF_UINT16 x,
    % N- J3 w8 R7 V+ ^, B: k3 |
  394.                          LPDF_UINT16 y)4 X4 u9 h9 x1 k6 |6 [- T' o, p8 D
  395. {
    8 o; V6 ]- v  {8 H5 W
  396.     LPDF_INT length = 0;' ]6 Z. {# b. f* w  z3 ]
  397.         LPDF_UINT writeBytes = 0;
    ' ^* c% k# D' O2 u& u
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    % e3 L) E( f! y  Z' \4 U
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);5 A6 s& h" @  Q7 q2 ~! D
  400.     if(LPDF_OK != ret)
    % c& F4 P- q6 i3 F8 `6 L5 u1 J
  401.         return ret;
    7 L) L# {/ {$ V- o
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    5 q! E+ R4 B8 {& p1 d
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ) r1 ?& }+ e* F7 A% q8 c8 T4 L. K
  404.     pdf->offset += length;
    ' }  x1 W# S: `
  405.     page->length += length;3 A$ \) n. k, \+ g. ?, c+ c3 r
  406.     return LPDF_OK;8 V+ z$ a$ Y9 R: D
  407. }% n2 M1 y% G0 W$ ]- Y/ H/ _  `
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)
    3 ^/ B8 S; o" n0 g9 M. @7 H9 [" [
  409. {
    ) I$ E+ U1 C; f: {1 `
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;% e% d6 F3 A6 S+ R2 Z
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);( A3 v+ G' Z& _/ c2 j. ^
  412.     if(LPDF_OK != ret)
    & [8 t% e" y0 `8 f) x
  413.         return ret;
    * H2 O9 L% r0 x8 q; n& v
  414.     LPDF_FPRINTF(&pdf->file,"S\n");) I  O5 @7 K) K+ L
  415.     pdf->offset += 2;7 {4 s8 u) k& r2 L$ m
  416.     page->length += 2;4 T; u/ P. W1 N: ^) w
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;+ m2 o- M. n( n+ c
  418.     return LPDF_OK;, Q7 e' p2 A# h, |0 m& x! Q& Y  U* q
  419. }6 R1 I# f# r0 d/ e  S; m
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    * _- E; s% ^3 s% G5 ]. C
  421.                       LPDF_Image image,% u1 K/ D1 p1 y4 b- P
  422.                       LPDF_UINT16 x,
    6 P1 `0 \% [) W! \
  423.                       LPDF_UINT16 y,
    & m) @+ H4 z) k
  424.                       LPDF_UINT16 width,
    , r  `3 a) a4 }3 c
  425.                       LPDF_UINT16 height)3 t9 W( N1 @" d3 t' k
  426. {
    6 C  j; l/ T9 |) }
  427.         return LPDF_OK;9 w/ E+ W& Y0 I4 i
  428. }
    ' d  E& [/ R" \* O5 {' t
复制代码

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

  1. pdf = LPDF_New();
    : C& E. ?( A7 s! M$ H, Z
  2.     page[0] = LPDF_AddPage(pdf);
    2 F8 ^; o& _2 |" R- |7 I
  3.     LPDF_Page_SaveParams(page[0]);
    0 K+ \' _* z4 w5 i' ^5 {6 _
  4.     width = LPDF_Page_GetWidth(page[0]);
    8 Q8 W$ }; `, D' g
  5.     height = LPDF_Page_GetHeight(page[0]);1 {0 v3 D* i2 H8 Q" h
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);
    ( D# z1 i3 {+ V& D$ X1 m
  7.     LPDF_Page_BeginText(page[0]);
    8 L0 A) I0 P4 ~) F  a" \  d# G
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);6 O( J" s" B* b3 {- q) `! o3 I
  9.     while(font_list[i])
    - ~; y& T9 b' Q+ \9 q' t
  10.     {3 Z  c' [$ d* {, U$ H: n  W( D4 K
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    0 C9 v5 Q& t! J
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");: C, o# [! C3 `0 o  E: g
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);' ~' F  e+ U7 K% [4 K
  14.         i++;
    + K- A1 J) W0 {
  15.     }
    / v7 f& M+ C/ R7 B
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);7 [$ I- r$ U/ L# E. Y
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());# [# O. l6 s/ }4 e# v
  18.     LPDF_Page_EndText(page[0]);3 ^( u& q0 O0 k9 H' H) C8 w
  19.     LPDF_Page_SaveContext(page[0]);
    . k2 s& _7 V0 x/ c! L
  20.     page[1] = LPDF_AddPage(pdf);7 A* p* D' w! Y  k
  21.     LPDF_Page_SaveParams(page[1]);' S) r: P/ I0 |  g7 @  X) S
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);- O4 ]. g' l: |* a( R. q
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);) J. H& l" Q2 o+ {5 }6 e
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    & ]) O( x* N1 w
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    . H8 p6 u) A* [( O& r
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    , L8 H" p9 F3 R, b, h/ c
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);
    3 ?: V% h* ?$ U4 A
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);
      ?# O1 v8 @! v. \8 G
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    6 G! E9 ]! `. ~- n
  30.     LPDF_Page_Stroke(page[1]);6 D1 r& S8 C' O+ @, O3 B
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    & p, A# ~& ~  ?2 C, t, [9 v- O. B
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    1 B( R3 M+ `+ S. q3 i3 E
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    3 m- v  w; T, n- c# G) }* L
  34.     LPDF_Page_Stroke(page[1]);8 l' C8 f* w6 G) a/ Q6 v5 }( R, [9 }6 H
  35.     LPDF_Page_SaveContext(page[1]);1 ]: y5 ~; _" c5 k! K8 S5 }
  36.     LPDF_SaveToFile(pdf, "/red.pdf");& S8 v) H$ s" H) Q/ s3 n
  37.         PRINTF("\r\nCreate pdf file success!\r\n");, f. S3 e) q; g  B
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了
. R5 c9 T5 I6 c7 ?9 v3 `

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    0 F) R' Y' e) |6 G6 L0 M; I: z/ _9 l
. |" l. H- J* |8 W- Q# u

pdflib_V0.04.rar

下载

6.1 KB, 下载次数: 456

pdflib库

点评

加密怎么处理呀,有没有大佬指点一下  发表于 2024-7-13 16:56

评分

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

查看全部评分

赞 5 收藏 22 评论152 发布时间:2017-6-17 23:03

举报

152个回答
kiki.zhang 回答时间:2018-2-27 10:19:19
anobodykey 发表于 2018-2-26 22:55
/ e# l* H( f0 w3 ~8 S' A2 k9 E只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...

+ J! e# K/ }. S& v& l  gLZ,我怎么没看到有添加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:33
7 K. W6 U: Q+ n5 b8 g9 T首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
, t9 q7 C) M. P  z8 U
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
/ O6 a4 R- @/ |5 a# l5 D2 w
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:457 `+ K/ C4 o. t' n' T8 o( w0 D
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
' |3 d4 L* S9 v  L
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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:44
8 g4 b6 F3 K4 B2 [厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

8 K+ u+ v' ~+ {0 ^; K这个还只是一个简单的库,实用性还是差一些的
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:27
) w# g2 ~' Y% Tff.h在哪里呀,我的是keil4.73版本,需要手动添加吗

0 P, I' P* u/ Iff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:226 N- G5 _. G: `3 c- w" {
ff.h是FATfs中的文件
! i1 p$ n; v* X0 f; A) b" T1 Z
嗯,这个画线能改变线宽吗

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版