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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑   R% T. Y, Y; R) b4 D

2 k% Z% X  \8 N. _

主机环境: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__
    3 W- }& W! ~7 y' w- m/ |
  2. #define __PDFLIB_H__
    1 |: E* B3 S6 {' Y+ M7 k, ^' I* o
  3. 9 o, P; I7 q1 A/ W, Z$ a; J
  4. #include "ff.h"
    " h0 Y$ }1 |, Q; k5 K- J
  5. /*----- standard C library functions -----------------------------------------*/
    0 j3 R- w; A, s* y, v/ ^

  6. # T- D3 r  F3 p/ U: S/ D# {
  7. #define LPDF_FOPEN                  f_open
    - `7 L4 _9 P5 W
  8. #define LPDF_FCLOSE                 f_close
    . C: m1 G6 {9 j  @/ g8 X, G  t
  9. #define LPDF_FREAD                  f_read
    . j9 c/ B( f* F7 X( A; ?3 r
  10. #define LPDF_FWRITE                 f_write
    & h# M) q1 j% I% {9 _! H1 F
  11. #define LPDF_FFLUSH                 f_sync
    4 e6 J8 k5 f0 ~" W# E3 c. |+ L' r3 f
  12. #define LPDF_FSEEK                  f_seek
    # {# k& |8 o/ Z! i' f0 L% c
  13. #define LPDF_FTELL                  f_tell; B8 R2 k  ^& t8 V9 h  P$ s3 ^
  14. #define LPDF_FEOF                   f_eof- P" C) D' Z- X% ?$ o
  15. #define LPDF_FERROR                 f_error7 M1 v3 y8 u3 |5 z. u# I2 @) Z0 e
  16. #define LPDF_RENAME                 f_rename3 R8 l* F" B! \4 Y! q6 S
  17. #define LPDF_REMOVE                 f_unlink
    2 [3 S/ q& [! M, s4 `9 Y! q, P
  18. #define LPDF_MALLOC                 malloc  ?& ^5 {5 D# v: z+ f
  19. #define LPDF_FREE                   free1 _, S, e" \0 j3 U
  20. #define LPDF_FILE                   FIL4 O1 o0 n8 ^) Z/ e: {, X
  21. #define LPDF_TIME                   time* G% f2 d+ |7 S: o8 \- o# N  |
  22. #define LPDF_PRINTF                 printf
    : J! K8 a2 R: n! N' s- t" p3 ~
  23. #define LPDF_SPRINTF                sprintf
      @1 o- n, y4 a) C( Q; V# U
  24. #define LPDF_FPRINTF                f_printf( J% w& v' \( T' W8 F( t3 u! {
  25. #define LPDF_VOID                   void0 w3 J- W7 Y: J+ }' T
  26. #define LPDF_SIN                    sin
    5 n3 A! T) _3 o/ l- |: e& j
  27. #define LPDF_COS                    cos
    ) j0 N# S+ w, k! ?+ ]" B
  28. , f' V( F1 h9 z2 P. V. S9 v3 E( l
  29. /*  native OS integer types */0 d9 B5 Z$ f. V
  30. typedef  signed int          LPDF_INT;
    8 i( A7 \( l  b2 Y
  31. typedef  unsigned int        LPDF_UINT;
    2 t/ Z8 A" l" v; s7 `
  32. . q! V& i- f7 o& d+ q& [' y
  33. , C# h3 W- o/ m1 B
  34. /*  32bit integer types- x8 y. z$ c" E& n5 U; ?
  35. */2 S4 y; I, w4 H; L
  36. typedef  signed int          LPDF_INT32;
    4 Y( N+ g" [5 |1 w( k# B3 v5 \
  37. typedef  unsigned int        LPDF_UINT32;
    # w) f# g/ d" O5 F5 S, p% s. e
  38. & k$ E" ]) {2 r
  39. ; P9 o  b5 w4 |
  40. /*  16bit integer types
    9 e/ O% A/ l- u6 ?1 \
  41. */
    8 d. r& j  l  H' u1 l3 o& ]
  42. typedef  signed short        LPDF_INT16;
    0 @; \, o* n+ f% i
  43. typedef  unsigned short      LPDF_UINT16;
    ( |' l% I1 q2 P$ R
  44. : x. g" g% }* Y. Q) y9 H% s# [

  45. # n  c, A: S' J7 X, ]1 e
  46. /*  8bit integer types
    2 o! d$ ~# A( k7 l
  47. */
    8 h+ [8 f: g, |  E
  48. typedef  signed char         LPDF_INT8;
    ( h  \8 t. k4 q: Z! L( J7 t, t3 m: s
  49. typedef  unsigned char       LPDF_UINT8;$ g1 d" _7 X  Z0 I6 Q: Z! i/ b
  50. 5 U) i5 d" r4 c8 o) {: T9 J9 g

  51. ) t1 B4 |( L0 Q$ Y1 F+ |
  52. /*  8bit binary types  ?: k  \+ m, e( I/ |! ]
  53. */0 N6 ~& m7 r/ e. y: ?$ x
  54. typedef  unsigned char       LPDF_BYTE;
    6 g1 E! p: L# }% d
  55. 2 F$ S+ C/ i$ @* _# q8 E  U  T7 G' x. \
  56. $ F- r' d0 {5 y  L8 P6 [
  57. /*  float type (32bit IEEE754)/ m, E" c" T& Y0 {' D* v4 `7 h  O
  58. */8 x$ a' k  X- \6 ^' W$ @
  59. typedef  float               LPDF_REAL;
    , q- r) M2 j! T1 R( R3 o) i
  60. 1 u" U1 V6 C' a+ X: b: |. N: ?7 a
  61. 4 Q9 d2 e' w. ]$ m
  62. /*  double type (64bit IEEE754)) z3 Y1 w9 S5 }' o, u  z
  63. *// \8 F* B$ e9 ?7 U5 N
  64. typedef  double              LPDF_DOUBLE;4 t2 M) h2 s* ?& X* }' o

  65. 1 E4 Q- z  @% q8 w/ Y

  66. / g" m3 L3 x' |. V! _
  67. /*  boolean type (0: False, !0: True), s  v! G: f# {. j) a
  68. */2 p' S# P& t" g% l; W( {$ n- F5 g
  69. typedef  signed int          LPDF_BOOL;
    . E/ h) Q5 n# f# p( a
  70. / F" u7 M) N. ?% D! w& {

  71. ) W# C6 d+ J6 L1 g
  72. /*  error-no type (32bit unsigned integer)
    ! C- l6 p% G8 a" L: v4 C% Y
  73. */9 [: b6 B$ K  H: t
  74. typedef  unsigned long       LPDF_STATUS;& L! h5 X. K! ~/ _/ D
  75. 8 d. _+ X1 [2 Q- s( t
  76. #define LPDF_OK                     0
    0 Q% Q  ~7 e' {4 o4 r
  77. #define LPDF_FAILED                 1; j. j! `/ Y, K0 J. |6 z) j
  78. ; R* n7 [' E: `8 _, D+ c6 e
  79. /*----- font state -----------------------------------------------------------*/
    & n( u5 m  J5 s" s6 e
  80. #define   LPDF_FONT_INVALID                 0x00FF
    1 z+ v' B8 }( a) W  K* n
  81. #define   LPDF_FONT_COURIER                 0x0000
    0 Y! x3 _. f" o8 e+ @% d/ [
  82. #define   LPDF_FONT_COURIER_B               0x0001
    / Z% B. x! Y+ f, y8 k, q/ D. h
  83. #define   LPDF_FONT_COURIER_O               0x0002, B) `0 K5 E& T  s- O: C* J7 B
  84. #define   LPDF_FONT_COURIER_OB              0x0003& ^+ _! S  ?$ m! d
  85. #define   LPDF_FONT_HELVETICA               0x0004, g, G5 h' i, ^2 z
  86. #define   LPDF_FONT_HELVETICA_B             0x00056 s5 w; ?5 m7 `/ F" Q0 Q& B
  87. #define   LPDF_FONT_HELVETICA_O             0x0006# r) m( i; N) `% Q! v$ I, J( n9 R
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007/ z/ E' ?/ G, d& m2 f. B( O
  89. #define   LPDF_FONT_TIMES_R                 0x0008$ Q) H+ G6 L% j7 L/ x. Q! o4 {7 Z) a
  90. #define   LPDF_FONT_TIMES_B                 0x0009
    ; a; N0 j5 y* {3 f, N# c
  91. #define   LPDF_FONT_TIMES_I                 0x000A2 N) M; I8 \0 s1 E
  92. #define   LPDF_FONT_TIMES_BI                0x000B. M& L" i8 o  `3 J. G0 C
  93. #define   LPDF_FONT_SYMBOL                  0x000C  D/ C* E/ k" l8 M/ M! |
  94. #define   LPDF_FONT_ZAP                     0x000D
    % S* F2 R! S2 F4 m! D$ n& e
  95. /*----- Graphis mode ---------------------------------------------------------*/
    $ r  V. r) h! Z! A
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    , T: O" {% X6 C  W" h- p
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    # D4 }, V+ e  J# C7 ]8 n
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    ; X1 \( q5 T9 T0 t  G4 s
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008/ e/ R2 c3 r2 i; [- x
  100. #define   LPDF_GMODE_SHADING                0x00103 |' O. v7 l% Z8 M
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x00208 W& ~: C5 L1 N. B" G! g
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
    + U& v% L6 ^* {' q+ `
  103. #define   LPDF_GMODE_INVALID                0x0080
    & j0 ~8 C% U( w& v1 Z2 u
  104. #define   LPDF_GMODE_OVER                   0x0100' s. U* P( t. a) y
  105. # c7 B1 H: q' P! H& z5 {
  106. #define OBJ_MAX_NUM     2564 `3 z- l5 O! u2 p4 h! t
  107. ; u( t6 h5 o7 {0 g: v
  108. /* Page的结构信息是否需要树形结构 */$ h) L1 ?- d1 V3 G7 A( R
  109. typedef enum / _( M  _+ C1 F& b' G) q( ?
  110. {
    ( O. h' R& W$ t4 f2 U3 s2 y# w( A3 J
  111.     OBJ_info,3 Z  M! _' V! v( V2 B, p! C/ I7 Y
  112.     OBJ_stream,$ ^5 F! q0 V% N8 H; s
  113.     OBJ_font,
    6 O  w7 l( t" F: s
  114.     OBJ_page,0 M- C2 A5 p1 O# @7 h5 O& V
  115.     OBJ_catalog,
    6 a. W" N" b' ~1 J
  116.     OBJ_pages,: w4 m; l& N9 d( @0 t- H9 p
  117.     OBJ_image,
    7 V- |/ e: E& I% Y9 `) d3 ~. _9 q. Q
  118. }LPDF_ObjType;7 y8 q7 Y! k. ?: A( ?3 K, y
  119. 9 x- X8 r9 q( c
  120. typedef struct, J% o+ x; ]. F( E$ Y. d
  121. {
    0 [, B+ r9 F3 }" x2 |8 w" |
  122.     LPDF_ObjType objType;( v0 k: @2 I5 X
  123.     LPDF_UINT16 objIdx;, @/ u" g% }9 ^
  124.     LPDF_UINT16 height;
    8 P4 O3 s" h7 L- R3 |
  125.     LPDF_UINT16 width;: K$ e( S* a$ G5 I% G" C% N7 k
  126.     LPDF_UINT16 length;. w' J3 ?1 X! \$ \* k2 }
  127.     LPDF_UINT gMode;5 X( i; n6 W6 K* N! x
  128.     LPDF_BYTE fontType;
    * n0 W3 ]0 x# {. R8 g9 v# u
  129.     LPDF_BYTE fontSize;% D  E* J3 X3 q
  130.     LPDF_BYTE pState;
    * h3 p% L& r5 |1 O9 u1 _
  131.     LPDF_VOID *doc;
    ) V" g' t) P$ A) f, V+ @9 T0 |
  132. }LPDF_Obj;
    3 h$ P9 ^' N. F! L, C9 a
  133. + n( U. u% F/ g. O) M
  134. typedef struct
    : w2 i6 G4 w9 D' N6 w  ~( L
  135. {
    1 w! V' N0 W$ i3 [# K1 O! |
  136.     LPDF_Obj obj[OBJ_MAX_NUM];, y* [/ b# ?0 P  u9 K
  137.     LPDF_UINT32 offset;+ y& a: {" A2 s; E& p5 q: T
  138.     LPDF_UINT16 objNumber;
    1 w+ B$ m" H) I
  139.     LPDF_FILE file;
    5 l* e4 g. m& r1 b& H
  140. }LPDF_Doc_Rec;) v5 _; w* d$ u$ C  t

  141. + n8 b5 ^' `) K
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    ; E7 F  l% t4 c% M% B- ~/ h, A
  143. typedef LPDF_Obj *LPDF_Page;/ c& F9 n! E2 a3 p3 i% w! r- C
  144. typedef LPDF_Obj *LPDF_Image;
    6 \: Z* c* ^- M9 \, z) M0 [" O' v
  145. extern const char *font_list[];
    8 H; J& ]  M3 G
  146. /*----- LPDF Interfaces-------------------------------------------------------*/, K; M1 m! h5 I
  147. const char * LPDF_GetVersion(void);
    : G# i( v) V& @" J! I% }7 n) s
  148. LPDF_Doc LPDF_New(void);
    ) K9 D' a( i) Q: h
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);' p$ Q+ |3 ^5 p& g0 b0 T
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);
      n$ H& D8 d: Y- z# c% k
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);+ \# w# ?) z( U# e: M
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);1 X3 o! x6 ?* D/ a7 t
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    . r6 s2 e: h+ F/ j( |  J7 s0 g
  154.                            const char *font_name, LPDF_UINT8 size);
    & b: `! o: E' F% f! _. h
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);
    6 J0 Y! U/ r9 ?9 ^  M* R. s! ~  ?5 ^
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);  K9 B5 f* _* Y- m0 i
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);$ C: T* P4 {% j  b- M6 V- I
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);
    , D: g% c3 T5 ~( U5 O- ^2 N; z8 Q. t
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    % S8 y7 E6 |3 N( c8 r/ ?( e
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);: w6 p+ N; Y; @6 K0 w* A+ J
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    % V+ E: g6 M+ N  C
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);
    & K" Y8 l) t& A% i) X" a$ x
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);/ d8 K5 B% t1 X/ p
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
      p, |/ s" @3 ]; J1 w0 Y
  165.                          LPDF_INT x, LPDF_INT y);3 j: W& z+ T% l+ X6 K
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, & g- [1 f8 _/ ]
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,& ?. v7 k! w+ A! b  v8 l
  168.                          const char *text);/ B2 R' K) p, `& ?7 o
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    5 C. N: S! Z* i9 Q4 p- \
  170.                          LPDF_REAL r,
    * W7 L1 b  T: h$ a! N/ X
  171.                          LPDF_REAL g,- p3 K7 R$ L- F, F8 c* ]' S; J3 i
  172.                          LPDF_REAL b);' N+ h7 C4 f0 @' l# F: ?" K
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,6 h! }1 p5 G5 q$ h/ ^2 N
  174.                          LPDF_REAL r,
    # ?& o! A2 t6 W3 q9 L$ N$ `
  175.                          LPDF_REAL g,3 B- }% Y8 J7 X7 @
  176.                          LPDF_REAL b);
    2 }& v9 X( E; b9 p
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,: c7 i; ~9 [& g% f1 H% s5 E7 Y
  178.                          LPDF_UINT16 x,3 h/ b4 ~3 Z! H# ]5 z1 M( z
  179.                          LPDF_UINT16 y);, t4 Q9 l& \- L& A: t, C
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    ( p1 t1 _1 X& v2 _. |& I
  181.                          LPDF_UINT16 x,
    7 }( D+ ~  y1 H) U' A
  182.                          LPDF_UINT16 y);
    # X9 S* }) n5 w3 X1 t7 F
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);( W# ?2 ^+ l& A/ }: {6 }
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);
    # b/ k6 {" V: G
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    - Q/ ]' o) H2 ^" l6 |
  186.                       LPDF_Image image,, y% _% m6 X- j7 m
  187.                       LPDF_UINT16 x,
    : b$ S: m4 e3 q8 d, q
  188.                       LPDF_UINT16 y,- T* y- Z' Z' Y' P5 e0 L
  189.                       LPDF_UINT16 width,
    0 B, O$ }6 P6 b6 D8 I4 h8 ]
  190.                       LPDF_UINT16 height);
    1 n( V) {% j5 M. T) e
  191.                                                                                         1 d7 J1 K8 \. O8 }
  192. #endif. z6 L% K1 q/ `
