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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑
2 S1 g0 p' B1 {' {
& |, s1 P  R) y) z! M' m' E

主机环境: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__  N! ^/ w2 ]+ a* z2 _$ B0 Z+ j% f  x
  2. #define __PDFLIB_H__
    : _/ [( X  Q  w/ a8 Y6 f- g3 w
  3. , ^+ C8 k0 E* q8 b& ^
  4. #include "ff.h"
    " t/ z( n$ Q0 v! e
  5. /*----- standard C library functions -----------------------------------------*/
    7 L' Z- k& d8 i, u6 m  k
  6. ) @# _6 `$ y* o% D- J  I
  7. #define LPDF_FOPEN                  f_open
    0 m: E8 h+ C& c) ^& D
  8. #define LPDF_FCLOSE                 f_close
    . C* L9 n( s, z" u: R- N
  9. #define LPDF_FREAD                  f_read1 b) z6 @7 i9 a3 \" x
  10. #define LPDF_FWRITE                 f_write! Z: T) Y  L0 H! m
  11. #define LPDF_FFLUSH                 f_sync8 _4 h2 w7 J( o3 @, S( g2 X" u
  12. #define LPDF_FSEEK                  f_seek
    0 }. A5 W& D2 n4 e1 H
  13. #define LPDF_FTELL                  f_tell3 r" e1 J$ M8 G" x
  14. #define LPDF_FEOF                   f_eof
    : q* a" Q% b9 G2 g6 A3 O
  15. #define LPDF_FERROR                 f_error9 K  ^3 q$ M3 P/ O
  16. #define LPDF_RENAME                 f_rename, \% w" j+ S/ h( \+ ~8 |
  17. #define LPDF_REMOVE                 f_unlink7 H) F; I$ x+ L" Q0 ]$ D
  18. #define LPDF_MALLOC                 malloc2 |+ N" h" \. W4 b0 V6 L
  19. #define LPDF_FREE                   free2 P- [2 G4 g* c2 z& L' U
  20. #define LPDF_FILE                   FIL
    / \1 a) s! M& Y" ~6 \1 z% O0 a
  21. #define LPDF_TIME                   time6 @7 l8 H! X# _
  22. #define LPDF_PRINTF                 printf; r  Y5 X' F- j& i; ?+ y
  23. #define LPDF_SPRINTF                sprintf
    % T8 ?1 ]1 P, u4 b; G3 D
  24. #define LPDF_FPRINTF                f_printf
    ! ?% A" d/ z) o; G9 U! A' ~
  25. #define LPDF_VOID                   void
    + R2 n& h6 I" V4 t# B
  26. #define LPDF_SIN                    sin! m; L" D; Q; }
  27. #define LPDF_COS                    cos
    + U: `8 `1 ]  s. N

  28. 0 ~* f7 J; |0 O$ r3 J
  29. /*  native OS integer types */
    % c6 B* }$ g& s2 V: X
  30. typedef  signed int          LPDF_INT;9 @0 ^. S" W. d  [3 ?
  31. typedef  unsigned int        LPDF_UINT;8 n. ?2 f5 g$ |- e* J

  32. 3 p$ W3 Z! F  R5 p( L

  33.   p2 Q7 k7 [) T( S. f/ \  `, k
  34. /*  32bit integer types
    1 m5 Q! K# g0 s- A
  35. */
    ' `4 n* w" ~- c3 V3 }, F& W) K0 k4 S
  36. typedef  signed int          LPDF_INT32;
    * n: z6 H8 w3 n+ X. ?
  37. typedef  unsigned int        LPDF_UINT32;
    5 x: H- ?; O' w! j( P

  38. 4 f" i2 w$ m( L# D+ q

  39. % g/ B- y& j+ \+ ~* _% t1 i
  40. /*  16bit integer types9 E% s6 ^7 r+ B% H: K. c7 f
  41. */
    / w3 X: S) M) Q* B
  42. typedef  signed short        LPDF_INT16;8 f/ L4 q7 q2 W6 V# x
  43. typedef  unsigned short      LPDF_UINT16;
    0 V9 u- H) q7 l/ O& |% X5 z: x3 G

  44. 3 f- E; x) w$ B$ T

  45. 6 M& v) W) T+ F% e2 i2 L
  46. /*  8bit integer types3 l* P& o0 N8 R6 W! F% L$ @
  47. */4 d  \3 i0 {+ I: m8 }/ n2 n* n! O
  48. typedef  signed char         LPDF_INT8;
    , E) Q4 V$ k# Q8 A% g2 J
  49. typedef  unsigned char       LPDF_UINT8;/ P, L9 e* `) O" ?2 c
  50. ' h+ I# m% J# B4 N9 o2 W6 W

  51. 2 a; A+ t" A8 h4 J
  52. /*  8bit binary types
    . [  S; t  i: f4 J1 m4 N
  53. */
    . }. n3 Q. V: w' R9 z7 W& S4 S
  54. typedef  unsigned char       LPDF_BYTE;+ J: `) Q/ R' s& G4 p: A0 t1 m" N

  55. & t  K6 ]! C$ |9 K0 p' g0 G

  56. / h5 G9 J* @! A$ H
  57. /*  float type (32bit IEEE754)
    4 O4 x! ]0 n$ F& D6 k1 C' g6 ^' C
  58. */
    0 _' z1 q) p7 y; }. X* {
  59. typedef  float               LPDF_REAL;- h) x+ ?# W2 W  J8 Q7 J( u8 }

  60. 2 C& F* r, [$ r$ @7 R3 [

  61. 0 e7 Z2 @' x1 [
  62. /*  double type (64bit IEEE754)! K# [9 b; n* a" h( V, _
  63. */
    7 I( _( t0 J5 o( Q' c( H
  64. typedef  double              LPDF_DOUBLE;
    : ?) n' g% Z! P
  65. " ~1 s3 i" @* a6 K
  66. ; A" F  J; v4 T" M4 A
  67. /*  boolean type (0: False, !0: True)& w, K5 @* H# m5 D8 L
  68. */. G) d, a9 y- h7 }
  69. typedef  signed int          LPDF_BOOL;; A, l5 I5 [* w5 y, K) M

  70. , Y! l( @! z0 Y* }* o9 p5 G7 \

  71. # a" G- ^1 B( \9 |8 n7 h
  72. /*  error-no type (32bit unsigned integer)( A" Y5 X. O: I# n
  73. */
    5 o. O: D  X7 m7 H
  74. typedef  unsigned long       LPDF_STATUS;; s6 b2 E: h, t/ [

  75. ( V& Q1 |* m* z, T" y6 u
  76. #define LPDF_OK                     0% x4 ]' F# Q4 h
  77. #define LPDF_FAILED                 1% @. C  E, ]5 Z$ |0 |
  78. $ V% C* B9 H  x# C7 D8 S
  79. /*----- font state -----------------------------------------------------------*/% e- I7 m7 k6 A- ^% F
  80. #define   LPDF_FONT_INVALID                 0x00FF
    7 B9 ?- x  H& Y4 u( F
  81. #define   LPDF_FONT_COURIER                 0x0000: b( `# E0 s( E' {
  82. #define   LPDF_FONT_COURIER_B               0x0001; s  n6 F& E* m# Y
  83. #define   LPDF_FONT_COURIER_O               0x0002
    2 K1 `+ o8 p# o, e  L* P* W# t9 a
  84. #define   LPDF_FONT_COURIER_OB              0x00030 w! Q+ L' Y5 ~0 w/ D
  85. #define   LPDF_FONT_HELVETICA               0x0004* F% J' |' u1 @; @1 o
  86. #define   LPDF_FONT_HELVETICA_B             0x0005
    0 ^) B1 J6 G: l5 [+ v. x' O+ {
  87. #define   LPDF_FONT_HELVETICA_O             0x0006
    # N( r1 F0 }5 l1 B* O5 _
  88. #define   LPDF_FONT_HELVETICA_BO            0x00070 x7 D  v8 ?2 U* r7 M
  89. #define   LPDF_FONT_TIMES_R                 0x0008. I% m, @2 M% @$ u* [9 s3 Z
  90. #define   LPDF_FONT_TIMES_B                 0x0009  ^( ^5 J! o  D3 [
  91. #define   LPDF_FONT_TIMES_I                 0x000A* Z  f- t2 V, L9 i5 u" V" `4 h8 K
  92. #define   LPDF_FONT_TIMES_BI                0x000B  D+ t: J. _& e9 J+ |
  93. #define   LPDF_FONT_SYMBOL                  0x000C5 v$ P- O8 W* n! r
  94. #define   LPDF_FONT_ZAP                     0x000D) q+ u) G: O! ^' Q9 D+ a
  95. /*----- Graphis mode ---------------------------------------------------------*/8 C1 B- Y, n2 l& X/ X' x
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001! W  T( x( ^5 x
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    % ^) A* V# F' J) c) G8 s* J' p8 e
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    5 Y1 o; A3 V4 u9 Z2 c; F$ Y7 d6 G& t- ]
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x00086 ^4 H% d" I& B+ B7 U4 q
  100. #define   LPDF_GMODE_SHADING                0x0010& a7 l2 F- f  V/ e9 b0 S/ o
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020
    . m  r- N' g. N% x( a
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
    8 D9 \6 \# H8 \1 b( B7 l
  103. #define   LPDF_GMODE_INVALID                0x00808 l7 s6 r- E5 E  L
  104. #define   LPDF_GMODE_OVER                   0x0100' E' \0 O6 r: P0 A0 d. L
  105.   Z5 \; l% E) \2 P4 A/ o
  106. #define OBJ_MAX_NUM     2568 v8 i* e& |0 M+ x! x; x8 I

  107. 5 Z. y& p( n! }. X+ J' G
  108. /* Page的结构信息是否需要树形结构 */4 h; U! C* {7 F* B/ a6 k
  109. typedef enum
    ( E3 Q$ y) _, I0 W9 r  P( p) ^3 W
  110. {  m) |1 C# T. ~$ `# |
  111.     OBJ_info,1 b: b! m8 A+ y6 H8 P. n# ?
  112.     OBJ_stream,
    6 e: l+ `- q% G5 L3 ?" U
  113.     OBJ_font,- |2 r: W) ]; q
  114.     OBJ_page,
    % c+ n( O0 `# Q1 o4 H& k
  115.     OBJ_catalog,
    - M, i/ f9 {! `& j
  116.     OBJ_pages,
    4 S  W. t) q; |6 z- e
  117.     OBJ_image,: q9 a8 {0 J5 l9 @; y- i; G
  118. }LPDF_ObjType;. K: e* W4 X; F' i1 D; \
  119. * [7 O4 X9 _7 I( Y0 n% f- J" e
  120. typedef struct
    " `3 U0 p+ A! B! ^% ^
  121. {
    . u  R1 e$ }+ K% Z. q6 v& T0 s
  122.     LPDF_ObjType objType;7 r- M* [2 ]* p7 P
  123.     LPDF_UINT16 objIdx;% f4 q4 u8 `/ S5 u+ D
  124.     LPDF_UINT16 height;
    5 b3 A- B- u1 t
  125.     LPDF_UINT16 width;& l$ |4 Z" |! ^. X
  126.     LPDF_UINT16 length;' f( C9 M$ t- ]$ k
  127.     LPDF_UINT gMode;
    % p* m. E6 d& L
  128.     LPDF_BYTE fontType;
    0 n/ ~! C9 h! y# |1 j- h
  129.     LPDF_BYTE fontSize;
    8 {% [, Z5 J* M- Z& y9 U) O8 m
  130.     LPDF_BYTE pState;
    : }, @; S3 ?0 X) t# F. ~
  131.     LPDF_VOID *doc;  p, v7 \9 v3 y" e; z  b* E
  132. }LPDF_Obj;$ v4 p- e/ k( a: |

  133. ' ^* @4 y9 B& B3 z( m8 W0 g
  134. typedef struct
    & [) L$ \9 B( y6 b% `$ T
  135. {: Q! s8 I! s% G
  136.     LPDF_Obj obj[OBJ_MAX_NUM];" d" A$ k" E: v/ H! ?; _8 F, }; w2 @
  137.     LPDF_UINT32 offset;' w5 E7 d% S+ }8 N% n+ J
  138.     LPDF_UINT16 objNumber;
    & X/ p* i% [6 u
  139.     LPDF_FILE file;9 T  e# \- R# L8 Y
  140. }LPDF_Doc_Rec;. e* X; k& ^- m
  141. ) X$ X# o# n2 l9 I7 J7 b
  142. typedef LPDF_Doc_Rec *LPDF_Doc;% p8 {( z3 C3 F# r, ?2 d
  143. typedef LPDF_Obj *LPDF_Page;
    1 s( h8 j1 c$ |7 A3 r: U" \
  144. typedef LPDF_Obj *LPDF_Image;
    " C8 a8 ~- A; S
  145. extern const char *font_list[];
    $ e% @  `8 b- O
  146. /*----- LPDF Interfaces-------------------------------------------------------*// j! H: T- U" g# t
  147. const char * LPDF_GetVersion(void);
    & ^% b& n* f2 c) N4 H8 B: v
  148. LPDF_Doc LPDF_New(void);4 m: t% g: x$ Q- v
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);" ^( |% \# J! k
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);' [5 B/ _+ c3 a# l7 Z4 s5 G0 Q9 }0 ?
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);
    ! G! V2 ^. I; X, s3 j
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);
    . K$ q) Y7 [" A2 c
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,! ~& O6 s; K; L9 u
  154.                            const char *font_name, LPDF_UINT8 size);
    3 R4 R$ b; i! a3 _
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);
      @8 C( z" f2 M4 @
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);! @; k4 s3 _& E) F4 ^7 i  ?
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);
    $ f6 Y) H1 m. z& y& T' A+ N5 ~
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);$ v5 H8 B# J' d8 o# ~2 y
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    6 L$ ~' b0 j$ W% f- `( \
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);
    8 {  [! A1 ?5 _1 L4 A; v
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);! t8 \) ?; u& ]& _
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);
    1 g# g- w5 p# s/ U1 x6 O0 c
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);
    * ~- j5 n; {: q- W
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,$ ^' q0 b! h% y$ f& Q8 t5 m0 X: k
  165.                          LPDF_INT x, LPDF_INT y);
    " f1 R5 h3 q" A
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, 4 w' Z; g0 b6 j: D1 K
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,* O" {3 i1 a) ]& [5 c
  168.                          const char *text);
    / Y& G. N; U# F6 d0 v+ e  ?
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    & Z1 A( C1 {$ S: R  h1 ^
  170.                          LPDF_REAL r,( X* g. ?8 N0 \1 F0 z
  171.                          LPDF_REAL g,+ ]* \# M8 H4 B% I# w; d
  172.                          LPDF_REAL b);; T/ r& A1 m4 S0 e9 k4 q
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,6 h8 R- M- i4 x, d6 r/ d2 L, ~
  174.                          LPDF_REAL r,
    6 P1 x$ {, `6 U  m- f' R
  175.                          LPDF_REAL g,
    ( Q! M( _) x# d& }; S% q
  176.                          LPDF_REAL b);
    + m: m8 }( F3 q- `( }5 R; i
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    ) _; H3 F5 A$ u0 ^; ~- @
  178.                          LPDF_UINT16 x,1 J" d" e; g7 ^& R$ N7 ?& ~
  179.                          LPDF_UINT16 y);
    ( ^3 s/ l: w1 Z" k- V% n
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    8 F$ e4 s- ?. h4 n/ [
  181.                          LPDF_UINT16 x,
    ( a4 o3 o. q) s" b7 w- c. j
  182.                          LPDF_UINT16 y);2 M& b5 `+ e6 l# B  k6 k
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);
    ' U) l- W6 h7 j: E
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);
    8 X0 \: K3 [* G8 d! b0 S
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    . n3 E& c9 V9 X& D6 h9 y2 Y# ]
  186.                       LPDF_Image image,
    5 A* [0 g  ?- G, e
  187.                       LPDF_UINT16 x," N3 Q* `. p8 ?; N. t* Z
  188.                       LPDF_UINT16 y,6 O3 J. {9 o$ X& h; v
  189.                       LPDF_UINT16 width,
    ; ~5 I! @; s; X6 j  N
  190.                       LPDF_UINT16 height);
    " E" d) w! a4 a2 l: Y2 `, h
  191.                                                                                        
    ) B% M$ k# z+ q
  192. #endif
    1 N- N; V/ `- |
复制代码

源文件如下:

  1. #include <stdio.h>
    ( h6 E* H/ r/ _- _7 W, K
  2. #include <stdlib.h>
    ' k- ]# V6 O- ]5 V
  3. #include <stdint.h>
    7 f+ y/ ?6 }' P0 w! f2 H" J/ O
  4. #include <string.h>2 \# C/ q  l3 v' U' i1 L2 _
  5. #include "pdflib.h"" b" ?5 M" O4 s7 y( Z! @7 Q
  6. ) n- j3 ]2 m; u3 _- {
  7. #define LPDF_INVALID_OBJECT                       0x1033
    . G. l' ~' r' P: i
  8. & U$ p" T. a/ `) z& R; @2 r+ q% |) l
  9. static char pdf_buf[512];
    7 b  ~- A  E4 J' z% f

  10. ! }+ e  J; H3 T5 ?
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"
    & e: r2 h, k' H) L5 `" G1 @1 i
  12. #define LPDF_FILE_HEADER_LEN        15
    # O( j) o" s  C& E  `3 l, u/ l
  13. #define LPDF_BASEFONT_NUM           148 q0 o& a& }, ~# R
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    % T7 l5 t$ u% X% O1 h1 s5 `' U
  15. const char *font_list[] = {# U2 K. k% [3 C
  16.     "Courier",3 ?) K# q) t; D, i2 ?6 f6 J* R
  17.     "Courier-Bold",0 i1 V- y  T/ ^" T$ a
  18.     "Courier-Oblique",
    9 \4 B% e2 O1 Y. v
  19.     "Courier-BoldOblique",
    * p! Q- N4 R. o/ m7 U
  20.     "Helvetica",
    ; T5 f  X( v9 Q: p! q6 ]% c/ j
  21.     "Helvetica-Bold",
    2 X$ c9 l8 W- x; E
  22.     "Helvetica-Oblique",2 |8 q+ w' G  i1 F9 i- s
  23.     "Helvetica-BoldOblique",
    - M8 K& q/ }# i- h! L
  24.     "Times-Roman",
      ^6 w1 P) L- u% _# ]; |7 d0 R
  25.     "Times-Bold",
    4 B0 n& l4 O3 G
  26.     "Times-Italic",
    7 \4 L5 g  O* X4 v$ j* o7 }: R
  27.     "Times-BoldItalic",0 L: w' `* g6 k- h- X
  28.     "Symbol",
    ' k5 ~  \. ]( k' c5 u
  29.     "ZapfDingbats",
    " L/ H$ Q. q/ v! [) Q
  30.     NULL
    . |6 y2 v. K+ r* r( M7 s3 K, U  \
  31. };) r/ l7 q7 k* b+ G) y+ d
  32. 1 s2 J2 M: \! A
  33. 0 C3 A1 W1 f5 v: r% \3 @+ N
  34. const char * LPDF_GetVersion(void)- `8 A" I5 P) I# o; x/ l
  35. {
    2 N, ~% h2 C7 S# M
  36.     return LPDF_VERSIOIN_TEXT;+ {. Q7 L$ N) Y/ N
  37. }
    " r2 J. A5 q1 {) z  c7 W
  38. 9 y# v7 e/ q$ I6 Y; K5 F
  39. LPDF_Doc LPDF_New(void)$ r3 \1 u% l5 v& T& z: F
  40. {
    1 w7 S5 t3 _- D8 g/ u* f
  41.     static LPDF_Doc_Rec pdf;& W0 w4 t2 H6 @  w% V' `' U# H; O
  42.     LPDF_INT length = 0, i = 0;
    . \; P) m6 X, j. r- x5 u4 K1 {0 Z
  43.         LPDF_UINT writeBytes = 0;
    - S' Q) b* ]8 q& s, u; T, z
  44.         FRESULT fr;% P) R2 z3 T# P8 G# K2 P5 l2 l
  45.     , w0 A. F0 F# h7 ^6 B& c9 W
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);1 b$ S2 N5 b8 h
  47.         if(fr)
    0 H! ^2 z- }! t) n6 A7 m0 P
  48.         {" d. u; c/ H% x! m5 a
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    4 z3 B& v6 v2 Q/ i3 b
  50.                 return NULL;
    , h. z8 {! |  V7 ^
  51.         }
    . b. u# S% D: K  l+ u& U
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */
    . q% W6 a# ~+ K* l# _7 b
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;/ `5 c- f9 X; {9 m
  54.    0 C' N* F7 j% @8 [
  55.     pdf.obj[0].objIdx = pdf.offset;& J: @2 |- }# C  k- d
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
    - s. r7 C5 N" K' Z4 ]- ^" f
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);* Z: L5 ^' F( S. e
  58.     pdf.offset += length;
    ! ?3 G; G  D0 [$ U+ @' D- s: J
  59.     + S6 A8 a, [' |4 Z
  60.     pdf.obj[1].objIdx = pdf.offset;
    ) H( K0 a- R8 v- K. e# n& T
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"6 b6 m% \  y! b1 k1 `  [0 S
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");; k  e& J  {1 i9 q
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    5 H1 h$ o. h+ U- e
  64.     pdf.offset += length;
    - j9 [* Y  d/ h) W6 h! E
  65.    
    . `& E% _1 ^$ u0 D7 S7 |$ T+ W
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    3 j+ y% R% P0 W/ j/ |1 Z$ u7 O
  67.     {' ?, e+ U' ?% T/ ?
  68.         pdf.obj[2+i].objIdx = pdf.offset;- Y) c2 V- k" D. M5 N7 r# I
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n". t) \4 [6 O7 p% P* ^: a
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
    9 q% {9 |7 R% E. L2 n7 w8 `
  71.                         "endobj\n\n",3+i,font_list[i]);5 o  r1 |6 i1 `+ f1 D& o
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);7 f9 U0 G% T& Z, N" b1 j# Z
  73.         pdf.offset += length;
    ' G, p2 B) K3 F$ p7 k
  74.     }1 F$ n4 F, ^& G/ F: L! V3 d! Y
  75.     for(; i < LPDF_BASEFONT_NUM; i++)6 l5 v  Y  ?8 |; v; _" E
  76.     {
    & ^. \8 R6 Q1 n7 T. E! g9 j
  77.         pdf.obj[2+i].objIdx = pdf.offset;
    ) C5 c' U+ L. E1 P; F
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"+ x2 Y' z7 q8 K& J6 _$ H! }
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
    0 R* e2 M- }; |& Q: ]0 G) j
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    6 F$ e5 N' N) }5 W  y( ^- k' T1 p7 g
  81.         pdf.offset += length;- g7 e: K- z$ D1 r
  82.     }0 D3 P2 x" ?: `1 v' e
  83.     pdf.objNumber = 3+i;
    9 t. [( o9 {3 Q0 W& f, t
  84.   
    7 l' c# U9 m% M! u5 o2 L
  85.     return (LPDF_Doc)&pdf;
    " D+ ]: D7 q8 G. ?9 q" m- \( f% r
  86. }5 u2 m1 }# @1 _- r+ d- H5 P
  87. 9 k7 A9 d, U7 ?9 s
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name). ^% F; i" F4 Q& W* a
  89. {% V. J: k8 E) T4 s2 t8 O! N
  90.     LPDF_UINT16 i = 0, child_pages = 0;
    - H* J7 J" Z- Q: d0 u
  91.     LPDF_INT length = 0;, h5 N% {  V* |5 @+ U. `6 U+ C
  92.         LPDF_UINT writeBytes = 0;* p& E: d  O& s8 j5 y- Q% P) I( H
  93. ' ~9 g4 @4 U' Q$ l9 X2 Z8 q
  94.     pdf->obj[16].objIdx = pdf->offset;
    - |: G1 w* N2 n' C1 g7 `
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;
    9 u" r+ D4 x2 a5 e, B5 l
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);' U' s7 }# v+ h2 ?4 l9 v
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    + f* S0 ?' t6 r  D
  98.     pdf->offset += length;
    5 S: }% ~" u, C
  99.     for(i = 0; i < child_pages; i++)
    % b( @, z' {. H  d1 Y
  100.     {0 G3 R' B4 P3 Y1 J4 i1 ?
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);4 [1 F3 a" I1 M1 M# G: g0 ?1 V
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);6 T0 P  I, T( j5 r" ]/ r5 b% Y
  103.         pdf->offset += length;
    - z& R4 i: d+ b0 F( `* R
  104.     }7 E5 ^, ?! ]* D+ B. W; m, [
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");
    $ L2 K) {3 i" o' A- P, A! e
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);. r( S4 e& y. Q+ U3 x3 b
  107.     pdf->offset += length;
    ) ~) q  l/ P1 {: T8 O, ^6 r/ f
  108.     ( k% [3 v7 w' ]6 q1 C: x6 e8 X
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);; Z: k) [8 i$ N9 F& V; m8 L5 R
  110.     for(i = 0 ; i < pdf->objNumber; i++)
    # B( R) c$ h6 C
  111.     {8 v; r$ f" Q# d4 R
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    / R& S) i% }0 s$ c
  113.     }( A) c2 X' M8 v
  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",; l2 C7 Z& ^' q; W. r) u& V
  115.                 pdf->objNumber+1,pdf->offset);/ x1 p3 P5 i3 l' m5 o: I
  116.     LPDF_FCLOSE(&pdf->file);
    + Z5 j1 P9 t) b- o4 w( O9 l
  117.     LPDF_REMOVE(file_name);% }" z+ Z8 S2 Q* L. N0 G
  118.     LPDF_RENAME("tmp.pdf",file_name);
    ( @7 ^+ a2 a; s% d4 X
  119.     return LPDF_OK;
    1 e) f$ _$ E+ R0 M* _; B! h& c
  120. }
    4 @7 i; e$ a! t5 H; v
  121. 5 H+ a3 j/ d7 f9 m
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)' B. v. H3 B$ Z
  123. {$ S) N4 L& J) G0 u7 y2 }
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);8 H, ^* P4 \4 X
  125.     return LPDF_OK;# n% C% V1 H4 @# s, {! i8 w3 i
  126. }
    7 h# C) k& d. A2 {9 \7 V

  127. 5 u1 E) i; j# Q" K+ s" o2 ~2 [
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)+ t" c$ R. R2 w: V9 [$ X* v
  129. {
    4 g* F9 d5 J! X: O
  130.     LPDF_INT length = 0,i = 0;0 H+ V% z; S: F6 I
  131.     LPDF_Page page = NULL;. u8 J9 V. k) q! y- }% U1 A
  132.         LPDF_UINT writeBytes = 0;
    0 y# T. `3 D) D/ X8 s
  133.    
    " w/ t& W, C5 e- f
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;/ v9 n+ M) f1 g
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"
    1 W# Q' @! p$ K7 r8 ]
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    : E9 |9 l% {8 ?
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    1 E% D% D+ @. L
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);! `  s2 N1 Q! G% G, o9 E# |
  139.     pdf->offset += length;
    4 [: O$ ~* M- ?7 A. J9 T) c( _
  140.     while(font_list[i])
    : k0 l" d8 k! O  u, q
  141.     {
    . I! Z0 \% C' y5 `2 N$ b5 B
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);
      h1 V3 W, \  K& g+ H- U; Z, j* w
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    3 t5 \" f2 D* A+ f) l
  144.         pdf->offset += length;
    $ }  ]2 }/ N1 R) d( _
  145.         i+=1;
    , ^/ D" l2 C+ G' S1 c- q
  146.     }
    . q8 }9 ^. T0 c9 O7 q- a
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");. X/ [1 P0 o: h: t- \8 {- d  N
  148.     pdf->offset += 4;
      ^0 k- k; T! m8 |2 B
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];
    3 B4 T2 W+ G% H& Z5 F' Z  _9 v
  150.     page->width = 595;6 B: {' q1 o& z
  151.     page->height = 842;
    " L# a- Y& C% k$ [; {# k
  152.     page->gMode = LPDF_GMODE_INVALID;0 ?1 F3 g7 n1 t+ n& Y
  153.     page->fontType = LPDF_FONT_INVALID;
    8 x: d) d" ~; _1 T0 M
  154.     page->doc = pdf;! c+ ^& f8 M3 n0 ~. j
  155.     return page;
    0 w0 @& r) c$ Q  V- r
  156. }( F% e1 X! L/ y0 \( I9 w" a7 x

  157. 0 R1 R- `- @5 S# P# q/ k
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)
      f' y" s' [. U5 }) Q& w
  159. {: E7 f) Z# v) h. G2 v
  160.     page->height = value;6 K9 d3 y( v7 W' r3 d
  161.     return LPDF_OK;
    9 y7 J$ l, S" t7 r& A2 u
  162. }
    1 ^  J  K5 u& M* {. @1 ^
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    # b% N4 w9 `. G: ^5 \% Z, }7 d
  164. {
    # F/ Z3 d8 y. o# a% j9 n
  165.     page->width = value;
    7 i, e) Y4 v1 W) v# Q. Z2 `' b
  166.     return LPDF_OK;6 q: a7 x( {; a" j
  167. }, y- A0 e/ S! l- }5 g1 y

  168. * C$ f7 `; T5 B" E
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)/ h: S6 }' o, R2 S. M' p/ R
  170. {
    : M0 D- P% U$ y2 S6 E! @
  171.     if(page)
    2 k. I1 |7 i$ K4 e. E$ O
  172.     {
    1 v" u% {- Z+ ]4 H8 e0 \: H
  173.         return page->height;
    . L% c' x9 R" @% E3 r% j; h* ?( s% B
  174.     }5 L& s+ E5 \, e
  175.    
    $ D+ a' r# W$ {% M# l7 T) p
  176.     return LPDF_OK;
    + a. z9 |: i8 B8 F& i  i! u
  177. }
    ) j$ g1 a" i/ Z9 K6 }) z6 g" U

  178. 5 }+ |3 `- E( I1 b$ O6 _9 z& r
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    6 a1 `' }7 n* \6 A$ r
  180. {* k; |* v6 r2 s1 [2 m
  181.     if(page). a1 J' t6 P  `& c7 n/ E
  182.     {5 ?4 C) S, `3 M, s4 g
  183.         return page->width;
    5 B& Y9 W1 q1 F2 R' L2 X! E7 `
  184.     }
    5 b: T, H/ L3 `# h2 h
  185.    
    # i. L5 I6 L" S: ?8 U) s9 o+ v
  186.     return LPDF_OK;; o7 S; l) c+ R( ~
  187. }6 U% x, b+ y( m
  188. # x7 ?6 U% h6 _6 Z% `& U5 `' G; x
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)
    * H) e8 a$ n  W& d) v, ^
  190. {
    ( ^6 a7 V0 `- q5 ?2 J7 G
  191.     if(!page)
    2 m8 c& t+ O2 m/ ^; l# Y; z7 [9 a
  192.         return LPDF_INVALID_OBJECT;% C5 Z+ h$ ]2 x# [8 I
  193.     if(!(page->gMode&mode))
    ' x2 Q& T0 Y! R  o
  194.         return LPDF_FAILED;
    0 n7 [4 M1 j. v  x. M, y
  195. . a3 D, ~! H2 Q9 X
  196.     return LPDF_OK;/ @2 d. B! E/ ^% [  b) i( C
  197. }
    0 e" y4 ^$ L2 N4 A4 d8 ^+ T/ E
  198. + x4 e! Q7 y! Y, H+ T, m
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    . `8 H9 C2 b2 q7 w
  200.                            const char *font_name, LPDF_UINT8 size)
    4 i+ f' W- y* `: G- y
  201. {
    5 ?8 Z. Z( G4 i; _
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    + k1 V$ q7 x; \8 X) Q( K
  203.     LPDF_INT i = 0,length = 0;
    9 ?, l0 F% h1 q+ h! ?9 g* \
  204.         LPDF_UINT writeBytes = 0;
    4 O# X; \6 X+ n1 e' d9 N) k0 L
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    0 F3 C6 d2 c  ?( p
  206.     if(LPDF_OK != ret)
    / _1 O( b4 c  |3 B9 b
  207.         return ret;6 \1 S: L# k8 f( D  \9 \5 `6 R

  208. + H* h7 U2 O2 x" z
  209.     while(font_list[i])% z6 C1 R! Z' \
  210.     {  ]- {7 m  T5 W3 G2 k" ]+ t
  211.         if(0 == strcmp(font_list[i],font_name))
    5 }0 g. m. v1 X( q8 T0 n4 k
  212.         {* T- a  D+ E% V6 H- U% ?
  213.             page->fontType = i;& W: N% F' {; ]6 s5 S1 N# n6 O
  214.             page->fontSize = size;
    % J0 k3 h. D+ O5 M  @1 }! B
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);) u: S  G. o( S; Z: b) P
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);5 ~6 ]/ u9 R2 @" Q+ H5 C
  217.             pdf->offset += length;8 r" }! a6 V+ Y- M3 H
  218.             page->length += length;; A( ?% ^' |! l) E/ W3 }5 A2 K0 C
  219.             return LPDF_OK;
    . B1 a( G% r9 C  R
  220.         }
    / G8 @( p; N# v- M; z/ ^
  221.         i+=1;7 g2 z# M- Q# ^2 p5 u- e) M- C# _
  222.     }0 k7 M0 \3 u( ]1 e) g( C
  223.     4 i( }5 l4 R3 T9 N- j( R; t, f% c% t* q
  224.     return LPDF_OK;
    . \3 ]; o* ^8 u
  225. }
    * W- ]: s2 J7 ~: V9 r# k

  226. 3 W& Q! I/ o0 R
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)- \  B% ], u3 a8 d1 k4 L  O; r, k
  228. {
    * W( J3 u; c& V) O& W( i8 u
  229.     LPDF_INT length;& Y0 T0 C9 ?- v# d" [7 u
  230.         LPDF_UINT writeBytes = 0;
    0 ]# I. M2 |# w# i1 u* C
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;  w4 U9 I; e/ {% ?' l+ ^* C: h$ x0 _
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    8 G/ x- i/ `2 I  t% Y
  233.     if(LPDF_OK != ret)# i0 ]) u% K- U- F# u
  234.         return ret;' Q) |9 y# C0 v- n; s
  235.    
    5 z. @; y, h, t2 L
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */5 _: Z  n$ ~4 J8 }8 q; R+ G
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
    1 O. n/ Y% K+ \/ I7 N+ G8 y
  238.                         page->width, page->height);/ b$ F. e: q5 {+ B% u$ j0 i
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);( c3 k( ?8 o& U0 ?2 H
  240.     pdf->offset += length;7 x; {$ C* Z2 ]/ a1 u+ E: [
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    , d) O5 R' F( f+ D- N) \- K6 z$ G& j
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",
    6 ^7 M* f+ D6 O9 b% ?5 n; X
  243.                         pdf->objNumber+2, pdf->objNumber+3);( W; v: j- L) ?  [( g9 e, G
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
      r( e) b' w3 s2 v5 v4 F
  245.     pdf->offset += length;2 ^) o5 q& c8 x8 q( ~
  246.     page->length = 0;8 c! N$ v4 U  \
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;( x/ T/ X, d, I) U2 M6 V1 e
  248.     return LPDF_OK;, ?+ H! E. X- S
  249. }% b5 w0 M! Y" \% j! P- n
  250. * P/ T1 J' h5 ^) }
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)$ @) j5 H  z1 X, V! K9 t2 s9 q; U
  252. {
    : ~9 a8 s: @2 W; g) a! ^
  253.     LPDF_INT length;
    . X, w2 z3 N7 Q$ l1 m" d
  254.         LPDF_UINT writeBytes = 0;
      a- M& _. I* D- T
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    , |8 O6 K. e9 |2 x/ o8 ?
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    # c* K+ I# B# M- W4 l: r6 |& t7 e
  257.     if(LPDF_OK != ret)
    + V( y8 ?, J/ O; w6 M4 p: K* {' _
  258.         return ret;
    0 s+ A( a1 W1 |6 J
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */& `. O* e4 e7 b. J
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    , g' u, ~# N# R6 X
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes); 0 F4 j3 k8 S! g8 v2 y6 U
  262.     pdf->offset += length;
    7 R9 R) k" i1 [- o. d4 t+ |! w
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;
    , Y# z& H( J  F2 e3 E4 Q
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",$ {0 t  k5 C1 W$ m* T$ i+ F: m  a9 S
  265.                         pdf->objNumber+3,page->length);8 n4 ], E- ]0 V& l% i
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);% f6 d3 h& h( Y4 P
  267.     pdf->offset += length;
    ! j  v) i& i5 f
  268.     pdf->objNumber += 3;+ n" e) A( P; h
  269.     page->gMode = LPDF_GMODE_OVER;4 U. q% X8 g4 {$ H7 l6 R9 I$ `
  270.     return LPDF_OK;
    & u) U; z9 h5 F) V+ V9 R
  271. }
    3 ^. `/ g  p3 O6 y# F, }) B

  272. ( C9 Z3 V3 Y& z, P3 i; a/ c
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    % [4 L/ _. _" ]8 B7 O
  274. {
      a4 h# p" J; P. J4 J
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;1 r6 o9 h7 K8 p/ C# J7 N! s! M
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);" H$ H$ I7 h/ V. |$ S
  277.     if(LPDF_OK != ret)& Z+ Q, a* r- _/ C
  278.         return ret;/ Q7 Q7 r- U/ d
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    3 m2 J. M3 ~& A' z
  280.     pdf->offset += 3;
    % G1 r5 s% B# j& p4 |' E
  281.     page->length += 3;
    8 e2 P  ^, v# B# d
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;8 d3 [* C; l  J
  283.     return LPDF_OK;! P/ V# i" d2 C7 i( r3 ]$ o( `
  284. }
    4 ~) p, |$ n0 p1 g8 l/ K7 E
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)6 R- g7 F4 X/ j. N6 `
  286. {+ J. L9 E, U8 H/ A
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;' _2 q. b8 F7 W3 Y3 }
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    7 @7 v( ]7 w4 r& ^. C) {+ g
  289.     if(LPDF_OK != ret)
    " |( \# k$ u' v/ V9 Q
  290.         return ret;
    8 D2 O& F% J! \1 _
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");% c7 r: @7 g8 B) b
  292.     pdf->offset += 3;% `- q7 M7 r: v' B- x) d  S" G
  293.     page->length += 3;6 w0 q4 G2 H2 G) C. \3 s4 G/ _& U+ ^
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    , z; v3 M  R8 N* E% A4 x7 d
  295.     return LPDF_OK;
    3 ~: Z, n3 d) D- c( K) c0 b& ^
  296. }; p& L& i0 J, Q, E1 v& b3 y8 h. X
  297. 4 x" K+ R1 m$ i
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    4 v1 @; y8 h2 B) T( V+ D% S
  299. {6 q6 Q8 G& P/ P' F& H* U7 d* l
  300.     LPDF_INT length = 0;" L; R: i) L2 n1 ~9 S
  301.         LPDF_UINT writeBytes = 0;
    1 B8 Q0 S8 @$ q2 q( h
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    % e8 E+ A: |4 {, d( |
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    5 Q0 d2 ?  K2 N! [. Y
  304.     if(LPDF_OK != ret)! B0 J+ N) W. ^' u, i) U$ G
  305.         return ret;
    ; s: C0 c/ U! m. e" s
  306.     if(LPDF_FONT_INVALID == page->fontType)
    8 Q# s* o8 R4 r
  307.         return LPDF_OK;
    1 m0 b" L. V8 U' e/ d
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);1 _3 B5 h8 A$ b4 R
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);* b2 n5 D$ J8 g0 a; t
  310.     pdf->offset += length;: D. d0 G2 c8 ^" a/ [. q6 A2 Z
  311.     page->length += length;
    , i9 d' y8 @+ L
  312.     return LPDF_OK;
    $ p7 _+ }1 q6 g+ R# f' Z
  313.    
      G' p: T+ ]8 `1 r
  314. }6 S4 O0 f* z( x, i  M- ]
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,1 h  x$ V; D3 s0 L
  316.                         LPDF_INT x, LPDF_INT y)2 [/ f8 Y, S' |( A3 q+ z
  317. {; Z; Z$ b! k3 e6 ~2 @# z, E
  318.     LPDF_INT length = 0;" V' r1 Q5 P1 K# E" y" U2 C3 ~
  319.         LPDF_UINT writeBytes = 0;
    , G& y+ k0 p3 N( _
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;7 r7 o% R4 e# x. d8 c! K
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    - q, p; K6 }0 B
  322.     if(LPDF_OK != ret)! q! Q( q+ u. c9 K" Z3 Y! o
  323.         return ret;8 i$ }3 O' I4 K4 }7 r$ O0 S: F6 n
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);) a& d# U0 [# O+ v7 @- `2 Z
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    1 Z5 u4 X0 r8 Y% P
  326.     pdf->offset += length;
    # h* [- Q% Z0 C% F0 [9 }
  327.     page->length += length;
    # t- {; I# Z0 A6 \9 |
  328. $ a: m0 w! o7 S2 K
  329.     return LPDF_OK;: G9 h+ L) g7 Z7 j2 I
  330. }5 j" X7 m( l2 ~3 D
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    + N8 i7 b( H$ Q( J1 ^
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,
    2 R" c! k3 p; S/ u# h5 c- t
  333.                         const char *text)1 |8 l3 q+ e5 h' @1 n
  334. {' r, f, C/ ~4 g) z# l
  335.     return LPDF_OK;7 b+ f) z7 D- W9 E) G
  336. }. V* F9 j' `5 u5 ^! }$ W

  337. 2 \! \" @# o# \  s: c* U
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,' x6 J' k0 g) @4 C) [
  339.                          LPDF_REAL r,
    + w. i( R; k! U$ N" G2 ^8 l
  340.                          LPDF_REAL g,
    * w/ O7 f" _! k# I; T& }: p/ ]( q
  341.                          LPDF_REAL b)- f; V# Q, ?& t/ O
  342. {
      X' H$ h  y! L4 A
  343.     LPDF_INT length = 0;4 z, S/ h$ d% j" @/ T
  344.         LPDF_UINT writeBytes = 0;) P. _+ \& N3 K* y1 P( a
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;- F7 P! L4 q) ]6 A3 A* B
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);' Z# c- y( l9 G+ n7 X0 C4 J3 s
  347.     if(LPDF_OK != ret)  p1 u% v& C9 I& m, E& B, Z! j
  348.         return ret;
    & A# F1 m9 @1 x& j
  349. / l) p  N" y+ Q/ ~
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);: j6 u" w) h' N
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    $ N, z' _4 e& x, V
  352.     pdf->offset += length;" g  v; z& p, U9 ?( S" s: O8 [
  353.     page->length += length;" h+ }) m& v- U
  354.     return LPDF_OK;( @! d% T" K, f; s  x6 h& ]
  355. }! y9 p$ `2 E8 b; y- k: T3 _* E; p* s
  356. ; k9 e8 H* W: M# K& Y; ?
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,# h4 C2 o' L; v5 }. U4 d( l/ D# I
  358.                          LPDF_REAL r,
    / r  c# d' j2 y; h
  359.                          LPDF_REAL g,1 D( P  E( n7 Y* L
  360.                          LPDF_REAL b)- H' b) y+ [3 g  v. u( N* i: \: e7 N, t
  361. {
    ' o' |. O, m9 S# ?" ]( a# S( N
  362.     LPDF_INT length = 0;
    5 x$ z# Q9 a: C1 ~
  363.         LPDF_UINT writeBytes = 0;3 u5 O- _* X3 v- x8 v
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    - T+ i& [1 v4 P9 N! d& X$ F4 z. j7 N
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    % K+ g  v5 R, a6 N$ N0 n
  366.     if(LPDF_OK != ret)
    # n% c% l+ L5 l
  367.         return ret;
    7 p5 x0 W+ V$ j; x" }  M/ I8 Q
  368. 2 ]) o: V! [! S/ F+ s$ J3 L* z
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);+ D% W4 S, j! K( q
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);( g0 ~- j3 ]' h, L/ y' C
  371.     pdf->offset += length;
    7 L  G% P5 U, k# a0 X/ o9 i5 ^
  372.     page->length += length;4 L" v# l( w2 U/ X3 a  J; B
  373.     return LPDF_OK;
    / e' m3 l" j4 {  z% z
  374. }
    & C% K& y* c. j7 s0 M. l
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    : R0 M# O3 k2 S2 _
  376.                          LPDF_UINT16 x,
    $ a: `2 s' x$ L" ^  q/ O
  377.                          LPDF_UINT16 y): f' o* \7 K  j5 k
  378. {
    * R7 l3 u) t: L; n, |- h+ ^
  379.     LPDF_INT length = 0;2 b+ C/ r2 k+ I& F$ R& _
  380.         LPDF_UINT writeBytes = 0;
    : @+ F* q' {5 r- Z, U' V1 a
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    , ^+ k: d$ v7 U
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);
    7 @$ e5 @9 x/ _
  383.     if(LPDF_OK != ret)9 Y% B0 a6 L& z  N
  384.         return ret;! u  C. u& D0 D3 `/ q
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    ( y; M/ r- a3 f" H5 B4 W2 M, A  ]
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);% f0 P6 O' ~8 I( m: b8 F9 Q5 d
  387.     pdf->offset += length;+ D8 p  S  [& n7 H3 M4 }6 a
  388.     page->length += length;9 V! c  l9 |  b
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;6 f& F/ x. e- Q* W* a# N5 f9 h8 B
  390.     return LPDF_OK;
    / g8 D6 P7 _: L  E3 B# H2 q+ ]1 k
  391. }+ F1 A" B& y4 Y5 I+ Z
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,: \+ g/ h8 d& a% Q
  393.                          LPDF_UINT16 x,
    2 f- X  ~: V9 y9 K( H5 A- P
  394.                          LPDF_UINT16 y)9 x) X  S* F; F# t' C! x
  395. {
    ; W% Y( z$ _! v" ]$ J
  396.     LPDF_INT length = 0;
    ! M2 u- E- F: q7 |
  397.         LPDF_UINT writeBytes = 0;
    ) [/ {; |4 I: E3 j% j% V: G/ [$ c8 A4 f
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    & y0 j' r* I0 D  n5 Q
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    ) r* F$ \3 j! W) K3 _% M( W! K
  400.     if(LPDF_OK != ret)
    ! O; n% r: g. {9 g
  401.         return ret;
    : R, T% x' E- k6 W
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);) J6 H* k% s- V* y  W, }
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ! F) k5 A& m; `/ y6 g5 j3 Z
  404.     pdf->offset += length;
    + t$ d! D( r) P$ W7 g7 k# |
  405.     page->length += length;
    0 p, t; }+ D! `
  406.     return LPDF_OK;) y( |; p& W( V0 C$ a1 p8 @
  407. }
    2 J3 L3 i- g! c3 H! O9 a3 ]. [8 x
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)
    . I5 I3 P* T. k' f+ r
  409. {6 _9 m( v, n' t% A, X. |
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
      o6 f  t" A4 r
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    6 S0 c4 L! q) b' G: Y# b4 y- |
  412.     if(LPDF_OK != ret)
    1 K/ O8 ?2 O. g% {
  413.         return ret;/ Y+ ^  Q5 f1 N
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    $ g8 v; l9 \# X; U. |, N1 A9 ]0 q9 Y/ ?
  415.     pdf->offset += 2;# ]& E4 U% i0 q7 F: L2 m' H% v
  416.     page->length += 2;
    3 Y$ K& b1 I6 b& y
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;( d' X% `' X+ g& A0 B
  418.     return LPDF_OK;4 x( b2 i5 t6 M& E1 G8 M
  419. }# F# A- g/ }! a2 P3 L% D/ J
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    % `, }; E/ O9 P
  421.                       LPDF_Image image,# W0 @3 a; R- u6 e5 h, ]& y
  422.                       LPDF_UINT16 x," W( g* z  i  P/ H# U) o
  423.                       LPDF_UINT16 y,
    " e! Q; B5 n/ B
  424.                       LPDF_UINT16 width,
    & i8 t% t) x- R$ y1 @$ D! X0 {' `
  425.                       LPDF_UINT16 height)
    8 `: x, L2 T" `4 [4 L* U
  426. {
    . V+ `# P: B4 z. `2 y" Y. K
  427.         return LPDF_OK;0 V! ~: f; W+ U! }
  428. }% L; U2 R* U8 g) f
