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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 % b7 f$ j; |% `7 B/ `
7 d6 X' R* E% R- X9 [: z

主机环境: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 ~' H# h8 m) f( Q0 p5 I5 T0 |
  2. #define __PDFLIB_H__
    / ~5 R& B0 y- Q: s- M' ~+ ]! \
  3. & u8 i$ Z: s; F0 k+ b; n6 B7 f
  4. #include "ff.h"9 K' p) d6 n  o
  5. /*----- standard C library functions -----------------------------------------*/0 y# n' m4 N# Z, K7 |( r! X
  6. 9 k2 \/ J- z* q& q* O" }5 S
  7. #define LPDF_FOPEN                  f_open9 ?, k/ I% A8 [2 G. X' ?# H9 D
  8. #define LPDF_FCLOSE                 f_close9 u% W; {- j7 r( I
  9. #define LPDF_FREAD                  f_read; _7 R6 ~4 t+ Y/ N
  10. #define LPDF_FWRITE                 f_write+ T; z, N6 z: L' @" W
  11. #define LPDF_FFLUSH                 f_sync# H6 k6 `3 G( Q
  12. #define LPDF_FSEEK                  f_seek
    0 _* h  t* @+ W7 Z
  13. #define LPDF_FTELL                  f_tell) {1 C& u9 j6 J6 d! F
  14. #define LPDF_FEOF                   f_eof
    5 V5 w- s: |+ v
  15. #define LPDF_FERROR                 f_error2 o7 o8 n" u* O2 Z- v/ M5 ^, V
  16. #define LPDF_RENAME                 f_rename
    ( g/ u6 I( s6 D3 x
  17. #define LPDF_REMOVE                 f_unlink
    8 S  T8 h! N" \2 V# l0 R+ F$ F1 D  _
  18. #define LPDF_MALLOC                 malloc
    2 W) u1 [5 \& H6 K
  19. #define LPDF_FREE                   free
    5 K  f' R5 d, V0 B! a. K
  20. #define LPDF_FILE                   FIL2 R# z% w0 ^4 J4 u: U
  21. #define LPDF_TIME                   time$ {* _" f0 \, s7 F. n
  22. #define LPDF_PRINTF                 printf
    " E. x/ \% B$ J$ S4 o6 \8 _
  23. #define LPDF_SPRINTF                sprintf) O8 l) I( O8 d. _
  24. #define LPDF_FPRINTF                f_printf# R8 E0 I( K& B
  25. #define LPDF_VOID                   void
    * l) Z; q. F9 u8 }1 q" R
  26. #define LPDF_SIN                    sin
    8 `' _' ^, s4 R3 _
  27. #define LPDF_COS                    cos
    ' X7 |0 S9 i) E( Z4 i/ h
  28. : Z, ~; k) g# F4 F7 {% T
  29. /*  native OS integer types */" D" m  d0 v: P+ h4 `, q+ [
  30. typedef  signed int          LPDF_INT;
    4 Y! `' o* j; B# U3 n$ u
  31. typedef  unsigned int        LPDF_UINT;
    - e5 j" Q& E. _1 C- P; [$ p
  32. ; q5 I- c3 W% d6 h% |+ l, {
  33. 4 }( ^+ \$ I1 A- o% y2 S% o
  34. /*  32bit integer types
    8 r/ j, a0 z1 N3 s0 A
  35. */' m6 C9 y, \. r# V( u) Y
  36. typedef  signed int          LPDF_INT32;9 m* F0 J. p! l2 @4 p
  37. typedef  unsigned int        LPDF_UINT32;
    $ l9 L* R, \# s! ?

  38. ) F6 u  E: _" N

  39. 3 D- C* o% t. f6 {4 C
  40. /*  16bit integer types
    ! `. Y2 v% Y: I- d0 p& S$ Y
  41. */
      h3 r' u' H8 f4 b& \5 ~  h2 s; x$ n
  42. typedef  signed short        LPDF_INT16;
    # U5 V% V" A& g0 b
  43. typedef  unsigned short      LPDF_UINT16;% U4 P: w( j! A5 W  M( b3 ]

  44. # L/ \: }; ~" u% [5 L, n3 y; T' S2 [
  45. 5 k, G9 h& X- Y1 q1 S/ @& C" d1 @
  46. /*  8bit integer types* p! [" @. y. M, e5 z% p8 d% S3 W
  47. */
    : c- Q5 J: ~) ?5 l. i) Q
  48. typedef  signed char         LPDF_INT8;
      F8 K3 ^, B+ m6 C
  49. typedef  unsigned char       LPDF_UINT8;
    ( n0 t" R2 F* f. N. |! X
  50. 1 n5 G; f' ]) j7 Z+ D0 p7 x
  51.   p2 ?6 Y. b2 L/ [9 j* l
  52. /*  8bit binary types0 R4 r3 C% D( K; m& G
  53. */
    9 R: ^) A7 Q2 Z8 l7 ]& }
  54. typedef  unsigned char       LPDF_BYTE;
    $ a, `; p. S" l

  55.   t4 G# h8 j9 y, |

  56. ; b9 j5 T6 a& f* Z' \1 [
  57. /*  float type (32bit IEEE754)
    + x% Y3 l* L. v
  58. */  ~4 \1 k4 I  |. j8 m
  59. typedef  float               LPDF_REAL;) I# m3 j3 g( C8 |6 k

  60. 5 k# `$ M0 X3 j7 \  ]9 y( A

  61. % N, Z) [  C4 n( e+ i: `$ Z
  62. /*  double type (64bit IEEE754)7 J5 C, Z% E$ U6 Y/ Q. w
  63. */
    " Q6 F/ M& P2 f8 ?
  64. typedef  double              LPDF_DOUBLE;
    ! Y! c# k1 R7 O4 c, s; ^$ o

  65. # d/ _' ?% R$ h& _' C
  66. / ~1 w; A5 N3 c
  67. /*  boolean type (0: False, !0: True)
    6 r  h# P5 G2 m3 W$ T7 f9 d$ B6 S/ ^" v
  68. */
    9 b5 j/ G( a6 O
  69. typedef  signed int          LPDF_BOOL;
    ! M. N$ N0 Z9 m! ^
  70. # ~; B* i% W" ?; d3 K5 y( H
  71. 1 Q2 a, m3 Q6 V! ]
  72. /*  error-no type (32bit unsigned integer): x; u# s' L( ]& o
  73. */
    8 d0 z: t* f# O, @0 ^
  74. typedef  unsigned long       LPDF_STATUS;, M# C: S, u$ x) _- w
  75. ! F! S% V, n" R0 @- e  I7 F
  76. #define LPDF_OK                     0! J5 l7 d9 J2 ~
  77. #define LPDF_FAILED                 1
    8 _) }( K7 o& h! ~' o& {5 y7 R/ S& _) }
  78. " o" w' Q2 c4 _' Q3 P) w- f
  79. /*----- font state -----------------------------------------------------------*/
    # b, |7 ~- G& Y/ w3 r% h5 a
  80. #define   LPDF_FONT_INVALID                 0x00FF& t' T. l: t& x7 d, R
  81. #define   LPDF_FONT_COURIER                 0x0000
    * E; Z2 k" g* O  R  I7 E* A
  82. #define   LPDF_FONT_COURIER_B               0x00017 n5 n2 c9 }  V5 t9 s2 c1 m
  83. #define   LPDF_FONT_COURIER_O               0x0002
    & e. Z; O6 N6 k# g* }' }9 e
  84. #define   LPDF_FONT_COURIER_OB              0x0003( g6 E9 z- w( d
  85. #define   LPDF_FONT_HELVETICA               0x0004
    8 B6 Y/ Q# j* T7 N6 [  O9 s! U
  86. #define   LPDF_FONT_HELVETICA_B             0x00057 q$ s. {9 }* q: ?9 E  d
  87. #define   LPDF_FONT_HELVETICA_O             0x0006& N% Z& x/ i% `. N3 [3 s4 b  X
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007
    9 y+ m& m0 V( q1 ?" p& i* W
  89. #define   LPDF_FONT_TIMES_R                 0x00088 @; b4 @/ L: C' b% N1 m1 g. ?% y
  90. #define   LPDF_FONT_TIMES_B                 0x0009
      m: M! g% c  @  i7 D
  91. #define   LPDF_FONT_TIMES_I                 0x000A( o# h' X2 i" }$ i: h7 Y
  92. #define   LPDF_FONT_TIMES_BI                0x000B
    " v3 F. |3 m. y1 a0 C
  93. #define   LPDF_FONT_SYMBOL                  0x000C
    - E5 z* n- K# X) h  C4 t+ D* h
  94. #define   LPDF_FONT_ZAP                     0x000D
    " N, _$ a2 t, u+ k; u& f3 i
  95. /*----- Graphis mode ---------------------------------------------------------*/& H6 b0 z, f3 z/ C9 U$ v9 u
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x00012 i1 ~1 W' ~1 d
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002/ _* [( }6 h- n- b* P
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    + P/ N5 a: f; f. @( }) N
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008
    2 J) z: ], C& S
  100. #define   LPDF_GMODE_SHADING                0x0010- {" [2 s7 H- `) w' L
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020
    $ }3 u  M0 j" g- F; T
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
    ) w9 I! V! C- d( o: Q- _
  103. #define   LPDF_GMODE_INVALID                0x0080  s; }1 S  @8 Q7 U  P3 w. c
  104. #define   LPDF_GMODE_OVER                   0x0100
    1 ?; d' h0 R" Y& ^" H" U
  105. # ?+ `6 A) Y& F3 u
  106. #define OBJ_MAX_NUM     256" T$ v& Y1 i6 K. M
  107. 9 |9 l+ W" p' o
  108. /* Page的结构信息是否需要树形结构 *// N5 c* \8 T* r6 |0 p, \
  109. typedef enum - k$ \3 e1 ^  m- j/ v
  110. {+ u( H2 I( f0 d$ J! a
  111.     OBJ_info,$ m  x( q. }+ c) T
  112.     OBJ_stream,; c' D$ e  T, l5 W
  113.     OBJ_font,! n0 I" P* \: X" X+ M! e5 }+ `
  114.     OBJ_page," ?! q; {! x4 j3 Q& S) |$ W
  115.     OBJ_catalog,  E* x) V- d( y/ z: ~
  116.     OBJ_pages,+ U* Q' Z5 h9 U% Q
  117.     OBJ_image,7 l: U8 I# f5 x( s9 \) y; z
  118. }LPDF_ObjType;
    2 m9 l9 Q' l9 N8 @2 d/ Q

  119. 3 D% k  H1 f2 u, b% s, h( J! ~& |
  120. typedef struct9 `( m. p" s# v
  121. {7 h6 m$ h- g- q8 f$ C+ b  x: M
  122.     LPDF_ObjType objType;
    1 N  I4 E! ]2 R1 c
  123.     LPDF_UINT16 objIdx;
    % [4 X# J0 q1 }. X
  124.     LPDF_UINT16 height;
    5 c) O8 ~' c) y9 `9 w
  125.     LPDF_UINT16 width;( W3 l, c* u% d1 Z
  126.     LPDF_UINT16 length;$ ^# L) A! b% h& l$ T3 P+ w8 |1 @
  127.     LPDF_UINT gMode;" N/ q" e7 s4 P& G
  128.     LPDF_BYTE fontType;
    3 ~  b" [9 h) i! x! q
  129.     LPDF_BYTE fontSize;
    8 t1 G  a9 |" d: q# u
  130.     LPDF_BYTE pState;3 B$ b5 h5 i6 Q1 r9 P" ^
  131.     LPDF_VOID *doc;5 y9 r  o5 p) G0 n
  132. }LPDF_Obj;
    # f$ }6 J7 E* G6 ~. ]0 y1 n; P
  133. & B; {$ W& T3 U- d: Z7 m
  134. typedef struct
    . S" F% }3 a, h% O+ J
  135. {; C+ t2 K, {  \( `9 w8 U' H- L2 n2 d+ D
  136.     LPDF_Obj obj[OBJ_MAX_NUM];, r* @3 _0 C" n) {$ L6 {' k# X
  137.     LPDF_UINT32 offset;( ?$ {$ W) a% o- \, w
  138.     LPDF_UINT16 objNumber;" G0 i0 Y) b( Z- M+ ?! X
  139.     LPDF_FILE file;
    $ }5 G: J! f# B: e
  140. }LPDF_Doc_Rec;
    / q, N( |: L7 G: n
  141. * n. D. y3 `: ]2 ^. @
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    5 v2 a' Q9 t6 R9 l
  143. typedef LPDF_Obj *LPDF_Page;! X( N; P$ b8 h' u7 D$ E
  144. typedef LPDF_Obj *LPDF_Image;& i9 x" J1 t( m9 [
  145. extern const char *font_list[];' X. D- q6 R# P1 d5 y: K
  146. /*----- LPDF Interfaces-------------------------------------------------------*/9 h" u3 Z2 O& r! ^8 e
  147. const char * LPDF_GetVersion(void);
    & H4 {3 p+ Q5 I/ T; M
  148. LPDF_Doc LPDF_New(void);
    % M* P+ Z' }5 o) ]+ n+ R* }2 c
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);9 A" b' P' @' x+ P( e, g; f
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);
    / g+ ^# @6 Z# L( P  E
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);
    ' _* H; r8 U: `, G+ E: H
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);6 \* n% @. c' d: k) l. U+ a' j
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    % {3 F- P6 U! @7 I
  154.                            const char *font_name, LPDF_UINT8 size);; f& R1 [- D3 P1 n4 O9 Z
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);
    ) v! `5 O6 }4 [8 g+ P. K! Y/ [
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);
    2 Z# |0 N; I/ p
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);2 Y! t$ _5 @! U& {( C0 I) J
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);& p( Z& a& p6 m2 y$ X
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    5 w7 s6 K1 u. U9 a
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);
    6 v, i1 L, c6 L% T% u
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    5 w) Q$ B( ^  q% `
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);
    ! _- p& C! y( k: a0 m, a
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);* S: K4 `- h3 M# n
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,* |( Z: m& y% j+ K* X
  165.                          LPDF_INT x, LPDF_INT y);
    9 s3 r8 X( f7 H4 p  }: [# U9 M, k- h8 t
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    1 Y: j- |7 Z3 z4 m+ s
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,- x9 q5 B* ]& q# u) R) _- ]( W9 X
  168.                          const char *text);
    % {3 b: d  _7 P6 G
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    2 z# d; r# N7 c/ j: ?
  170.                          LPDF_REAL r,
    5 [$ e9 I. ?- w% z+ \# F9 b
  171.                          LPDF_REAL g,
    6 y" m! X2 {& _  |' f. f9 T
  172.                          LPDF_REAL b);0 D0 r0 ~2 i) H, X/ N
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    1 J" \& C) ]2 Y8 _; r" ^+ [
  174.                          LPDF_REAL r,7 C6 l1 |+ T3 F" F$ H" R
  175.                          LPDF_REAL g,2 x; Z* w# U/ g
  176.                          LPDF_REAL b);9 V. Y( X. l9 a7 }: `8 K  v: j
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    7 i& I4 Q6 w8 G' H3 Z
  178.                          LPDF_UINT16 x,% i3 b! N/ ~9 P2 u
  179.                          LPDF_UINT16 y);
    & ^0 {7 G( H6 S. b6 i4 ]5 l8 }0 ]4 M
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    " _- U0 z7 Z& M6 x% Q6 Y8 _3 i/ M
  181.                          LPDF_UINT16 x,, @& ]9 `; N, _* v
  182.                          LPDF_UINT16 y);8 C" J" M9 R( Z1 H* W
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);5 l9 F# X2 ^+ p' z
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);, b6 y0 U) i! ?; I  @8 A# h
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    0 |+ }5 D$ ~# r% W1 a
  186.                       LPDF_Image image,2 B) q, U9 y, k3 f6 r
  187.                       LPDF_UINT16 x,
    2 V4 g5 ~# u( P. p5 P
  188.                       LPDF_UINT16 y,
      E. Q% F- Y) s0 y+ Z4 Z
  189.                       LPDF_UINT16 width,% c0 K  W2 Q  r7 ]3 \
  190.                       LPDF_UINT16 height);
    4 I4 [9 L  S$ ?" n3 a% Y
  191.                                                                                        
    % s2 N. |3 R7 o+ s3 J7 F  M5 c
  192. #endif' s' a* D4 @" |( f( j
复制代码

源文件如下:

  1. #include <stdio.h>
    1 `6 ~5 S/ Q, n* S% R1 D
  2. #include <stdlib.h>6 o  H0 o; f9 H1 N: S/ M9 _
  3. #include <stdint.h>5 O" H' O, C2 T( n9 F; U
  4. #include <string.h>! }) W: _* d7 ]: i" E
  5. #include "pdflib.h"; E% S; e+ n* m, D* z7 F4 ]7 ^+ O

  6. & l& S) Y6 F. f
  7. #define LPDF_INVALID_OBJECT                       0x1033
    # ]+ n' B/ G  O! Y! N
  8. ) b& G+ o% m. D$ y: b9 N: [
  9. static char pdf_buf[512];# E. I& ]9 g, b6 {! S

  10. . `: V0 e5 O+ l6 k6 u
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1") o3 f! n4 s9 C8 L( x' t! A
  12. #define LPDF_FILE_HEADER_LEN        15, z- |+ D2 m  k8 d
  13. #define LPDF_BASEFONT_NUM           140 j' e- w. r, `' Y
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";4 M( Q9 g5 U5 r% t4 Q: Q. W, A7 C8 ]
  15. const char *font_list[] = {# }6 p# S' V: {9 @+ I4 k
  16.     "Courier",
    + R  l7 }. n. y  r
  17.     "Courier-Bold",; H; A% w7 I( g/ m
  18.     "Courier-Oblique",
      Z$ o: ^: }0 W, Y8 C5 o, H9 i( ]
  19.     "Courier-BoldOblique",$ [1 C" X0 ?: C3 b5 t
  20.     "Helvetica",  A* L0 i: w$ m
  21.     "Helvetica-Bold",! i" x5 Y9 G+ G5 x8 }
  22.     "Helvetica-Oblique",5 L/ B, D( Z+ Z- ?
  23.     "Helvetica-BoldOblique",5 Z) `9 q8 D% P/ t& p# ]! a
  24.     "Times-Roman",% k3 @6 k+ g* y% E3 T# D4 J- A+ Y$ u
  25.     "Times-Bold",
    $ E- P" |: u8 c
  26.     "Times-Italic",
    6 W. Q1 ~; P7 w7 z& e" q
  27.     "Times-BoldItalic",+ g8 p% S3 N3 |& y8 a- Q2 [% P
  28.     "Symbol",
    5 A& a4 [6 L7 ]% B" R+ g) H, N$ q
  29.     "ZapfDingbats",
    / S# }+ G, ~* K9 |- m4 S3 A6 A3 Z; c
  30.     NULL& E2 W* p" A2 q! a" Z2 h4 ~% y
  31. };
    : S/ [3 N/ C1 B* m5 G5 r9 e9 n1 C

  32. ' }" [% \9 x  @; m. G% l) p# ~6 I" x
  33. 9 o6 H9 K/ h0 e! u
  34. const char * LPDF_GetVersion(void)4 ?0 K& [- Y! ]# t
  35. {5 ~/ O( H3 e" S% j2 \9 N9 @
  36.     return LPDF_VERSIOIN_TEXT;
    9 E4 ?7 T2 W7 E( P, p5 ]
  37. }
    6 V# H* X; ?( G4 ?* J

  38. / V6 s! x* k1 Q. i1 ^3 x% b9 L
  39. LPDF_Doc LPDF_New(void)
    3 d( l1 Y, Z( F! o
  40. {( n. `  w) N- m4 o  z
  41.     static LPDF_Doc_Rec pdf;# A$ H. a  a& @- m- D4 h
  42.     LPDF_INT length = 0, i = 0;$ Z. F: b2 b6 t! m# U' k
  43.         LPDF_UINT writeBytes = 0;
    . K* n% l5 n! M4 z
  44.         FRESULT fr;+ }1 X% T! L6 o) z5 k$ s0 m
  45.     ( T9 R1 E  \8 e& D0 U7 ~
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
    ! a7 `0 i0 Q$ k- S1 o8 \
  47.         if(fr)0 P) w1 V$ p) C8 s
  48.         {
    ; U; v. v. w8 N0 y
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    8 u+ P; I4 V- Y! C
  50.                 return NULL;3 \- L, k( W) p! v
  51.         }- d9 |% x$ S+ H) i6 {$ L4 X  K! ]
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */
    4 G% V  G. _8 }/ H8 j* p) W7 Y
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;
    . S% h+ w1 N& z, l7 g0 z/ r2 Q
  54.    " [. W, Q8 I. h$ W3 o
  55.     pdf.obj[0].objIdx = pdf.offset;$ a' G3 d8 v( q
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");, d; f, p% m: @" K2 X# C. F! S
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);& }3 Y( D4 O! f1 j
  58.     pdf.offset += length;
    5 B+ ]0 r+ {2 O+ e5 Q
  59.     ) X% C3 {  g, X$ A+ n% [
  60.     pdf.obj[1].objIdx = pdf.offset;8 r9 u0 s# y# G% r8 r$ O5 V
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"
    5 M  m8 _: A5 e! k& |8 P
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");
    1 U' j8 R2 L) w0 L0 ]9 _
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    - x0 {# l# y$ r  s. i; U
  64.     pdf.offset += length;: @  ~" Y* Z; n$ ^2 e
  65.     , p( X# N3 n! }# V& F1 t. f
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++), e0 j9 v4 V! a, H
  67.     {
    . O: |8 K% x8 z2 i, a' D: \: Y
  68.         pdf.obj[2+i].objIdx = pdf.offset;+ _+ e( _# Z. k: P# j9 u- h
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    ; L+ R: @7 M& Y4 Z" L- j6 c
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"% l- S- ?4 {- U# z6 e# R) ?
  71.                         "endobj\n\n",3+i,font_list[i]);
    6 {- {! g$ M! U% Q( ?
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    8 Z+ [7 U( i. c
  73.         pdf.offset += length;
    9 N+ ~* ^1 R: H8 x1 [! ^  z* \+ t
  74.     }! \$ t* x; X8 k& U  g# s
  75.     for(; i < LPDF_BASEFONT_NUM; i++)
    # K" t/ J2 _% D% t! o( ?. v8 O
  76.     {
    0 _$ I2 S+ a3 u5 R
  77.         pdf.obj[2+i].objIdx = pdf.offset;
    . k) q% _2 i6 ^* n$ C& p+ T
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n", j5 F9 y, _, N$ K) |, _
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
      U+ i8 z0 a) b' x
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    # Y* _% J* z6 V# ^* e6 Q; v
  81.         pdf.offset += length;9 K& N" ]% G. z+ k3 X
  82.     }
    - u) F3 P, o5 J1 B: E* y
  83.     pdf.objNumber = 3+i;
    0 G0 Y) d) o* U) k# X% f' f
  84.   
    ! s8 t% x9 z' Z9 R+ M9 |+ f+ \) n
  85.     return (LPDF_Doc)&pdf;9 b/ ?2 M9 `' l2 s# o+ k
  86. }
    & K2 L# u$ B  t) [

  87. " f5 i4 F$ o$ }5 J
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)6 V# \  B: B; g0 V0 x+ D- ~
  89. {
      t3 K% `/ J' g, s8 d
  90.     LPDF_UINT16 i = 0, child_pages = 0;
    ' S5 X. J& ]6 U. b8 t! t" h' o* t
  91.     LPDF_INT length = 0;
    & ]+ F" `" l' ^
  92.         LPDF_UINT writeBytes = 0;
    7 ?% J0 v+ x6 r* {6 A4 k
  93. 8 E7 R$ {; o* E5 s5 d6 `
  94.     pdf->obj[16].objIdx = pdf->offset;
    ' X+ M" n! [, j7 Y2 }* K  o, ^# `
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;$ {1 @' g$ z1 O" p/ E' s. H" I9 e
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);
    0 Y- W: U+ h8 e: |) h6 M
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    $ \- W- T4 O- J/ `" C8 E% X0 P, S5 J
  98.     pdf->offset += length;
    $ A/ ~% S5 `, j9 P8 h
  99.     for(i = 0; i < child_pages; i++)6 }" |1 _) l; A. p
  100.     {
    " V0 ]+ j3 H. T) O1 U
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    ! Y* m, x( q" }% V. Z; j" g
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);0 i0 ]; V; z% C  b% F
  103.         pdf->offset += length;. G, X4 y3 g$ [/ f3 X+ d3 X2 m
  104.     }# h! @% H0 ?0 B* e% N" Q! y
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");
    & z9 n7 f! v1 f) L( g
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    - \9 H* \( ?, k$ c! @
  107.     pdf->offset += length;3 j( k. M% C1 r4 b# ]  _9 _* {1 L. G
  108.    
    / k3 s9 a- ]- g) ?7 x7 `3 V0 l
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    1 D6 Z* P( \$ C& p" b1 z; o
  110.     for(i = 0 ; i < pdf->objNumber; i++)6 L: ]) e* ]" F. f1 P- n
  111.     {
    1 X+ r1 L; I" u. C; s1 i* b' ?
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    . }7 W3 a9 _; p
  113.     }/ v7 W4 M* ~, g+ q! v( Q
  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",
    ( Z' W' b+ f2 i3 @/ B# l, j
  115.                 pdf->objNumber+1,pdf->offset);. S% Z  Y# \" {" N' J
  116.     LPDF_FCLOSE(&pdf->file);
    : i: x1 |- t) Z: P% ], Q
  117.     LPDF_REMOVE(file_name);
    * C  D2 N' Q+ ]5 U  V9 B
  118.     LPDF_RENAME("tmp.pdf",file_name);
    9 @, F, u7 a+ n2 B4 K5 r7 u0 @
  119.     return LPDF_OK;
    3 w0 ]' H* O1 w) s( y6 ]; z
  120. }
    7 a6 ?- }$ x  N, G6 _/ ]* U5 N
  121. 8 p$ P; n6 {5 ?4 c% B  z1 ]& h1 n
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)5 o* L. a  ]! G9 E! }
  123. {
    - C+ M3 S6 M  m& n( K
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);
    : J% g) T0 x4 I7 [
  125.     return LPDF_OK;
    8 _: r+ \" g5 M2 y, D# k  p
  126. }
    2 `; X7 D+ P. D

  127. 8 `; G& B1 j; c. r* D6 F' r
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)
    " ]% A( y* i/ I. P; v8 \9 ?
  129. {) D& e7 C- l2 h6 p6 h
  130.     LPDF_INT length = 0,i = 0;; U: J3 J/ i% I3 B: q
  131.     LPDF_Page page = NULL;. k0 J) S" h/ j! K* e) \
  132.         LPDF_UINT writeBytes = 0;6 x& @6 s) I1 s1 ?0 i
  133.     ! ~1 b6 W$ ~4 i* a( K9 h
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    ' b# a/ v* O  Y- t& W
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"
      y3 C7 N. s' W/ P' A) k
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    / D' P8 {' n! G3 A% A& [8 r# l
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    * D. Y, I& d8 R
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ; V# |$ [, @6 B3 s% k7 b
  139.     pdf->offset += length;
    ! v6 h' v* R% N% F
  140.     while(font_list[i])( R. B. s5 I+ `+ q, N6 X
  141.     {4 x$ _0 X5 Z0 `
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);
    # M3 J* q5 g, g8 O& t0 `
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);5 L4 ~1 g( r6 e  q1 S' p( n& Z
  144.         pdf->offset += length;! q( t; P" B5 S  A, Q
  145.         i+=1;* a4 D$ S) R/ V6 E$ H5 P: w7 L
  146.     }
      V, W) A9 z: r. O' U
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");/ {5 n3 }  R/ A* M& J
  148.     pdf->offset += 4;# `  k' N4 c  U, Q1 z% @
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];* ~' ~0 R# r3 R2 s( j
  150.     page->width = 595;
    / H8 s2 S* F8 H( f' C) _
  151.     page->height = 842;% p. d1 M* g" `
  152.     page->gMode = LPDF_GMODE_INVALID;2 ?2 d) y, J: f) J5 I5 D; U* x
  153.     page->fontType = LPDF_FONT_INVALID;
    & |; Z" Z( S, U2 U
  154.     page->doc = pdf;6 F( f: `. B2 ?3 q1 H+ [% x
  155.     return page;$ y+ e$ ^4 E* M, M# A3 V' G3 S3 C
  156. }
    3 m3 o* c* e( G
  157. 1 k$ T, i$ U% V# |) J$ y$ s
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value); V6 U+ X5 u$ P- D+ ?
  159. {% a. P( @8 v9 _! T, u: S
  160.     page->height = value;
    4 g5 e/ m/ Z) R! h, u- I* J
  161.     return LPDF_OK;
      i) j* d8 A8 P8 R$ x% S* S9 ~
  162. }
    ( t1 H9 \& ]( H% j4 X) u+ q# H- i3 Q) W
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)8 K& [/ r1 V7 [' n
  164. {0 f, s0 p! E. W" P
  165.     page->width = value;+ G. J; A5 p# S/ p
  166.     return LPDF_OK;0 v# u+ C( q  K) e& u& [
  167. }& W2 Y& S% q' x9 W3 l1 j$ B

  168. 8 Y& h, E3 [  V5 N/ I
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)
    / \: N6 s# O( y  ~1 }
  170. {
    : B+ H1 d, W9 L
  171.     if(page): R2 d6 }+ \0 m
  172.     {
    ) R, c; x$ H6 O3 N$ d
  173.         return page->height;
    + v2 |4 e, Z8 E! {+ O6 x+ V) X
  174.     }4 m2 q8 v3 c# ~- G: b
  175.     & r9 p& q( X6 V8 x
  176.     return LPDF_OK;0 p2 t9 @/ S- k- H+ N
  177. }1 S# G5 g1 Z; K( G

  178. - b+ x' ]8 U; \
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)2 j$ L1 `4 y0 r9 M% W
  180. {4 u6 R' [& `6 n3 g" b- [
  181.     if(page)) z* G8 l1 x$ _4 x( P( C0 {* Y( y/ \! f
  182.     {- E# \" V* G3 D# H9 [% i; C
  183.         return page->width;/ E( I# ~5 l. _7 q. @
  184.     }
    : S3 G+ A# u) a/ |8 G$ Q8 ~9 [
  185.     / k. R' O7 a. \; E, B5 p
  186.     return LPDF_OK;  Y$ g0 Q+ @: k
  187. }, |8 `/ h, @0 Q7 g9 Y5 ~& S2 Z
  188. 7 z- Q' U7 E7 s' E. f! k: M
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)
    & Y$ S2 e5 y- q* H4 v8 L% y# K
  190. {
    7 \6 [: B  ?! A5 ?
  191.     if(!page)
    : K( J% Q# x4 T9 b7 [3 _7 l
  192.         return LPDF_INVALID_OBJECT;1 q* E4 A2 l. K5 A7 b8 A) `
  193.     if(!(page->gMode&mode))5 `+ d! G6 f8 z! o- S3 I- d
  194.         return LPDF_FAILED;
    ( ^4 b  e- g/ y7 e6 f) X9 C
  195. 9 a2 V& R2 N9 s! Y% m+ Q
  196.     return LPDF_OK;- [, j$ S( O% X1 h  Z" I
  197. }
    % v1 c! x5 Y* @- h: a: M, V$ m9 R
  198. . P) {( U7 o( ^( ]' b
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,4 a1 K( y+ g# a+ ~$ Y
  200.                            const char *font_name, LPDF_UINT8 size)" B' m" y$ [: T/ ^+ r( A
  201. {
    / D7 k0 |8 g! F% O
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    , ?% _2 }# J" b# d" B+ D
  203.     LPDF_INT i = 0,length = 0;
    # \5 n; h! L9 N
  204.         LPDF_UINT writeBytes = 0;
    # p, O9 {  O, G) I; g- U8 o# }0 G
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    ( L6 l0 y" E$ r' R
  206.     if(LPDF_OK != ret)1 w  t( }, G: I% i1 D/ M
  207.         return ret;
    5 C  _" j3 C6 l$ l4 _. Q
  208. . q' s- F! \* P) b: n
  209.     while(font_list[i])
    & u: T. R* T( p* b$ @
  210.     {
    4 L; h/ U! K, _  i. S6 O3 s" c
  211.         if(0 == strcmp(font_list[i],font_name))* f- K* ~8 @- V9 Z
  212.         {" B* S; @1 S$ k3 |( H0 D
  213.             page->fontType = i;( Q- B. {, [1 ^( G  `
  214.             page->fontSize = size;
    : [  r, b( y6 }' q- S7 d
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);
    . }4 O- P/ x& [
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    5 f. j) Z, t$ {) G9 w& W
  217.             pdf->offset += length;! X& b! u2 S4 }4 i& V' S  }
  218.             page->length += length;
    ; s- `- @+ b* |: O$ d3 O  Z2 K
  219.             return LPDF_OK;% L; M2 a; _, F8 U2 G+ J' H
  220.         }( |. H; r4 t% |- u) d
  221.         i+=1;0 a, T7 l, x# I! L- n
  222.     }
    1 n/ g& ]- l) Y: ^* Q$ J7 {, O
  223.    
      {$ O- F- D7 M
  224.     return LPDF_OK;+ J8 C0 T# \: B1 J8 `
  225. }
    6 h* B0 g# J, g* I, z$ H5 O, ~0 }

  226. % ?5 Z' ?( R+ I0 }* G9 p
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)1 j8 y" e2 c. Y/ U/ z# T* J9 D
  228. {3 C: ~% g; }( r1 i5 e* C
  229.     LPDF_INT length;, E' P( a' X4 q( l1 J6 p* s& H
  230.         LPDF_UINT writeBytes = 0;8 H! |) t& L' \, k
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;5 [- m$ L6 c: z, X
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    6 Q3 J+ C: G$ V' }: ]
  233.     if(LPDF_OK != ret); b0 y: J" U9 J" }8 y7 c: }
  234.         return ret;# i0 ~. I8 L  M; v$ @  B
  235.    
    8 c7 k7 K: \+ O2 s" K5 K* [
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */# ~5 C& o4 H6 x( l
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
    ; |; `: b- S) a; J
  238.                         page->width, page->height);
    8 d" }+ q& Y5 C4 K6 @1 d
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);- a  C8 F. R0 H- e9 g
  240.     pdf->offset += length;/ L1 M: z0 U( m" V3 B% C
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    , W: D5 P  H8 m' B( H9 |1 g; \
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",
    . v) [8 [3 z. k2 @( e8 u
  243.                         pdf->objNumber+2, pdf->objNumber+3);5 ]5 l. {! {3 V" b" U
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    $ D9 m; r! V, I3 d. e, d$ w
  245.     pdf->offset += length;
    ' W" R- I8 ?. ^% u
  246.     page->length = 0;
    - U* h- k7 y. f6 m
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;- M. n7 c' [7 O! o, D
  248.     return LPDF_OK;. q8 x5 U/ {  L& o: |9 {) k% [
  249. }
    4 A2 p$ u6 m9 E, x6 T  d. [; i! }

  250. * x! y; b2 R1 ~1 j
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)8 M& {- W0 ?4 [2 q0 O' R( \
  252. {
    # j( Y6 E* i# K/ v+ a
  253.     LPDF_INT length;
    ! E5 J+ I. w7 A# G9 ~2 H( t8 f% b
  254.         LPDF_UINT writeBytes = 0;
    1 i5 f0 R- C. Y# \2 p3 s, A
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;  i/ B2 M) n# z9 k( \
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);: U  _3 x! ~! O1 x/ _, w! d3 c
  257.     if(LPDF_OK != ret)5 y# ?; O) Y/ \1 x8 C+ J* V5 M4 P% A  Z
  258.         return ret;" ~8 j2 _1 ~, z8 C4 @( _
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */7 |, J* ]) G* i* C
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");7 C  n' e  Y- x0 E+ P' [5 k8 t
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    4 f) ]! t/ o: Q5 c% c
  262.     pdf->offset += length;
    $ v4 e: N3 s: W& N, z
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;1 L; g0 N0 B. g; ]
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    1 e' s  p: T  B" i! i1 P9 L
  265.                         pdf->objNumber+3,page->length);
    * B4 j+ F. g0 g5 m1 G. S+ a
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    1 ~( a( y* U8 e; T) @0 w; \. a
  267.     pdf->offset += length;
    3 X' Y  Y8 ^# r0 c2 r* v1 _
  268.     pdf->objNumber += 3;! |/ T; h6 `8 i  D- Q( @- f0 t5 J
  269.     page->gMode = LPDF_GMODE_OVER;9 P: A/ F# e8 h/ b1 |0 G
  270.     return LPDF_OK;7 H. v# f$ R0 `" k
  271. }. a) l& b" K/ R" T! {2 F6 {
  272. ) t  O# @9 h& S1 V" [
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    ( E% N; d/ N4 }7 n
  274. {
    : O* i* s8 }6 M8 P
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    6 f; U) }! t: p! J6 X, f$ q- M) ^
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    1 f+ B" s. U" p  D
  277.     if(LPDF_OK != ret)$ _0 Z% M1 p% Q% u; o$ M9 X- n
  278.         return ret;
    ' @# x# c: ?1 [8 Y* w3 T2 y/ R
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    1 N& b3 w0 Z) [
  280.     pdf->offset += 3;
    ! W6 u% u6 C% G" F& T: G
  281.     page->length += 3;
    9 E9 U  C8 C# {) }
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;( z* M; P- P+ ^0 r0 [% ~
  283.     return LPDF_OK;, h5 t( h- y. y( \
  284. }& F8 [. z6 N' j
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)3 k* D# M" x+ w1 x" l- @  U
  286. {
    + a! G) j7 u8 s( `5 j  ?; ~
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;# ^) e! n3 l1 Z* O
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    ) o/ g$ q) x5 Q# R" V
  289.     if(LPDF_OK != ret)! ^5 l; S/ A: i
  290.         return ret;* P: ]% l# H5 W9 A, l) C
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");
    ! y8 H& f# K0 F. N* \+ g* e' @5 m
  292.     pdf->offset += 3;; D& e2 @( S2 B4 D: @6 g
  293.     page->length += 3;3 f6 L! H% r- K4 G5 j6 x) @5 [
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    4 _. p0 L4 \) R" D
  295.     return LPDF_OK;
    . l) T! _5 u1 [: ^& O
  296. }
    0 I+ h& k/ i  O5 ]9 H
  297. ) K( Y! V8 ?. I) F
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    1 b4 w4 i" u* N5 G" O$ @2 L1 H3 s
  299. {$ E* @' J' t: x8 k0 y( O2 V8 ]- o
  300.     LPDF_INT length = 0;5 T9 }* Z2 ~) W, y6 H8 Z
  301.         LPDF_UINT writeBytes = 0;" g( q2 b7 O1 g( j, ~) f2 {; D
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;/ n' s3 \9 o8 {, T
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    2 q  c, Q4 Z7 b9 x
  304.     if(LPDF_OK != ret)
    " |3 q: `/ O& |  {/ B" M* p5 Y
  305.         return ret;9 F  G6 v- w8 w4 B1 g
  306.     if(LPDF_FONT_INVALID == page->fontType)/ e: C9 y. S% U
  307.         return LPDF_OK;  y# x/ P; N# B7 [- L' N! ]
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);4 Q  C, R/ ]1 m8 H0 j. Q) Y7 S; {
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    * F  A, G2 r( t3 Y1 R1 f: t
  310.     pdf->offset += length;" @( T& e6 h6 x, C
  311.     page->length += length;
    0 ]# x7 }% `% @/ N8 ?, p
  312.     return LPDF_OK;
    ! N* g3 K- Y) [* A5 \0 a& r
  313.    
    / T2 L+ Z# I" n) A3 z
  314. }
    9 n  s7 X9 p& T8 z9 ^- Q5 U% s
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,; }( J' q/ `7 J" C" u
  316.                         LPDF_INT x, LPDF_INT y)
    : a8 j9 f& M( K
  317. {* @7 y  m5 e- D% R
  318.     LPDF_INT length = 0;
    ( d) p- [6 h0 p& V$ K
  319.         LPDF_UINT writeBytes = 0;
      b, A* j3 b) r
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ) E8 F0 B9 W, L& w5 Z5 m/ Y4 x
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    4 }: H. b8 q: ^; G7 p
  322.     if(LPDF_OK != ret)
    & Z; U6 T9 V' g8 L
  323.         return ret;
    ' j! Q1 g* u2 `. D% \! z: `* n: h
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);
    0 f+ i+ Y  Q5 y$ k& _
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    * k( ?7 A- A) X+ p. k: s% Z
  326.     pdf->offset += length;0 x/ f3 Z& N! h- a' X
  327.     page->length += length;* @/ e# U, L7 e2 A9 k5 i* |4 W5 ?

  328. " _0 P$ y; y; {' E4 i
  329.     return LPDF_OK;7 n, C' q  {8 g& M" s! v* j4 T! I. E$ i0 [
  330. }% d+ S4 i& G4 S1 c; `
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, 4 @# H- W1 c2 _4 O0 U& b
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,; X4 G$ m* S3 j: P- q( x. ?/ D
  333.                         const char *text)
    / \) O) N' v1 b- i0 H% o% q6 e) ^
  334. {
    . U- ?, n( t; D+ D* O' y- N0 z
  335.     return LPDF_OK;6 _* X  Y1 q6 e8 D6 h+ Y; Y* Z
  336. }
    4 A& B: }6 H6 [5 u3 S" p2 R- M
  337. 7 O' @  O; t# }5 a8 j2 @
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,2 T/ Z  X3 R4 L# t- R
  339.                          LPDF_REAL r,7 t! ?' b8 [3 `3 b% R6 l
  340.                          LPDF_REAL g,
    7 ^0 O$ G2 }6 t9 T, b, N! P4 Q
  341.                          LPDF_REAL b)5 z( Q, X' Q! p5 X
  342. {
    4 F, m* I* ~& Q+ @
  343.     LPDF_INT length = 0;
    9 b, D  K4 K* l+ I
  344.         LPDF_UINT writeBytes = 0;9 s5 [* Y- m* [2 @
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    1 _0 ^# H+ y7 W( j
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);7 a5 W5 b9 r8 {: S
  347.     if(LPDF_OK != ret); \4 _9 ]' h4 Y2 t/ ~
  348.         return ret;
    , B% T+ j/ I8 y2 M* R
  349. - _/ Q( Q- r2 L
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);2 R$ ]7 S+ N; `( Z; l' \" ~$ v
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    6 g) F0 W& W  E7 C
  352.     pdf->offset += length;
    8 `* T; H4 p) O) e( e
  353.     page->length += length;$ z8 m9 Q( Q+ H3 @  T/ B+ K
  354.     return LPDF_OK;; U+ E2 p2 ?5 S* R/ C, ~6 y4 _
  355. }: o" H' Q7 ~1 }, w: G$ a' l# J/ S8 U

  356. . u8 D* V, R+ b) P$ p; D
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,- E& L! T9 C' S( h
  358.                          LPDF_REAL r,
    - ]! Z) a# v' t: L- o1 [* [
  359.                          LPDF_REAL g,
    ) K9 T9 |0 J  i2 W) }" v4 K; F# m
  360.                          LPDF_REAL b)
    ! ?1 q6 v6 m1 f4 R, J, g' t+ k
  361. {
    - Y  M7 x: S: X7 ?
  362.     LPDF_INT length = 0;+ A5 L0 l6 g7 D- q
  363.         LPDF_UINT writeBytes = 0;
    : A3 C: F2 L( q( w
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;  ?: Y. V5 k% @9 h! k
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    ; t2 ?6 i+ O8 o: ^8 j+ z
  366.     if(LPDF_OK != ret)
    + N6 H8 L1 T% U) f6 f  ]
  367.         return ret;# V0 _  T1 `' |* q" S; r

  368. 5 T& m* t% H# x$ t4 i
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);
    6 p0 m9 b/ l$ [) y- G
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; @- S0 J8 B& U/ b7 |+ v" }, V
  371.     pdf->offset += length;5 M( p8 X& @3 P1 {' u. ~5 }! k
  372.     page->length += length;
    6 F, `$ \7 e7 |
  373.     return LPDF_OK;6 J! c+ c6 D; T0 i+ q
  374. }: P" z4 d) a+ f4 B2 i$ d, `6 x
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,! G# f9 C1 M( Q( Z/ s- X2 u
  376.                          LPDF_UINT16 x,+ x! X& n+ h( A3 [( p: k
  377.                          LPDF_UINT16 y)3 l# H6 p. @! s
  378. {
    3 v/ l$ n. r; F8 z7 a
  379.     LPDF_INT length = 0;1 h; D3 _: p+ X+ L* d+ L% D% v
  380.         LPDF_UINT writeBytes = 0;
    - o( Z( x% X& p; S% h% E. D( \6 W6 u  a
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    8 X+ ]  W4 I2 E& ?& |
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);2 G! \0 N6 c4 ]5 _
  383.     if(LPDF_OK != ret)
    7 Z* E% w% t, c
  384.         return ret;1 _% n1 e  K( f: s
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    9 e( n# L% l# a. J
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);9 w' [% h9 s. e- O$ f9 d
  387.     pdf->offset += length;
    5 X9 u: P; h$ i) B: b
  388.     page->length += length;: b6 c3 s( w: ?* p
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    8 V6 X( f) x: f; z8 S; @  H) I
  390.     return LPDF_OK;
    7 r% Y* s( p( p& V
  391. }
    * |9 W( e/ W# C$ N+ Q2 Z+ q
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    ! C0 ^* }, ]5 x; A, Q, Z
  393.                          LPDF_UINT16 x,
    7 s; A: S/ e( H8 u1 j) U' q
  394.                          LPDF_UINT16 y)  \3 A1 G& x& |* X9 ?5 D
  395. {
    7 ]( b* P( F  x) p: o0 w" P
  396.     LPDF_INT length = 0;
    ) _, Q2 g# Y( `( u
  397.         LPDF_UINT writeBytes = 0;% a1 ^& S6 ^* O' [" b$ v. r  i
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    * a1 p. |1 j: F9 u. ~! y' Y
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    ' i9 L7 ~# d* q6 ^8 U& m# [
  400.     if(LPDF_OK != ret)! H* k. Z% E% c7 m0 [
  401.         return ret;
    % s# X( O9 k2 I, i  y9 `! s
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    ; ^$ D7 z. f! L3 Y% v* \
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    0 D/ M& `1 d+ A( g
  404.     pdf->offset += length;3 C$ z; {% _# J
  405.     page->length += length;' W6 G1 R  H# z
  406.     return LPDF_OK;$ o( b4 g( n* h( z* S" ]
  407. }1 |" _3 J. x5 X3 H1 R
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page). A/ ^1 ~8 J) ]* {% q* H- c3 p3 E4 Z
  409. {/ A5 E1 W. A2 D1 O  k# n
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;2 q3 W6 ~) D$ \2 w
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    - v1 g' Q7 P$ C1 ?# t1 b5 ~
  412.     if(LPDF_OK != ret)
    9 i+ p- g! n0 y
  413.         return ret;
    1 Y( |5 S+ H. s
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    ! e% m: i$ D" W$ \8 m+ {4 h
  415.     pdf->offset += 2;. x( ~) |8 \0 ^$ Y( e# U- \4 \
  416.     page->length += 2;
    4 {! z: ^9 p/ I- F  S/ \
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;& c( M1 P7 B0 x2 p2 g4 o5 l
  418.     return LPDF_OK;( S' l$ t( z) ~
  419. }& f3 }: i) q" S# ~. B9 A
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,  Y& G6 }2 C3 T8 T5 W9 K
  421.                       LPDF_Image image,
    ' J: V: ^% i8 O% l, d0 i
  422.                       LPDF_UINT16 x,# f( E% R5 ?% F  x2 v8 E, |
  423.                       LPDF_UINT16 y,
    & \+ {( a3 G$ V5 v4 x, ]
  424.                       LPDF_UINT16 width,
    + e) {3 Z: Q0 Z4 L; ?9 G5 a
  425.                       LPDF_UINT16 height)
    : w/ X9 _( b; [, D
  426. {
    , R4 O! C' a  g# \
  427.         return LPDF_OK;
    ! b- o7 P/ j; v* g+ B% \1 n1 z
  428. }
    ( Q- C7 ~0 X- V# [
复制代码

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

  1. pdf = LPDF_New();# c' V' F$ W/ W
  2.     page[0] = LPDF_AddPage(pdf);' T- [0 s# v& t4 I6 }
  3.     LPDF_Page_SaveParams(page[0]);; ]9 m1 g* Q! s6 _. H% }6 d
  4.     width = LPDF_Page_GetWidth(page[0]);/ c  a1 I$ _+ ^8 e
  5.     height = LPDF_Page_GetHeight(page[0]);
    ( M& \% y/ K7 J- O
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);# G* h6 H3 V5 X6 r8 e2 o
  7.     LPDF_Page_BeginText(page[0]);: I, i" V/ _) o$ X9 }& x& ]
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);6 g1 f2 M: m4 d3 Y* a" m9 r
  9.     while(font_list[i])# z" Q5 r/ ?6 g- u# L# ?2 g9 e
  10.     {; V) N3 `$ u7 m! a5 V! f5 }
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);9 W% s2 s. \# a7 J1 z% O  j9 @
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");: d4 J/ A( L+ k6 @+ _# u4 V  ~5 `& r* ^
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);- t, Y; V9 a/ F5 R& e
  14.         i++;5 H3 \) _: e. s. }! |: b
  15.     }
    4 I$ X9 c+ ~0 [! d; e
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);
    ) t5 s3 [5 l; s0 h' M0 l
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());  r1 i1 e! \0 [6 Q: G
  18.     LPDF_Page_EndText(page[0]);; z$ Y1 b6 z0 z) n; ^( D' p* J
  19.     LPDF_Page_SaveContext(page[0]);$ a+ k" G6 T0 Y% W4 i$ y& G0 y
  20.     page[1] = LPDF_AddPage(pdf);7 l/ i5 _/ z7 |4 D! [1 [
  21.     LPDF_Page_SaveParams(page[1]);
    5 }+ W) B- J+ P# I
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);
    8 X* n+ t' H2 n7 k4 L/ d) L0 T
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);6 d" K; X; }9 O* W
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);8 u; {1 f  C" N0 j1 w0 s
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);* Y, M& O# g1 x0 o! v+ _, U
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);) B3 p2 g1 |* ^( L) c0 J! [
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);; P' I( Z6 h! t  j6 P; D
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);* V( }- O/ v7 }: w
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    0 Q% i# }5 ]2 _; m3 [3 c
  30.     LPDF_Page_Stroke(page[1]);/ h8 ~9 D- f3 w( |9 j
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    9 R& S2 E6 i* L
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    : N; Z  u, a. A7 s$ E" \
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);& v7 Q  G' E" f( _  D8 t4 s2 R
  34.     LPDF_Page_Stroke(page[1]);
    1 \7 u% p: h; S1 o- L5 v9 f
  35.     LPDF_Page_SaveContext(page[1]);& T4 P1 {: ^  x- h
  36.     LPDF_SaveToFile(pdf, "/red.pdf");/ P; Y( d7 j' W; _, x& p1 U
  37.         PRINTF("\r\nCreate pdf file success!\r\n");* T' g* K$ N' M' U# g
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了: a$ @' S' \3 M/ \2 b8 t

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    4 T+ Z( v6 v) s+ o

/ A4 E7 a7 ^# L. i: `+ ^

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
  B; p7 J1 A$ [& I只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...

) D" X% o5 o7 @' |; YLZ,我怎么没看到有添加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:333 Z) i6 [7 |9 h  E3 a" C8 J8 U7 ~; V
首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
! S" W  g! w1 J7 G
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
$ X  N0 d: Q) `  \. L( l
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:454 T0 y+ @& Q8 j; o# w* x! E
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
; y& z* T7 V, M- w" |$ r: {
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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" k9 p. E3 c2 B! R
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

  E2 j; _# H: _% J9 Y$ i' a& n这个还只是一个简单的库,实用性还是差一些的
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' g. D! _! U0 t. F
ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
9 F4 @2 f# q0 I' h" f" [9 j
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22. d5 s' l0 N0 I$ }8 m2 N8 ~6 z: T
ff.h是FATfs中的文件
8 T( u1 P+ A% B  o% F- e; A
嗯,这个画线能改变线宽吗

所属标签

相似分享

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