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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑
" ^. C; A( f" L) i- Y
2 t# p4 E8 Q+ n( d

主机环境: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__
    ' E" W! S9 P3 l0 M+ d$ d
  2. #define __PDFLIB_H__
    , t5 c$ H* S; F1 Z2 i7 x
  3. ) ~/ q) }2 t+ w% I9 U7 P
  4. #include "ff.h"
    9 R; [" @( g) F- R1 E; A2 t1 ~
  5. /*----- standard C library functions -----------------------------------------*/
    6 j" P6 u/ W4 X4 d% b

  6. * D: |1 _% I+ L, F
  7. #define LPDF_FOPEN                  f_open: l0 n4 N2 e, ?9 b  a+ S" Q
  8. #define LPDF_FCLOSE                 f_close3 F* _' h* q# r% Q
  9. #define LPDF_FREAD                  f_read* f1 J+ J4 C1 Y
  10. #define LPDF_FWRITE                 f_write$ }8 o9 y8 `' h: O/ a* _7 @
  11. #define LPDF_FFLUSH                 f_sync
    ) X. i, S, p8 J* A* o  b
  12. #define LPDF_FSEEK                  f_seek& Z( Y4 u! M$ v1 j/ b0 t: f# z
  13. #define LPDF_FTELL                  f_tell
    . Y& O9 `5 `9 ~4 j( ^' s
  14. #define LPDF_FEOF                   f_eof
    + m0 G7 g* ]6 ?7 d
  15. #define LPDF_FERROR                 f_error2 r+ L) ]6 b. b' M7 h+ Y! r" B
  16. #define LPDF_RENAME                 f_rename
    , d! h5 E2 X3 t2 Y& P* e
  17. #define LPDF_REMOVE                 f_unlink
    ) E7 B& G7 V2 ~2 l) r
  18. #define LPDF_MALLOC                 malloc6 I5 W8 q! A9 c
  19. #define LPDF_FREE                   free5 Y3 L' }6 C# z: Z( M
  20. #define LPDF_FILE                   FIL' a# ~- P; V7 R; X7 h+ b0 ~
  21. #define LPDF_TIME                   time
    9 q5 N/ b. t' x
  22. #define LPDF_PRINTF                 printf
    ! [( m3 U' V2 ]) a
  23. #define LPDF_SPRINTF                sprintf
    ! i1 ~) v5 w4 a; |6 ~/ S
  24. #define LPDF_FPRINTF                f_printf+ ~/ @  a* l; I
  25. #define LPDF_VOID                   void
    0 Q- z# S  \/ Q+ J0 u
  26. #define LPDF_SIN                    sin& n# J. U" p* E. d
  27. #define LPDF_COS                    cos" u- |" D  @$ X3 O& |& X; l) J' v. q

  28. % S+ K2 K1 A7 `
  29. /*  native OS integer types */! G* m% }  `% N2 ~" G' \8 |, o
  30. typedef  signed int          LPDF_INT;
      W1 k* M9 p. J2 Y: {
  31. typedef  unsigned int        LPDF_UINT;
    ) m. R+ U: X3 I$ n: o
  32. 5 ?" K3 d3 y. j# Q4 N1 s' S- k/ T( w
  33. / {/ G2 _3 r. ^4 ^& P7 `7 X, Q" V
  34. /*  32bit integer types
    ( z9 C( ~6 g" l* a8 d) ~4 |+ s0 R
  35. */8 H1 _) P) J+ g- ~
  36. typedef  signed int          LPDF_INT32;, M- P; N1 X4 `" ]3 F: M( |
  37. typedef  unsigned int        LPDF_UINT32;. B) B( r- M: d4 k+ \

  38. 0 U8 j0 ?" c: ?/ @' ^

  39. & ~6 Q: F  N3 o! C
  40. /*  16bit integer types. _6 [$ X+ s% \2 c
  41. */
    2 k. M) ?) Y. C* O9 b" f
  42. typedef  signed short        LPDF_INT16;0 K& }* z8 m# g- Z0 u9 Z
  43. typedef  unsigned short      LPDF_UINT16;
    1 a6 H; O7 P; e2 v+ v+ a
  44.   ^+ d# M; O* H* H5 c6 R
  45. ) P8 e, s, j: t1 P; g) ]5 x
  46. /*  8bit integer types
    ' w, Z& X4 W7 N, S4 B
  47. */
    - l  K8 u6 X* X0 V! O% M7 W3 Z' L
  48. typedef  signed char         LPDF_INT8;
    ; J- \1 T0 S& u% t5 R
  49. typedef  unsigned char       LPDF_UINT8;2 D* ]$ T+ k! }" b2 l: U7 S

  50. ' `& q; Z3 J. x( J/ b: N2 x

  51. * S0 `  d2 y) t) ?
  52. /*  8bit binary types
    / N/ A5 T5 V2 V( D
  53. */, R- m: k# I& g; R
  54. typedef  unsigned char       LPDF_BYTE;- z9 h2 [' W7 K

  55. % C3 {# W2 j1 |* |, W
  56. / x0 a8 `6 O6 k7 E. Z
  57. /*  float type (32bit IEEE754)- D: l% C: k1 l% k0 N# ?. X- ]8 M
  58. */4 j, K$ j0 w! J- a
  59. typedef  float               LPDF_REAL;
    4 f8 A4 D& m5 w% B( Y

  60. " e1 q% ^& Z  R1 C

  61. $ T3 P7 O# q) f) g7 R
  62. /*  double type (64bit IEEE754)
    ' z% e& y: z$ ]/ T$ o! {/ V
  63. */
    7 U3 T4 D4 v. P1 p* D6 G
  64. typedef  double              LPDF_DOUBLE;
    + }1 @. C9 _; S

  65. 5 h& ~( S- a9 u1 P% l
  66. ) g) x0 l" \( P; B- ^% Q7 w/ Z
  67. /*  boolean type (0: False, !0: True)  D: o- n' }" l! z
  68. */
    % y9 Q$ N& s. k0 c: A
  69. typedef  signed int          LPDF_BOOL;! G8 r- `5 ?7 z6 G0 i& ?, M

  70. / ?- ~2 E1 `6 D/ m5 d7 q

  71. # q# W9 Y( K1 ?/ F9 J/ q4 J) n
  72. /*  error-no type (32bit unsigned integer)4 w& ^$ ~% D, r9 W2 p
  73. */* g6 c7 F8 E  C) g
  74. typedef  unsigned long       LPDF_STATUS;* o5 d5 k7 R: v: x7 b$ B/ q0 K

  75. , Y  X) b9 ]  n( g9 d
  76. #define LPDF_OK                     0
    ' @2 J4 X5 D$ s# o# H9 y0 `
  77. #define LPDF_FAILED                 12 [. P  A. l# g* J/ [

  78. 7 m: S3 F8 f7 q
  79. /*----- font state -----------------------------------------------------------*/
    3 N. P: G# w/ M" `, S: E
  80. #define   LPDF_FONT_INVALID                 0x00FF5 R9 ^# V# l8 n( W2 r
  81. #define   LPDF_FONT_COURIER                 0x0000! h1 ^9 r, B5 V; [
  82. #define   LPDF_FONT_COURIER_B               0x0001' f  _6 \) g' A1 Y
  83. #define   LPDF_FONT_COURIER_O               0x0002! s' i) n* h/ R- t4 b
  84. #define   LPDF_FONT_COURIER_OB              0x0003' H: b) f' d8 F9 L
  85. #define   LPDF_FONT_HELVETICA               0x0004
    7 A2 s# D8 c+ \1 N  _) u* R
  86. #define   LPDF_FONT_HELVETICA_B             0x0005( P1 w1 k! r6 R; ^0 C& F$ m
  87. #define   LPDF_FONT_HELVETICA_O             0x0006
    & R4 a  N, K  q- k3 B# t
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007% a' x, o5 v7 g
  89. #define   LPDF_FONT_TIMES_R                 0x0008
    % }. y6 Y; N  }. ?
  90. #define   LPDF_FONT_TIMES_B                 0x0009
    & V. w1 E& Z  Z5 D/ ?9 s# q
  91. #define   LPDF_FONT_TIMES_I                 0x000A
    + s! J; @0 G* J- @3 C7 k$ p/ ^
  92. #define   LPDF_FONT_TIMES_BI                0x000B' `+ h* y$ |. b. c5 Q; X
  93. #define   LPDF_FONT_SYMBOL                  0x000C
    9 [' c1 N8 p5 p- B: {1 G) d
  94. #define   LPDF_FONT_ZAP                     0x000D5 a& N: g9 Z! O! D
  95. /*----- Graphis mode ---------------------------------------------------------*/' t, T  c% a$ p! K
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    ' X- p3 a% j/ X& i
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002- a8 q& f6 z, E% @8 D
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    6 R2 u1 W% x. B
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008
    7 u+ g% j) E( I
  100. #define   LPDF_GMODE_SHADING                0x0010+ p- w4 |* {# C& m  i
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020( a* D' O9 w6 U4 X" l, \
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
    2 [1 s/ N2 D4 o1 N2 U, E
  103. #define   LPDF_GMODE_INVALID                0x0080
    & l$ M' a% l% z8 p" W( @  k5 N
  104. #define   LPDF_GMODE_OVER                   0x0100; @1 e, w+ G" P* U

  105. % X: y. K; W7 u4 U7 E
  106. #define OBJ_MAX_NUM     2565 e/ X6 N% ?2 Y# B# m
  107. ' M  s) m2 L7 u
  108. /* Page的结构信息是否需要树形结构 */" Y5 J4 `- f/ Z8 T
  109. typedef enum ; v; Y: n) V. B! J8 S. v
  110. {
      _& P8 [  f0 E: A5 {* i' K
  111.     OBJ_info,2 m# T1 U' k/ R: S: A
  112.     OBJ_stream,, x# \4 z$ }/ Q2 o" P
  113.     OBJ_font,
    # {2 U0 `$ D* a+ q
  114.     OBJ_page,
    ' q( U9 |4 Y9 U! m. c
  115.     OBJ_catalog,, s8 x* u3 r1 e* g
  116.     OBJ_pages,
    6 p" }: }9 l. u7 q
  117.     OBJ_image,) c- [5 j" V8 N
  118. }LPDF_ObjType;; I: A; O% h7 n
  119. 1 U  Q! Q' I$ p8 w! V
  120. typedef struct
    3 x: u" t. }8 h" Y( H( L- c5 @" z
  121. {8 E0 s  S* P4 ?# o: E( c
  122.     LPDF_ObjType objType;
    5 L; U5 {/ s# B3 k0 z
  123.     LPDF_UINT16 objIdx;& h& D2 W% M) @" o$ ~. j+ R4 ?
  124.     LPDF_UINT16 height;
    + ?7 [% N( [1 P* `$ P) Y
  125.     LPDF_UINT16 width;
    & g* L1 g" ^4 w" ~4 z- ^; e- b
  126.     LPDF_UINT16 length;
    + f6 W* `7 y" |
  127.     LPDF_UINT gMode;
    + w7 `- }. s8 b
  128.     LPDF_BYTE fontType;
      X' s8 X& v  r7 X( @& j
  129.     LPDF_BYTE fontSize;, l7 O9 B/ V, [0 V; b; d
  130.     LPDF_BYTE pState;
    " F# _# X1 p7 o( N- ~, B! d
  131.     LPDF_VOID *doc;: M( E1 h% Q; k
  132. }LPDF_Obj;
    0 {, \9 A+ i% C7 \& N

  133. " U/ X0 x( }' w* t: n' @
  134. typedef struct4 |2 I! P( o- A% E
  135. {
    5 c; q/ N6 z9 s, Y# V' n3 _* c
  136.     LPDF_Obj obj[OBJ_MAX_NUM];/ @% R$ `/ }! N6 l1 d
  137.     LPDF_UINT32 offset;  j, [9 t$ A5 _( Z4 {! f
  138.     LPDF_UINT16 objNumber;
    & c& b) S1 y2 d7 P5 I2 N  o
  139.     LPDF_FILE file;
    ( K$ k, Q0 W4 Y* _/ K) j8 a
  140. }LPDF_Doc_Rec;5 E# r- Y% G0 x+ B( l

  141. - r1 u2 q9 V2 g$ m6 f* T0 T
  142. typedef LPDF_Doc_Rec *LPDF_Doc;5 X" J) Y. v% S3 y& Z
  143. typedef LPDF_Obj *LPDF_Page;4 t$ k- T- f% C9 `$ _
  144. typedef LPDF_Obj *LPDF_Image;
    / R5 n5 O( i, y2 z
  145. extern const char *font_list[];9 c4 f  l( F/ v" w; M( u9 ?
  146. /*----- LPDF Interfaces-------------------------------------------------------*/
    2 f+ F0 `& B& z
  147. const char * LPDF_GetVersion(void);" n$ X8 q9 T' P% [! E8 G! D  b6 L; e
  148. LPDF_Doc LPDF_New(void);
    * Z. `+ E+ J. o/ K0 X; j
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);
    " C  d* H5 x  Z
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);7 y& w' N1 f, p) B) ^4 I
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);- i9 E" J" I4 Q% F
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);2 d0 f& \7 c% M) o
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    6 x7 Z" ?- K7 k/ m
  154.                            const char *font_name, LPDF_UINT8 size);
    9 a  _0 ~! `  g" {3 B
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);
    # X" p0 o& u: ?& @' k% E
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);( S$ y% @" X3 B) I: s
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);% m; \% Y. R0 j" z! \: v2 u; `
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);# b; g' R4 c+ f+ Q- u1 |5 B9 h: N
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    # o* Q, m, e; `# l
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);4 y3 o" a7 C. C
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);) d4 }1 w% q: }) X5 }
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);" V: q5 Q0 f4 W
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);+ k) |. B$ X9 z& `! s$ W( j
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,/ I, }4 x; H3 c0 W9 M3 D: K) s
  165.                          LPDF_INT x, LPDF_INT y);
    / t" H0 P5 Q7 @5 T0 x# z
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, 2 Q- t3 v, E4 a3 \- P% r
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,, m" H$ u! N% c; g) i6 m
  168.                          const char *text);
    ' j, X: i6 K% E& d
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    " N4 x1 D3 p% n, T; O
  170.                          LPDF_REAL r," @6 Q, D7 B" l, O- p/ Y7 S
  171.                          LPDF_REAL g,
      O- U& e0 G( Z3 {$ k3 y9 {
  172.                          LPDF_REAL b);
    / |. y0 g; Q3 d$ ~9 j
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,5 r& j  l" l$ G- j, r" F, C
  174.                          LPDF_REAL r,
    6 x( r% q) J: Q) ]# q4 r; N
  175.                          LPDF_REAL g,! P6 F" y) N' L6 W
  176.                          LPDF_REAL b);
    9 a/ t, T" g% c; m
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,8 c% t4 Y) v+ A  c8 _/ T% c- ]
  178.                          LPDF_UINT16 x,: |* b' A7 L) s3 m
  179.                          LPDF_UINT16 y);
    ' ?2 q4 r4 I* E% b0 \. L
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,9 v$ W$ w. E& t' Z, S
  181.                          LPDF_UINT16 x,( W5 a' Q; W: A! o6 f! K
  182.                          LPDF_UINT16 y);
    7 h, j1 g8 ?7 w+ @
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);
    0 I+ x2 z8 v2 \& X+ `( Y: j
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);
    5 o+ A0 y7 [4 I2 i4 Q% D
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    ) q2 m, H2 ^/ t' [
  186.                       LPDF_Image image,0 U8 Z4 V" |, }4 ^. Q5 A
  187.                       LPDF_UINT16 x,; v# f1 h3 _4 |& ]; H
  188.                       LPDF_UINT16 y,% \' g2 H/ j! Y+ T! U8 I8 q
  189.                       LPDF_UINT16 width,5 e6 e6 w  Q6 F' j" }- p
  190.                       LPDF_UINT16 height);
    + q9 W1 x: m+ n- e$ r8 g# r
  191.                                                                                         , g( X% Y- x$ K
  192. #endif2 `. [5 y. n& ]6 W* ~( A
复制代码

源文件如下:

  1. #include <stdio.h>% Z7 ^) `- T# a& h( W/ `# R; A4 q
  2. #include <stdlib.h>" R; r+ y8 V& K4 Y' U
  3. #include <stdint.h>0 y. ?2 W9 i7 _2 t5 R0 ?
  4. #include <string.h>, }! t( N! _1 Z7 U9 _$ u
  5. #include "pdflib.h"
    + a: v* Q, X; D/ B- ]9 D) F8 j& ?
  6. - z; F8 S' r" h
  7. #define LPDF_INVALID_OBJECT                       0x1033
    7 F" b! w6 A- w+ U2 ~, l
  8. + H; r8 M" C6 f# _+ C9 F6 Y
  9. static char pdf_buf[512];$ L) _# |, E2 h" N7 B9 M, P1 ^7 T( @

  10. ; w! u/ `4 F# J; h# `9 o# a
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"  h- l' n8 ^* ^
  12. #define LPDF_FILE_HEADER_LEN        15; S0 L% E% l8 P. {
  13. #define LPDF_BASEFONT_NUM           14# Y4 ], H0 |3 I% O
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    # s$ `. |) z0 ]; M! B* k
  15. const char *font_list[] = {
    : o1 a6 o9 F. C
  16.     "Courier",: x. r5 t' B( N  X+ t8 Q6 R
  17.     "Courier-Bold",- ~/ }  `8 \8 }( P, N
  18.     "Courier-Oblique",
    . P* w6 u" R% e7 ~) x% P
  19.     "Courier-BoldOblique",8 S, \1 J  U; J% ?0 D$ w# I% D
  20.     "Helvetica",$ ^# |' ^5 @3 Q4 o0 d4 n. ?7 ]2 q
  21.     "Helvetica-Bold",! ~* O/ h$ D" T& t& @, f/ a, S; s
  22.     "Helvetica-Oblique",
    ; `( J6 b; p% v, b
  23.     "Helvetica-BoldOblique",
    . s" W) ^$ U8 L* T
  24.     "Times-Roman",, `/ _* `2 M- s3 \
  25.     "Times-Bold",1 w6 H! F# U) |  N
  26.     "Times-Italic",
    / X- V7 H' p6 b
  27.     "Times-BoldItalic",
    + f$ @- V& l& V. u2 {
  28.     "Symbol",: Y4 y& I. W5 P2 C7 a2 e* W
  29.     "ZapfDingbats",* A! _  m3 Q" ~; K3 \  |
  30.     NULL6 b" `' P6 p8 C7 g9 D2 l
  31. };8 w  G. i! o3 {- ]6 o6 u

  32. - Q! y) u. r& y; F' \

  33. ! X0 ~8 @# |% E6 }2 i. ~% G
  34. const char * LPDF_GetVersion(void)  W$ p+ G# e8 g& D: S
  35. {+ j5 a5 j# P; `3 `$ k: a& `0 P7 O
  36.     return LPDF_VERSIOIN_TEXT;5 c: e5 d8 \6 C6 B; t
  37. }% C5 \, X" p, k" c' }4 U9 W
  38. 8 j* }, S: f$ e/ R- Z+ J
  39. LPDF_Doc LPDF_New(void)
    3 |0 T% Q- E. i# L: U9 t
  40. {
    9 x- A: o" k& d9 h7 @% p5 |2 J! r
  41.     static LPDF_Doc_Rec pdf;0 r% e  @. p8 w# ^" Y+ M
  42.     LPDF_INT length = 0, i = 0;
    7 R  V/ }# n/ c" ?
  43.         LPDF_UINT writeBytes = 0;/ Z! q' J' a* I6 v- u1 e5 `$ X8 h
  44.         FRESULT fr;
    . u' W  g* H& Z; |* j2 P/ r
  45.     + v- I" @7 r4 ~" [) Y2 Z
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
    + @4 f; i) R- T# @# y6 R
  47.         if(fr)
    : P0 X) h: I0 n. X' N5 n
  48.         {
    8 r2 x2 X! u8 F: M
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    / N/ P. ~* ^9 l# j
  50.                 return NULL;7 E! N$ r; W4 F. q, H
  51.         }1 U4 C: w& T, m1 l" I
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */
    + B& R$ ]* e% f# A$ k% S4 G7 O* p
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;
    - I3 A; M* X. O% p! t  F
  54.    
    0 h# o  E) P+ {, O% g
  55.     pdf.obj[0].objIdx = pdf.offset;
    ' _3 c+ E/ k! b* u. e
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
    & P( J8 |* H, s8 V# q8 H( G7 {
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);! [1 [/ G% \- T
  58.     pdf.offset += length;
    1 ]! f9 p7 l0 T
  59.    
    " O; k+ q0 ^7 o8 L
  60.     pdf.obj[1].objIdx = pdf.offset;
    ' s5 p) D! \5 p. Y
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"0 O# l! u: g* n2 @. f
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");8 Q# Q: h' U5 ^9 v. i
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);5 h% W6 f( J. X
  64.     pdf.offset += length;
    7 J$ b6 y: c5 {7 S- s0 [# e
  65.    
    - j0 U/ n) G  }5 D
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    7 o! J8 N$ V$ ^# ^9 |& a! o* k
  67.     {2 _! K3 `0 |9 V# v. r
  68.         pdf.obj[2+i].objIdx = pdf.offset;( y! `6 ^4 r8 C0 u0 `2 v; r# ]
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"' ?* C" k# g+ y5 V* o  \# P
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
    ) ]0 S3 e* d8 r  F( D) ]8 z  C: o2 f2 F
  71.                         "endobj\n\n",3+i,font_list[i]);
    ! e$ D1 K4 E  i
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    ' W5 b+ ?$ i2 d3 G' d4 P
  73.         pdf.offset += length;! @( Y6 M1 T: o* ~
  74.     }6 X8 `4 J& F& o9 c& P
  75.     for(; i < LPDF_BASEFONT_NUM; i++)
    * b* l* L0 _2 d+ M
  76.     {
    , O* j' c+ I. d5 M8 N2 U) _: W4 ^  q
  77.         pdf.obj[2+i].objIdx = pdf.offset;
    ) Q9 L1 W! C$ H
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    & H* V# @' K& A+ W  Q7 W# o
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
    3 `7 S6 H/ L" d, K! f# {1 [
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);" Q% r! y( G6 [8 x6 P
  81.         pdf.offset += length;
    3 b$ |( B% u+ ?1 p% r: P! [
  82.     }
    # M2 u& ~9 j) u
  83.     pdf.objNumber = 3+i;# b1 u2 ?; |% K8 ?; a# y
  84.   ( R% s) D3 D8 g3 r8 y+ Q( b& Q) e
  85.     return (LPDF_Doc)&pdf;
    7 j; j/ Q. w5 m& T' r; _& z
  86. }
    " @& D5 ]) [, v- S* m6 c. L
  87. / J* r* D  a9 @, f# W2 S* x
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)* N9 a. w8 a- c) `# x
  89. {
    3 k! K5 D$ r2 h5 h& K1 `: K$ M3 ?
  90.     LPDF_UINT16 i = 0, child_pages = 0;& O, R  N- I7 Y& |7 G; `
  91.     LPDF_INT length = 0;
    : u% `6 L7 w  x0 M" }
  92.         LPDF_UINT writeBytes = 0;
    7 A  I7 t) G5 \: p
  93. 0 @& o- ]' y7 V+ s
  94.     pdf->obj[16].objIdx = pdf->offset;- Y6 @* v, |# y* @5 X6 g
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;6 V5 y# ?; S; j6 [5 [
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);7 g1 K# x4 D+ R/ s+ e4 a
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    . f9 x. K0 P& s
  98.     pdf->offset += length;
    1 J8 e0 f5 i/ Y3 q) J
  99.     for(i = 0; i < child_pages; i++). i, V$ {4 r$ P
  100.     {, b# _+ v3 T8 L( r! W) l/ f
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);, G% }7 ?* m- [8 u3 r" h
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);" }5 d5 g0 J* j* k' N4 k8 n
  103.         pdf->offset += length;
    - [) F5 w9 ~' V9 _
  104.     }
    . _* X7 {" M1 m0 B6 P& Y" A
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");9 W; N, ~5 |, A3 C0 k  s, [! X' z' p. F
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    9 q$ h* e7 |5 h
  107.     pdf->offset += length;9 @: ~, f/ f1 o9 F! k
  108.     6 b- }+ _5 o- F2 J4 P! _. v- s
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);8 a1 p$ N3 p+ q2 W$ _/ \- _5 N& {
  110.     for(i = 0 ; i < pdf->objNumber; i++)1 e3 D* J+ l; z' l" u7 z
  111.     {5 C! l, O$ K$ V) N4 B
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    " \4 G( x4 m# Z8 x4 M& i9 h
  113.     }4 ~) I& d1 _$ u5 K# _
  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",8 t+ r$ h# L; Y: R7 C
  115.                 pdf->objNumber+1,pdf->offset);
    2 b' B9 k, @- N7 H0 S4 E
  116.     LPDF_FCLOSE(&pdf->file);
    # {7 _' S2 p9 @$ q" w4 d9 _' c' S
  117.     LPDF_REMOVE(file_name);
    $ z- E' T3 u8 G( A+ g9 s
  118.     LPDF_RENAME("tmp.pdf",file_name);& D0 c( l9 ~( ]: @( l: ^7 T3 U8 t; n
  119.     return LPDF_OK;! F  X+ X6 R& s5 Z
  120. }0 p% m4 D/ Y, r+ o5 q  P# @6 z

  121. 1 x) R3 x) B# ^. R9 x/ M  I  M% s
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)
    $ j: l# I3 |1 [
  123. {
    : o. \/ Y6 D7 O# Z  V8 d. q
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);) n* ~  {( F+ [) u: Z
  125.     return LPDF_OK;
    - S; v# B# G+ e7 W8 M5 u6 v1 b
  126. }
    $ f3 ~6 R2 O) o$ y

  127. 9 C( H' ?1 R7 b1 l6 G( }" V+ W
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)
    , L/ T2 {: _2 d' e, N  N9 M7 O
  129. {
    6 K5 c4 N# J" g+ y2 n1 Q
  130.     LPDF_INT length = 0,i = 0;: d  Q3 \* b$ P8 ]" B
  131.     LPDF_Page page = NULL;
    " T  R; f4 z  D# ]
  132.         LPDF_UINT writeBytes = 0;
    8 t0 S  ?  S5 v/ v) \- d$ u
  133.     8 z6 O( \" e& d" ?5 }! i7 n) }
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;3 k0 s9 a( R2 }( v, s9 z4 z
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n", u+ I; E5 E2 w% ?9 h
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    . a4 d" h$ `/ x+ J) Q2 J
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);9 ?3 V7 ~+ }/ G% D2 H6 X4 y
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);7 ~. Q" {8 d4 s
  139.     pdf->offset += length;
    . S- X6 _! S  n1 d1 G! X( x
  140.     while(font_list[i])
    0 X0 N9 V% I0 C
  141.     {" @1 D5 c( @4 o. ?1 k: c5 a
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);8 K/ _: L/ D/ L; {
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);, C4 K# t1 k/ k$ h9 S
  144.         pdf->offset += length;
    $ E9 d- J( m2 V6 y% d' _  }
  145.         i+=1;( R+ R4 B: s, B' K3 c+ y
  146.     }
    & Y" a. s# [8 C4 s$ W) ~$ Z* |
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");' Q, a2 ?' z" ?* k9 E
  148.     pdf->offset += 4;
    $ Z2 H9 |( }# U- K
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];& V: i) ?) S. ~% r) Y- Z
  150.     page->width = 595;# C* n" _) G1 ^' E6 t
  151.     page->height = 842;
    8 f$ v3 J, {: H9 r+ t$ e1 {& K6 I
  152.     page->gMode = LPDF_GMODE_INVALID;
    8 c1 ^& \% Y8 y- Y7 o3 k
  153.     page->fontType = LPDF_FONT_INVALID;. V4 e* d! x% D9 ^8 h8 a
  154.     page->doc = pdf;
    2 n5 o7 K3 o9 t
  155.     return page;0 D1 p2 v6 [$ ]$ L4 D  \" O: w! {
  156. }  f" G8 I- y7 i7 {

  157. ; t! k+ g  P. J( `+ b/ E
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)8 J' b+ G" Z1 g8 J/ \
  159. {3 T5 j9 }1 `7 |7 u: R& e$ _+ H
  160.     page->height = value;. t5 F1 P: I# ^# z
  161.     return LPDF_OK;
    1 p2 t) N7 s8 ~; R4 y& n  r
  162. }
    * I& a/ y+ J' e6 [% F7 C
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)5 u1 l) p7 R3 r2 `5 d$ G
  164. {
    6 f' Z, e# [2 L" Q( G2 ^. c% N
  165.     page->width = value;
    7 h' Y6 ^0 w, |6 B) R: ]
  166.     return LPDF_OK;
    3 K9 `: N3 l9 Z0 ?: Z
  167. }
    ! o3 Q" z2 f  e: P- R

  168. 6 y# k8 I1 P- D/ _) T. p
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)6 }) F0 I2 g  M( g
  170. {9 {. `" f4 y, H: T) \
  171.     if(page)- M1 i" A" ^$ J6 j, U0 P( P0 S  }
  172.     {
    . N! t0 b% H# G, U3 G* K- Y! |
  173.         return page->height;
    : C$ {( B/ i6 f4 r+ n) Z
  174.     }
    3 w+ N) o- z6 b0 \! V! G7 B
  175.    
    % F' a7 X7 J! k, Y& Q5 U
  176.     return LPDF_OK;
    ( y- L* i. A& S3 k1 v* C; [
  177. }
    8 T$ e& a# O1 a+ F. D5 {& d' R/ l

  178. $ k( v/ q9 j* e
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    : s9 m: N5 e* e6 X7 U
  180. {
    3 _  `5 L9 F1 z( o
  181.     if(page)
    " b% E5 @8 M0 M- W
  182.     {1 q1 r  g& ]& e5 }
  183.         return page->width;
    1 s# D, P) S) K( h* }+ c# r
  184.     }
    ) i; o2 _. z, n% h. h$ W/ \, j% f9 b
  185.     2 b% b; p' f3 \1 m
  186.     return LPDF_OK;
    0 a- `7 W: }' i  w# V" F
  187. }
    9 j/ [6 b/ R1 n1 k  O7 W& s. _# ^

  188. 8 [5 c, Q6 a7 \
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode), j" C- l: v" V9 X% V
  190. {+ Z' W+ T0 Q* o0 q0 }
  191.     if(!page)$ M2 {& V% @  N, u# c
  192.         return LPDF_INVALID_OBJECT;
    ) X4 |7 W0 `7 R# e1 V5 b# Q. e
  193.     if(!(page->gMode&mode))1 O8 D; s# @& h9 r
  194.         return LPDF_FAILED;
    2 S" v8 V# l& j9 ?1 {3 i

  195. * ^$ I/ b, T2 W: v7 I& X. o) `
  196.     return LPDF_OK;
    5 d8 T) Y( C4 ^7 `
  197. }- M/ s7 Y. ]; v+ w" I! r
  198. $ C4 h3 P5 Y1 c) {! v3 F
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page," y5 K) _) q$ F0 P6 V
  200.                            const char *font_name, LPDF_UINT8 size)
    ) b' G! M3 Z$ e) h
  201. {
    . P* O& |8 P: z5 p
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;; C: i# N3 A) M# X
  203.     LPDF_INT i = 0,length = 0;
    . ?4 i% h3 C* G( G
  204.         LPDF_UINT writeBytes = 0;
      G) t) g6 T" C* _
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    ! U1 p- M) ^( t, A9 [, N
  206.     if(LPDF_OK != ret): l0 D, K/ y7 @0 i0 C. {
  207.         return ret;
    0 }7 l+ x6 }9 T+ V

  208. / T& V3 r+ G& r
  209.     while(font_list[i])1 x. `6 J! ^7 x6 ?: V
  210.     {) e! p, }5 Y2 Z# ^- c* t
  211.         if(0 == strcmp(font_list[i],font_name))
    . ^' H1 i) ]- k" K- s. U" T/ u
  212.         {
    ; X$ e( E! R! D( H8 l5 l
  213.             page->fontType = i;2 \8 X$ l3 z  b3 t8 y9 Y
  214.             page->fontSize = size;
      H0 F, a; H6 K. Y
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);# ?9 ~! _) T, h( B) V
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);) Q! O# r/ W" F! O
  217.             pdf->offset += length;( q  `" m2 b; a$ V0 ~3 R- m+ V
  218.             page->length += length;
    , Y) N( k+ j- I$ A& J
  219.             return LPDF_OK;
    0 T3 V( g' j. [  ?% _& @9 @6 `
  220.         }
    % f' P' o& n/ I
  221.         i+=1;
    * C1 L/ G. s& o  Y5 f
  222.     }. X7 \, u2 S( ~- a5 O- B
  223.     1 x; q6 ^( s* p: v
  224.     return LPDF_OK;( e* U' p9 Y- x. @' U
  225. }- I' c* }  E' L2 P; i. ~
  226. " h$ y- l: y  X5 n* K/ L" Y
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)8 o5 f: H3 L  E( V
  228. {
    , `0 Q8 M6 _4 W
  229.     LPDF_INT length;$ U* I; o9 H8 m* o6 _: n4 H5 Y5 l
  230.         LPDF_UINT writeBytes = 0;
    9 n4 z2 y: k0 r
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;( z# z! ?4 i4 }* I$ l1 ?
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    , l* o( Y2 F1 b$ V# r/ F
  233.     if(LPDF_OK != ret)
    + }7 q- c0 I* R
  234.         return ret;
    . d3 f& E, J4 @! I: R7 K/ @/ \
  235.     % W! J3 x1 D" s4 I) d
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */
    $ }- S8 `) k! a1 M( P
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",2 _  L6 H  j0 A9 h
  238.                         page->width, page->height);$ |8 D# S. K* M
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    / H+ g! Z+ p! r% x5 l, l: j/ V2 w! U
  240.     pdf->offset += length;
    0 `- a8 i# F- Q3 \
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;5 y; b; s9 u/ }* q  f: \8 K
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",
    * C* B* M# q: Y# c6 c) ], [7 l
  243.                         pdf->objNumber+2, pdf->objNumber+3);
    ; J: ?% }' u! H
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ( Z' ^$ c+ R$ {5 w- N" C; j
  245.     pdf->offset += length;& S3 K+ I% r8 z" Z0 m( S. `; v
  246.     page->length = 0;
    9 _8 E" ^1 x, W
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    6 \2 @# T+ n' Q- M0 @! r
  248.     return LPDF_OK;
    0 ^1 L+ A& ?9 @( z7 Q& K
  249. }/ w1 E4 y9 a$ C$ R) Y
  250. 2 `" E7 R: B! r1 t9 z
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)
    / B6 _1 w  R/ A% G
  252. {% z% c( M6 d  _/ `. y1 E$ V& s
  253.     LPDF_INT length;+ p" ]7 z& f8 ^
  254.         LPDF_UINT writeBytes = 0;
    6 }8 [' I4 i# L
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    3 F# [4 ]7 u! z3 y  G, @
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    4 w7 |! e1 R8 X
  257.     if(LPDF_OK != ret)8 j! f- h2 a' L$ D
  258.         return ret;, f5 s3 {8 r; U4 ~# I
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */9 A6 y7 |+ Z  s* u) U
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    5 _) v+ C5 d0 W+ q2 h7 C
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes); 0 ^2 n& ~1 X7 M! @* ^: o0 N
  262.     pdf->offset += length;
    ; \5 L+ b9 M0 v
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;- _  @2 n7 o% r4 }$ K- e' e
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    : H) `9 K1 `5 u) f6 C- x- n
  265.                         pdf->objNumber+3,page->length);
    7 [0 [/ w4 ^. [; j
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);7 ]7 D6 a! v9 k# E& G* J# Y) E* M
  267.     pdf->offset += length;" s: t+ h! T2 @1 W5 _: f
  268.     pdf->objNumber += 3;# }4 t/ P# }+ h
  269.     page->gMode = LPDF_GMODE_OVER;
    - _. T  {+ G, t# d
  270.     return LPDF_OK;
    6 p* Q4 p% u" q( R
  271. }9 T4 |6 H* r4 a  c& F. H( B: Y

  272. - w' y3 q6 Z1 t* ?
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    ( T8 }4 o& ]( D" l2 H5 O) H! M, d$ D
  274. {3 U  d' d) U5 v- p" f
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    8 p& R0 {* V& [/ A8 B8 F. O$ V
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);9 E; ], x) A4 g$ L
  277.     if(LPDF_OK != ret)0 q' y% l# m( |" y
  278.         return ret;2 R8 k4 I( T, T% A$ ]
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");1 i: h/ J3 n% k( F
  280.     pdf->offset += 3;
    % o( V0 Y& W. T" c
  281.     page->length += 3;
    0 [  F# p4 A7 W
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;" v  r4 y3 D' l/ n0 h" f; j4 j% [
  283.     return LPDF_OK;# f# H* s( o0 U5 ]! ~8 c
  284. }* i( I9 n. m, L+ g' e
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)+ B! q4 U1 f% y* n
  286. {
    5 |4 A9 v5 \8 u& X) N
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    3 S) m  E# X9 n7 N# P' y
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);; B6 ~$ n3 |" Z% G. |4 D
  289.     if(LPDF_OK != ret)9 \2 x& {/ O  K+ t" t6 j. ]  K
  290.         return ret;
    5 v: S" y! q2 q. z
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");6 v) i. E7 ?# F+ B4 E0 S9 q6 t
  292.     pdf->offset += 3;6 y  _0 d& c# ?: W5 r; v0 c$ w
  293.     page->length += 3;; r& A  u$ R% P- r7 J8 t/ i- ]
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;: e" p4 w6 s$ c! _. g8 Z* L- Z! N
  295.     return LPDF_OK;5 [! H" V& Q2 P9 i4 w* R
  296. }! N# u* c" j, A+ L7 u  F
  297. 9 L9 n3 K& j% V7 G
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    + Y% G) c9 W4 v0 _, [4 A
  299. {
    , r3 a+ I9 H6 e; v
  300.     LPDF_INT length = 0;8 j) Y8 z( n+ |& o- \+ G: }
  301.         LPDF_UINT writeBytes = 0;
    ( I: E2 H: ^1 B$ b
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;9 K. _$ y- J; N; R. L' X
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);' Y6 i/ U9 _( f* P
  304.     if(LPDF_OK != ret)3 n3 u5 m$ H7 M. ]$ D* h% b
  305.         return ret;: {  Z# x' S1 p& e
  306.     if(LPDF_FONT_INVALID == page->fontType)
    " W2 Y0 B4 |) K, f3 n6 e3 }
  307.         return LPDF_OK;
    7 K" a5 A2 F9 C/ B- U: p
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);9 X3 Q1 H& A2 R# s. n
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    8 {/ d" e1 o9 o6 @- _4 F
  310.     pdf->offset += length;1 S! H; F5 [+ [! C2 H# E3 v
  311.     page->length += length;; ]9 W; A2 @) T
  312.     return LPDF_OK;
    , w; `4 v7 ^/ o& r) n
  313.    
    / N" {! o# q1 ?+ h
  314. }" G* v" Y# Z8 l8 Q
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    ( Y( S/ r. l/ {+ q5 r- |( ^
  316.                         LPDF_INT x, LPDF_INT y)
    3 R( [! n/ S) [. L  b- z% V, L% n
  317. {5 \  r8 Q% A+ v  [
  318.     LPDF_INT length = 0;5 d/ W0 e) V4 D
  319.         LPDF_UINT writeBytes = 0;
      Q3 b- @6 O( y! o
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ' b- j- D3 C- _5 z7 j
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    0 s1 d: G2 e/ N
  322.     if(LPDF_OK != ret)% k" \, O$ K# L# D* v' o# [
  323.         return ret;
    0 G; b( E$ P; P0 [3 y8 A
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);) `6 i% o3 F: D( D( l
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
      x3 Q$ H/ |' ?- Q* _# A2 q; @- d
  326.     pdf->offset += length;% ^* B5 x# {  M: y3 f
  327.     page->length += length;! K3 `5 A5 E5 g
  328. ( l- l# n8 M$ U$ o$ Q
  329.     return LPDF_OK;
    1 K: }6 d& m# T9 L. N
  330. }
    6 ^! v5 A: R+ i4 q3 F1 f, F
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    9 z) N: ~/ P0 D) D8 o7 V: F* X$ h
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,
    5 L; z/ Z% M; g2 j5 Z
  333.                         const char *text)
    ) ]( d* w0 `* A3 \! A. d$ I
  334. {
    / P0 B. e0 y; ?4 q
  335.     return LPDF_OK;
    : f: A: L2 X6 M# T6 q$ |0 f/ T+ M
  336. }
    0 d+ }: U  O1 Z4 [, E6 x4 @( R

  337. 3 z& f9 b0 p0 u& ~
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    , y- ^5 T! C3 p6 S/ j
  339.                          LPDF_REAL r,1 K( J  {% N' V; s  Z
  340.                          LPDF_REAL g,2 [* _* B0 m- R& X! T. c
  341.                          LPDF_REAL b)% T4 O/ R( C, L* t
  342. {
    # Q3 t; ?) j  f2 |9 p1 l  O4 |
  343.     LPDF_INT length = 0;7 u6 r% l5 Z) r* J1 j% l! D- @
  344.         LPDF_UINT writeBytes = 0;
    3 C/ s! _# ^! d5 Q. |% o
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    . }5 O7 p- d; b- v' g
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);/ y8 R- |9 L( H
  347.     if(LPDF_OK != ret)
    % |# [& S3 k# k  t  S
  348.         return ret;
    0 y0 Q- A( S& H
  349. 9 _3 K8 G7 Z) J) S
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);( \7 ^+ [& {( [; A" L3 ~
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ! L$ p- b2 k$ f( ^* B# q+ E
  352.     pdf->offset += length;0 L8 h8 Z  i& x9 g, t" c$ H
  353.     page->length += length;2 y5 T$ Q% b  l- s, t" A, j
  354.     return LPDF_OK;
    & E8 j9 d: S" G  b! {
  355. }$ f" ~. l( R1 D& w
  356. 2 _! j2 n- z6 V% R" ~/ X8 u- g
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,7 O+ m1 @$ n: t( n
  358.                          LPDF_REAL r,
    5 j  Q/ o+ R  T. e7 ^
  359.                          LPDF_REAL g,) L* G' W: x. U- L7 @- K
  360.                          LPDF_REAL b)
    $ N8 t1 h  R+ `4 \- Q! Q, |
  361. {
    $ t' ^! U3 o; i- N; K- o: ?
  362.     LPDF_INT length = 0;+ K5 X8 x" e2 e0 N2 Q) V8 l
  363.         LPDF_UINT writeBytes = 0;
    # a2 j) o8 H; n* _6 B
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;3 _, d. A* q# c9 o( ]  D+ x5 w
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);0 {8 N2 D& |/ I; @) Y+ f
  366.     if(LPDF_OK != ret)
    - n4 e2 d3 \# f
  367.         return ret;( z# Q# X% j. ~% a
  368. , t. O  ]4 y- d0 j1 H! r! c2 W9 t# \( c; r
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);& N: P, E% s9 m2 D
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; S: t! U/ q, v& U5 B# Q' P
  371.     pdf->offset += length;
    1 H+ U5 ?! _5 K- J
  372.     page->length += length;
    ) G& M6 f7 o& V0 f7 X# _$ K
  373.     return LPDF_OK;6 n$ M; Q4 x" Y6 d$ z
  374. }
    / g: T( h7 V: U/ K  V
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
      D+ b6 s& `% |
  376.                          LPDF_UINT16 x,
    * {( E, P, E: x# e- ^  E
  377.                          LPDF_UINT16 y)# V; g4 s9 U( l% R( _" |
  378. {
    % x' ]; ~2 f0 O
  379.     LPDF_INT length = 0;
    / Y/ I8 S0 m& y
  380.         LPDF_UINT writeBytes = 0;
    7 x7 I% [' r5 D6 ^
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
      Z4 |3 q. q6 |* f* e: R/ I" h
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);" K, u  }8 T( J' a5 A
  383.     if(LPDF_OK != ret)
    : l6 y3 A' {0 f
  384.         return ret;
    , P  L. n2 H6 n2 t$ g. B& o/ i
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    " ?1 _: p0 @; t0 l( e; `# u
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);$ {8 @3 y: n3 E8 P) y
  387.     pdf->offset += length;3 ~4 \" d4 Q9 c4 w: m; ^
  388.     page->length += length;
    $ v7 A3 t1 T( Q
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;& Y8 F$ b6 D% o! i4 B
  390.     return LPDF_OK;
    7 M! o4 U$ [( i- R; W5 o
  391. }
    * ^& Q4 M7 x6 ?
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    ( v2 a" }, \# w$ N, M! o9 U
  393.                          LPDF_UINT16 x,
    7 p* @+ x  G3 A2 ]* h0 o- b! k
  394.                          LPDF_UINT16 y)* S) h' E* M/ {" K; s
  395. {0 a, X  J7 l: a* E  S  Q
  396.     LPDF_INT length = 0;
    - `% n# D% W0 t& u
  397.         LPDF_UINT writeBytes = 0;
    9 r$ L) _+ K9 X* p( j1 `
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;6 T; K, @3 O) d
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);8 n1 z& w& _$ t; k: u. M. s6 k
  400.     if(LPDF_OK != ret)
      l0 s% j) D+ f, ]# {
  401.         return ret;
    # P# V% l7 Y; O* [3 K; y
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    ; _) y; L, i. [2 C9 `4 p) n" a
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);6 a7 m8 u8 j' G. P7 |* X0 _( `
  404.     pdf->offset += length;
    0 f: n  @" G; h/ M  k6 _0 ?1 \& I0 \
  405.     page->length += length;# `* m$ A: K; C' l( D: d. q8 X
  406.     return LPDF_OK;5 |9 q7 }' D3 m  `) B& Z
  407. }8 {; f/ G# G8 `% d1 R7 ]% x$ f
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)* }7 c' u5 x# Q
  409. {) ~# U/ F# o4 t; c; d5 r! k7 w6 V
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    # Y- @. D! W9 T& g# S
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);8 T" _" E+ {5 ?
  412.     if(LPDF_OK != ret)
    . {- I( O& w# ?/ K8 q3 j2 e, x
  413.         return ret;
    9 {  n" u! |" q: f' ^
  414.     LPDF_FPRINTF(&pdf->file,"S\n");5 n& O6 u7 X  M6 Q7 N' T' \
  415.     pdf->offset += 2;
    , q! e* o2 V- W% u4 `; k
  416.     page->length += 2;
    9 b) P% ^( V' C3 f
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    6 C9 d% }0 V, m1 J( j' h$ b
  418.     return LPDF_OK;
    . X+ a5 a+ f2 j+ j
  419. }
    . s" H* K5 C5 S# {
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    2 O3 `" R) A: m8 v, K0 T) l
  421.                       LPDF_Image image,
    6 t! c3 k$ ?. N- r! w
  422.                       LPDF_UINT16 x,9 Z6 Y! x; k5 A9 `9 i: A: Z/ l
  423.                       LPDF_UINT16 y,
    * g6 [) }% ~0 Y  m7 s5 e  D) `! j
  424.                       LPDF_UINT16 width,& n1 z9 j: r2 h  ?5 g
  425.                       LPDF_UINT16 height)) A+ Q. k. u* w5 O) t' a
  426. {$ C- w6 Z* a  w4 R* T
  427.         return LPDF_OK;
    2 m8 i* ]9 |2 H) y2 P
  428. }
    7 L6 G0 V* J, r* G1 R
复制代码

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

  1. pdf = LPDF_New();! e) i* [# N( Y" L/ k' Q
  2.     page[0] = LPDF_AddPage(pdf);
    7 H  ?9 B' _2 ?+ o3 j, W& T9 e
  3.     LPDF_Page_SaveParams(page[0]);3 O: z0 k3 m0 D" K; I9 W8 ?# F' {
  4.     width = LPDF_Page_GetWidth(page[0]);- m6 T# u6 e  ]8 ^; k1 l- Y0 Y
  5.     height = LPDF_Page_GetHeight(page[0]);- ~( M# P. L7 k. b
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);% m& @  C1 s" l) S( @! ?- J5 z3 R2 f
  7.     LPDF_Page_BeginText(page[0]);; T. S8 N. n. e
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);
    4 m$ P3 |" \7 K( d$ W
  9.     while(font_list[i])
    1 z  R" W! r( U0 v% W- I+ N) a
  10.     {
    & o2 R: ]) ]  E, S: j: u  @# l8 A0 n6 C
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    5 T1 _& F# A9 b# c9 F
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");, k$ H' w% k# a6 D2 l$ e6 d4 ]
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);
    % F- J& j: X; L5 E' d
  14.         i++;
    & h" e9 q8 Z% H$ T
  15.     }4 o( _% l6 j8 M5 @, T' R! V0 ?. Z
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);
    ( Y! X' C8 g9 {8 M  k* T
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());
    , i& \, y% q: C- u
  18.     LPDF_Page_EndText(page[0]);
    % j- L6 ^/ q4 ~" H; o* u
  19.     LPDF_Page_SaveContext(page[0]);
    / H, B1 U% S& L8 w
  20.     page[1] = LPDF_AddPage(pdf);: V; }' l' R0 y2 O+ C( ~
  21.     LPDF_Page_SaveParams(page[1]);; I, j' _4 y* E5 d5 Z0 }* T
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);6 ^$ R" J( u9 p/ v0 \$ @
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);3 G$ O: T- I9 m
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    : w2 ]$ I1 j7 |4 S8 a
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);6 ^. Z, b" E; r- M7 ?
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);% E5 L0 g$ L( D# k8 t  r
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);
    8 h$ e0 X' o: C4 O$ H
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);. V; o9 t% C/ d7 F1 a2 D$ g
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    & V, ~1 _+ T! l& F
  30.     LPDF_Page_Stroke(page[1]);
    ; r6 v4 {. ^; N' x0 J8 {& T! J
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);- M+ c; A2 D7 x
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);) i( S" m- z3 e
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    * Z, @: P& _0 H
  34.     LPDF_Page_Stroke(page[1]);
    , M5 j0 J7 d" Z6 A* H
  35.     LPDF_Page_SaveContext(page[1]);% `& p; L! v) J7 A/ W5 [" F6 _
  36.     LPDF_SaveToFile(pdf, "/red.pdf");
    ) c( S( v/ }+ E  d, P  b! w
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    ; `: W' B7 p, K( H
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了
* U4 p0 C  u( f; l. S7 d6 F7 {! c

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体  V. A+ a8 {5 L# N* n3 N: c3 l% Q

6 ], j+ `( w3 v% B# m: [/ E

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
' b9 C# [& e3 i! i3 j( n5 H只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...
# Y) l  b9 Q( B- m1 }/ A( h( w
LZ,我怎么没看到有添加image的接口,您的pdflib.c中LPDF_LoadRawImageFromFile也没有实现哇,您说的可以添加image,是哪里~LPDF_LoadRawImageFromMem这个是直接传入读到图片的buf么?有什么办法可以直接拿别的pdf中通过编辑软件看到pdf语法格式,拷贝图片的那段buf,直接添加到我自己的pdf中呢?
anobodykey 回答时间:2017-11-20 13:35:19
醉宇a 发表于 2017-11-20 09:33
: m# P5 _& U. L* E2 z首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
% ~$ X# q; Q- u- {& R$ L! t. g
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
/ a! }# S, ]5 k. T5 ~$ W  \) E: x
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
- }7 h- d8 A1 p+ i) m; U, m% }看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...

) ^& _2 `1 R1 A: h0 }" Z) `这个我也还没遇到过,只是之前看到有人问这个,所以看看
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  a+ R" X/ a4 Z& j( O
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

! f* S% Y$ a8 p这个还只是一个简单的库,实用性还是差一些的
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
# X2 Y: [1 s5 L, U0 }ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗

1 E0 L5 ^. [# G0 D0 z9 yff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:222 X& f8 N! ~, D2 j0 _$ }
ff.h是FATfs中的文件
/ Z6 t. F, t& ?
嗯,这个画线能改变线宽吗

所属标签

相似分享

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