复制代码

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

  1. pdf = LPDF_New();9 z, n0 x6 i3 p, ^# j- i* _
  2.     page[0] = LPDF_AddPage(pdf);
      l# ?! u! E3 |3 @: d) L  V3 v
  3.     LPDF_Page_SaveParams(page[0]);' @- W( i6 o7 h& a# J& B: h
  4.     width = LPDF_Page_GetWidth(page[0]);
    1 u& j, _5 N4 s5 f5 T; A4 ~# D
  5.     height = LPDF_Page_GetHeight(page[0]);
    1 U( l3 ~8 \& |( m+ ~
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);/ O8 R+ I1 F% }7 }
  7.     LPDF_Page_BeginText(page[0]);8 E& ?8 }4 N! W8 T0 M
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);7 k$ B, r5 B9 |3 {+ C% `0 a
  9.     while(font_list[i])
    # B% n$ J: c8 m. j' ~+ ^
  10.     {  ?% g& u' m# F# i6 H3 ?
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    % F2 Z, _6 l) e6 i
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");& N8 E% r: s5 L# v
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);1 ]- S+ y  {/ g' d' w6 y
  14.         i++;
    % r) B1 C( V9 l, T" c1 ?
  15.     }' ^# s$ I5 w2 R: Y6 i0 C& j
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);
    3 \! B! w1 q  ^
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());$ B4 J; t1 i$ U8 z. v7 v
  18.     LPDF_Page_EndText(page[0]);
    1 e* k* k- G! W9 \' [8 z/ [
  19.     LPDF_Page_SaveContext(page[0]);
    * j! C) e5 ^% R% ]6 U: f
  20.     page[1] = LPDF_AddPage(pdf);; B0 \8 ^& f/ w8 d% g7 I" \! E, |
  21.     LPDF_Page_SaveParams(page[1]);
    ( D# ]; x/ L. s. i, M4 ^5 U) f. ?/ L
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);
    $ M! j, _0 a; y
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);+ C; E8 F' _" d0 [7 `3 H
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    # M+ x2 X3 k" n* l2 u7 }' m5 `
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    3 {+ r! c8 M3 l* {
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    % N9 b" a) a/ T
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);
    " G5 A  z& M: B: w
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);9 p  G' @9 o6 o3 a/ d+ e
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);0 ]+ }1 N# Y. |+ F' u* O5 v1 d0 k
  30.     LPDF_Page_Stroke(page[1]);  K. G, _7 C2 x0 H1 P
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    0 y7 \; A& u8 V3 }. V
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    7 y* O* j- I2 [& s( J
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);* M) c% g1 {2 p( M1 v
  34.     LPDF_Page_Stroke(page[1]);
    8 [6 d# j% m! v9 D5 l' E0 @
  35.     LPDF_Page_SaveContext(page[1]);
    6 _8 g+ j8 {& S
  36.     LPDF_SaveToFile(pdf, "/red.pdf");6 r, o* {0 l. ]! q
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    ; W! @% i0 k7 U) ?
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了
' {, r+ r$ R% \$ ?; {7 v( B

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    $ L+ t# u$ K5 x1 t% w7 A
$ D" ~+ I' [$ ]9 S$ j- v

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, `3 R" F9 i5 u
只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...
2 ]/ d6 t# [6 Q5 W/ e) g( ?' W  f2 p* L
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
2 J8 v7 p3 y4 F# t首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
( A4 N0 e9 j/ Q& d( g
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
, C6 A8 r' _2 |( X
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
: j, S7 U  V7 w: d  J+ ^6 M, {看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
) y/ s3 E* n+ f# e
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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! W# m% x# ?2 O# c# r
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

, v, Z# c/ V$ q4 Y7 [这个还只是一个简单的库,实用性还是差一些的
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' d# ?6 l7 t, x
ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗

# u% v  ?0 g# U2 A/ B3 g, ^ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
$ k% o: b5 |6 B" J. g' pff.h是FATfs中的文件

3 n9 F4 A6 ?( _* g- V( J嗯,这个画线能改变线宽吗

所属标签

相似分享

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