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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 . Z. P: o# W0 N: m

7 @, A3 m) \1 _

主机环境: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__' a. f9 A4 e- [/ z2 L1 u# _% T
  2. #define __PDFLIB_H__
    * c9 a& Z. H0 S
  3. , {  b, @# n# q3 ~7 s. v
  4. #include "ff.h"* }) W6 U+ t3 O2 o7 R  p
  5. /*----- standard C library functions -----------------------------------------*/" |" J" ?% J5 @, Z* p

  6.   z* p* r. W0 C0 i
  7. #define LPDF_FOPEN                  f_open
    $ ~& G7 P$ j* K8 m7 H: v) J& A7 q
  8. #define LPDF_FCLOSE                 f_close
    2 b3 e5 |2 p- t1 Z9 x$ S
  9. #define LPDF_FREAD                  f_read! s) s8 N$ O: \0 L* ~/ O
  10. #define LPDF_FWRITE                 f_write: L+ U; ~8 |( y* h- p* n5 g; M
  11. #define LPDF_FFLUSH                 f_sync
    ! a) H; L" g" X) p# y& o& A
  12. #define LPDF_FSEEK                  f_seek$ w) i$ P8 P: L" p! G1 x
  13. #define LPDF_FTELL                  f_tell4 Z8 K% Q3 [& j6 O0 S9 t
  14. #define LPDF_FEOF                   f_eof
    $ {9 Y% D+ Q4 b
  15. #define LPDF_FERROR                 f_error
    4 V. X' }9 ]" w' ~- j8 [
  16. #define LPDF_RENAME                 f_rename
    ' [3 Y( ?8 D5 a! y. A
  17. #define LPDF_REMOVE                 f_unlink9 M9 v3 K0 p, O7 Y' x( y
  18. #define LPDF_MALLOC                 malloc
    - w, Q5 p. q8 i3 O8 G
  19. #define LPDF_FREE                   free
    * b5 b, e% l6 H1 f  o% y9 T
  20. #define LPDF_FILE                   FIL" M0 D5 D5 t2 [) z: \2 {
  21. #define LPDF_TIME                   time  I9 B! i( ^: J! Y
  22. #define LPDF_PRINTF                 printf
    4 N, G6 o  s8 i5 l
  23. #define LPDF_SPRINTF                sprintf
    4 o! \8 _* j5 K+ Y0 Y; e) |, w
  24. #define LPDF_FPRINTF                f_printf
    : \6 X& I) u, n, R5 P8 t; ?
  25. #define LPDF_VOID                   void
    - M# I! X% d+ P  u) _9 v. k
  26. #define LPDF_SIN                    sin
    % ~* d% K- B6 Q0 m; {
  27. #define LPDF_COS                    cos: Z9 t, `# @! _( G8 U
  28. 5 V: K2 A7 S0 P! Y! h7 _
  29. /*  native OS integer types */( |; l! A5 ]3 M
  30. typedef  signed int          LPDF_INT;
    9 `* b7 t! {- U6 z
  31. typedef  unsigned int        LPDF_UINT;
    . m2 {" y9 a) d5 ?9 s# B

  32. $ i/ m8 w* I7 v4 x4 K( m# V) S) S( U, ^

  33. ; j2 j3 S& C9 T+ Y
  34. /*  32bit integer types; Z: {4 Q5 W+ f& C; r* K
  35. */
    * u+ q' f8 t5 m+ l0 B) e) Y% K
  36. typedef  signed int          LPDF_INT32;$ V/ k, ~/ ]4 e  v& g
  37. typedef  unsigned int        LPDF_UINT32;1 K5 P  p" x+ s/ |" d/ o

  38. # b: j) |( e2 ^" a) K' j

  39. 8 }5 `- G: k' x- E5 s8 ]
  40. /*  16bit integer types  b4 N5 A$ l) h) v- }
  41. */( e0 U# z! T2 C6 @: U1 s2 O8 O9 e3 ]
  42. typedef  signed short        LPDF_INT16;- v: }9 E5 V5 q4 [& K
  43. typedef  unsigned short      LPDF_UINT16;6 D- }5 d# P, }3 O8 W3 D2 i

  44. # k6 q0 H6 b- G

  45. 8 v: |- h3 R) |2 T8 p( L
  46. /*  8bit integer types
    % G4 Q  r! s0 f5 E; s2 K0 q
  47. */
    9 [2 Y) ~3 ^5 u0 K
  48. typedef  signed char         LPDF_INT8;# ^9 x+ F' H1 |6 B
  49. typedef  unsigned char       LPDF_UINT8;
    : I8 C. b( z0 y+ j( z! W8 I& D

  50. 9 m( a& h: Q  r& b. ^
  51. ) M( h1 i9 A% I8 A- i* f1 Y
  52. /*  8bit binary types
    8 Y7 l: B  E. B& f
  53. */
    : S8 k, G$ G8 q
  54. typedef  unsigned char       LPDF_BYTE;8 O' u$ C: Y. O' l5 a, d
  55. % k+ ]6 \5 ?( r
  56. + k* E! j4 e+ L, w! n9 K. h
  57. /*  float type (32bit IEEE754)
    % F7 D2 X5 u: k) _, O' \1 V2 b
  58. */
    ( \; B9 m; l# a6 E# o+ {
  59. typedef  float               LPDF_REAL;
    * ?  h& Q- P) o+ ~9 Q
  60.   m- h9 M* f2 y2 Z) |$ x, A! @
  61. . j; `. e% Y5 a4 q$ i
  62. /*  double type (64bit IEEE754)& B% g  Q" Q% l
  63. */
    6 u$ S+ }! |) v" o+ s
  64. typedef  double              LPDF_DOUBLE;
    ; @# Y. A3 F  p- g  E
  65. 6 Z2 D( Y) L  ^4 X, ~1 [0 o8 v9 v) X

  66. 8 S4 _' n2 q; s* Q
  67. /*  boolean type (0: False, !0: True)
    6 p" S# |# o* Z2 `7 n: p
  68. */
    " z5 c' T9 w* A& Y) D. v# c4 T
  69. typedef  signed int          LPDF_BOOL;
    $ g$ ?6 Y9 t* M

  70. 9 ^8 G: b& h* v  L  o
  71. . K9 ^8 _3 b9 k( i8 h" C
  72. /*  error-no type (32bit unsigned integer)
    ) L$ R) q+ t6 g! Z
  73. */# I/ \$ |. a: E* x) T
  74. typedef  unsigned long       LPDF_STATUS;7 {- @9 Q& n5 g8 y- q

  75. + Z4 h: z9 h0 v6 ~* Q) i
  76. #define LPDF_OK                     0/ A/ `  j3 Z  `# s! H' `
  77. #define LPDF_FAILED                 1" d7 _/ o. r9 N3 W# L9 _- F
  78. 5 b4 _2 D' i# O- t/ [2 R( h$ s
  79. /*----- font state -----------------------------------------------------------*/
    & j: c! V/ n3 h4 n  S
  80. #define   LPDF_FONT_INVALID                 0x00FF
    / d: k  c4 r2 Z9 x
  81. #define   LPDF_FONT_COURIER                 0x00003 |3 b; k- U' E3 G4 G
  82. #define   LPDF_FONT_COURIER_B               0x0001
    " K- a; K9 b  c! I, p% y2 c8 }/ b! X
  83. #define   LPDF_FONT_COURIER_O               0x0002
    8 k0 W  e; x! `! R! G
  84. #define   LPDF_FONT_COURIER_OB              0x0003
    % F/ \  F& r# B  B; m$ Q
  85. #define   LPDF_FONT_HELVETICA               0x0004$ I+ v0 A) V) f/ ]6 R4 v
  86. #define   LPDF_FONT_HELVETICA_B             0x00054 v# Y4 h3 s$ C4 [  a/ p
  87. #define   LPDF_FONT_HELVETICA_O             0x0006
    6 r  Z/ z7 `/ z8 S4 c1 R0 k
  88. #define   LPDF_FONT_HELVETICA_BO            0x00075 ^- Z4 H6 |" z$ m1 g7 k5 s2 [% X
  89. #define   LPDF_FONT_TIMES_R                 0x0008( @7 h- R4 g6 F. x
  90. #define   LPDF_FONT_TIMES_B                 0x0009
    : z9 U) j. A$ c2 g- |7 l& [
  91. #define   LPDF_FONT_TIMES_I                 0x000A
    & k% |  j+ N$ _. M
  92. #define   LPDF_FONT_TIMES_BI                0x000B
    9 E1 }7 Q& S$ B/ W' ~. R# M
  93. #define   LPDF_FONT_SYMBOL                  0x000C
    - G5 R% J0 H% u% n% p
  94. #define   LPDF_FONT_ZAP                     0x000D1 B6 t9 k4 R8 {$ H5 W3 E
  95. /*----- Graphis mode ---------------------------------------------------------*/* R- f- d+ }+ L, r
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001! O5 z9 `8 R3 w2 `' l/ Z9 V" N" ^
  97. #define   LPDF_GMODE_PATH_OBJECT            0x00021 m# {' W' P$ W) O! D. `0 V
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    & J& L; ?% u2 m6 O2 G$ @1 o
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008) h7 N; j1 W1 _" U  c; F
  100. #define   LPDF_GMODE_SHADING                0x0010* n5 x4 Q7 d  X  E
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020- W: M3 Y) n/ d& I) H: l; P  c, M
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040% v' v5 Z. s4 V/ w  g7 U& d
  103. #define   LPDF_GMODE_INVALID                0x0080
    , y: |# @5 P- V! q* B1 M2 D0 p
  104. #define   LPDF_GMODE_OVER                   0x0100
      }$ d  f: E+ @9 U. @- i. g8 i: A

  105. ' i6 W3 k9 n0 H+ q: ?1 F
  106. #define OBJ_MAX_NUM     256. V: z; @- |- H

  107. 6 q; @, x& m& l  n4 G) q# D
  108. /* Page的结构信息是否需要树形结构 */  F3 c, t5 Q! m6 I$ |4 t
  109. typedef enum 8 i% ~: ]8 L! z0 d1 \) d. _# S% t
  110. {6 ~8 m! w. L( q% u0 N
  111.     OBJ_info,
    # i1 f3 u- V9 A% z8 i3 G: D: ~
  112.     OBJ_stream,, B4 f* [3 ^3 V! r2 @4 \: j
  113.     OBJ_font,% w: I! [+ g' Q
  114.     OBJ_page,6 B) j9 B0 e( R. D0 u$ ?
  115.     OBJ_catalog,
    1 x0 [$ K  N' V, @2 u. u
  116.     OBJ_pages,
      p! x  j* g( a/ W
  117.     OBJ_image,3 A% Q/ P% n8 N
  118. }LPDF_ObjType;) r9 ^5 g- d( Z# p3 A3 ?+ b

  119. 2 E6 ]" b) ?1 o
  120. typedef struct
    ' z3 o9 M9 Q. a% H4 Y
  121. {( H  |  @6 S1 M9 @5 t! w6 _
  122.     LPDF_ObjType objType;* H# `" j8 g5 F4 H
  123.     LPDF_UINT16 objIdx;
      B+ R& h3 i, n9 z* l
  124.     LPDF_UINT16 height;
    5 o, y! ^+ M/ R& N
  125.     LPDF_UINT16 width;
    1 c* c) y) w/ j5 L# z% z. W
  126.     LPDF_UINT16 length;( \& y4 j. G  S1 T  a& d
  127.     LPDF_UINT gMode;
    : i: z: ?) f; T+ b
  128.     LPDF_BYTE fontType;
    7 H2 e! m' s/ d* Z% f1 Q; v
  129.     LPDF_BYTE fontSize;
    . `: {" h& ]7 j% B  k* c* G0 c
  130.     LPDF_BYTE pState;( R0 B/ b# }6 W4 y! M
  131.     LPDF_VOID *doc;5 v- x- R6 `. F! W) p
  132. }LPDF_Obj;
    ; h/ u( Y2 t7 _
  133.   C- D7 [* E0 c7 w6 I2 b/ c
  134. typedef struct) h: M/ a$ f$ E+ u; ]3 x7 X
  135. {
    - r, M+ w: {% T. o' d3 T! l0 T
  136.     LPDF_Obj obj[OBJ_MAX_NUM];- Y  C' v8 o- W# l2 }
  137.     LPDF_UINT32 offset;
    - J& s6 j4 C) o8 ^0 l/ G" {
  138.     LPDF_UINT16 objNumber;
    - B+ j& {, S3 }5 o2 Q# S+ R
  139.     LPDF_FILE file;$ u+ R% w$ P" V# y
  140. }LPDF_Doc_Rec;# @6 N5 b! G1 |$ R' T$ `( P( U

  141. 7 B9 V* u, q2 s5 U  c2 a1 i
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    % q, C' k9 a, c, B4 J
  143. typedef LPDF_Obj *LPDF_Page;2 ?. T1 _# X8 h) S( i3 O9 p
  144. typedef LPDF_Obj *LPDF_Image;% Q9 u& T/ L9 S8 v$ c
  145. extern const char *font_list[];% h3 A- h7 l0 D: P; F0 ?
  146. /*----- LPDF Interfaces-------------------------------------------------------*/
    " x& t9 n$ o+ U9 h; o( q6 i
  147. const char * LPDF_GetVersion(void);7 @; C9 H+ A& D0 X
  148. LPDF_Doc LPDF_New(void);! U0 }$ p8 ^3 {# K! S
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);6 Q5 v/ z- W7 @% N+ |2 }- B
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);
    ( E5 R4 r8 N8 [( g3 Y
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);
    + x# |; {4 t  k
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);, }9 X0 }- V% Y3 T5 [3 m
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,' M$ M4 K$ k/ d4 k  G
  154.                            const char *font_name, LPDF_UINT8 size);$ `" Q% F# T+ X2 ~3 J
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);
    7 m/ A! R  J* @' M
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);
    5 e, h2 a2 v7 l+ s
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);
    3 v3 }/ T7 |" |. {" v+ @  U. F; c
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);
    * l- G3 C, ?. f& J7 x% {6 G
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);! m! ~/ \  z( [! s- p( V6 N- h' {
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);
    & p) ]2 B- s; J  J0 Z6 J7 ?$ ^7 ?$ P# L
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    6 P( b) Z+ P; V
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);6 \5 n4 q) N6 k' s# J
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);2 p; ^! ?: t4 y1 i
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,% i8 a: H6 C) W+ A# F
  165.                          LPDF_INT x, LPDF_INT y);7 p3 F4 o+ f- y; u8 z7 a
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    9 p% d5 b8 Y: Z  O; f- U% o- u# H$ E1 C6 l
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,
    , m+ m3 \1 f) @
  168.                          const char *text);4 N+ _4 q' S0 f3 w
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    9 L+ T. K# w$ M. Y; S4 r
  170.                          LPDF_REAL r,
    1 g  }- A0 ^1 Q
  171.                          LPDF_REAL g,
    6 p% N) D8 R9 n  ~3 G. ]
  172.                          LPDF_REAL b);
    / l/ q' l; F( _" |6 @" h
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    ' C8 n5 W$ a* \
  174.                          LPDF_REAL r,
    * p) Q. Z3 ]6 x( U
  175.                          LPDF_REAL g,% i* m0 P0 N: N
  176.                          LPDF_REAL b);
    2 s5 U9 }% n8 e3 [" _
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    * y0 z! G1 q" R* T4 c" q$ ]; E
  178.                          LPDF_UINT16 x,3 c0 T7 `7 I- J* d
  179.                          LPDF_UINT16 y);0 w1 p. P. {4 ^* B
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,4 p% X0 q! s1 g# c' g! y  j/ G% U
  181.                          LPDF_UINT16 x,
    ) Z+ ^0 {7 {$ Y) B2 Y( ?6 l
  182.                          LPDF_UINT16 y);
    & ]& y5 p9 ]3 d0 P0 D
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);
    $ z# ?$ D3 {* I& n0 Z
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);
    7 _% g& _! @# X4 {) @
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,8 Q( t5 A% T6 d; A" @8 ~- h0 L
  186.                       LPDF_Image image,
    6 g) L: R* j9 x- D% T& X' u/ [
  187.                       LPDF_UINT16 x,( J5 Z! M0 ^7 G  d! J! U$ e  F* Y
  188.                       LPDF_UINT16 y,
    # k$ k' r: `7 S
  189.                       LPDF_UINT16 width,+ S2 P7 \$ I8 \8 H
  190.                       LPDF_UINT16 height);
    . h- ]: p5 e( G9 z
  191.                                                                                         7 W" o7 e6 A" R9 ^% T
  192. #endif1 O) [( m. p+ ~3 N! p0 ?8 G, ?# N
复制代码

源文件如下:

  1. #include <stdio.h>
    - B" @% H5 C* l9 R
  2. #include <stdlib.h>. y& C) A0 R0 y4 N; Z' D
  3. #include <stdint.h>& n' @' J3 u1 q2 N4 C
  4. #include <string.h>
    ! ^6 l4 _; `$ J: A
  5. #include "pdflib.h"
    ! ~: P4 n- x+ e+ m

  6. 8 C( N9 ?0 [/ C8 B& U8 p" q1 D
  7. #define LPDF_INVALID_OBJECT                       0x1033
    2 ?1 `5 G' b7 f/ v- X3 T0 o" ^/ q
  8. ) ^4 G1 q! q! d8 K
  9. static char pdf_buf[512];
    + M+ W% z7 ?& c8 ]# a
  10. 9 \. Q9 c( ]) C& O
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"& g) V2 v* u8 O% k1 f1 V) E/ w" N
  12. #define LPDF_FILE_HEADER_LEN        15
    / ]$ f5 G; @" O/ W% M
  13. #define LPDF_BASEFONT_NUM           14
    * K* V! X: H8 `- g
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    6 u+ I( i0 \2 b' S  M
  15. const char *font_list[] = {
    4 S6 |& O* U+ J; i5 [
  16.     "Courier",) h) j* |. Q5 I: c
  17.     "Courier-Bold",
    ( l* n8 ~# X' R/ _. k% R
  18.     "Courier-Oblique",( s7 `$ _7 Q3 M5 i  E8 V
  19.     "Courier-BoldOblique",3 F% J- E' Y" v5 }& L
  20.     "Helvetica",
    . \2 _* f" {7 [5 F2 h) S
  21.     "Helvetica-Bold",8 u1 N* l$ Y  P  f) w  G
  22.     "Helvetica-Oblique",
    7 v; ]2 \$ \4 F
  23.     "Helvetica-BoldOblique",
    + W. r7 Z# c( s  X4 ~' Y; {2 T
  24.     "Times-Roman",; ]( x1 N( f" J% D4 I4 v: C7 V% E
  25.     "Times-Bold",
    ( v5 i2 x5 d+ G6 V1 |
  26.     "Times-Italic",
    : D! K5 E8 n! ~9 Z/ s- m; H
  27.     "Times-BoldItalic",
    + p3 v' A. b1 `
  28.     "Symbol",. b; M# T( k2 f+ O6 K% o
  29.     "ZapfDingbats",1 Q8 n" R: B# D/ ~
  30.     NULL0 Z+ \0 h. _  d6 d9 j" H
  31. };, I; t( i9 l( d' V
  32. 8 w, X$ C8 s: M  }: @: ]7 e
  33. * ]% @4 t6 l/ Q7 {# x. C$ @, U
  34. const char * LPDF_GetVersion(void)& ]6 l9 ^& M) o5 }2 A0 d& w
  35. {
    1 Y4 P/ ?. S/ {+ X8 |8 F$ D! S0 y
  36.     return LPDF_VERSIOIN_TEXT;
    4 G1 x, A5 f) `& G
  37. }+ p" n# v4 {( G  \0 V, o# x  S

  38. / W. \1 U  B9 @/ V
  39. LPDF_Doc LPDF_New(void)
    ( J0 g; L1 |  j; N5 V- u" ]
  40. {
    7 z+ P5 s/ d2 _) C( e
  41.     static LPDF_Doc_Rec pdf;
    2 V& w1 R. S4 w" c3 ]& r3 O
  42.     LPDF_INT length = 0, i = 0;5 \6 H+ i9 l5 |4 a
  43.         LPDF_UINT writeBytes = 0;/ [( ~$ W/ G( E* z& G! `2 g8 J! r
  44.         FRESULT fr;
    4 w  X* `6 N4 m
  45.    
    : M7 \  Q  L5 O+ D, w0 n7 s
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
    ; C  L% a. T( @3 D& S- N
  47.         if(fr)
    % F: w- G' R- \* z% y' g
  48.         {
    3 k$ L( ^2 K$ w2 F2 l2 |4 N
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    ( u* w+ ?$ f7 Q
  50.                 return NULL;
    4 K) _/ R! O# @- u! _
  51.         }
    0 ^; \: L' q6 l, ^$ ^! R( ]
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */
    7 M$ B1 [$ b1 S
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;
    $ g2 V! w$ l$ O, N5 @' ~( S
  54.    ) H0 ~) J; ]; c! o
  55.     pdf.obj[0].objIdx = pdf.offset;
    , Q% K9 r/ e; E4 Q+ U" P( w
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");/ y: S  W9 M7 e2 O! A
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);8 h5 u2 @; [- G1 J/ Y1 l
  58.     pdf.offset += length;
    & |- _- p/ _' O$ a; }5 L) \- D
  59.    
    : R' G) r) I% v( U, T8 D7 ~
  60.     pdf.obj[1].objIdx = pdf.offset;8 G+ @+ N9 b- J# h$ e( G" I" B
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"% \- G3 U9 H- U& I8 h! o
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");; `! a. y+ A9 a. y
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    4 q: e" }5 |) p7 A6 S
  64.     pdf.offset += length;6 \# }1 @  r4 ~3 H- r
  65.     1 f9 f& P3 s$ N0 R5 v
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    6 {" `( w# I6 E: n2 q9 o
  67.     {7 M: Y1 G3 I6 F5 t
  68.         pdf.obj[2+i].objIdx = pdf.offset;
    ; T2 [  i* X% F8 A1 f
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    2 [8 F9 Y1 S# s. S
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"! X3 W/ |  v) }0 l5 M) B8 p! E
  71.                         "endobj\n\n",3+i,font_list[i]);
    # ~; X0 w6 L4 V+ v( I) _1 T7 g7 s* d* s
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    2 C6 o3 e3 K* F; U" ~/ O( e
  73.         pdf.offset += length;
    2 m. D* D7 w# u
  74.     }2 y4 W6 y  S" f; k
  75.     for(; i < LPDF_BASEFONT_NUM; i++)
    - u2 e# {% H8 @/ L1 y* Z0 Y
  76.     {  J$ i2 N4 W) M0 n) H, s. `
  77.         pdf.obj[2+i].objIdx = pdf.offset;6 v8 A, S$ P, j" ]% J
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    0 v, `  |8 Z& Q
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
    ; \' [# F( a3 {& v0 {
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    ! c, \( K# M3 w, a  ~/ b
  81.         pdf.offset += length;: R) Z% s# R4 E( x! v) Q" J
  82.     }" D; n& _7 |0 _% S
  83.     pdf.objNumber = 3+i;
    & i+ H  @- w9 A9 t0 G7 A2 N
  84.   0 m) ?% e* [3 O
  85.     return (LPDF_Doc)&pdf;
    ! P# s9 e$ K3 w& B% t7 D0 _! m& S
  86. }
    8 V, @! s! X7 C' B' L

  87. " j! e$ X6 p  O( |" F1 @
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    + `' w. t! F+ w3 p$ ?% m
  89. {+ U( k/ T; T% a. z  X1 I7 i- s
  90.     LPDF_UINT16 i = 0, child_pages = 0;
    , ]3 r6 |9 r2 n0 i
  91.     LPDF_INT length = 0;: }% d9 F+ H( z9 u& d. X" y6 {
  92.         LPDF_UINT writeBytes = 0;
    2 w/ f% M& h& y! e/ Q1 k* K
  93. ( P6 a: F$ I# S! T" I3 y
  94.     pdf->obj[16].objIdx = pdf->offset;
    + B/ t" n: S/ n2 S  y+ P
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;
    4 U6 |. @3 ?- w0 [; b
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);* B" Q) v0 p% F) G- Q
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; Y: g/ i3 Z$ |8 K7 E
  98.     pdf->offset += length;  O- i# b8 I( T- l  b. s
  99.     for(i = 0; i < child_pages; i++)1 V8 m1 d2 K8 B( y
  100.     {& R0 S  {' i* y! B
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    ) v" b0 ~+ K4 `/ E! B6 T. f5 a
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    " |+ c& ^2 y7 T  v
  103.         pdf->offset += length;
    ) Q7 [: C. Q9 B: o
  104.     }1 L, ^& }' x. ~! i  l" l
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");" g3 M  @  L  z. x1 ?# P7 U
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);, Z$ a- E% p' r4 D9 U- Q+ S0 M! b
  107.     pdf->offset += length;
    , g0 l# q  u( `+ l
  108.    
    5 C5 C% J0 E& H) t5 }. V2 `; k. S+ C9 T
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);' Y. O4 `( E0 ]8 N" S6 @- {
  110.     for(i = 0 ; i < pdf->objNumber; i++)
    8 Z* B& Y, a% L/ I
  111.     {
    0 o! Q% {; r5 ~5 S$ A
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    + @, B: j4 F$ l3 Y( ?! R& i  s- C
  113.     }% ?/ O6 e( C+ y- m! a# _
  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",: w! w, V0 x, x/ y
  115.                 pdf->objNumber+1,pdf->offset);
    # S: S, q% I* z$ D& l5 U( M
  116.     LPDF_FCLOSE(&pdf->file);
    9 ~4 j% K( X5 D# P( A5 l& n
  117.     LPDF_REMOVE(file_name);
    + X; C& q( n9 p$ p% E
  118.     LPDF_RENAME("tmp.pdf",file_name);
    1 ?0 W: q4 I8 ]- ?; R# F2 r1 t
  119.     return LPDF_OK;
    & }6 w; O& x0 t2 |4 N" J  |
  120. }) z- c7 L' Y" g0 m
  121. 3 N0 k, f& V1 D0 p- l8 H
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)
    5 I$ B# b9 d3 G$ j9 u  k  ^
  123. {5 C# w6 p+ n( S" {
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);* A+ C+ y! @( V" l. q7 l7 ^
  125.     return LPDF_OK;
    4 W- B, M8 w) `/ U% J! R
  126. }
    5 a) H# Y# ~, v6 P1 [) e
  127. 9 G* t, X0 x. _5 L; H  j% ^) b
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)
    8 z! |6 _1 a4 |
  129. {7 |+ G/ n4 w, _- {
  130.     LPDF_INT length = 0,i = 0;9 S0 Y9 t7 o( M# ]  u& v
  131.     LPDF_Page page = NULL;
    8 @& f6 O- l" a% T8 |( E, R
  132.         LPDF_UINT writeBytes = 0;
    : N4 r3 J6 T+ b" v
  133.     - e( C" W9 s4 |% T
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    ) g: `4 Y$ G2 E1 }, e: x
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"
    ; |2 u5 K. i1 \
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    7 s7 L% Y( |% f8 h- e; u" k
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);* d, R- {0 `/ W$ S8 Z) d' M
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    . A( I0 z# W) j% n9 m
  139.     pdf->offset += length;
    % f. U* ^( P* T, R- _: ?2 M
  140.     while(font_list[i])
    0 H) P1 R( q* E/ V5 ?- z! X
  141.     {9 h7 s0 U  N5 n# J5 ]# r7 \
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);( ~- c& L- _7 }3 t+ p. h
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);4 q# e" Y6 [0 q3 l' i: R. |
  144.         pdf->offset += length;7 E8 q2 b8 @1 t# K* D% |# R
  145.         i+=1;% f# m8 V; ?4 k/ k7 t
  146.     }
    9 B% j0 @: a  J/ M
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");0 h3 ~9 o7 u" i  |3 A9 ?( o: F
  148.     pdf->offset += 4;2 X; h% m( i/ S) f+ B$ Q) W/ ^
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];. s9 M; ?+ U2 O* ~( D5 _% L. _. Q1 b
  150.     page->width = 595;4 j% [( n, z5 ^: ?
  151.     page->height = 842;# j* [; f5 X( |# B. b0 k; N
  152.     page->gMode = LPDF_GMODE_INVALID;/ A( U5 K. U% ?
  153.     page->fontType = LPDF_FONT_INVALID;3 y! }& c4 L* c( s" I/ \' ]" J
  154.     page->doc = pdf;
    % s  u; z# W$ W! z6 C+ ^0 h5 s
  155.     return page;8 ]) T% c! c& X( j8 Q
  156. }( c( p. Q7 ~) P2 m& O( Q! t
  157. + v+ C4 p: |% _; u: ^$ q' m
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)$ L1 d9 n( Z- Q, j8 r
  159. {
    9 q6 L; w" r1 u1 H: e" F# f: {
  160.     page->height = value;/ E; `) ~6 B& g
  161.     return LPDF_OK;
    7 O  e2 M: k, Z9 W7 u1 a
  162. }
    $ l$ G9 Y; a5 Z" L5 L
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value). ?& V  x# X4 S% F+ _; t) d- f- C8 C
  164. {8 H$ |: C) \! o) Z2 R# G, |8 G
  165.     page->width = value;
    ; a  P& e+ O  G  c  S
  166.     return LPDF_OK;
    + }% B7 y) b" @
  167. }
    - r1 a1 p- C2 W, A4 \+ L6 V0 M) W
  168. 6 I9 o, ~8 }8 d0 J' L) z
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)6 B* w2 W5 ~& K2 ^9 p
  170. {
    . F. p2 |5 b. |9 a
  171.     if(page)  ~0 I# {" T' W
  172.     {
    ; X) g- F+ _, G
  173.         return page->height;$ a6 p- p3 B- K; x& w( `+ k! U3 z
  174.     }
      B  H5 P/ ?+ S' O8 {
  175.    
      n/ R. o5 |4 `5 W8 L9 P
  176.     return LPDF_OK;; ~# L, o- C8 N& Q
  177. }
    ; h. a2 J- N4 s& C# V  b& B6 E& R

  178. & v/ J' T: g$ ], A) H/ p
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    . w' l$ n, U% O- I+ D
  180. {
    9 F/ M+ p: g  @
  181.     if(page)
    7 `. n6 v5 Z) o! V# l) R
  182.     {3 }" o4 ?/ n. U" u2 D" @. X
  183.         return page->width;; d; E5 y( [; F+ l/ [
  184.     }( [$ `' m, ?9 T" _8 f+ K# o
  185.    
    5 j2 S8 U0 v9 E
  186.     return LPDF_OK;2 D, Y/ o4 O* \: R/ H- e
  187. }
    * g9 c: I5 N3 u( B& d. @" U

  188. 8 ?7 |! C- q& e8 Z1 P
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)$ O; X9 Q+ [% d% \. u
  190. {( G$ E, |8 w( J4 [% j
  191.     if(!page)
    1 Y$ z5 E  e6 t$ y* w
  192.         return LPDF_INVALID_OBJECT;/ J* Z6 m- G4 s1 g
  193.     if(!(page->gMode&mode))1 l$ \8 A- M. t4 R
  194.         return LPDF_FAILED;
    ) ^9 Q( ^7 `' `+ b

  195. " q7 e' K1 n$ j% H
  196.     return LPDF_OK;% Y+ E4 [( I7 [) P
  197. }" z' U  d# C3 j1 s6 r9 v

  198. , O1 S! D9 Q0 Q
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
      x+ R/ U( g; d( L0 h# y9 v  i6 \
  200.                            const char *font_name, LPDF_UINT8 size)5 k" f! \" X# c
  201. {
    1 E  n* }( S) u. z  `) @
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    # Z+ g$ Z8 ^- o* d& u/ x
  203.     LPDF_INT i = 0,length = 0;+ N, ^; O' |* _3 T: l- f, w
  204.         LPDF_UINT writeBytes = 0;% V% c. e( s& L+ ^9 |7 A0 U$ e
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);7 i/ O" }0 w7 N$ }0 N, L
  206.     if(LPDF_OK != ret)( i! p1 U6 e2 c3 V6 b% O2 W
  207.         return ret;
    * g$ Y6 L0 K1 Q, B+ N% E  Z- t. W
  208. ; G& ^! U; B9 _6 `
  209.     while(font_list[i]); y+ W/ O! U% B+ q4 `0 c7 K# O/ D
  210.     {
    0 P; l9 _7 I0 ~5 E
  211.         if(0 == strcmp(font_list[i],font_name))
    9 ^* U1 z0 Q. S1 V5 p# H/ k
  212.         {
    6 z3 e) J4 i$ C% l
  213.             page->fontType = i;
      w6 t7 I) k% _& L. t- g7 p
  214.             page->fontSize = size;- a( e3 j, l, L
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);
    3 d( L7 u0 Q2 l( F/ C/ Y, t1 X+ k
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    # ~! B1 Y! t2 }! K% |
  217.             pdf->offset += length;0 y8 P$ ~+ T3 K- e# y. n' P# j
  218.             page->length += length;
      F6 F3 I4 F, U9 ^$ F
  219.             return LPDF_OK;6 a! l3 z2 E" \6 o7 q
  220.         }
      H; I) Z  s2 E  [; i5 y
  221.         i+=1;3 c/ d3 E8 u& @) r* w
  222.     }$ }; e4 L+ S2 V3 U: I
  223.    
    : o) y0 \% V. ~" o
  224.     return LPDF_OK;
    . F8 j. P: E1 w8 y4 [
  225. }
    ! Y  X8 W- a5 e: r" c
  226. 3 `! Q+ F1 Z) ?' N! y' [3 W
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)1 o; r+ q+ |8 x4 b+ ?% a# u7 I
  228. {
    # \7 {5 X3 v# }+ e) O
  229.     LPDF_INT length;( b. c% j- _- `
  230.         LPDF_UINT writeBytes = 0;2 N0 @6 a) y  _! X. }+ m
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;% l; V8 }5 N& S! _
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);! m2 f( j4 e* M6 [* O6 [) i8 o4 U
  233.     if(LPDF_OK != ret)
    ; N' q) [% O- D6 T6 ~5 e
  234.         return ret;
    & @) r4 ^" ^, H3 S
  235.     ) L* Z$ B7 }' e7 W4 q
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */
      z( g& O( a; f- E4 w$ w
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
    - b- r9 [( f! H' `
  238.                         page->width, page->height);
    8 ^" s6 {& u( f: a! ~( A5 O
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    - U( T- {7 D' M3 `3 J' u* Z0 r
  240.     pdf->offset += length;. l: E/ K, i% A! ~
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    8 _/ a; {* q( c. a, g; r
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",
    ) p! \2 i9 `( G; m+ \$ V
  243.                         pdf->objNumber+2, pdf->objNumber+3);: o: _" v, h1 q2 m
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    5 J  P8 b' @0 q
  245.     pdf->offset += length;7 }5 J6 z) N" x
  246.     page->length = 0;  |7 b6 A& d' V! k
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;7 J3 D0 L; ~3 Y) V2 b: S
  248.     return LPDF_OK;
    , k% Y5 h5 a; f- `# \/ L% u
  249. }
    ' t# R3 Y0 e. G. t( K
  250. & W" K. }0 e0 M2 ^. k* l9 D9 R
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)
    / N0 j" u, ^" D4 W8 e8 H. `7 m; l
  252. {/ `! d6 ]! |  g% o
  253.     LPDF_INT length;
    - r$ N/ h- e( M. g, V6 L) N4 [
  254.         LPDF_UINT writeBytes = 0;7 f" z9 i3 w- `) K+ Q( R( A$ Z# q
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;& X3 W3 O% ], s. s
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);/ E  Q2 Q9 W; V; m' a; i& t
  257.     if(LPDF_OK != ret)  t1 t9 v" j1 z
  258.         return ret;
    , Q- ~4 a2 U9 [9 U7 r& t1 [& }
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    - T& B) D& B' g- t7 s
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    7 c8 }2 u; U% [( f2 a% D0 z
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes); * X# T0 l4 N- n
  262.     pdf->offset += length;
    , w* F+ [1 ~2 F, @
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;* h; K/ r; o5 h+ F& c. y
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
      N) n! Y# B* Q) U1 m; |- ?
  265.                         pdf->objNumber+3,page->length);
    ; w# i3 ^  h- O7 n; g1 p% o
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    3 {5 k1 [, q5 I  o7 g3 p
  267.     pdf->offset += length;
    " d( R: v6 l; B: z
  268.     pdf->objNumber += 3;2 k/ z2 Q$ w- f6 z. L: Y
  269.     page->gMode = LPDF_GMODE_OVER;. e( s  C+ K: _; j; w) @1 p
  270.     return LPDF_OK;+ i' x+ O  k# M6 q
  271. }
    9 H! a& P, V+ u  N/ ~* Q

  272. 6 N& e* o$ c% n5 d" `: ~# X6 M, Z
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page): \8 z* v+ r( t; G
  274. {
    * y: b0 j. x: s# F
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ! b6 J1 e$ s2 x* J+ u# z/ `
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);2 L! K/ n; l% G1 ?( X; h: t* n
  277.     if(LPDF_OK != ret)
    ( [3 \% F' V$ G
  278.         return ret;
    ; e% h1 e4 J( F
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");2 D: C, p( i6 r# P/ f1 n
  280.     pdf->offset += 3;* @6 \' V3 @+ o+ {# O+ L
  281.     page->length += 3;
    1 p/ N+ Z* q) E' b! w0 o! X; h
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;' o8 g% @9 {0 m+ b
  283.     return LPDF_OK;
    : p8 L: a! u: V" r! g: @
  284. }5 m- z7 c" h3 @; D4 w( ]% }
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)6 [/ G; E! n  ^
  286. {
    7 j+ O  M( i, E& G9 l
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;  ?* E7 {9 }2 D. Q
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);4 h+ b5 z6 ?& H
  289.     if(LPDF_OK != ret)# ?& T. u! S* a
  290.         return ret;
      V9 K- `. V8 d& f
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");( h3 Q* o* s1 v5 {
  292.     pdf->offset += 3;8 h8 ?% m  i! {% `
  293.     page->length += 3;
    ; @  W& y3 |) ^: @1 l5 ]  i
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;- _: P# d# b' `( h- l4 {" d: N/ I
  295.     return LPDF_OK;  a9 |- n9 C, Z$ F3 ]
  296. }
    , @8 C5 u; u. `- \( J9 q

  297. . \, n7 h" X2 c4 r: b: R
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    1 V" `! s' ~$ Q. _( z( j9 C
  299. {. d9 a- s0 l) `, `4 E3 B
  300.     LPDF_INT length = 0;( T$ p" \% t+ y$ s; X3 {
  301.         LPDF_UINT writeBytes = 0;
    & k2 ^  L( X! j# R
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;4 ^0 J9 R* ~/ f8 H  S
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);, F: d, |" Q# [
  304.     if(LPDF_OK != ret)
    9 s1 z. t( U) x9 M$ z$ y1 U6 ]
  305.         return ret;+ b% x  O2 \9 r2 R% n
  306.     if(LPDF_FONT_INVALID == page->fontType)/ `/ b3 @# k. A( I. L. P
  307.         return LPDF_OK;
    6 J# k, t. {) }
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);. c( |+ D$ o- S: Z' o
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ; n0 l6 @# g  l. a- r
  310.     pdf->offset += length;9 u9 c. c) ^" H" F
  311.     page->length += length;; q7 G8 k0 m/ O# A- b( r
  312.     return LPDF_OK;
    - x  d/ J/ \$ Z' d, q0 S. s9 b: v- P
  313.     4 R: d4 _3 O1 I# Y
  314. }- }' W+ y9 i* v" v' n
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    * I  X) U/ U& n" i
  316.                         LPDF_INT x, LPDF_INT y)9 M0 W4 Y9 _) J
  317. {
    ! d* j) _% t/ D  v6 g
  318.     LPDF_INT length = 0;
    7 u3 Q  l! P! g0 x
  319.         LPDF_UINT writeBytes = 0;# W, ?. Z; X' ^/ L& K' R
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;) x" l' L6 P$ E3 d: q" U- O
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);& C  k9 x( ?  |
  322.     if(LPDF_OK != ret)1 E# C$ ?) {3 ], ^
  323.         return ret;1 Q  h3 |  A; ^0 N1 u$ L$ j
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);# Z% |$ d$ _9 [0 N& P; l9 G
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);- t  Q( q, W$ {) l9 X& G$ d; v
  326.     pdf->offset += length;
    * e4 s$ s# I! P* {7 o
  327.     page->length += length;
    % v0 U3 z9 T7 ?

  328. 6 M5 W2 z* [: h) r2 b
  329.     return LPDF_OK;1 }, @% l) U1 p& T
  330. }
      ?( \. ?5 Y+ b) C+ W
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    3 O. N! ^' }  u4 B8 q) f
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,. `# ~. M" \9 u+ C/ f, S) b
  333.                         const char *text)
    , S& b9 a6 ~# i! `
  334. {
      D! h3 G  V- q+ t, ]* l
  335.     return LPDF_OK;
    ( O, U5 ?" x. x) W" U6 ]7 k
  336. }2 M; s& ^, u3 A6 u) U, h

  337. . e6 ?% M- [4 [# w
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,4 f2 p, Q. p% Z1 W6 e3 e! K
  339.                          LPDF_REAL r,
    ! O; \- S" P1 H1 e% N3 I
  340.                          LPDF_REAL g,
      ~( X5 Q# T$ _- |8 U- n* r
  341.                          LPDF_REAL b)( R( d1 d4 Z- W- Y/ i
  342. {
    . E# y$ U7 v" H6 l
  343.     LPDF_INT length = 0;
    + P& q8 n' p% \( [
  344.         LPDF_UINT writeBytes = 0;
    # H' H  U3 l" k& W7 R1 ?" N" t
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;8 D- O  T2 Z4 T% i' @/ m! P+ x
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    + X/ M; c6 j. M' z+ o
  347.     if(LPDF_OK != ret)4 \( O) t5 H5 G7 S
  348.         return ret;
    ! |2 P. q: _& _+ Y) A$ l% L( F

  349. 5 Z4 [% R& S; n, T
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    3 V) w9 T- }9 Q" g/ [& r7 g
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);1 C9 T" V/ D' Y  d
  352.     pdf->offset += length;0 ~- U8 ~0 ~7 X
  353.     page->length += length;
    # f2 W) X6 l0 P8 K% s
  354.     return LPDF_OK;3 H8 ?1 R5 \  @+ k/ n7 `
  355. }. W! g# y0 u: P0 W) ?* ]: A! s/ J
  356. 7 V  @; ^- b) \+ i' K7 c( n" ~
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,: \4 E! O6 d/ S/ y) i
  358.                          LPDF_REAL r,
    " x  b& s8 K3 J$ A( S# t
  359.                          LPDF_REAL g,
    8 z- I. Y% ]. P* f+ i: M5 Q
  360.                          LPDF_REAL b)3 V1 A' S4 z  b+ O1 K; ^
  361. {
    . ]# y; X9 ]* H( N! X( Q
  362.     LPDF_INT length = 0;
    0 o* Z2 ~5 `6 @. Z# a0 z; M
  363.         LPDF_UINT writeBytes = 0;
    . s% e8 X/ [, f; j
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;6 L: s  x3 L4 |( D
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);, e5 j( `" c0 m. U, N; E" U" C
  366.     if(LPDF_OK != ret)
    - ]$ A  ?- F0 a, Q
  367.         return ret;
    4 J( b: U) g( f

  368. / G+ J. R  u) I, O4 ]
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);0 f* l5 d& B" C: |/ |- X
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);# H& a4 P+ f! e( f/ L: [
  371.     pdf->offset += length;
    3 q9 `2 x/ n2 Y, a, m% C
  372.     page->length += length;  N# u+ r/ J# ?7 Z
  373.     return LPDF_OK;
    : `# X% j4 U) M  y
  374. }
    8 u6 l5 c) L) U0 y3 ]6 e
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,/ h4 c" d) d: d. a0 h; _# D$ y- r7 |6 P
  376.                          LPDF_UINT16 x,
    9 P8 W* Y# ]: G
  377.                          LPDF_UINT16 y)
    % S2 B; D; d+ `- b, m; N
  378. {$ X, a( \5 }& z
  379.     LPDF_INT length = 0;
    6 L7 u3 q+ R- |6 M! K# h
  380.         LPDF_UINT writeBytes = 0;
    + Y* p/ m6 F* C  L# u
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;2 X5 v1 j7 `- Q5 f* D6 Q
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);; r- o+ f( ^- z7 r+ W+ z1 ^7 l
  383.     if(LPDF_OK != ret)0 r2 N7 ?. M1 [4 Y  L/ N, e
  384.         return ret;
    ! i$ d% y: [! y  M
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);" y, {( R9 i6 u- Z8 ~
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    & f5 b3 r# u, F1 S& C; v
  387.     pdf->offset += length;. M) J0 ~* b3 {3 y5 T: k  g" W
  388.     page->length += length;; d- O) A2 X& J) q
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    ; D; \% s# j1 u+ y9 [( w$ \5 v" O
  390.     return LPDF_OK;, T% p( K3 B4 q
  391. }7 Q& j! f& r+ o( k$ g( B
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    7 S/ T! K0 P: F" n
  393.                          LPDF_UINT16 x,
    4 ]4 U0 G" @& Z
  394.                          LPDF_UINT16 y)! ^- g; E, x" T# d2 a# O( G
  395. {. ]3 y0 g+ U. Q6 ?) H
  396.     LPDF_INT length = 0;" W6 m& I! K) |2 t
  397.         LPDF_UINT writeBytes = 0;6 D  b, b. Q8 d/ Y5 t3 k
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;4 e" F: P7 h( R! m0 l! D1 p
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    ! ^& J* i: ]" p' P1 i& e) p% E8 ?7 O
  400.     if(LPDF_OK != ret)
    3 b# A8 C' H# n) B. V, m; q  G
  401.         return ret;8 Z2 B# T7 k6 ?4 r; a3 O
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    ' ]( v5 R1 C, ?+ K; c4 y& M
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    / C$ N- H& A# P  e" r/ R" l
  404.     pdf->offset += length;3 \( j# S: I; r" X9 N4 v" a+ O
  405.     page->length += length;
    5 n: l( a( ]+ z9 \
  406.     return LPDF_OK;& ^  M+ \* P' c1 V" B
  407. }
    $ Y# A4 R) G- B: n
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)
    $ u! |' S4 r7 r# {1 i
  409. {" P- c' Z% ]2 u% Q9 Z
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ' Z2 f( p, w2 m6 o
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);. u8 |; M4 Q* Q/ u0 B. a# w
  412.     if(LPDF_OK != ret)
    0 D: W. E6 ^8 u  w
  413.         return ret;
    # R( \7 S9 N9 W% }# V
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    9 a: t6 R2 N  j! ~: F
  415.     pdf->offset += 2;
    , h8 U/ q! V+ x, O9 g
  416.     page->length += 2;2 B0 }- Y; T1 W* z/ ]
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    # V) M4 b% x& K) B
  418.     return LPDF_OK;+ H. V6 b; T5 j3 }" {& p  {) y
  419. }
    , i% K7 C6 i5 N5 }. g2 x
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,4 _3 A( f+ _( I1 c& @7 l
  421.                       LPDF_Image image,# o3 i0 _3 s+ t+ f0 X; b/ p. B
  422.                       LPDF_UINT16 x,6 x2 |' }3 j+ G9 ^) b4 K
  423.                       LPDF_UINT16 y,1 y6 D$ A3 U! U6 [
  424.                       LPDF_UINT16 width,
    , Z8 F7 X4 z2 Y$ H! |  @
  425.                       LPDF_UINT16 height)$ C( k) Q. Q3 M8 ~
  426. {
    + I. y5 N; @1 P" g1 t
  427.         return LPDF_OK;
    ; B/ ?8 [9 n+ H  U( Q9 B
  428. }
    & Q7 t* R" \5 p- C: ^; N3 F
复制代码

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

  1. pdf = LPDF_New();
    $ ?* `* {( V9 g& ]
  2.     page[0] = LPDF_AddPage(pdf);
      m) @+ P; i) y
  3.     LPDF_Page_SaveParams(page[0]);5 ~( ^$ }- e% l% x
  4.     width = LPDF_Page_GetWidth(page[0]);# t2 K+ I3 z; E# A" f' z
  5.     height = LPDF_Page_GetHeight(page[0]);3 i8 m9 W" I9 M/ d4 P; e
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);/ K7 q. X$ i, [; u, r; E
  7.     LPDF_Page_BeginText(page[0]);
    5 ~: k4 R  J1 M) r' d) z6 }. ]
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);
    & G, }$ o2 T; c0 s. j0 g
  9.     while(font_list[i])6 v& w7 B2 d* P% ~; S; ?
  10.     {
    9 g9 l0 k* W8 ^
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    ! f% v* s& O( h  u9 u0 p9 `
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");
    * g$ w7 d; [5 x# y
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);! h( J8 q' I0 c7 u+ A* L
  14.         i++;0 c9 ~2 C, Y7 ?. B- ?: r- Z; v) u
  15.     }" [5 m* i. W5 y' S) d
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);# `4 c9 T* H* L7 |9 O
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());% ?2 X! o- p9 c
  18.     LPDF_Page_EndText(page[0]);
    0 y' ^: U# ?# e9 n) m
  19.     LPDF_Page_SaveContext(page[0]);
    * F) `! S+ u$ G5 W/ Y8 Y! Z
  20.     page[1] = LPDF_AddPage(pdf);
    7 K8 h; M% G$ c, q, i8 ~- g
  21.     LPDF_Page_SaveParams(page[1]);
    # q- H0 g5 z8 V" [7 g7 B* B
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);
    : ~. @" ?! O' s& E$ q" i
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);$ O7 E9 D  }+ t  {# R  G3 }
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    : i( Q+ n4 s1 s9 V+ V9 d1 b
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    6 r& p4 X/ N0 s( X! j" w% I
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    8 o3 Q$ @. y; h, G1 a
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);% a& C6 j3 {' ]) \% k
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);
    1 V; R! i9 }2 \* @" |2 I- Z5 A
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);" t2 e  W# U9 V0 s8 G
  30.     LPDF_Page_Stroke(page[1]);" G% g2 J8 L5 ?7 S: h
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);9 x7 `- H% k8 ^) p
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    . y. p3 A3 t0 ]2 N: m
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);% H8 ~3 y* ^1 c) j7 A, f
  34.     LPDF_Page_Stroke(page[1]);
    # w% |% X  }- D4 q9 B6 i+ `
  35.     LPDF_Page_SaveContext(page[1]);# y6 S5 y2 J7 ?( s# I9 h" [1 T4 `
  36.     LPDF_SaveToFile(pdf, "/red.pdf");
    # [! \# t; j3 Y( c* ^& @9 ~
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    , J1 C( r6 J, q# Y3 F
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了" Z: D+ k) G- d6 A" ]

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体, x4 G+ r# l7 S! B  E7 ~/ ^7 z0 Y
& ]0 W' @3 t' L6 P$ e9 s7 |* C  L

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:551 Q. j$ A2 s+ p8 c
只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...
- ^7 I- X% R  K9 k: A6 I7 P
LZ,我怎么没看到有添加image的接口,您的pdflib.c中LPDF_LoadRawImageFromFile也没有实现哇,您说的可以添加image,是哪里~LPDF_LoadRawImageFromMem这个是直接传入读到图片的buf么?有什么办法可以直接拿别的pdf中通过编辑软件看到pdf语法格式,拷贝图片的那段buf,直接添加到我自己的pdf中呢?
anobodykey 回答时间:2017-11-20 13:35:19
醉宇a 发表于 2017-11-20 09:33, T$ G) U# Y2 e( p& G0 }
首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
, `) `7 k! d* @" m8 f; S
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思& x7 s2 @" n4 K
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
0 F* q1 y( T& T. A, b" m$ L4 |6 c看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...

( ~# h$ H! }- ~' j这个我也还没遇到过,只是之前看到有人问这个,所以看看
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:447 `7 |! W  g) K5 l
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

( V/ X  p" x. |) L% b: L) v# 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/ G) R" y0 y* d
ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
9 V9 z$ Y; x  Q# P6 Z7 \
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
& C2 a6 E, s' H% h0 rff.h是FATfs中的文件

3 A5 K  e+ R9 p# w  S$ b嗯,这个画线能改变线宽吗

所属标签

相似分享

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