复制代码

源文件如下:

  1. #include <stdio.h>0 ^+ h8 s5 P6 L: G! i# u% I# r
  2. #include <stdlib.h>
    ; r. M( n; }" u; a+ A
  3. #include <stdint.h>
      b* q; b. ?8 j% f
  4. #include <string.h>: D- P9 p/ K6 ?6 z
  5. #include "pdflib.h"8 J  U" v( f) k3 b0 d% l8 n9 A+ q/ B

  6. 7 f, ?0 V8 N3 A6 N+ m0 N
  7. #define LPDF_INVALID_OBJECT                       0x10336 P  W3 z9 e3 }. ~' y* `& g2 i
  8. . W7 @7 p# S% k: ]) Z
  9. static char pdf_buf[512];
    8 q( p; C" i5 W1 o+ L8 y' c2 A

  10. # k+ ~  w' j, x0 Y4 E; @# r
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"
    : y" U$ n0 C) P; v9 i$ F
  12. #define LPDF_FILE_HEADER_LEN        15
    * q( q. x( E. m, R0 d. J6 W
  13. #define LPDF_BASEFONT_NUM           14
    * e6 y8 O  l! e/ E, e
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    " Z, ^# c6 A& k% U9 H
  15. const char *font_list[] = {
    % S9 E& y* s/ q6 t; I" t* Q2 w
  16.     "Courier",7 a5 G+ x5 M2 Z4 w
  17.     "Courier-Bold",
    ( e3 J( ]9 x+ M5 m2 C2 b
  18.     "Courier-Oblique",+ o0 f9 E* ~( L
  19.     "Courier-BoldOblique",
    * W( v  k: |' l* g
  20.     "Helvetica",; B% F9 h; X/ e1 f
  21.     "Helvetica-Bold",$ a# Z+ m: [1 x" _. a/ O6 u
  22.     "Helvetica-Oblique",
    . O5 S  V) f$ E& W: W8 g- I0 f
  23.     "Helvetica-BoldOblique",' k4 s$ l; y+ K8 w- E3 f$ ^
  24.     "Times-Roman",' N3 m/ ~  ]4 ~  R* K2 a
  25.     "Times-Bold",  D- [/ q5 Y  U! E+ G" p" e* W+ S
  26.     "Times-Italic",
    ! ^, ]6 B& s$ t/ ^
  27.     "Times-BoldItalic",0 |. q( h; i  X! [9 q
  28.     "Symbol",
    1 [2 u8 S, }3 |' Y: @. T6 n
  29.     "ZapfDingbats",
    3 s5 ]: t0 n: V2 S# V: S
  30.     NULL
    ; @) P) i* ]; a& X
  31. };( G" g* i$ h$ Z) Z- ]. u6 U

  32. 9 E9 B" c, b& O# N/ p

  33. + e$ z9 F/ ^8 b2 U( d
  34. const char * LPDF_GetVersion(void)
    9 s4 X( q9 v, v0 {; X( o! f
  35. {3 k" j+ ]# y7 x- [  h( N
  36.     return LPDF_VERSIOIN_TEXT;
    # [5 P* d0 ]7 Z( L& }( v3 l- H
  37. }; h' V$ |4 Y, o
  38. 8 w5 v# k' H7 ^  ~' C0 Q
  39. LPDF_Doc LPDF_New(void)# `: y2 \; J1 B" L; K7 @" G
  40. {; T* e1 [- `* N
  41.     static LPDF_Doc_Rec pdf;
    % M1 D+ n5 ], k5 K$ o- h: U
  42.     LPDF_INT length = 0, i = 0;: u7 v7 u4 W$ f$ `9 x6 m1 b% x
  43.         LPDF_UINT writeBytes = 0;
    6 n: N  E1 d! E0 Q
  44.         FRESULT fr;, T* Z$ m7 Y" l: @' r: Y8 @
  45.     - U) C% d" Z9 t: g. M. I+ }
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);2 a: T1 ^! M2 [0 _* L4 Q2 h
  47.         if(fr)- _6 h5 M5 _* m
  48.         {
    2 d8 S! `- ^% y) ^% k- j* @1 V  y3 Y3 ?
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    9 ~8 ]2 @6 {  V
  50.                 return NULL;! U8 {# }1 Q7 v
  51.         }
    " ^8 q2 }1 a. I5 B1 y  g8 n+ k4 }
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */
    ' B! ?; K% X- p$ W+ }# H0 V3 u
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;  t# J0 R* d+ C! O* g. p3 B# x$ u: J
  54.    
    * N: T2 z! J2 W
  55.     pdf.obj[0].objIdx = pdf.offset;; }+ }9 J9 M: Y+ J1 {: }+ Y# z
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");5 K4 g" S8 [& g1 ^' C8 |1 X) A
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    ; V8 M5 x. u7 C6 o  g
  58.     pdf.offset += length;$ f' {" J/ b9 }' `$ M- ?
  59.       [# j9 h1 g9 O
  60.     pdf.obj[1].objIdx = pdf.offset;, L0 t: e2 Z, A$ A* B
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"2 a! e) g$ D8 T7 N" B
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");! z4 w( v; }1 Z7 [* }
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    4 I4 p8 ~) w/ T- s% S3 H
  64.     pdf.offset += length;
    " u( V0 X; U% w+ q) C. o& ~
  65.    
    : {6 }& a# J5 g5 Z, {: [
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    / G# V0 f+ r4 L: ]/ L
  67.     {1 b2 E2 o( b0 {8 B! f; o$ ^; P) h
  68.         pdf.obj[2+i].objIdx = pdf.offset;9 P0 f- J/ N0 I4 q, M; g, c( ]
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"9 U- r  F8 ^9 }4 F4 |  @
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"' U( a; k! S. I( V8 C6 [/ r
  71.                         "endobj\n\n",3+i,font_list[i]);
    : W, L& Z% Y5 O1 E: x4 q
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);0 R5 U4 ^  ]7 v. h# ]& p; W. z
  73.         pdf.offset += length;- h' _% M+ U- T5 ?, R0 l0 w  P- _
  74.     }6 u# l+ N: t2 D6 Q
  75.     for(; i < LPDF_BASEFONT_NUM; i++)
    3 q. N1 c- Z# |) h$ U" J3 e' `
  76.     {
    " F, z+ F$ _# S/ W
  77.         pdf.obj[2+i].objIdx = pdf.offset;
    , D2 G7 N- k) m- r5 n
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"  V# T/ z0 f5 ~8 C/ h- g
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);; s/ t( n2 i$ M7 v2 y6 Q" O
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);' C; n" ?% Z% [5 c5 b
  81.         pdf.offset += length;4 C/ n" _7 k: e
  82.     }. d! W% P# a+ V, k1 c/ ?
  83.     pdf.objNumber = 3+i;
    1 Z. d; U% {5 D/ v. q5 n% u
  84.   + i3 k' {; a$ c$ l1 U
  85.     return (LPDF_Doc)&pdf;* l5 j1 H5 K. s$ h+ n
  86. }% T9 a+ V$ ]3 P3 L! z6 s

  87. " ^' r- K% z9 M! i6 w
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    ; `4 ~. d) V3 ?' X3 D$ H% l' I
  89. {8 T$ |: ~# d' F
  90.     LPDF_UINT16 i = 0, child_pages = 0;
    1 S5 Y2 ?% c& _
  91.     LPDF_INT length = 0;9 v2 i" f* c( |/ w6 t0 }" Z
  92.         LPDF_UINT writeBytes = 0;
    1 G& K/ {5 _, J3 o( a% i6 x: G1 @

  93. 6 s/ x8 X& `. h2 B6 C) W
  94.     pdf->obj[16].objIdx = pdf->offset;) Z+ ~" z" x" h/ N( p) M
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;. E3 `/ J. e8 M) G) T! K1 z5 B5 o
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);
    % F8 Z" }# v- m7 }' i' P: d* q" [) R
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);' X( D) S) N5 D6 X0 J
  98.     pdf->offset += length;
    & U* f1 x; m7 J* t' t* E$ p
  99.     for(i = 0; i < child_pages; i++)! N* ^1 i- Z& y& w/ c- @% y7 P
  100.     {. D: P4 H) c' q9 C% V
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    - `5 g/ c$ t+ n% b1 h9 i
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);$ m% ], P; J( ~* t3 |: V* Z  K7 \
  103.         pdf->offset += length;
    - A/ f( c5 e5 [: E/ C
  104.     }
    , ^, L, _; v7 G' h8 _
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");
    5 A) N# ~! T9 \+ G. z
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);2 g# w4 m  I% e* l
  107.     pdf->offset += length;' I9 t0 T# ^5 e0 Q7 g% P8 G0 ^
  108.     2 p/ O, j0 H; K: s5 g; O) d. `
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    * Q2 j% \/ b! ~- X& k
  110.     for(i = 0 ; i < pdf->objNumber; i++)
    . V' ~, ]5 g6 @6 l4 N( w* Z( f" H
  111.     {. B. w( ^4 d9 `+ h7 F
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    " V7 p: t, _. B! [: b6 [$ `- p
  113.     }
    % x; E4 ]0 y2 ]
  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",9 q; j+ H% q, F
  115.                 pdf->objNumber+1,pdf->offset);' A, \% G. u' c# e8 R3 _0 n
  116.     LPDF_FCLOSE(&pdf->file);
    ( o: M& x, W; W4 O2 `8 s& K+ i
  117.     LPDF_REMOVE(file_name);( A) ]; i$ g2 d& Y$ n
  118.     LPDF_RENAME("tmp.pdf",file_name);# a: ]# x8 X; ~. p  i- l
  119.     return LPDF_OK;' g! w  K* o% A) T1 h# Q  j2 U
  120. }
    # l6 X& T3 k' I  ?5 \

  121. / l; W2 s. o) Y5 p# I2 O
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)
    5 H0 G4 N6 U. q( j( e
  123. {
    ! @8 G! r1 i7 Y
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);
    & a1 b& d" x# ?3 ]" F9 V9 x
  125.     return LPDF_OK;* _0 b# X' c) ?! ?4 n# \  F8 z
  126. }- x/ F( ~7 w  h. n6 g; c" r
  127. 7 I7 M: E0 j9 s4 ~. M$ W
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)
    ! v$ {7 ?! \1 J: r$ U: ~# e
  129. {
    ' x9 `' `' X' p1 a" f  i0 X; r
  130.     LPDF_INT length = 0,i = 0;
    5 m2 T9 E/ K3 M" u5 J
  131.     LPDF_Page page = NULL;
    1 s0 z$ Y4 s/ k
  132.         LPDF_UINT writeBytes = 0;; c0 k; \- x" H* O8 u% G
  133.     9 q2 `+ J% l7 e9 F, ]* {, s: u& Z
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    + G$ G% r; d) }, E( c7 G2 z2 i4 B) f
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"3 \. q  C' c9 x0 n7 I" j* g
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"3 Y- Q& a; Z  p6 j9 X
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    - B4 m1 \6 @4 w0 |8 Y/ G3 @
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);, d; s+ Q7 g6 i4 E" _. U8 u( M' |
  139.     pdf->offset += length;# P" k) l$ m( D/ J4 V  k) z9 ]
  140.     while(font_list[i])
    1 \' m! y2 a5 \" ~1 O
  141.     {
    / h' T1 ]% e2 [
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);! ]0 k! a. Z. h$ F, Y; I
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    8 Y/ i/ \- ]( g
  144.         pdf->offset += length;
    % W2 k, k/ z3 o2 n$ @
  145.         i+=1;+ _' r4 ?4 R: A: _, W
  146.     }2 {+ I$ ?& v: s) ^
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");6 `0 Z; h5 H" B
  148.     pdf->offset += 4;
    $ W2 d% Q. _0 o  ]# Q  t, s
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];; @* V+ {6 }( }) Q; F" s! H
  150.     page->width = 595;" s2 F9 q3 P* J( a9 w
  151.     page->height = 842;
    $ ]+ d' \8 W2 }7 W
  152.     page->gMode = LPDF_GMODE_INVALID;( Z( x1 R# S4 X
  153.     page->fontType = LPDF_FONT_INVALID;+ W5 y" x: D$ F7 e. P
  154.     page->doc = pdf;2 T8 o! N, s! J, \
  155.     return page;4 D  Q  z0 F! L; T9 y% U
  156. }
    , ?% A- r0 W5 V' [

  157. , X  O4 I: Z9 N9 V: V
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)
    # t9 E5 q  |8 e1 F
  159. {
    # f+ g: C6 \- O5 x7 ?7 q  X
  160.     page->height = value;( S# A& B8 m- k3 A7 q
  161.     return LPDF_OK;
    9 ]+ W  ^5 w$ r
  162. }
    # R, V" N: i. }" K
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    ! m. n* s& s; H6 b' ~& n7 h
  164. {
    # |0 J7 w# K! ^, m; o" @7 j
  165.     page->width = value;5 I( ]# S3 Z$ S! I$ x0 U, |' E1 K, p
  166.     return LPDF_OK;- q+ r, `" t9 \
  167. }
      c! `/ c9 ^7 t0 Q/ Q) E

  168. # ?, ^; Y" A! M2 U% P3 f$ W
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)" r, Z8 P  Z/ y/ A& u$ Y9 w
  170. {8 M! r/ X; K# B% o' n0 E$ r' m
  171.     if(page)4 [# B* K1 n" Z3 N# ~' Y" ~
  172.     {
    1 T7 F. Y7 z1 I' f  F9 c) ?
  173.         return page->height;0 D/ e6 m0 j4 v* G
  174.     }/ |. L' m7 c- R: I7 W- k0 H
  175.    
    4 x/ Q4 v& @" d9 s+ T
  176.     return LPDF_OK;, h& t  g9 _. |. e! V
  177. }
    # q- m- i& W5 r1 A+ r4 _; p

  178. . \' o& ^' c& Q3 q! f$ j
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)# a0 y0 g+ x+ K  W$ L
  180. {& D# N' p2 {& M* n( C" H( t' b
  181.     if(page)
    : A3 s- e* x9 Y# L6 \
  182.     {
    ' r& i6 l. f! u, `
  183.         return page->width;' H3 `* D! x% C6 n: u, y' |5 [
  184.     }. I6 @3 V4 i0 l' A3 y
  185.     4 v: e% U1 U. }  r0 t5 L
  186.     return LPDF_OK;
    - z% ~+ J, L! k/ y: F: S9 a
  187. }6 q& b0 Y# k) R* B) p* M
  188. 8 {, f. U1 q/ p/ |
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)- A  u) z0 n( w% \) e6 x) r
  190. {
    8 s* c4 c+ x6 l* ^7 u; \
  191.     if(!page)
    8 z+ T  y7 i6 u. g
  192.         return LPDF_INVALID_OBJECT;7 T  N" a% X$ Z0 ?
  193.     if(!(page->gMode&mode))
    % m( Y) x* \1 h7 ~
  194.         return LPDF_FAILED;
    9 }& r7 f- C9 N+ J6 p  [
  195. # W# K$ T. H; d  W
  196.     return LPDF_OK;
    + b" p& u' I. }+ Z2 Q3 N4 c
  197. }
    ' u* \; b; N# Y  A

  198. ; T! z) v  j/ |" p& D" P
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,! {' n# n- {0 s0 l* A
  200.                            const char *font_name, LPDF_UINT8 size)" U  C+ v1 X! z" y
  201. {
    0 e' P1 a, t7 z  M" b( ]' F' @
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;) ~5 ^+ r5 r9 x3 x9 ]7 i5 ]
  203.     LPDF_INT i = 0,length = 0;
    - _1 |! q8 I. t% w! j% W
  204.         LPDF_UINT writeBytes = 0;) t  T1 M- c3 ~+ W' I" a: c
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    ) L; L: q8 S% Z; @
  206.     if(LPDF_OK != ret)
    ; w  h2 V; k' B& D. I( o9 e) L
  207.         return ret;3 z5 r. P, Q2 F- s4 |( `! m" e$ z

  208. ) o0 J: l1 C# ^; l/ I* \5 {
  209.     while(font_list[i])
    * M9 J7 {8 m1 A' Y/ u3 I! A% \
  210.     {7 P# v; B4 q* B0 Y8 P
  211.         if(0 == strcmp(font_list[i],font_name))1 B' H0 m1 b! j
  212.         {2 C$ _. B- B' I1 R* [1 e1 _0 f7 \
  213.             page->fontType = i;/ z9 X, D: R) Z: m7 D) {7 O
  214.             page->fontSize = size;
    7 m( A/ K% o, Z5 M+ w+ t3 V
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);
    8 t: l  \, H2 E2 B* o$ |
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);4 d, Z- B, P$ e; {" k5 Z
  217.             pdf->offset += length;9 i' a7 c( ?7 S+ U/ v; k
  218.             page->length += length;
    " U. i/ f3 C6 i6 w' o' e- M
  219.             return LPDF_OK;8 M2 H- B, O( h% @, w- f# G8 B
  220.         }' X' Y8 K$ q6 Q) `# l4 d% h
  221.         i+=1;, [! W, \" R& W
  222.     }
    5 P5 W6 Z+ F, [0 ^
  223.    
    & c1 x3 i# @" T- I- P2 f
  224.     return LPDF_OK;
    8 ^% H% @0 {4 M( i: u! m
  225. }9 {+ o* U0 B2 @" W
  226.   q$ ^: r& y# _, Q! p- c+ `) {* M
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)5 g2 |1 e6 J2 U' m4 q
  228. {
    6 \; y- [$ ~( t7 |1 q$ U3 z
  229.     LPDF_INT length;- b0 y: k9 M( B9 U9 Y$ ~* l3 H
  230.         LPDF_UINT writeBytes = 0;
    : U" ^( M/ ^3 Q1 j% K( r
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    5 l) G6 Y) m" g- G0 `
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    & K0 ]: C) z$ R6 ?4 d& g/ g
  233.     if(LPDF_OK != ret): y5 ?8 w2 w+ M" V2 {- f
  234.         return ret;- p8 d3 u% ^, l
  235.    
    8 a* |% {" G4 E, t
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */0 Y. q' _7 \  b# T  K* U4 C7 t
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
    # E2 y0 Y- ~$ q* M3 E
  238.                         page->width, page->height);$ H( m- C9 U  m
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    1 `! w) T& D0 w: q
  240.     pdf->offset += length;
    ; E0 G  R' V7 f3 n% G# J4 c
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    $ z. R4 G  V2 T" ?; Y2 g& P
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",( H6 W' Y5 n& s; C. z/ q# M$ e
  243.                         pdf->objNumber+2, pdf->objNumber+3);9 w" g& ^: s! L  ~, J* C2 O
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    7 U( X5 Z0 f" S5 @/ e& x0 L
  245.     pdf->offset += length;
    9 D8 g0 c; Y) r! N+ D/ N
  246.     page->length = 0;2 c0 n5 R# n! |" S/ N  z
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;$ P+ e; _5 l6 F
  248.     return LPDF_OK;
    5 M0 z, r  t% A: S
  249. }
    / y+ Y5 D& w+ q

  250. 6 ?' F1 v1 h5 U" z, r( [4 z
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)* j" O& i- p  G4 `  T+ W7 H
  252. {
    8 O0 R- l  F; I3 a) p0 R( d) C1 B
  253.     LPDF_INT length;
    8 D( p) \/ D9 n
  254.         LPDF_UINT writeBytes = 0;- L( q" H4 ~5 x+ ~3 Q  }& r( t" x
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;* `3 }& e4 j3 M7 G
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);- n. J, p5 }2 v2 t! e7 i4 u$ t+ k
  257.     if(LPDF_OK != ret)5 {) L  l( i, N& J
  258.         return ret;
    . v7 ]/ }+ F& W! j" L0 B9 g
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */* ~, a) D8 n4 N; }9 v7 h
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    4 x: ^4 ]0 x% ?% Z6 _
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    + W% z* k  T' J1 ?
  262.     pdf->offset += length;3 p' e7 Q/ V- p3 T  ?& n, p4 p$ f
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;
    : h3 ?" O7 P1 }1 ^
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",3 z1 f0 z& S4 S3 W& p
  265.                         pdf->objNumber+3,page->length);9 @" \. @8 V" v5 O' }5 Z6 f
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);+ h* B$ {% N* A8 ?* |% s4 ?! D
  267.     pdf->offset += length;
    6 r& I; \) c& `2 ]! g, _
  268.     pdf->objNumber += 3;: v, b# i4 p6 z5 Y1 S+ g
  269.     page->gMode = LPDF_GMODE_OVER;6 h3 Y' a5 c9 g$ D
  270.     return LPDF_OK;5 q: B7 P  g" t* E# L4 l$ r
  271. }0 J* U. O1 C" Q6 k- F
  272. & c4 z( X3 Y  p: l* W6 p: d9 V* ^
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)" @. T; Z& x4 g6 N# w
  274. {
    6 C. W% H' R& a3 n, |; k2 ?7 y
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;' X' H4 w1 z. D9 q; T* N! [3 l
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    $ V+ I- N! |* c% c" S
  277.     if(LPDF_OK != ret)  T8 W9 }$ T! G( n- P( V
  278.         return ret;+ r) X. ]) E- i0 y
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    , r/ t  ]1 j$ e) q' _
  280.     pdf->offset += 3;- {" S2 l, W# L9 Z) h# Z; m# r
  281.     page->length += 3;
    6 I' q9 W" D( w
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;
    2 i+ \5 [1 q' u9 |1 C0 T6 ^
  283.     return LPDF_OK;' c+ C+ K$ ]- R1 v  T
  284. }
    ; a# L' j1 [& U0 v" l! f9 n5 r
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)5 P/ _/ D% y3 E: r) Z6 h5 s
  286. {
    5 @$ q5 c3 I: X2 w0 n
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;7 u; y" C' D1 ?# J
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    : z% |0 p5 S' m1 Q" [7 k$ H( X
  289.     if(LPDF_OK != ret)
    6 @6 z& U# L, y1 t' W% ]
  290.         return ret;! R( ?2 E  `7 I7 U- T% n0 o% `
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");; M/ i2 `+ S- m4 v" h3 A+ v
  292.     pdf->offset += 3;2 u6 r; g5 M' V1 W
  293.     page->length += 3;% F  p' x& u& G& H
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    + ]! q; B! k4 u5 ?1 W
  295.     return LPDF_OK;
    ; a8 P4 g/ c, r
  296. }
    ; w; _+ b' |' m' y2 @# W. e, q1 o! }

  297. 3 O4 S2 X# U) ?7 _9 f
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)8 X# c) y- @- W" _3 R2 _
  299. {  L- U2 B- }: q/ e
  300.     LPDF_INT length = 0;9 z) E- L) h% X$ _+ B% v
  301.         LPDF_UINT writeBytes = 0;0 o+ [, n3 t2 Q
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;- ^! v5 [" e* k- Y  k* g" h
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);% D. g0 g/ R8 |: z1 I8 ]  T
  304.     if(LPDF_OK != ret)
    # r% _- K$ ~: f
  305.         return ret;7 a2 Z/ b6 o# t- z* U: S, ?
  306.     if(LPDF_FONT_INVALID == page->fontType)
    8 t! D+ v- D0 u
  307.         return LPDF_OK;) @4 e% k! P3 E% Z9 Z6 S
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);" W# r& t" p0 G1 w3 X/ x, u0 T
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    % H6 H1 R. q' }9 N$ V& ~
  310.     pdf->offset += length;
    - X- r! K  n5 F% P( A8 u
  311.     page->length += length;
    . \) @  V2 ^, C
  312.     return LPDF_OK;+ U, W. q- ~$ e' A# e+ ]
  313.    
    - M: Y: `4 W/ U- [/ R
  314. }- _% f& [" Y. m  e
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,0 \. e5 L9 U0 y/ O! R1 `
  316.                         LPDF_INT x, LPDF_INT y)
    $ {5 d; D: m* ?& `5 z( y, v
  317. {
    9 P; v: M* E2 U- c7 d: z' Q
  318.     LPDF_INT length = 0;
    # ^6 Y. Z$ u$ @8 U! x
  319.         LPDF_UINT writeBytes = 0;
    " `6 `  J$ P( O6 V  y4 X
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;( R" s" G( m" t0 |
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    7 x8 x5 c% q& }) @. r
  322.     if(LPDF_OK != ret)
    / z! V( E, M& j& O) g
  323.         return ret;" m( m1 }  [% S( q) n
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);
    0 l% f* Q1 b- Y5 |3 L( q
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);7 D: N3 s4 V/ a* i" f8 e' i! s+ R
  326.     pdf->offset += length;
    5 n% o2 ]& T  v# P# y; {7 k) @
  327.     page->length += length;7 n1 v% m7 B1 L$ Q2 i
  328. ' W2 y: e5 _* L4 ^9 _; r
  329.     return LPDF_OK;" g- }) ~" l4 ^! a$ k3 Q$ r: y3 @
  330. }- N' |9 t- c( }; W* V
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, ! S) c' `3 U  g! Y  w3 F
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,6 k$ k- j/ ~5 R+ i* t
  333.                         const char *text)2 d( q- U& y. m
  334. {
    4 k( V0 {1 q4 ~  W4 G
  335.     return LPDF_OK;/ G7 t! B  B2 a% f
  336. }
    6 \6 m+ s# n% {/ ?  N
  337. ; n& |; P5 t& o! x7 x
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    0 J% Y" M, x" e1 @- v/ j
  339.                          LPDF_REAL r,! T# \& ]  D& O5 |2 e9 O
  340.                          LPDF_REAL g,) w. j/ [9 P3 d! F; v6 h0 `
  341.                          LPDF_REAL b)
    ( z, g6 {: ]: b' K) U/ ?+ @: ?8 t
  342. {
    7 O7 c5 s; k1 d/ p/ |
  343.     LPDF_INT length = 0;# }& r' M+ o# i
  344.         LPDF_UINT writeBytes = 0;
    2 V+ F! C/ c3 n! ^9 C; e1 J
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    & h& X* ]! U9 G' T/ z4 j
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    , P5 ^" F1 }1 H3 @- X
  347.     if(LPDF_OK != ret)
    * i  R, ]  ?' _  K: Z
  348.         return ret;) T7 D9 v1 u5 s6 q2 \, i, D4 b; B

  349. 3 v6 L- a2 [; f" G
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    ) u& C5 r0 l$ C6 R) t# Q1 e3 c
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);& u/ T+ y; F7 k$ B: u
  352.     pdf->offset += length;  i8 C( I2 S/ ^+ W) X
  353.     page->length += length;# h* F; g1 U, y; C, v# m& }
  354.     return LPDF_OK;
    9 Y% E: x; ~& L5 B# K6 P
  355. }1 y- w6 |. A- ?
  356. - \1 F4 b9 E3 M1 c0 A3 I. j% C
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    5 M" f0 g0 X* f
  358.                          LPDF_REAL r,! ]/ V. t; O8 V
  359.                          LPDF_REAL g,1 }% `( P' j9 I" \: z3 f. K) f" _
  360.                          LPDF_REAL b)
    2 v7 W' M) M0 u, @7 p
  361. {
    ' \) }( a) b8 F& y0 s
  362.     LPDF_INT length = 0;; `8 l" W4 s* P# O
  363.         LPDF_UINT writeBytes = 0;- ]4 K8 Y* U! U( T  t8 @8 h
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    - o# O$ O  B% H8 u+ D5 V
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
      z% q" h1 l" K( Y" Z" ?2 p# l
  366.     if(LPDF_OK != ret)" c+ H/ t5 N) z4 P- X6 e/ _
  367.         return ret;
    / |4 B" {1 {; s$ e

  368. 8 v! _' S+ u& ]
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);
    $ Z. Q% I0 P9 c! v$ T: x+ `
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    * A  @+ C1 d1 F5 y. e0 Y
  371.     pdf->offset += length;8 \* E+ m3 {- U5 }
  372.     page->length += length;! w. @8 E+ V' \# D6 X5 n% J
  373.     return LPDF_OK;
    5 y) U* E$ D5 [9 a7 u; ?" g& l
  374. }9 Q6 m" J  {: |1 x- {* m
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,% ?6 i* a* P; l4 q: g, ?
  376.                          LPDF_UINT16 x,
    * E0 t/ K4 J5 I3 t( ^
  377.                          LPDF_UINT16 y)7 A; a' X4 Q8 f7 f# W
  378. {/ t, c8 P# ?# g8 c0 W: ]+ \5 r
  379.     LPDF_INT length = 0;
    ) y7 O! u  ^& L: o
  380.         LPDF_UINT writeBytes = 0;
    ) D6 h. f3 \; J: h4 q! h
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    7 l& x- M" A7 ~$ R+ k. c2 e, b
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);& s" }  E) A' ?& v5 R" \
  383.     if(LPDF_OK != ret)
    # L) C! D1 L8 C9 ^& f
  384.         return ret;7 k3 h2 F3 m9 k+ B
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);8 |7 T0 ~. G/ T# d" M& h
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; a! G: n' c- d, n1 ^  u# d2 {
  387.     pdf->offset += length;
    4 h* G% @. \" x$ s- ]% J6 V
  388.     page->length += length;* L* ?7 X" s8 y& q2 M
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    8 D$ _" \! t2 R0 }* Y
  390.     return LPDF_OK;5 A& z, B2 t& C9 t2 B" w
  391. }2 G3 T0 Q  W2 n" L
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    9 a" P. H9 L' Q0 {+ N0 J
  393.                          LPDF_UINT16 x,
    6 Y! Q6 z3 P4 p7 M0 s8 H
  394.                          LPDF_UINT16 y)
    + D3 }7 |$ a, p4 P, [& i, C
  395. {0 J* v. w- o. q
  396.     LPDF_INT length = 0;( t* A2 o9 f* q
  397.         LPDF_UINT writeBytes = 0;
    ( N+ H# B7 O5 W. t4 b  @: z% [3 T
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    7 ^) F- f% S7 N
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    ( ~: l; k6 N7 G7 p- y/ d  M9 \
  400.     if(LPDF_OK != ret)
    , e$ S) b9 y; g6 d
  401.         return ret;
    4 T7 x7 w6 X# K# p, x
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    6 n% k8 M: A6 F" @, U4 g8 x, Y
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    - s5 F, R/ I: P3 T& S, f. w' _
  404.     pdf->offset += length;! _- E9 h' s  \* K' N1 v
  405.     page->length += length;/ A9 P- j6 i$ w/ I6 y
  406.     return LPDF_OK;+ A1 O/ u5 v" l
  407. }
    " |2 Y( V; o' h  T$ R
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)
    9 F, {8 q/ }  b
  409. {
    3 l9 Y9 _, E2 }/ W) U, K
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;2 L2 p. C7 {, J0 [. q6 i( S3 l2 ^
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    1 `% y! t, x" t
  412.     if(LPDF_OK != ret)% o. ]! |) M  K
  413.         return ret;
    * E5 `) h' w6 i
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    , J9 D! M, Y# l) ^
  415.     pdf->offset += 2;# C. o7 I3 ?* R# N
  416.     page->length += 2;( O+ I  K5 `: a0 S( s$ Y
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    " p5 ~/ w" k9 x
  418.     return LPDF_OK;
    / y' m; @3 P* `, X$ f& \9 x
  419. }/ K; }9 p& _, m2 q' e: }/ I
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    5 w- ?: x1 q, ]+ {# j6 w
  421.                       LPDF_Image image,% E; a8 [1 X, f) L0 Z7 y  z& D
  422.                       LPDF_UINT16 x,1 Z$ I: Y, [" N  R! C
  423.                       LPDF_UINT16 y,
    2 T# m/ l2 C& M# t
  424.                       LPDF_UINT16 width,
    2 n; d- D; [' |
  425.                       LPDF_UINT16 height)4 A$ ]( J) F! ]: k; r: ]% t6 N
  426. {( u5 i9 I" k4 N* v5 o5 x
  427.         return LPDF_OK;7 i' Z* j1 h% ~5 a7 B( P
  428. }
    / c0 y/ P/ B4 U3 N. U0 F8 u
复制代码

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

  1. pdf = LPDF_New();
    + ?2 y$ S1 E" e
  2.     page[0] = LPDF_AddPage(pdf);
    ; j' P5 u+ n" h1 C9 v6 V1 ~* q( r
  3.     LPDF_Page_SaveParams(page[0]);
    $ [/ P9 @" p. m( K9 P
  4.     width = LPDF_Page_GetWidth(page[0]);
    ! v- W9 w, j. ^0 O& [
  5.     height = LPDF_Page_GetHeight(page[0]);- O. a3 b' y$ a7 L
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);
    9 Y* X" H8 G0 H2 n
  7.     LPDF_Page_BeginText(page[0]);9 A5 y5 p* i- }* {
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);
    ) T8 Q1 R: a3 w3 ~1 }. {+ C
  9.     while(font_list[i])/ }3 b7 ^/ D) F* B- T" [6 r
  10.     {
    9 y- }$ I( x; E1 F
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    ! G  p! Z% n* S$ z' p0 d' t0 X
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");
    0 {, {6 p5 X2 K% s4 B3 W
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);
    2 K; L# d1 m. \* \: r" b8 H
  14.         i++;6 z6 x  H* @" b# }' C! z7 B9 x& b: k
  15.     }
    ) H# ^; g. h: `  _4 s! K2 b
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);5 f) `4 @) b4 F1 b
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());
    - U: m  L' y5 t' C8 [/ ]1 c
  18.     LPDF_Page_EndText(page[0]);+ U* M; X3 m7 P* X: c
  19.     LPDF_Page_SaveContext(page[0]);
    ( E1 W, ]. z2 c4 p  J3 }( i
  20.     page[1] = LPDF_AddPage(pdf);
    : V$ p( p7 L3 T' a! W3 F1 l5 c
  21.     LPDF_Page_SaveParams(page[1]);
    7 B: I2 E1 ?8 l* e  ?; {0 r
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);5 L' L* D- J# [' E
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    " H' [) r6 x0 p% K- G6 Q1 H
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);/ ]0 B; s/ O; j; h
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);: i! f4 X4 R# m0 j# t$ F3 i* z
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    ' q9 i7 o  u: J' [1 g6 n
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);
    & c4 @' `1 X! \* p9 N
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);+ w) t; |; Q( [7 a; d
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    6 w' q7 X& w* W- O) t
  30.     LPDF_Page_Stroke(page[1]);
    . D3 }" u. l0 S
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    + k0 [% D# J+ }' n7 q7 g1 p
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    - J' z  ?+ J& [* @
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    ! b5 x- m8 N0 a% f7 q
  34.     LPDF_Page_Stroke(page[1]);
    ; C  i- l' r" h; h9 }8 h
  35.     LPDF_Page_SaveContext(page[1]);- a( Q0 W& Z7 h
  36.     LPDF_SaveToFile(pdf, "/red.pdf");9 J5 g+ \/ V4 ]% G- p. V2 S
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    2 ^9 u- c$ ]  y7 T! A
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了
6 T% s" `$ L6 e5 D: p3 p4 q6 @

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体( R6 m8 L+ [" R9 A
9 H8 a0 Z8 U3 @0 S( b/ d0 H

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* P; P$ g2 m+ {- d# O
只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...

0 N. N* i8 w  s9 X( F' O+ ~. B8 `8 XLZ,我怎么没看到有添加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
$ u, I. p4 f6 W" P0 y首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
. o' _/ D9 D8 t  _9 L
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
' x. B6 A# s. B( N' l6 C% ^, n
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
4 ^& B( I( C  I看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
- q4 E$ k6 l0 X* y4 n9 `
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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
: d' ]1 q; A: [- k6 `6 _厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

2 {0 @* t0 n3 _5 i- ~7 J. B5 i这个还只是一个简单的库,实用性还是差一些的
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$ Q" a  Y% z& P$ H7 s0 I0 u9 R
ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
7 t+ u% Z1 Q1 v5 `; o
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
* b1 ~% `% I: y+ a8 vff.h是FATfs中的文件

. v# y, I. \3 K+ d  f2 e7 _$ h嗯,这个画线能改变线宽吗

所属标签

相似分享

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