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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 ' A4 H; y3 m0 M6 h8 W

( H" M% i$ t6 @- z3 m7 e/ p

主机环境: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__
    2 O9 `4 ?) ~& E" u6 E2 v: M8 G
  2. #define __PDFLIB_H__
    3 V9 v' \0 F+ `

  3. ! ^1 c7 N1 A9 Q+ a  e1 p
  4. #include "ff.h": y: L  i3 m1 M4 k3 P- ~
  5. /*----- standard C library functions -----------------------------------------*/
    2 T5 Z0 ?* B3 J9 }2 m8 p8 G

  6. % T5 Y( i8 y9 y: k" F8 i
  7. #define LPDF_FOPEN                  f_open
    9 c2 M' @/ r8 p" v+ d; v8 o
  8. #define LPDF_FCLOSE                 f_close- o: U  t$ H/ Z9 |8 n$ A
  9. #define LPDF_FREAD                  f_read* e& S; M( M( G8 W# h+ @+ N& x* R/ \3 N
  10. #define LPDF_FWRITE                 f_write( l* L" @' {+ V, t9 @+ R' y
  11. #define LPDF_FFLUSH                 f_sync
    * }% S5 Q$ ~) Y4 P0 x
  12. #define LPDF_FSEEK                  f_seek
    * E8 S3 f; D" H1 T' L  v5 n
  13. #define LPDF_FTELL                  f_tell. K) Q, G$ ?/ P7 E% Z" N5 t
  14. #define LPDF_FEOF                   f_eof! t1 g* ]2 O/ F: H4 k4 ~0 g! {7 R. z9 ~) c
  15. #define LPDF_FERROR                 f_error2 C, F9 u4 [5 G  l
  16. #define LPDF_RENAME                 f_rename
      w3 n' A- [2 G/ I8 N" G% y6 N% T- a
  17. #define LPDF_REMOVE                 f_unlink
    2 q; r0 S2 H( V* L/ i) x( ?) g
  18. #define LPDF_MALLOC                 malloc
    & L+ ~8 x3 N. d' h
  19. #define LPDF_FREE                   free: W6 y( j8 s% Z
  20. #define LPDF_FILE                   FIL
    2 `3 B. F# X8 S2 }) v
  21. #define LPDF_TIME                   time
    : F1 C, \& H6 x5 o* U
  22. #define LPDF_PRINTF                 printf& c. x' l) `9 Y( @3 h( h
  23. #define LPDF_SPRINTF                sprintf: F( m. [1 D% l/ J: s
  24. #define LPDF_FPRINTF                f_printf
    3 x. V  V7 I& a
  25. #define LPDF_VOID                   void+ s5 l0 a- g7 M; A1 D
  26. #define LPDF_SIN                    sin
    8 n! g1 M0 P: Y3 R
  27. #define LPDF_COS                    cos
      e- V! q9 _5 o3 {$ l1 A

  28. : t+ n- L+ Q! K; y# ?
  29. /*  native OS integer types */
    / E/ M- [# m+ Y; V
  30. typedef  signed int          LPDF_INT;% o, h: {, j- {) v* S- y
  31. typedef  unsigned int        LPDF_UINT;
    6 T( z  u6 R) w

  32.   x: ]9 U& H% V: m
  33. % L: @8 u4 w2 O
  34. /*  32bit integer types9 E2 m6 O' K0 Q* q' ]1 j- j; E
  35. */7 F: o$ @! X$ ]& d: k) f
  36. typedef  signed int          LPDF_INT32;% v) ^( H" e/ k
  37. typedef  unsigned int        LPDF_UINT32;5 s1 F9 ~& l3 W

  38.   b& g4 W- [' k" Q6 q5 X
  39. / E( h9 W& V' x+ n5 a
  40. /*  16bit integer types0 T2 ]) o. [0 I, t0 \" V
  41. */; X  F  |" b$ m8 T2 H
  42. typedef  signed short        LPDF_INT16;
    ( F& z9 L$ e$ K, N3 H! ?, Y
  43. typedef  unsigned short      LPDF_UINT16;
    5 z' H) \; D, ^) A" ?# v
  44. 3 f# A/ ?  j. m" n
  45. " S) _8 s/ H, ^0 V& S) N- O
  46. /*  8bit integer types
    9 d+ {' {1 v3 V# o4 d. o
  47. */
    9 g" O2 L% J% C% M4 ]6 B0 M
  48. typedef  signed char         LPDF_INT8;3 ?: {% m4 }) z& S3 p: _" p6 @7 e2 c
  49. typedef  unsigned char       LPDF_UINT8;8 `# B& b; h4 L, `) k& {
  50. ( {1 {; w5 V3 l# x
  51. % @$ Z0 m1 G( s0 C- Q7 T3 y) j
  52. /*  8bit binary types
    4 U8 d5 S) {1 [
  53. */- ]4 u* a) M% E) t" O; `
  54. typedef  unsigned char       LPDF_BYTE;* t( X2 D) j5 _) J7 `, Q2 S6 g, T
  55. ! Z" G! G/ C9 g8 j
  56. 0 y7 K: |) @* T, V! i
  57. /*  float type (32bit IEEE754), _9 N* Z, X0 @) ?9 }  o
  58. */
    $ X; L2 T+ K) ^- m4 h( ~, r$ t
  59. typedef  float               LPDF_REAL;( Q7 d; L$ _0 \' ]. ^4 Z$ y
  60. 3 h2 d2 I) Q& B0 o
  61. ' e& d4 P2 s+ r5 z
  62. /*  double type (64bit IEEE754)
    9 z5 s! s# e4 \- C! [7 W
  63. */( B4 B1 x) ~# V  @& \# e5 q+ y
  64. typedef  double              LPDF_DOUBLE;# G2 v' \6 p8 d2 p- v6 C' T
  65. ! I! m; w: r  \- Q2 ?3 u% M2 z4 n( l

  66. 1 ~+ I; U- }' D  @- Z# Z
  67. /*  boolean type (0: False, !0: True)
    " J6 J0 F5 ?4 [+ n0 C: G
  68. */
    : M3 |0 w( P: T0 ]
  69. typedef  signed int          LPDF_BOOL;
    / m: _% X& ~+ t5 e
  70. % q$ ^, ^8 ?3 w# f+ H9 T& r) p
  71. " H7 s8 S4 A6 d0 L; u' V
  72. /*  error-no type (32bit unsigned integer)
    0 z3 V, l( i  |6 I8 X2 v7 e3 y% n( }
  73. */
    , K! [  z2 y( X0 V  U" m& M
  74. typedef  unsigned long       LPDF_STATUS;
    5 Y4 u* R: I2 R) J! X. t

  75. ; }& K7 z. ~( Y( T2 o* M  ~
  76. #define LPDF_OK                     0
    7 ~/ Y7 R; i( M. z) }
  77. #define LPDF_FAILED                 1
    / U4 l/ x0 \" @

  78. ! P+ p  U1 j" z/ \- Y  h1 `
  79. /*----- font state -----------------------------------------------------------*/1 U8 q3 D- p5 _- }
  80. #define   LPDF_FONT_INVALID                 0x00FF
    # _3 F3 q4 v4 f! ~/ `5 k2 k
  81. #define   LPDF_FONT_COURIER                 0x0000
    & ]- L- j% L4 E, j
  82. #define   LPDF_FONT_COURIER_B               0x00012 e* q8 s; W3 o  I8 a! D
  83. #define   LPDF_FONT_COURIER_O               0x00022 i+ r  M. G' J$ r; e( ]
  84. #define   LPDF_FONT_COURIER_OB              0x00037 \; ?) A5 M/ m% N: S' v+ K
  85. #define   LPDF_FONT_HELVETICA               0x0004
      F) {* U2 m, l; ~  n' ?  S* H
  86. #define   LPDF_FONT_HELVETICA_B             0x0005
    " v6 O' \. _! \1 {% R8 W; T
  87. #define   LPDF_FONT_HELVETICA_O             0x0006
    3 b' q0 y. T. X8 t
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007
    % ]3 J! M  |: G6 ?$ Y. w, ]
  89. #define   LPDF_FONT_TIMES_R                 0x0008* X2 U- K; r4 G3 R' d, g
  90. #define   LPDF_FONT_TIMES_B                 0x0009  l( i; c) ~$ A, e( r
  91. #define   LPDF_FONT_TIMES_I                 0x000A# |& P6 L. l' K/ H, w
  92. #define   LPDF_FONT_TIMES_BI                0x000B' h5 t. c8 O8 m1 O' I- X
  93. #define   LPDF_FONT_SYMBOL                  0x000C: _7 H: y# F: _
  94. #define   LPDF_FONT_ZAP                     0x000D
    # T6 w( M- \8 L& t6 A( X4 j
  95. /*----- Graphis mode ---------------------------------------------------------*/
    2 u$ F9 n8 l* ~0 O% j# p5 d; c
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001" |' d4 o" u1 m) d5 k7 k! u
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    4 {: @/ H* Q. L' @: H
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004) e. t3 ~3 D. A) l' g+ C
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008( j6 N! v) V6 V$ E+ v% p
  100. #define   LPDF_GMODE_SHADING                0x0010
    . x( R: D7 {4 `( T( `
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020
    ' ]" n  N+ o: p6 P1 u' j+ m
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
      s' b7 R& F+ ^* }
  103. #define   LPDF_GMODE_INVALID                0x0080- Q" q' X' m& b( a
  104. #define   LPDF_GMODE_OVER                   0x0100. c$ u. `' {3 V) e; Y  @) _
  105. + _/ v* o' I2 w  g6 M
  106. #define OBJ_MAX_NUM     256
    # Y+ g" W2 e5 Z

  107. 0 _% m9 ?* x3 f* U
  108. /* Page的结构信息是否需要树形结构 */9 @; K1 T0 b. v
  109. typedef enum & K0 r$ ~/ G( V" r* W# y. {
  110. {
    ' l  |, ]+ f' `- [" c/ |1 O
  111.     OBJ_info,0 U3 `# C2 |: F/ k
  112.     OBJ_stream,
      g% I9 F- U5 E* z) }2 F
  113.     OBJ_font,
    3 U5 b- r3 C& s  ^
  114.     OBJ_page,
    / c- O# A+ Q1 w. v  i, A
  115.     OBJ_catalog,
    8 F5 f& o/ D$ b% J; u! T
  116.     OBJ_pages,3 E4 p6 J' R2 m& S5 n
  117.     OBJ_image,
    # E0 n6 i8 n5 I( e  G( ~8 B5 `
  118. }LPDF_ObjType;
    " }: P' W4 u! |  B
  119. & Y3 b. v$ t7 S3 W4 Y, t
  120. typedef struct
      N0 `8 l' B, H3 Q
  121. {
    % i9 P* g# D" }4 f* I2 b" M3 I
  122.     LPDF_ObjType objType;
    . F+ |, l1 e; i
  123.     LPDF_UINT16 objIdx;6 T2 |- A. X$ E- {7 Z/ J
  124.     LPDF_UINT16 height;
    3 B) M2 ]; |; u" v* ^) x0 i
  125.     LPDF_UINT16 width;: L8 J1 r- z" R& z  f
  126.     LPDF_UINT16 length;
    , Y+ p) \! [8 j! P- O6 b9 F
  127.     LPDF_UINT gMode;
    9 p+ k. w: v' d9 x2 X8 c- t! m" D
  128.     LPDF_BYTE fontType;6 I6 O0 \1 I0 E0 E# j1 t6 b
  129.     LPDF_BYTE fontSize;
    8 A% w" z3 l# |
  130.     LPDF_BYTE pState;% ~/ Q7 i7 Q# b. u5 L. _
  131.     LPDF_VOID *doc;" |, e! _7 }5 k! k6 R
  132. }LPDF_Obj;
    * E8 M0 M. s& O7 n/ A

  133. 8 J) H1 ?+ ?: ~9 Y3 |6 c; c
  134. typedef struct! ~1 W: {2 E) ^6 N& V2 n* r. ^) U: }
  135. {( Z. {3 `6 m2 m& w& [! [0 d4 W5 q
  136.     LPDF_Obj obj[OBJ_MAX_NUM];
    . I/ r5 T3 H0 r! O
  137.     LPDF_UINT32 offset;
    2 y9 E6 }1 x2 y5 ~  y6 A
  138.     LPDF_UINT16 objNumber;
    , C$ r0 J9 E: j6 m; ?
  139.     LPDF_FILE file;! j  T! z: i) }9 j* l+ k- {
  140. }LPDF_Doc_Rec;8 K1 ~. R) S' Y7 y; ^' ]) x

  141. 9 {" c& R# A1 e( F+ Q' k! ?
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    ' C8 Q0 b4 ~2 |) n0 ]5 o2 j* t0 Z: d
  143. typedef LPDF_Obj *LPDF_Page;. {8 N3 m8 A3 n1 n. T2 L
  144. typedef LPDF_Obj *LPDF_Image;& Q# E, C# H+ y
  145. extern const char *font_list[];
    ( {# q0 \9 G/ m
  146. /*----- LPDF Interfaces-------------------------------------------------------*/! T3 k( f! ^5 q, x) I1 c+ h  z
  147. const char * LPDF_GetVersion(void);
    5 j& R: T* z* i7 [+ r
  148. LPDF_Doc LPDF_New(void);  W" N* o; z% R: k9 [0 ~) s
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);
    5 ]1 G% i5 `" y2 U% h7 X7 s
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);
    5 x* G% `3 ^, y1 o2 g
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);
    4 B: X- \  ]9 r. O0 Q5 m1 K
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);7 ^  H% x, s# L& k
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,+ O% Q4 @. s. i# S
  154.                            const char *font_name, LPDF_UINT8 size);% }( E$ O) v4 [2 h
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);# E. q8 i5 G) M0 M( K' y4 R/ P! a
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);# D& a8 W5 q5 |
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);
    5 s* V; y+ _# Y  Y) G* x/ \7 O
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);; _1 g6 Z: y; ?/ `% f& g+ i/ T
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    * l2 Z4 D; \, W' P9 M! P* X
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);
    ) C+ b8 R/ a! s- v
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    9 P: U% t+ s7 \9 ]
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);/ U- W/ b. i/ |
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);
    6 H6 c9 q8 y5 |$ t2 Y1 N6 Q
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,: q- d) m; X0 o& ?( n
  165.                          LPDF_INT x, LPDF_INT y);
    ( v( K5 X$ R& r/ A9 w; r
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    9 j+ p6 Z1 A2 Y) @1 n8 s/ ?* o
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,. Q; e  Z5 f( g! u
  168.                          const char *text);$ D9 A) D- V* O9 Y  G/ }+ n
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    5 K6 _4 d& n% e  k# d, m6 x$ |
  170.                          LPDF_REAL r,
    5 d  b1 A! Z8 o8 ^0 w; j! S# L9 `* ~
  171.                          LPDF_REAL g,7 I+ P/ x& Q8 C* {
  172.                          LPDF_REAL b);7 c$ F- c2 C0 q) L, K  t4 j' z
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page," O. M! S1 s( j2 a: l
  174.                          LPDF_REAL r,2 S& p) @( V0 L% W$ e
  175.                          LPDF_REAL g,
    - I" A; V  K4 \
  176.                          LPDF_REAL b);
    6 M+ D1 N/ j: @( ~
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    ' |6 q% R/ j  V) K( B& [
  178.                          LPDF_UINT16 x,
      t, ^0 U- y3 O- H2 r
  179.                          LPDF_UINT16 y);# `7 h0 I6 {1 o% ]) L* C  _
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    ! p* d( m% ?0 T2 i2 ]- z$ i
  181.                          LPDF_UINT16 x,
    % ~5 c/ E- q* H1 u; r2 j! T
  182.                          LPDF_UINT16 y);
    + U6 l8 G! q1 E& \) \
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);
    / O# k8 ^" c5 w. m6 C
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);5 S" T' K- E6 B# v
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,: H* h. p5 n& ^; I
  186.                       LPDF_Image image,
      D9 d0 K+ t( K# o
  187.                       LPDF_UINT16 x,2 J+ Z  O9 ~  ~6 i1 _& U
  188.                       LPDF_UINT16 y,, `: m  m' T- F) p& A1 `# G- x
  189.                       LPDF_UINT16 width,: L3 `6 F% A7 S1 m
  190.                       LPDF_UINT16 height);0 u9 Z& n6 y2 M
  191.                                                                                        
    ; s# o. l% R$ E. c1 g* B$ q
  192. #endif1 _: v5 u1 E, M' y3 e$ \# s3 w3 ]
复制代码

源文件如下:

  1. #include <stdio.h>
    ; L% ^2 s# U3 U
  2. #include <stdlib.h>
    2 a% g% x. i! _; a0 X
  3. #include <stdint.h>8 P3 v& K( ]% H0 A
  4. #include <string.h>6 M8 i3 g5 z0 {$ O5 J
  5. #include "pdflib.h"4 }% e8 e% l9 j$ B2 a

  6. ; G7 m9 Z- I4 c7 ~. ^4 N
  7. #define LPDF_INVALID_OBJECT                       0x10336 f$ X  c0 _1 S/ b# h. _
  8. / v, L6 j$ D  P9 K4 C. B
  9. static char pdf_buf[512];
    2 }: R: q3 ^3 R$ D; `- p, s
  10.   s: f8 b8 X( d% {
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"
    3 g% b& {9 `1 G/ u! L8 [6 e( g9 S
  12. #define LPDF_FILE_HEADER_LEN        15* b+ H' W% b, g2 F) h& v6 w) H* X8 A
  13. #define LPDF_BASEFONT_NUM           144 j; A/ `+ J- O) ]- D0 M
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";' p7 f/ v% n- }+ j
  15. const char *font_list[] = {9 U6 ], O- g; u
  16.     "Courier",
    4 H( |7 P/ j7 @$ b1 o9 O
  17.     "Courier-Bold",
    ( i+ p! y  ~8 \% ^% j5 @" u) d
  18.     "Courier-Oblique",
    9 m8 h) c$ `" l- F/ n; Z
  19.     "Courier-BoldOblique",# N7 ?2 a- H* c/ S
  20.     "Helvetica",
    & {4 E1 P$ v5 T' w  n# h0 N$ |6 d) Y
  21.     "Helvetica-Bold",& J! D# E/ i# l; V! c
  22.     "Helvetica-Oblique",
    - q9 j$ t2 k4 f- U( n0 Z
  23.     "Helvetica-BoldOblique",. e6 n5 x; v  U/ Q/ v( C9 _, i
  24.     "Times-Roman",! U0 L$ ?1 {/ N% b/ W
  25.     "Times-Bold",
    ' ~5 o8 Y+ i, N6 G$ ?
  26.     "Times-Italic",% V: q. M5 u4 A4 F2 S2 E3 H
  27.     "Times-BoldItalic",
    5 S) F/ x9 V+ e7 G! C4 M
  28.     "Symbol",  a8 a# `3 W9 t0 Z2 p  ?
  29.     "ZapfDingbats",% |; k1 A. l$ R  S
  30.     NULL/ g+ b# O2 b6 ~+ W- ?& c% a
  31. };$ `$ y9 J" S/ }& K; u
  32. % N5 |! N5 n0 s/ G* {
  33. : z* J5 T" Y& N/ ], Z
  34. const char * LPDF_GetVersion(void)
    # M! P1 c2 ?; O3 b9 a5 g1 x
  35. {* h* l: a8 r1 P  v4 R$ ?, q6 d  ~! y9 e
  36.     return LPDF_VERSIOIN_TEXT;
    % {8 C; t- o; _7 t, f: M
  37. }
    7 Q7 r  F  e+ P$ Y$ a6 Q
  38. 9 t' c! p) L7 s5 N6 ^, C
  39. LPDF_Doc LPDF_New(void)
    ! X. z6 g9 u8 I2 x
  40. {3 F* [- e/ O/ e
  41.     static LPDF_Doc_Rec pdf;
    " N# u0 R# r% K1 j
  42.     LPDF_INT length = 0, i = 0;
    + [% E7 {3 c2 o& C4 {2 M# T
  43.         LPDF_UINT writeBytes = 0;
    1 O1 |9 I- k/ W) [
  44.         FRESULT fr;# L* Q! b8 P6 \2 W3 ^# D6 g
  45.    
    2 N2 d. W7 t1 W5 q/ v& C
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
    ; t$ f7 l7 U( D; S4 u/ C
  47.         if(fr)  [2 x4 x: {0 H- \+ t' S2 G
  48.         {
    + y1 q4 w. e9 D. G# S+ s
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");7 l, w3 E2 M$ \* f% Q
  50.                 return NULL;
    ( L5 n1 }! S. x
  51.         }4 r( A" ?3 |9 h/ B) t9 n
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */; G) F  q+ U) o; Z5 p3 l
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;. O; C* o. @. _( g& U$ }- p$ ^
  54.    , @4 L+ G1 |9 `
  55.     pdf.obj[0].objIdx = pdf.offset;8 c; v8 l1 t& Q' ]% _
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");2 f4 M& u6 S8 h. o8 A3 ?) j: x
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);7 q5 ^3 S. H! D$ f# M- ^0 w
  58.     pdf.offset += length;2 n& o' g# S/ J
  59.     $ l4 X2 \( {# \7 ~: J; w3 W( h! l
  60.     pdf.obj[1].objIdx = pdf.offset;2 v6 H: v" \. _+ C& g
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"& I! b: D9 @: [* H5 ]+ J% T2 b/ Q
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");
    9 s! Y( ~) @0 L) V* C  v# _
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    7 T6 f: ~' j. v1 ^' H& j7 {% h9 U! \
  64.     pdf.offset += length;! B& R% t2 F2 t! j8 U6 [
  65.     , \, d0 y# _0 d7 B) A
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++), `3 H* N- \" C1 E5 ]8 M+ z7 x
  67.     {4 n( Q* v2 v* W0 j' m
  68.         pdf.obj[2+i].objIdx = pdf.offset;# B. V, y- G& z% P
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"( e: C) L' D$ l3 P' O
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
    " N/ e  |: k8 R
  71.                         "endobj\n\n",3+i,font_list[i]);
    4 ]9 `- y1 p' ~. p
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    $ Y- q* K5 ]" N1 e, o
  73.         pdf.offset += length;/ B$ l/ ^& b- {" m
  74.     }
    ' d2 A& l1 j) g6 L. s: l1 _
  75.     for(; i < LPDF_BASEFONT_NUM; i++)
    : ~9 Z, T2 g) q/ i
  76.     {4 B, U- n' O* o8 h# x& r% H
  77.         pdf.obj[2+i].objIdx = pdf.offset;- F$ ~5 [: p# K2 A1 I! O, o& o
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n". o6 @  l5 G3 V& _. E
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
    8 o; G* g! Z8 `
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    " P. R7 h0 `* L" r# N/ X6 D
  81.         pdf.offset += length;
    ! \" v) ?$ S. m* E8 y+ V  z+ g
  82.     }
    5 s/ q4 L, o& |3 s1 {' W
  83.     pdf.objNumber = 3+i;
    3 o, G6 e. H: ~2 ~/ J1 ]' ~
  84.   
    1 t: B" j/ g: W$ O% h- w
  85.     return (LPDF_Doc)&pdf;
    " k; m5 U: D- S: p5 ~% G% y6 H
  86. }2 [& E; k* `: X* B: ^
  87. ' H2 C# @) F  e9 L2 m' ?' Q
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    . ~7 E0 @( b2 c) l) |. d
  89. {
    $ @" R- a0 q' T
  90.     LPDF_UINT16 i = 0, child_pages = 0;2 T! [7 ~9 y4 c$ ]7 H+ t
  91.     LPDF_INT length = 0;' ?/ Y2 ]0 {3 Z' ~% o* y& L
  92.         LPDF_UINT writeBytes = 0;0 D' z3 f7 X) ?; m: B0 P
  93. 0 n# d# G4 ?. ?4 Q" ~, E  O
  94.     pdf->obj[16].objIdx = pdf->offset;) y; q; D$ b0 `# [+ k) U7 m! T
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;1 a. z6 ?8 b! V! |
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);! F& y* ~1 M/ w; S$ i2 V
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);. H/ s! Y% d- d) c6 m
  98.     pdf->offset += length;
    0 j: j$ t/ A1 x* ~9 D) v/ [4 q9 N
  99.     for(i = 0; i < child_pages; i++)
    ! ?( `+ m2 v( a; b
  100.     {7 y4 O. V! k3 d# L; T- N) ~$ d
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);7 U& q1 ~) L, M
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    : O: O: w/ }, |2 P
  103.         pdf->offset += length;. I( Z* d) D$ m, d( F
  104.     }' i6 _+ Y) V) ?' G# q0 q
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");4 P# \7 d1 ]/ P5 T) s
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    - Y- i( i9 V7 b
  107.     pdf->offset += length;, m9 R* W; e( l) p: X: p. t% R% ~6 f
  108.     3 W' [$ s9 n% H4 M6 v- z; r
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    + R5 k* v6 e" O0 Y, z8 s+ |
  110.     for(i = 0 ; i < pdf->objNumber; i++); y; `* o. v0 j; A
  111.     {
    3 r! Z9 n  {( {: A
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    $ X5 s8 c9 l( E3 t- P1 l0 U
  113.     }
    . P* @2 M  W9 _; V' A% J% R: M
  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",7 w' v- Z+ |- P2 u/ a, {
  115.                 pdf->objNumber+1,pdf->offset);
    " o2 s* `& k0 O' C% T
  116.     LPDF_FCLOSE(&pdf->file);
    7 Q  F- y/ O: F, m
  117.     LPDF_REMOVE(file_name);( ]- f0 k- b) [" D$ G
  118.     LPDF_RENAME("tmp.pdf",file_name);1 q+ M1 _0 f8 U0 }+ S9 o/ M
  119.     return LPDF_OK;
    3 E, `1 f- k' c
  120. }
    & g' [. B  [- H( a! J9 _

  121. ; V3 }0 [$ h% j% G6 I
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)! s2 Y0 m) M4 Q' a3 f! o* ]
  123. {
    8 @$ F) B% _) j; ?6 R) h
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);
    : Q2 I8 B0 T7 n% }8 Z
  125.     return LPDF_OK;
    : n; l4 x9 {3 u' p0 b1 m# v+ L
  126. }+ L" m* y3 ?* x6 S5 _* y$ e+ Q
  127. " H4 I. Z2 y& H0 K$ ?' u, f
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)5 k' H3 {4 J% c+ T0 E
  129. {9 l1 Y/ y5 l* h  L/ k+ D" u
  130.     LPDF_INT length = 0,i = 0;$ j3 g: H/ c) F! b& S
  131.     LPDF_Page page = NULL;
    9 d: s9 v  N: O4 }: P+ l4 ]
  132.         LPDF_UINT writeBytes = 0;/ J% l8 {% S; x) o- Z  k2 x
  133.     % \/ u$ _4 ?9 l
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    2 t, M! K/ }$ Y' X! W" X, y; h4 i
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"
    ' l2 z% a4 n% K2 ]$ z
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"1 _: T" O9 n6 w7 b* K
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    1 ^+ Z, N$ T$ B& J
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ) `: }. p6 X( a* u) A
  139.     pdf->offset += length;& [5 H4 U  A8 x5 ~$ ?
  140.     while(font_list[i])
    " L- M* C( p& s' }* t& Z, h1 w
  141.     {
    4 m: F3 h, T5 ?: f
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);, `+ g! f' s7 T
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    % e, r, V! b+ D! O( ~  r
  144.         pdf->offset += length;; t! o/ p! D( z/ d
  145.         i+=1;( |" H/ ^4 G, o( U9 O6 \
  146.     }1 D; u4 D- V- d# j$ M
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");0 p6 U) N' E% Q9 Z. g9 c9 ~$ G5 B
  148.     pdf->offset += 4;
      c" t9 z; ?# @" R" W
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];9 B: B8 V  H- s; i7 }
  150.     page->width = 595;
    " y) a# U. X% X% F5 t, g
  151.     page->height = 842;
    1 K& H- C2 Q* o0 K" M( v
  152.     page->gMode = LPDF_GMODE_INVALID;
    + R' @# n/ }6 U+ b  m; F
  153.     page->fontType = LPDF_FONT_INVALID;8 J) e9 c: i* h, P" E# q) t- I
  154.     page->doc = pdf;
    ( y1 A' e! t* ]0 K+ I/ @
  155.     return page;1 P) r# ^% ?; H0 K4 F
  156. }
    9 a) k- \: y& ~

  157. : h9 C# o& k1 y' h
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)7 A4 N+ k3 y& l+ E) C4 u& m# I
  159. {
    9 x* C& z; S( J' x
  160.     page->height = value;6 \# p  @( d( d' \
  161.     return LPDF_OK;
      V3 E! q/ e0 O7 J
  162. }
    ! G( U( k4 {1 d) x! m& |
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    # M+ [5 `  F7 O; f! L
  164. {! C  [8 t* p+ S. k! ^  b& P
  165.     page->width = value;7 a" ^/ f/ l. Q
  166.     return LPDF_OK;4 O- H- w4 \; R
  167. }
    5 Q2 x0 h* B% \9 N# \
  168. 5 ~/ `  B% o+ P% X4 h+ J
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)
    6 ]0 e/ R9 v% m6 U
  170. {
    " f/ w: R) N0 M
  171.     if(page)
    1 m" k( x1 w/ a. i+ \
  172.     {$ d5 @3 g7 [8 V2 W  R  C
  173.         return page->height;
    5 ~% w; B0 `" \9 r5 Z; b
  174.     }) E3 N2 a' p! {/ [7 M' ~# ~
  175.    
    7 I4 j; q! r  s$ k
  176.     return LPDF_OK;2 k5 S! S9 X% e4 H5 Z- O
  177. }2 @( z& d8 j* O; ^; F
  178. ; z' O5 a3 W' O+ b
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    & T# |$ ~0 t8 W8 C9 R
  180. {
    * I% p/ ]% H! {  a# e
  181.     if(page)
    / P# Z. F% d4 J( {- L: Q
  182.     {
    0 M. s* G6 c1 @4 M* [7 ~
  183.         return page->width;+ m% e" W" X! i% i' c# _
  184.     }
    ) S" G- u: Z, h1 s+ M7 O, P* E" [
  185.     ! D) r5 R0 I' I, \; r& X
  186.     return LPDF_OK;; J- E4 h6 f  \8 m% l
  187. }
    # V; Q) h, V3 \4 y5 P' I2 `& J

  188. 6 e  _" `6 Y; m" R
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)9 M" ~2 E. V7 t
  190. {
    - U8 U$ E" {  H3 I% D8 [5 O3 H
  191.     if(!page)
    ' D3 `, e$ E% o3 a* N( _; k# s
  192.         return LPDF_INVALID_OBJECT;
    . E7 @0 M( @0 ^# W4 w% W. D7 B7 J
  193.     if(!(page->gMode&mode))
    / t* i0 }* b( _: b' ?2 J3 o
  194.         return LPDF_FAILED;7 o2 i( m9 K" D2 w  Q

  195. # S% q, }7 ^/ y8 n/ ~
  196.     return LPDF_OK;& R9 U) ?( k7 M! J# O" w, |
  197. }) ~2 Q7 f2 v" L; ~

  198. 7 a, Y. U$ |5 }7 S' F  @4 Z
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,2 y* b2 g8 ?4 p2 a2 W
  200.                            const char *font_name, LPDF_UINT8 size)
    % u" P* e. {: c" J" c3 l
  201. {( R: R4 S$ \: \0 r" F" I7 y
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;0 U7 N) i7 Z5 d- D; X; r$ w- W& V
  203.     LPDF_INT i = 0,length = 0;
    6 h- t4 W# z" b4 u9 I. b$ Y
  204.         LPDF_UINT writeBytes = 0;
    1 M2 y$ t+ q) J# ^% Z" a
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    # M+ j8 g- u0 B7 ]; J8 s/ Q
  206.     if(LPDF_OK != ret)
    4 e; |, y2 X6 _8 o4 p9 o- B
  207.         return ret;& g) U8 t( w+ A9 u, B
  208. * I5 ~, T4 X* D% n: ]4 \  ^
  209.     while(font_list[i])8 ~0 s" M/ i# a. i; s( H) c' S" n- c
  210.     {
    ( J9 r+ G# B: @) g
  211.         if(0 == strcmp(font_list[i],font_name))
    2 `- r* ]! N8 x8 M( t1 Q3 |" U0 t( g
  212.         {
    5 k2 z' T2 y, Q2 l
  213.             page->fontType = i;3 o: i  k4 n( ~& Q% {& u; R
  214.             page->fontSize = size;
    , }' j5 h' w* h9 e) H% L0 {
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);! c! e. L% X4 O( e; G  @, w2 a
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);# R; _- U( H  [  i1 s, q
  217.             pdf->offset += length;
    ' `- [: k+ V, W. u1 G
  218.             page->length += length;
    3 g. _; z2 i# |' L0 C4 q
  219.             return LPDF_OK;: E% N% P2 m1 ^: y0 K
  220.         }) t! h0 B) Y# w  d# @/ \
  221.         i+=1;6 {& q% `$ |1 N2 m; h  n" i% z4 Y
  222.     }0 D; X7 `: H& m7 b4 F$ M2 X
  223.     9 Q  C/ ^6 s- B( ^& q$ w
  224.     return LPDF_OK;6 D: o5 Z" U6 Z( n* X# ?7 O( v7 j
  225. }- ~4 s7 z, o0 v, C9 H
  226. . D0 p) ?9 b. ~2 w( v
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)
    3 c) |. F% K& `: g
  228. {, o' G$ W7 ]  h0 o
  229.     LPDF_INT length;
    . r- o9 T, w' g7 N6 U: ?( _
  230.         LPDF_UINT writeBytes = 0;
    " H3 S8 f& V% c: u& m1 P! c6 Z
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;, y4 U& y1 s- L8 [3 `" E' b
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);9 A! V5 s' F; z! j9 l
  233.     if(LPDF_OK != ret)
    + F* l; M" [5 [
  234.         return ret;8 [# Y4 P' g! _: `
  235.     % V1 c$ B* E, q! I1 D
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */
    3 O- Y2 ~4 G5 D: U, l$ U0 x8 E& T
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",% c  ^% a+ @2 y) m
  238.                         page->width, page->height);
    5 S- t/ V) P5 P' R6 g; M4 O! ^
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);! W1 J' S9 R4 [
  240.     pdf->offset += length;
    - C0 n" d1 ^, z. I8 }( M: S
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;- y( Z# p9 o" Q9 Z: u
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n"," {& \9 J* s1 r& c5 r
  243.                         pdf->objNumber+2, pdf->objNumber+3);% d! m. f4 h% M. v2 x0 ]
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    . n# N1 C' x4 i( h; D! J, e
  245.     pdf->offset += length;8 m: c/ C$ a1 t0 T; z
  246.     page->length = 0;' E0 B. m" w% B+ v6 G" M
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;) u/ W$ u+ q" S* T+ W4 b* v, }
  248.     return LPDF_OK;) F6 L$ U8 o5 |- S0 b  s7 K
  249. }
    & X: L3 k! f- g1 q; m; Y$ ~% n

  250. + q2 o8 B4 o: I. _& n
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)" w$ v* Z( s% s) A$ d
  252. {2 D, ?; ^3 x3 r4 ^7 W0 ?2 G
  253.     LPDF_INT length;
    . A$ N) z! p0 u" P
  254.         LPDF_UINT writeBytes = 0;. p, B( w' n, l+ _1 K
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    . u  u+ F9 p4 U6 D
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);  O- Z+ g8 `, h) _4 L3 \
  257.     if(LPDF_OK != ret)0 k/ x. w4 O& k( V
  258.         return ret;9 |3 @' Z  V1 B
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */7 N8 O+ z6 S" k; E0 ~2 M6 s: D
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");) s+ e% I( u: w6 U8 L6 r1 e
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    + [1 i, d& W0 Z9 T( v# H
  262.     pdf->offset += length;
    2 O) W& q9 b& h( u* |% i
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;/ o$ L1 i8 e" Z. d
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    6 [( U7 F) E3 R2 a" e
  265.                         pdf->objNumber+3,page->length);
    0 |3 R5 `, U0 F& d4 V3 L% i
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);- q. X7 V; }/ a8 q! A) u
  267.     pdf->offset += length;
    : [" ^, `% r! M9 ?( _7 u9 H" W+ W- j! ^
  268.     pdf->objNumber += 3;0 ~" E9 m) c( {# q3 J
  269.     page->gMode = LPDF_GMODE_OVER;
    " O& e  C" J6 q( i& I
  270.     return LPDF_OK;
    ) A: U: `+ ^; W* P
  271. }
    7 x5 ~$ K# x3 }1 w: M4 I
  272. 1 Q$ M, ~( k. }# u2 E7 P- @! A
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)' ?, P) l8 J& i, x
  274. {
    / V; a0 g" a( P- F: L9 [
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ) @( t; z" v* T
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);# A8 }3 l' ], V0 ]* w
  277.     if(LPDF_OK != ret)
    ' ^7 R; K% W) \
  278.         return ret;$ x5 c) ]2 [) X
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    7 y* D- E- q7 T: t: |+ w
  280.     pdf->offset += 3;6 E8 ?+ L! Q6 `- R
  281.     page->length += 3;
    $ |: j9 @/ j9 M+ @
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;. ]2 @; y0 r5 U0 d
  283.     return LPDF_OK;
    6 o+ ]5 y& o5 n" o, G9 k* Z9 D5 n) q
  284. }0 x# Q' h* L9 l2 @8 C. E
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)" A; H+ S* I' F  A9 q* S) a
  286. {
    8 d. h8 G' z2 w$ i
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;3 U( A) V; ]/ p2 \" X
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    + {9 ]/ a8 O. `8 @
  289.     if(LPDF_OK != ret)) W2 V! b& |( S- |9 H9 C1 I
  290.         return ret;
    6 \! ~, K( i5 h
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");5 n+ w% B" I7 s- g; \( B: Y8 \! M5 _
  292.     pdf->offset += 3;# W4 a4 b5 e, @& _
  293.     page->length += 3;
      y; w" m  n! @  q' B. D
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    8 w: X8 o  [9 R% z. N- e
  295.     return LPDF_OK;, Q4 R6 e- ]! ?, S, n" g" _
  296. }6 y: i: r% j8 Z2 y  X3 `8 B& {

  297. ) y, p) Z5 Q! I' g7 h
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)/ H- b) h+ T7 S1 I
  299. {
    & l4 @/ ~% Q! {# M! ~
  300.     LPDF_INT length = 0;) O% q2 n; S2 g+ t& b
  301.         LPDF_UINT writeBytes = 0;, @1 W0 l6 F3 ^+ L, i5 I. K6 H1 W! P
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    7 ~2 R# x( r! i& z0 L+ m7 e
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    0 O6 A. p' O8 W5 }8 g9 E! u
  304.     if(LPDF_OK != ret)5 X7 B6 f) x7 b5 s; M
  305.         return ret;& y- ?7 Z/ N* p/ A% c5 i
  306.     if(LPDF_FONT_INVALID == page->fontType)6 |2 p9 a1 E( f  l: i3 Q% O
  307.         return LPDF_OK;
    1 v, ?  n( U' B% k' O
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);
    % d, E: {3 g+ t, ]& O9 @1 o
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    8 n: o; V, m# ]: B3 W
  310.     pdf->offset += length;
      Z5 T$ G7 K: w- ^' s
  311.     page->length += length;
    ! P9 K# c; `( M6 b
  312.     return LPDF_OK;
    & e* Q5 J* i5 H) e+ t5 Q
  313.    
    1 J+ U7 u: C' S3 `# ~
  314. }0 e8 D: k/ w3 ]- \# L
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    6 I$ d7 F# I5 Q9 y* H
  316.                         LPDF_INT x, LPDF_INT y)
    " _8 v0 W$ w. `) w( T% v
  317. {
    : O$ u- e; ?  V% P9 V2 e" v  U( L
  318.     LPDF_INT length = 0;* i4 o; W7 Z. S
  319.         LPDF_UINT writeBytes = 0;6 G: i9 q* K* p% L# K% `' J
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    + e6 U, d$ q0 p" f. _
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    , r3 X0 J; z* `2 P$ j; h3 d
  322.     if(LPDF_OK != ret)
    8 `! m' u! r$ q, {; E
  323.         return ret;
    5 Q  |; U! U. I, t, P
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);
    ! ~1 V" m% ~# X
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);6 t- @) {. v4 X' N& T
  326.     pdf->offset += length;" C6 }8 ^1 B1 W5 y/ E) i2 }
  327.     page->length += length;
    5 h$ P9 L: a9 \

  328. ' |7 Q7 X  H! N* N' ~, M* W
  329.     return LPDF_OK;
    7 l# e/ I% N. |4 n! F  s5 K* c
  330. }
    - Y' {0 a. u0 ]' R) N( p' P1 ?
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, * e$ ^& e) t' [
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,
    " V0 |3 r3 W2 ^
  333.                         const char *text): ]/ h% R8 G7 {0 @
  334. {* }9 P' j# o; ^3 Y9 V
  335.     return LPDF_OK;
    - A0 o1 p1 A0 U0 ~
  336. }
      x6 h5 W6 I+ i- y% G) P
  337. 9 O) b0 i) v' B. h  F3 w$ \
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,7 {# ?+ ?; K( W; H1 ^4 u
  339.                          LPDF_REAL r,( j. S# Q8 s5 G3 O9 u6 H" {
  340.                          LPDF_REAL g,7 \- E% Q8 d! |' U3 ~
  341.                          LPDF_REAL b)
      s. i( q8 h3 H. X. t1 g  X
  342. {5 z0 Z4 q% `5 e+ A: N3 W
  343.     LPDF_INT length = 0;
    ! j8 f8 j: _4 h5 U* k, |( K) a# L
  344.         LPDF_UINT writeBytes = 0;- B2 {9 ]( ~; H9 }5 l% U
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    $ w2 O& D2 ]4 I, H
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    & _# b! [" M/ Y1 |0 T" O
  347.     if(LPDF_OK != ret)
    ; F. u) z' ?7 b1 c9 r
  348.         return ret;
    . H1 |2 Y! P: g( u0 _; v8 U

  349. & |  R4 A7 m# P; Z) N$ }5 Q, H
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    4 V' |/ ]5 z9 R' [4 f
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    3 m; H4 g( A5 ]. j9 |4 l
  352.     pdf->offset += length;' b, |: w2 h5 S
  353.     page->length += length;4 r: J# t4 d7 U6 V3 C9 i
  354.     return LPDF_OK;
    ) Y; O7 D( B6 O0 v
  355. }
    # y4 I' k( K5 {; n3 R
  356. , J: m3 t( Y% p  u
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    4 @$ w2 C4 \. E1 e/ G
  358.                          LPDF_REAL r,; Q6 W6 `# [% ~
  359.                          LPDF_REAL g,. `  d4 |* N; R8 t
  360.                          LPDF_REAL b)! a. P) j' \- l; K+ F7 K+ L  t2 c
  361. {
    2 I. G1 c2 w! ?, p# ~( i
  362.     LPDF_INT length = 0;
    . e: J" S3 x  S  _
  363.         LPDF_UINT writeBytes = 0;
    ! A9 p8 D- U$ v4 b( V" t
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;' V/ Z3 ^' L2 g, c& I# L- M
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);( v4 N: z. v% r' e0 j  P
  366.     if(LPDF_OK != ret)
    % d" n% W$ e3 T$ ?! ~5 l1 U4 Q9 Z9 Q
  367.         return ret;
    , n# x# B' Q, {1 D8 w% ?7 @7 A
  368. ) K, \8 u9 ~! ?2 b/ n4 o
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);6 w1 ]% b. K% s3 D8 d( g
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    6 T, _' C7 p! i4 a- T$ x! C4 ?
  371.     pdf->offset += length;
    " G/ ^. e' G( A& H2 W4 I
  372.     page->length += length;
    2 j' v/ {! F7 @2 q. q$ p8 a
  373.     return LPDF_OK;1 V; y9 @7 D# L
  374. }3 T6 N. Y: D/ r! W7 _' ~
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    5 U" w9 \# w, a" z3 L/ e6 [
  376.                          LPDF_UINT16 x,
    * Y: I* X* f4 q' V$ g% G; K
  377.                          LPDF_UINT16 y)
    1 L  e& E5 n5 F( |4 [  `- y
  378. {
    # _5 w% [( S0 P) d. X  a) b& f
  379.     LPDF_INT length = 0;+ z; a3 m/ N6 t
  380.         LPDF_UINT writeBytes = 0;
      k. c  f1 z# Z" Y1 K. `( k! V
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    1 I1 B2 B" u$ ^$ C, d9 V
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);, U! l6 X4 _$ ?  m. J- o7 P1 z
  383.     if(LPDF_OK != ret)
    7 e0 e* ]6 x& M; g9 F( W5 u0 L& R
  384.         return ret;
    ' Y# I2 \- y. X2 }2 o
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);% U# C* K" o/ r1 u& j' i
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    1 F* i4 l2 h! L, G  ?- w& b2 f5 L
  387.     pdf->offset += length;% X" y0 F8 ]! t$ q/ R
  388.     page->length += length;" F% j% O% C/ L: l5 @
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    1 V: B$ V  L* |7 F  `4 k$ U* k
  390.     return LPDF_OK;' [/ F: r2 o# Z: c, s. o1 @- W5 c( H- \
  391. }
      d6 i% |& P2 o' z! C: o
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,; I. L$ A# g. f3 {
  393.                          LPDF_UINT16 x,7 S4 K3 C( o/ Z9 B
  394.                          LPDF_UINT16 y)9 g7 x1 g) R3 P! x
  395. {
    / {0 h# d7 M' ^9 K# u; T
  396.     LPDF_INT length = 0;
    7 \, j( Z. _" r' v* [
  397.         LPDF_UINT writeBytes = 0;4 `/ B3 Z/ @1 x  n5 t
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    + {. v, t: G( J/ N6 t
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    7 g4 a, N* a* A: Y: k  A
  400.     if(LPDF_OK != ret)7 g7 G2 O  Q; c- T( E, e* a
  401.         return ret;
    8 O) P4 ?( L& H3 m- S, z' r% f
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    8 G4 B7 c6 \- R: @, }8 b- O1 q/ Y
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    . R- `* i  w8 v9 Q
  404.     pdf->offset += length;
    ) }* g& j5 f+ D- u& U  T
  405.     page->length += length;* Q' t. s* j* u1 H9 V
  406.     return LPDF_OK;  K* {" _* R' R0 u' h
  407. }
    : T& a- b3 w* x/ N
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)) R. X' I3 H8 M1 I
  409. {5 |  a0 d$ C' X6 b# E
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;! O4 V5 z9 [' h
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);; ?/ v) j1 b' C9 W! h; S
  412.     if(LPDF_OK != ret)) [/ X/ \$ `; {5 ^
  413.         return ret;5 s/ B+ M1 b* \4 |
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    1 w, a- o! y: a- N2 v
  415.     pdf->offset += 2;5 F' w, q: `6 j2 z) s( Y' W2 C
  416.     page->length += 2;
    ; B3 O! e( X) F1 U! D& p$ H; x/ g
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    2 X  ]: L) o9 H5 _9 i( g2 @
  418.     return LPDF_OK;
    : M( @5 {" H. m! `" E+ ]7 S
  419. }0 n! B: t% ?: k, o  a
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    3 ~7 ^* V# x* A3 X6 V/ B% g6 s
  421.                       LPDF_Image image,/ v& N6 ^; t7 m" G
  422.                       LPDF_UINT16 x,6 [7 a0 q3 D6 v+ M- T
  423.                       LPDF_UINT16 y,$ F! L* a0 o) D) g! O$ I, h
  424.                       LPDF_UINT16 width,
    % M4 V- }7 c' |; C# G
  425.                       LPDF_UINT16 height)
    ! l! a* G9 a) g" {0 g
  426. {
    5 w$ e$ k  M) F% B
  427.         return LPDF_OK;
    8 I3 J0 b. i! Y6 p' k
  428. }
    ; X8 K. N  t- [
复制代码

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

  1. pdf = LPDF_New();4 a, a; R$ \, i
  2.     page[0] = LPDF_AddPage(pdf);
    ( T! S7 N3 {5 R" [: f7 }
  3.     LPDF_Page_SaveParams(page[0]);* g; M' U) T: r" P' E6 u
  4.     width = LPDF_Page_GetWidth(page[0]);
    # H$ i3 ~: k1 {& t3 N
  5.     height = LPDF_Page_GetHeight(page[0]);: V3 v: C/ d( ]3 f6 I/ L1 E6 w# _0 D% S
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);
    ) k3 `  X0 Y: y# L! C: t7 ~
  7.     LPDF_Page_BeginText(page[0]);
    3 T/ V6 }' {+ }5 Y* W% G$ c& k
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);( P! B2 N/ ]1 X3 L* E$ {) y
  9.     while(font_list[i])
    # S* S  k5 X! L/ ^& t) v( \( i4 o) Q
  10.     {
    - b9 W& L- ~! E8 G; w/ F. T
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    4 ^& o# H; P! i8 c  e5 B
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");
    - w7 E' D, m+ J
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);0 O  ?& m- y7 U1 l+ c; V# H$ ^
  14.         i++;
    ' n9 B* m% a; Y+ Z' H0 C% e
  15.     }
    * Z7 j/ s% r0 |0 ^( X
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);
    . r2 O+ o% d  O* I
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());8 c' ~9 ]8 R" _6 v- j
  18.     LPDF_Page_EndText(page[0]);* ~! I  ~# v% z7 T( q( r: v5 w
  19.     LPDF_Page_SaveContext(page[0]);0 k* U5 j# y& e- q, r
  20.     page[1] = LPDF_AddPage(pdf);
    / m( w: T% W- q# P
  21.     LPDF_Page_SaveParams(page[1]);
    4 X, X+ Q8 t/ a4 w
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);; _$ _4 j$ F$ ^! r% J% o
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    5 J' g6 P2 a7 m: \( t+ ^9 s
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    & O0 k' y# @" V$ M6 P; ^0 T
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    2 E0 G9 w* u6 d8 Y
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    0 P4 I# }. ?7 c
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);9 p# d! P1 }# b% l- y
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);
    3 R3 o: w' q8 T0 r/ W( A# {, `2 p
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);( `; Z' ]* R6 A! k
  30.     LPDF_Page_Stroke(page[1]);
    0 L* c  b7 R. A* d% i
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    * f. q( E* L6 \* U1 h" ^) p2 [
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    " \2 r" R* u# p3 m6 d; F) S
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);4 q! A( X7 X1 Y
  34.     LPDF_Page_Stroke(page[1]);
    # e3 z. f0 @* x' L. b6 A4 d( B6 s
  35.     LPDF_Page_SaveContext(page[1]);
    3 l& K1 m  {7 P  N/ U& o9 Y+ r6 Y5 F
  36.     LPDF_SaveToFile(pdf, "/red.pdf");
    : X, T2 m6 |  E* W7 z, m- N5 I
  37.         PRINTF("\r\nCreate pdf file success!\r\n");+ D' Z3 Z* \2 J# ]% n& F
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了" E1 `* {9 K5 R1 d

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    ) h- e, k3 G9 l8 \3 g  n4 C

0 P' |0 z" N3 i: w4 `

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:558 [1 a% {, Y) O) b, S
只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...

( D! r0 p% d) d( ALZ,我怎么没看到有添加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
$ q" ?5 t3 s1 q  v首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...

" ~  q) |7 {- Q. ~$ E: C66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
: Q1 X5 Y# }0 _0 \3 o
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
" M$ l: m/ b: g6 B1 a看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
! C# |% D1 T9 I' g: T. h6 x# q& b
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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* G# S# U4 Y$ \$ Y2 d" Z* h
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

. Y3 W( ^1 F6 ^( o  ~这个还只是一个简单的库,实用性还是差一些的
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
* E+ S: t! q; ~& ]0 m1 `7 _ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗

* O; G- l( q# v, Zff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
; e% U1 ?7 i  nff.h是FATfs中的文件
# }: {* a- A: k; y# |& Q* C3 L1 X0 X
嗯,这个画线能改变线宽吗
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版