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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 + U, L+ C2 z: z' t( k2 W

5 |/ o3 w5 b* _3 g  t! {

主机环境: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__  ~# z3 s0 B% v! d
  2. #define __PDFLIB_H__
    ' |# h- V! L0 ^8 n$ F5 O
  3. & A' F! l5 r3 f
  4. #include "ff.h"! E- B; q) Y: \# @' W" t- ?) F
  5. /*----- standard C library functions -----------------------------------------*/
    % X! d/ Y# h8 p7 r/ G
  6. 9 {2 a6 e: q: d# u
  7. #define LPDF_FOPEN                  f_open; w7 H  f$ G4 ~5 x1 C! L3 [
  8. #define LPDF_FCLOSE                 f_close  U+ r* t& v) Z1 B: {/ q! J3 s
  9. #define LPDF_FREAD                  f_read  D) O# c; l$ u0 ~5 b7 J) C0 S
  10. #define LPDF_FWRITE                 f_write
    : e+ _) I' a0 L8 |
  11. #define LPDF_FFLUSH                 f_sync$ Q5 k& W# O+ [0 {- L; \" G8 r- N
  12. #define LPDF_FSEEK                  f_seek  G. ?' R6 z4 \9 n& [
  13. #define LPDF_FTELL                  f_tell3 @& W3 R, G# \! o) S5 ]: A5 J& ]
  14. #define LPDF_FEOF                   f_eof
      d' @1 i) r% u* @
  15. #define LPDF_FERROR                 f_error8 R4 h+ Y, i! w( K; U
  16. #define LPDF_RENAME                 f_rename( j0 V; _; H2 x4 P2 A. K
  17. #define LPDF_REMOVE                 f_unlink
    3 d1 f% f/ L, Z$ _% f7 Q; }
  18. #define LPDF_MALLOC                 malloc
    3 x, c! t" a6 r7 o
  19. #define LPDF_FREE                   free
    / Y5 v3 D5 D' I% c8 [
  20. #define LPDF_FILE                   FIL
    0 X2 P3 S# B& r' ]/ G4 w
  21. #define LPDF_TIME                   time
    - S, a0 C' Z* ]& [% L% Y) A- l
  22. #define LPDF_PRINTF                 printf% }* v2 k# Z% l
  23. #define LPDF_SPRINTF                sprintf
    6 g" G2 `) r, [; y; R; N# s/ J9 w
  24. #define LPDF_FPRINTF                f_printf, Q3 n: V6 X" j* |3 U* H8 J
  25. #define LPDF_VOID                   void, n2 r0 M8 h" S' Q
  26. #define LPDF_SIN                    sin6 o" h0 _* }, f- Y) }8 Z  m
  27. #define LPDF_COS                    cos
    3 c9 Z* D5 P8 W
  28. 4 \' B0 H# u+ l( p9 y1 s
  29. /*  native OS integer types *// {; ?# P% B1 z! y# Y4 O! p
  30. typedef  signed int          LPDF_INT;
    ( h% D! E0 B2 r8 _- p& U: j
  31. typedef  unsigned int        LPDF_UINT;
    5 y: K  `% J5 w( ~7 |# A$ U
  32. # G9 [6 f* z& w" g6 E; g1 P  h# s( d

  33. / q& x6 S+ j+ s' ]6 B' w
  34. /*  32bit integer types$ m' M, b+ K" ^% W: ^
  35. */# U, b# D9 |5 o' ^3 b3 G
  36. typedef  signed int          LPDF_INT32;- ?/ v  H, t$ C+ A
  37. typedef  unsigned int        LPDF_UINT32;
    * c4 j( t( I0 K% S# y/ k& W/ d4 f2 G. G
  38. 3 i* n2 \& Q) p$ D8 d$ w( v9 C& |1 J
  39. 0 L* P* R+ ~  m3 G! T. [/ Z1 c
  40. /*  16bit integer types4 q+ U# L" T. `0 R( w9 D, q
  41. */  L; B' q1 ?4 m9 F% I, n& S
  42. typedef  signed short        LPDF_INT16;
      P/ k6 e1 e( }
  43. typedef  unsigned short      LPDF_UINT16;
    7 z. x7 t' P3 M! i9 T; i- _

  44. 5 x: H7 @! X- W. U9 B" K8 h
  45. , {/ \6 n, h. w+ x+ b. u; W  u9 X
  46. /*  8bit integer types
    6 A( n+ ]1 q% J& p' K4 c3 F
  47. */
    + w5 v: B) c, Y) }- ^8 W% E
  48. typedef  signed char         LPDF_INT8;
    3 ^1 H% D! E/ r3 F' `/ [
  49. typedef  unsigned char       LPDF_UINT8;
    ( @* V+ l: S0 E1 |
  50. 3 K: e' F9 g8 e5 ?
  51. ! E7 z& I2 G% e# S% f6 {* Y
  52. /*  8bit binary types
      S2 c) U8 e/ N* w) z- p* |3 B
  53. */0 r  l* K" d/ }7 r( K4 u
  54. typedef  unsigned char       LPDF_BYTE;
    . J/ ]: A- m9 N4 U$ [# G; F* G

  55. 4 P+ {. y) u( e7 L- O# _2 I" T$ V; _

  56. , @* D, r: p& |9 U8 o5 p6 B
  57. /*  float type (32bit IEEE754)
      k  a% a! |* A: J) P
  58. */
    , I# d  E& B4 ~
  59. typedef  float               LPDF_REAL;
      R3 R3 S' b. U2 }5 V- H& I

  60. 3 E, j3 E6 [0 N, v
  61. 3 x: x6 {9 f$ W$ _1 S5 J/ M
  62. /*  double type (64bit IEEE754)+ @2 b" ~! `7 O
  63. */: j2 V2 u/ C5 e& p/ b& _
  64. typedef  double              LPDF_DOUBLE;# c2 x" M9 D7 T; q: S. T

  65.   H% [% K$ b+ G; Q3 y6 {, s
  66. 6 U% h+ Q3 E/ o- M2 x; o+ z
  67. /*  boolean type (0: False, !0: True)
    7 X; |5 ]2 n3 k9 M( y* o8 ]# ]
  68. */
    4 j5 d$ O9 w- h; R& @8 X( D7 q
  69. typedef  signed int          LPDF_BOOL;
    3 @  Q! L* m% [, R" u" h
  70. , x4 V0 g0 {$ A
  71. - Y  L1 {- ?$ m2 b3 F. Y" H
  72. /*  error-no type (32bit unsigned integer)
    2 ]  N5 t( ]3 j: X
  73. */0 @/ _0 `4 x6 O$ r: ^9 ]+ Y
  74. typedef  unsigned long       LPDF_STATUS;
    ' l& G) `0 ]1 h( z. t8 y" ^
  75. ' g6 d: ~$ q6 C8 U
  76. #define LPDF_OK                     0
    " L6 Q1 A' f8 l5 ]% ^
  77. #define LPDF_FAILED                 1
    / E- n' f3 ]1 ~3 S+ m4 v

  78. # A( u3 ?+ |# y; |) d
  79. /*----- font state -----------------------------------------------------------*/
      E! D7 k( a  X5 _3 j0 f0 _5 s" }
  80. #define   LPDF_FONT_INVALID                 0x00FF
    & g: v9 p. a$ U- G2 c0 i
  81. #define   LPDF_FONT_COURIER                 0x0000" @1 t' ~* c" d- U/ Z: j
  82. #define   LPDF_FONT_COURIER_B               0x0001
    * F* Z; }3 v4 ~$ q; N
  83. #define   LPDF_FONT_COURIER_O               0x0002
    ; B; {1 X2 b5 Z" u  }
  84. #define   LPDF_FONT_COURIER_OB              0x0003
    6 l  G  W5 }4 Y% X
  85. #define   LPDF_FONT_HELVETICA               0x0004: l* s& \* w4 F
  86. #define   LPDF_FONT_HELVETICA_B             0x00051 w6 K, {, h! q
  87. #define   LPDF_FONT_HELVETICA_O             0x0006
    0 m* Z2 x6 J) `* p& H5 m2 h8 e8 K
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007  x5 m3 z; m$ ]
  89. #define   LPDF_FONT_TIMES_R                 0x0008' ~/ |$ ?, k) t! {
  90. #define   LPDF_FONT_TIMES_B                 0x0009
    : E) y  Q* y4 z6 Z, c& ]
  91. #define   LPDF_FONT_TIMES_I                 0x000A7 J+ o) a5 _, x' ^5 X; B
  92. #define   LPDF_FONT_TIMES_BI                0x000B
    3 w# S$ x1 r  d; ^
  93. #define   LPDF_FONT_SYMBOL                  0x000C5 F9 g, U8 D" ]. l  X# y
  94. #define   LPDF_FONT_ZAP                     0x000D& q, n% v- W# |
  95. /*----- Graphis mode ---------------------------------------------------------*/- {$ H' {6 Y) N' p- S7 Z
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    % J$ A( q2 h! F8 Q
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    ; }+ N% k  F9 q, n5 L: ^( g  q
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004( r5 U7 }+ H4 ~
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008* U- [* I/ U' V# `: o
  100. #define   LPDF_GMODE_SHADING                0x0010  @' `: R9 ~$ G- A# K
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x00205 ?% ^) m5 H# x
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040- I5 Z9 s2 `2 q$ w2 G
  103. #define   LPDF_GMODE_INVALID                0x0080- c) Y. d; C# T# T7 d3 g; e
  104. #define   LPDF_GMODE_OVER                   0x01003 q, t; v' n6 v
  105. 0 T: x" E6 M2 ~9 A7 ]4 U% M
  106. #define OBJ_MAX_NUM     2565 O8 i: O0 J# [7 E, C# a

  107. , h, `3 T6 \/ n* `6 ?, A: Y
  108. /* Page的结构信息是否需要树形结构 */5 B: h. I5 d1 F2 L' L% B! }1 B
  109. typedef enum
    8 W$ A" P  |$ D3 J) N2 E+ L
  110. {& b7 Q9 V/ f$ N1 w, `/ i% |4 S
  111.     OBJ_info,
    $ w  q* K/ G3 Y
  112.     OBJ_stream,$ X0 G9 @2 f9 F. R3 J
  113.     OBJ_font,8 r- R  E; j: e) R0 I
  114.     OBJ_page,
    0 N% q8 `$ |3 W' P6 U6 |) c
  115.     OBJ_catalog,/ D8 a0 d  I& w
  116.     OBJ_pages,
    7 m  w1 O- n' x4 j" ^+ o1 N
  117.     OBJ_image,. ?2 E7 P" f: ^: H
  118. }LPDF_ObjType;
    / w6 W% m: `( w- }

  119. 3 B, I6 b  }5 g, P# G
  120. typedef struct
    " I. Q, b# S: F7 W5 y) _
  121. {! q. l2 F% G# A. u5 x
  122.     LPDF_ObjType objType;) {0 ^! j9 O0 W% j4 a  X
  123.     LPDF_UINT16 objIdx;
    ) Q5 B# q) x; Q4 j+ R0 ?. B
  124.     LPDF_UINT16 height;( ^2 m3 Z6 p: U$ w: t: n) m
  125.     LPDF_UINT16 width;
    ( |  B: c; M: o! y* H/ l# P8 v4 s0 X
  126.     LPDF_UINT16 length;7 v+ o4 Y. x& f/ @0 m
  127.     LPDF_UINT gMode;
    4 {8 t: j* m: t2 w) Q- `
  128.     LPDF_BYTE fontType;
    - X6 N9 \: I8 I* Q2 f3 S3 a3 y
  129.     LPDF_BYTE fontSize;5 B/ I, B2 H; H8 ]" A) m
  130.     LPDF_BYTE pState;
    1 [4 q4 p6 m0 w( v/ G
  131.     LPDF_VOID *doc;* g' V- h) @, v; e2 g- C
  132. }LPDF_Obj;
    * i8 M/ c0 M" R" y6 a5 |
  133. . l- @3 |* O. u: T( _. K8 u
  134. typedef struct, ^# s; g3 D. I' e0 N* A. v
  135. {
    8 X7 ~1 r' f9 k$ c, m% m! J
  136.     LPDF_Obj obj[OBJ_MAX_NUM];- I8 Y$ b: q2 {; L
  137.     LPDF_UINT32 offset;3 Q+ ?! \# p& z0 m, p) T# G
  138.     LPDF_UINT16 objNumber;8 ~8 U5 w5 j% F# U6 I# Z  q: ?2 a
  139.     LPDF_FILE file;
    8 x6 R) A" H. x9 ]( U
  140. }LPDF_Doc_Rec;! @# t% r' x/ t. v7 s" S
  141. , e* |: s! {& a. J
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    : p4 ~: z1 o4 i. z8 B. R
  143. typedef LPDF_Obj *LPDF_Page;
    ( p5 V8 J7 y# X7 M, F( B2 a
  144. typedef LPDF_Obj *LPDF_Image;) M7 [. ^& i$ t
  145. extern const char *font_list[];
    ( \2 b' B$ n8 w# K. o8 |' l
  146. /*----- LPDF Interfaces-------------------------------------------------------*// M  C5 }, Y2 n, l5 \, @
  147. const char * LPDF_GetVersion(void);/ h6 k4 O1 R- ^- P
  148. LPDF_Doc LPDF_New(void);
    / V8 e# ]# B- g  _8 [
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);% b  ~" @  ]; p) ?- a  A% W
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);: Z% }* X2 j$ ~# Z: X
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);
    , U1 o9 ~4 a9 P4 B! Z: v" y
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);* g- ^8 y4 q( [' L2 F) w
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,0 }4 C: p8 u& M7 I. c
  154.                            const char *font_name, LPDF_UINT8 size);
    8 }4 a3 S1 ~$ E
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);" G. X4 @. m6 C) f5 y) H: H
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);% M; V7 n  P: j/ d5 ?( ^
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);* m" W% B8 ^+ p. A6 R# {/ ~; x8 R  ?
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);( \9 f+ T. w% G3 i4 l. r
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);* e: L6 J$ z' K# F; k  D9 e" ?/ r$ b
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);* P5 c( Q5 q0 m8 j
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);: Y; S- r- P& N$ q6 E
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);' o1 c* M, D, Y2 u/ m
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);
    : b& ?  S/ \- i6 w
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,% Q$ e4 ]$ h3 ~* c' E5 T5 t
  165.                          LPDF_INT x, LPDF_INT y);; ?2 ?; I& s, R% Q1 I6 x3 g9 W
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, ! G9 }) c6 D; I! a. x* `
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,5 A4 Q# [2 A1 j& A, v
  168.                          const char *text);' ^7 X, m+ ~" J& J* f
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    - f: F4 O: u8 m; N/ _, c. w
  170.                          LPDF_REAL r,
    & d4 C+ {0 I& l8 D
  171.                          LPDF_REAL g,4 H+ J! |: C; q
  172.                          LPDF_REAL b);
      q7 G4 D- `/ N8 m9 h" _
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    ; ~; R( ?$ M& b$ V
  174.                          LPDF_REAL r,
    " b* m* ?7 U# j4 N* G, ]$ f
  175.                          LPDF_REAL g,& I1 L# a2 B1 K! |% v$ z
  176.                          LPDF_REAL b);6 q8 c3 K& X: n; Z8 N
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    # k- R2 ]- S4 z& K* M1 m
  178.                          LPDF_UINT16 x,
    1 M0 Y" i, U% k
  179.                          LPDF_UINT16 y);) f0 @1 l! K) s
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,! \0 F1 r3 {  A- X8 a  q
  181.                          LPDF_UINT16 x,+ e( u6 p- {# [9 c; `5 e
  182.                          LPDF_UINT16 y);3 `# T3 y9 {( I% X6 m7 {1 t
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);
    3 y5 I" U; `1 n$ L! w' r
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);5 r4 A7 d% l# @. l7 Y
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    , q  R- w3 c& y; r( J
  186.                       LPDF_Image image,, Y. M" A1 e& K8 T  q- b
  187.                       LPDF_UINT16 x,
    , ]( ~& \. R% F8 Q
  188.                       LPDF_UINT16 y,
    6 ?# M  K. R: i7 R+ V. ?: g% [" D
  189.                       LPDF_UINT16 width,
    * K7 @0 |* d. U, x. ~- E2 o6 f
  190.                       LPDF_UINT16 height);
    ' \7 J/ h4 d+ z: v
  191.                                                                                        
    ; ?9 U, o2 N3 P, N% k9 W
  192. #endif8 r, {( ^; W- P' n% K9 x
复制代码

源文件如下:

  1. #include <stdio.h>
    $ z, ~4 {: ]$ u  V
  2. #include <stdlib.h>
    / c: f* S1 \# e
  3. #include <stdint.h>( q( J# M& n; t7 v! E
  4. #include <string.h>
    $ l. S  c8 W  W& z5 X  z) m
  5. #include "pdflib.h"2 J, N" x5 n/ ?8 i) X' J1 U
  6.   Y( l# U1 Y; g7 k/ S
  7. #define LPDF_INVALID_OBJECT                       0x1033
    ; o; R' x2 T/ H. Z* a9 C
  8. # Z, q2 P4 f$ n/ M2 L
  9. static char pdf_buf[512];
    5 n. `: R3 a  g
  10. 7 k# m0 a  a  Z. f& b
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"  ]/ I2 M9 }' g8 I
  12. #define LPDF_FILE_HEADER_LEN        15
    - m" s% Y$ U& d* }/ ?; i
  13. #define LPDF_BASEFONT_NUM           14
    ; C0 L8 s0 k( Y9 P, x) e
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    - l& m5 c) G* q# Z; A
  15. const char *font_list[] = {
    ; C! h% @$ ~6 ]
  16.     "Courier",% B: g8 D/ c3 F% W* }/ v$ ]& D: k( Y
  17.     "Courier-Bold",
    2 Y* k' _" c  Q5 ~6 k; H4 U
  18.     "Courier-Oblique",3 u: T( ?- D# b; N8 G- w# Y6 c: o& V0 }
  19.     "Courier-BoldOblique",- g3 l) C5 V, S
  20.     "Helvetica",( [4 x/ O7 |, G, m# g8 D
  21.     "Helvetica-Bold",
    5 ^; k) C; \: h! m- ]0 r
  22.     "Helvetica-Oblique",, U$ Y" v0 D. m* m8 `5 m- |
  23.     "Helvetica-BoldOblique",
    3 |5 n# ]* e& J6 E
  24.     "Times-Roman",- f6 Z6 }, g3 `5 N
  25.     "Times-Bold",# p9 N# S* r% j, H7 B6 z" s/ G
  26.     "Times-Italic",2 C$ H. W: c) }
  27.     "Times-BoldItalic",8 A, u4 w7 C2 c- j
  28.     "Symbol",( G2 s$ K( G0 v+ J
  29.     "ZapfDingbats",
    # h: @- ^1 O( O! Q5 |8 h
  30.     NULL
    ! Y8 q6 l8 F: D1 b
  31. };( n, ?+ e4 L& f( ^% \1 {
  32. 5 o, `9 [  M2 }2 N

  33. 5 c2 G' M. A+ C0 r
  34. const char * LPDF_GetVersion(void)$ Y& v/ {( G! F5 M7 f  ]9 j$ \. _
  35. {
    4 a" b' o+ E5 U0 E
  36.     return LPDF_VERSIOIN_TEXT;6 y! o! K5 o+ t2 a
  37. }
    5 {8 A1 V) N2 H7 z# v+ ^2 ~
  38. : G1 {2 X- _: }- R  r+ x
  39. LPDF_Doc LPDF_New(void)
    ) p2 o$ K6 e! ~6 s/ L$ Y2 G* G7 K
  40. {$ U: J8 I+ E4 r9 j- |1 q$ R3 ^
  41.     static LPDF_Doc_Rec pdf;
    , c+ h$ b2 y9 |4 D, t
  42.     LPDF_INT length = 0, i = 0;9 M- J. S) E. r
  43.         LPDF_UINT writeBytes = 0;4 u7 U! g) I0 b1 Q/ `. y: n4 t
  44.         FRESULT fr;
    # h( C8 g" n. ?
  45.     : Z7 j! S2 G, \0 h
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
    0 ?2 [* [) N6 w2 _! w
  47.         if(fr)/ u$ a& C- X; V
  48.         {! u( {% A# a; N8 F3 i3 T
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");- n- b; y" N1 H/ W$ Q
  50.                 return NULL;+ ^2 T9 G/ |0 X( M( {. G3 _* r* b
  51.         }( w9 u/ z) Y: s- k; f  b
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */1 v) B  B' l  C% c( R2 p- Z/ ?7 C
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;
    # Z5 n5 T+ k. `$ f; A8 l# b  V9 W
  54.    ( U; z6 Q3 \  {$ u6 G
  55.     pdf.obj[0].objIdx = pdf.offset;3 B9 p, w/ `/ d" H  w
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");$ q; L: F5 v2 A1 @* a, [8 u9 w
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);* W" y3 k2 L5 m' t2 F0 v
  58.     pdf.offset += length;# }/ V' [7 L+ g! G+ Q7 ?) @/ H9 s, D  j
  59.     $ S7 n  z* ^; s2 X' t* H0 l+ E
  60.     pdf.obj[1].objIdx = pdf.offset;
    7 A4 s" w( T4 P; w
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n": C" t# u4 G# l) K% C
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");
    + E2 S$ k* V9 n* E: ~2 G
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);, p8 J* \' X' I
  64.     pdf.offset += length;: h' Z( [3 u1 {0 P
  65.    
    * T4 Q' u7 l( E" C3 L3 O
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)  Z* f8 b5 Z. p4 i0 e- C! l7 ]
  67.     {3 ~: B! d9 @  F* O8 v  }# y
  68.         pdf.obj[2+i].objIdx = pdf.offset;6 W; c6 b5 x) a
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    + }, Q! X6 _" ^- b
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"6 f, c9 ]) ]2 ]3 K9 j' i0 S
  71.                         "endobj\n\n",3+i,font_list[i]);/ i& R4 Z& ^* \& F
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);  u* ~# d. j$ @0 O! P
  73.         pdf.offset += length;' F& v5 Q% ~$ u1 q
  74.     }
    2 v5 s" e. B# C
  75.     for(; i < LPDF_BASEFONT_NUM; i++)$ S2 W2 m5 I6 n+ R& u" [
  76.     {
    ! F: I7 _- R% o- B
  77.         pdf.obj[2+i].objIdx = pdf.offset;
    . X! u( p' V, ~7 A& r, n
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    7 k9 l  @& S/ _- O
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);: K& K# H% X: ]8 {8 t( d. h
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
      [/ E" y7 j* _* ~
  81.         pdf.offset += length;0 k- f+ h) M* I/ X
  82.     }* R- G& Y( V% Z- Z3 o& R, \
  83.     pdf.objNumber = 3+i;
    * }6 C& J) }9 L* |; c
  84.   
    1 T4 }5 I7 k2 D0 X
  85.     return (LPDF_Doc)&pdf;
    1 S- X' K5 x! c3 Y7 v" G+ q0 u7 ^2 i
  86. }
    7 _+ z8 g3 R0 X7 m' x

  87. * b9 P# k% z. Y" u  u2 h( l
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)0 }: L' B! A: T  c# h* o
  89. {4 p, S' h' c# q
  90.     LPDF_UINT16 i = 0, child_pages = 0;# ^4 Q! Y9 ]1 h+ A" F: s
  91.     LPDF_INT length = 0;
      d* d, r2 u3 |4 \% h2 V' K
  92.         LPDF_UINT writeBytes = 0;
    ' a$ V6 E- J0 \

  93. . I3 q' D3 G8 ^
  94.     pdf->obj[16].objIdx = pdf->offset;+ l0 @* M5 C( g: ?9 X
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;0 T1 U* u' ~/ n* Y/ h0 s$ y. f6 }
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);4 ^; A; W! @" R! I- R& o' j
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);. |8 u7 W/ A; o: }; }
  98.     pdf->offset += length;
    & E0 B8 N& `. h' Q  g" A
  99.     for(i = 0; i < child_pages; i++)
    , r+ {. z% Q7 ]2 u  L
  100.     {
    8 j- w3 x6 O& Q; t8 K% v  P9 W
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    " c4 ?: w* Q1 {' I& t# o
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);- m) p! Z  \" k) n" U! ~. }
  103.         pdf->offset += length;
    2 w1 N  T' v% E, b
  104.     }
    % Z7 z7 T& V! A
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");! A' ]# C) X3 N* ~- A
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);+ H8 }' L4 K  w: y0 g, ^
  107.     pdf->offset += length;
    & g6 ]9 ]& c" |" B) p$ w
  108.     2 v$ j7 Y3 v8 `# F( [
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);6 t0 R  @  M& o
  110.     for(i = 0 ; i < pdf->objNumber; i++)6 l$ Z/ f& ]% I4 W3 X6 r  e
  111.     {
    8 z% R# Y- e- I3 [
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);8 J3 E% G) Z2 r- ]4 H, g3 G
  113.     }
    # K& t3 E- V5 o+ u  G6 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",; X; W8 D$ G7 |& g/ o7 H
  115.                 pdf->objNumber+1,pdf->offset);) `. c) D- B* i9 ]1 V. o% w2 B" H' G
  116.     LPDF_FCLOSE(&pdf->file);+ g, ]- k! B3 E/ [3 V. j4 Z
  117.     LPDF_REMOVE(file_name);5 t: W" |- x9 D7 O
  118.     LPDF_RENAME("tmp.pdf",file_name);( I5 v+ q5 J; O8 ?& Q/ d
  119.     return LPDF_OK;% K) T$ N0 ~2 b% L( \8 O
  120. }( {' i, R8 q- i7 B8 U: O3 M* @; S
  121. . W4 S& V7 i3 Q7 n- {8 ?
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)
    / b5 d0 N' W- L2 M1 C
  123. {8 Y7 _: W, d+ B
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);4 T7 Z- ~2 m2 U' b$ V, K; e
  125.     return LPDF_OK;4 g' K% W: g; v6 ]
  126. }$ ]( m2 H1 N, ~7 v4 J
  127. . @7 [" ?5 _. {5 ]( }" {
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)+ A' g1 B/ o2 E) |' t; s$ G
  129. {+ G% E$ R$ R( G1 W# g0 X
  130.     LPDF_INT length = 0,i = 0;! S, R4 R$ S2 h( v7 r  V
  131.     LPDF_Page page = NULL;- L' D/ U9 H* X8 {7 s- E
  132.         LPDF_UINT writeBytes = 0;
    ' r8 T0 N% A9 J' J8 C8 @
  133.     9 J7 v* _+ I2 q& ~6 K- p7 S% T) V
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    ; F* D$ ?7 z2 N, w1 R; r0 [% s
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"; ?" ~7 {3 i( F
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    / x$ n7 a/ I9 E
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    ) C$ b. E3 d  J! d4 k0 U
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    + D: i# o& i  f1 i; \1 U2 }7 E
  139.     pdf->offset += length;
    5 B% Z) z% Z) h+ X8 G( z
  140.     while(font_list[i])
    $ c! b: B9 m. ~( e' e
  141.     {
    9 H- s6 S! u: z' g$ u
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);
      U# I) a* j& t6 W; M3 q
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);1 z, @9 @( n/ P) B; x
  144.         pdf->offset += length;2 U2 e# A6 N% V
  145.         i+=1;' ]7 F+ \8 P  ]. l6 E( r$ A
  146.     }
    % Y8 a7 y& `+ @" J, Q
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");
    ; a  \" G. x$ E+ o  t  N* s
  148.     pdf->offset += 4;1 l5 \# H( r7 ]* n( |5 V* j4 g
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];
    * J/ W% S) s. u& U$ Q5 P' ~: N) g
  150.     page->width = 595;
    ! s) `: h( N8 o' H3 H2 l
  151.     page->height = 842;
    6 ?' o9 x- l4 D( m* Q  w2 y" J
  152.     page->gMode = LPDF_GMODE_INVALID;8 U" [" h0 v. d0 D8 T9 p2 Z; @$ r
  153.     page->fontType = LPDF_FONT_INVALID;1 c' G; C0 r& d5 h, s5 o5 y8 [
  154.     page->doc = pdf;
    ' K6 N' J) M. S8 Y  s
  155.     return page;
    $ R  t* G' {1 M! ]5 F5 j3 R
  156. }9 Q4 Y5 k" f5 f/ c/ n

  157. 0 W# s. I- O- p/ F2 }+ W5 e
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)
    9 c7 k- c) m. h! m
  159. {
    2 ?! G. G1 {" d: F( w7 O* f
  160.     page->height = value;
    5 m9 d9 ^- @, s0 _- m2 a+ Y
  161.     return LPDF_OK;  C# Y. p$ _4 Y4 g0 X; u
  162. }
    # b; s$ |$ U% Z2 _/ V
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    ) \! S$ W+ z! d: b
  164. {9 u7 G8 T' q0 H3 M; m5 n7 e8 G
  165.     page->width = value;( q) Y; T$ |$ T; H8 E% \" ^
  166.     return LPDF_OK;
    # z, ^1 K& [1 f; M
  167. }( |& W" k% j" c4 b

  168. 4 B9 L0 @) _; u, }
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)
    + I1 Q# p& u; E( x: d
  170. {) e. Z& I; A% J
  171.     if(page)
    1 e$ e6 N0 F. L& u3 m
  172.     {  t' m. j3 _% k. g' g0 \
  173.         return page->height;
    ! j" e$ s; c( q
  174.     }! M- J  A8 h$ x% z6 }5 h  ?
  175.    
    7 Z. g) r  x3 O( F, a
  176.     return LPDF_OK;, n$ T, ?% b$ S4 Y2 z) M
  177. }
    : u4 D; S. f$ a6 r
  178.   N3 a; [7 F  Y3 E( Y2 I$ L' e
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)' G) I$ t9 s) k: {
  180. {6 P, I  C6 `2 V* B5 J
  181.     if(page)& f3 W$ s9 t: R! L& \3 u
  182.     {1 C, h# {3 L- p# S5 G
  183.         return page->width;7 X4 ^: c2 P9 N0 |+ L
  184.     }5 U& i/ t$ Z/ Y8 N
  185.    
    ; J: X* N  D; Z: a7 @
  186.     return LPDF_OK;' B$ b$ p9 K# `: R. J6 g, N  s
  187. }- W: w. v( c6 W, `9 i6 g! b
  188. ) K4 I+ Q: U. j9 w
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)
    5 W$ A- H7 X; u6 e3 J
  190. {
    ! i) s* Y& \$ z# [
  191.     if(!page)
    + M/ P; o( B" L0 S8 y
  192.         return LPDF_INVALID_OBJECT;( |: w  B! d7 P
  193.     if(!(page->gMode&mode))
    0 Y2 W6 ]) J) \( h8 q
  194.         return LPDF_FAILED;' ~: Y0 v0 _3 ~; i% q
  195. 4 F" M( G* ~  B
  196.     return LPDF_OK;: C" s. i* a, W0 j1 K& x
  197. }
    / K8 |+ L, g, }5 |  I7 c% [, k

  198. 7 |! a; h+ L4 D) B5 p5 \* ?- s8 l
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    1 B+ R" e+ e) e7 v6 A3 d) j& Q. K. \
  200.                            const char *font_name, LPDF_UINT8 size)
    6 \$ [' D. s* m7 ~, g: `+ f# b
  201. {2 ?1 v9 K6 Y8 W" x; r* U
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;: D: ]# _# ^9 ]2 h
  203.     LPDF_INT i = 0,length = 0;2 V. `* `( k% ?1 ?2 `# o
  204.         LPDF_UINT writeBytes = 0;
    / o# J+ `' l3 ~- X" X6 \
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    1 B7 I+ p4 J# S4 \9 A
  206.     if(LPDF_OK != ret)+ D" E2 @: P$ S9 I
  207.         return ret;& O. M! z+ q7 [! L
  208. 0 p) \- g+ c( ]- K, ?+ j
  209.     while(font_list[i])
    + h! F, B, l& ?( V$ D% U5 s
  210.     {
    1 L. D! H1 {5 I- H
  211.         if(0 == strcmp(font_list[i],font_name))
    & z7 R% Q/ {6 U3 J; p# X
  212.         {. s: H8 Y0 _$ }! E
  213.             page->fontType = i;
    ) u+ K# h4 z1 V8 u! a
  214.             page->fontSize = size;
    & K' K$ _0 }! I. D
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);" A: j2 E3 C! g  w
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    . j% B! G5 O: e7 F
  217.             pdf->offset += length;
    1 C% ~/ Z( K2 v; I/ R: l! _6 _
  218.             page->length += length;+ r7 P' K! V$ G" u- M& ^& U; Q  C% @6 a
  219.             return LPDF_OK;
    % x. w& c; F+ ~1 _: o; R
  220.         }; [: M. f* N, O* y7 [" a. k3 m
  221.         i+=1;2 q2 I& N# @6 S! b3 K, Z5 T
  222.     }# |9 {( r  d* s/ d
  223.     4 V# r* o: l+ n% x  d, B
  224.     return LPDF_OK;
    . E7 A" F7 e) Z* v$ y- Q1 x6 w
  225. }
    - g2 D( W+ N8 e3 W5 ?% o, w

  226.   M% |' U* j% u/ C3 ^2 X* ]
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)
    : O: y/ K4 z' L& e* s# R3 a5 I
  228. {
    % L, W. N+ ?4 X( s& q& Z
  229.     LPDF_INT length;
    9 o  I: O% ~+ s$ F1 ?- b  v
  230.         LPDF_UINT writeBytes = 0;8 C1 t2 A& z$ ^4 T
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ; C9 ^7 r; J9 Q, r) j/ u  H0 K9 t
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);( K* [/ C" i* m* a
  233.     if(LPDF_OK != ret)" b1 a* D# R" R% |
  234.         return ret;* U# I8 T3 U1 v
  235.    
    + s! @3 k: N) u) h( e4 m; `
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */6 p  S  w3 d: a9 C
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",$ X) R- w8 D* o
  238.                         page->width, page->height);
    4 x, l& J: i1 v# v; g
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);% I% |) R1 A! p* O
  240.     pdf->offset += length;
    1 m5 p9 P5 ^0 T( `4 t  L' k, c- P
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    : L& \+ {/ a8 I% Z' s
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",& s' ]9 z2 a( L2 J, u
  243.                         pdf->objNumber+2, pdf->objNumber+3);
    $ c3 H& a+ Z" d+ _- A' K
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    + j# k. O! Z# m8 k# |  q: ^4 Y
  245.     pdf->offset += length;
    ; E, ]$ S( L/ c  ~% u
  246.     page->length = 0;1 D+ [8 V- s1 J& L6 M6 n
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;- K6 \5 o$ @1 T
  248.     return LPDF_OK;2 _4 [& w, t2 E
  249. }4 a# d& Q; p7 `6 l6 J

  250. - J& `$ N) K: l$ U3 N6 S
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)0 E! C  c2 ~9 I% |$ h% v
  252. {3 V0 g4 a7 ^( Q1 p  e. N
  253.     LPDF_INT length;
    + d3 `6 T- S; i" z* a% {; ]" k
  254.         LPDF_UINT writeBytes = 0;" `" Y9 {3 `2 \6 M/ j
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;+ U+ s! s0 d7 f4 O2 X/ y( B
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);- C$ @) _' A& _, I. q: L% |
  257.     if(LPDF_OK != ret)
    5 C+ u' O/ b8 ?8 J6 K
  258.         return ret;
    - m# M% G- h+ y2 h' p6 G
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    % b* n  p7 _  E" D3 A4 ^/ j' x" d
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    , M0 \2 l5 }6 y" b4 h. j
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes); * \0 |7 |0 \9 B; I
  262.     pdf->offset += length;
    3 I% b, [0 o; H/ n2 K" z6 D
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;* M7 }3 }1 D9 f/ U+ o4 @
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    ; [4 P3 K: D8 c- P3 L: \& t
  265.                         pdf->objNumber+3,page->length);* D/ p7 i) Z- S) P, _; b& s+ h
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    2 `* ]$ B( I& C: o3 k
  267.     pdf->offset += length;
    3 g- s4 O' `% T0 b8 k9 Z+ [1 [# s
  268.     pdf->objNumber += 3;
    + @* R$ M; I; U7 I0 c+ p# ~* T" [
  269.     page->gMode = LPDF_GMODE_OVER;
    4 w" E1 S% C. o* y( B. h  Z" J
  270.     return LPDF_OK;
    . H* y5 p" [8 g+ x* s6 Z
  271. }6 w+ b& p/ U3 C

  272. / ^' A" v. @9 G
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    1 b0 Y* @2 ^* E& i
  274. {
    2 H, T+ j/ m5 a4 [9 `
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;  @2 H# q+ c/ U( M
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);1 V$ h* z/ T  r# i5 E+ t  n2 x
  277.     if(LPDF_OK != ret)
      F* N9 t* [$ c
  278.         return ret;8 O" P% t. y" j+ X# g
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    / j, X6 T( d7 q/ H& N* x$ m
  280.     pdf->offset += 3;/ p/ g# W$ i) [, n7 i/ D1 t
  281.     page->length += 3;+ \& u/ w$ {* [1 g* {; i
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;' @! B. h3 D1 E6 t
  283.     return LPDF_OK;
    ' R7 d& ~; P2 {: u+ j6 r
  284. }
    5 d  _# [- d3 v' b" m
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)
    1 j* b: k+ {1 d0 f. C( B* x4 p
  286. {
    $ B4 B/ L# g8 c1 J+ X. x
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;# |4 d+ r; r) ^, @7 P
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);) ~# o7 K+ |9 p0 O' g$ x: T% z" O
  289.     if(LPDF_OK != ret)
    " M# f/ G' {# x6 K+ a- o& S1 A5 m9 R
  290.         return ret;1 X1 C: r$ q% g& k4 E
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");5 E4 n& Y5 S4 B# Z+ C  H  Q! X  Y# p
  292.     pdf->offset += 3;4 F9 a5 I2 M, R
  293.     page->length += 3;
    , d3 ]0 d6 p, I) o
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    & v' U. \  L( A2 @" g& W& E) _
  295.     return LPDF_OK;3 X- |, {5 @" a% Q! Y7 B& s
  296. }
    $ L, U( l1 Q% p* w; L
  297. 6 z; N# f1 A( D- f' l9 U5 G$ o
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    * o  k8 f5 _% g: P7 {$ _+ p1 b
  299. {1 W" P1 n5 Z( L3 y9 c- p
  300.     LPDF_INT length = 0;
    % E" J4 P# W4 z) ]& c9 Y
  301.         LPDF_UINT writeBytes = 0;
    6 P6 i( P% V% u/ Z; H
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    6 @( d8 W8 S: Q' k, s- \
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);. F. g0 ^* S0 i" H% l
  304.     if(LPDF_OK != ret)
    * |& r/ M6 v; Z/ R! s8 B
  305.         return ret;
    - u( r, b* A; ?& F" n  G
  306.     if(LPDF_FONT_INVALID == page->fontType)0 V; Y) \. }$ [
  307.         return LPDF_OK;
    % q& h9 N' |4 A5 H) ]; F
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);
    / a% g9 A0 i3 O! l
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);& m0 d; P- g' T' C/ ^. f  Z
  310.     pdf->offset += length;
    8 u7 P0 Y  a$ P( ]
  311.     page->length += length;
    & q5 ^% e" z. L( E  Y. C. |
  312.     return LPDF_OK;
    / M( O) X; d1 Y% u2 X+ l( ^% Z
  313.    
    . w, a6 R; H* O- t" f
  314. }# E% w% J& K* r1 Z7 N+ ~
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,4 N6 b1 d' m' ?7 ~) U
  316.                         LPDF_INT x, LPDF_INT y)0 F! Z2 `5 G8 i  a% [, p
  317. {
    + O2 k; h) j9 r4 U0 n
  318.     LPDF_INT length = 0;
    + @+ h4 m( u4 Y1 v& L
  319.         LPDF_UINT writeBytes = 0;
      p6 N, e' Q( S0 B' J
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;/ v, Y1 z4 l: `% p$ x
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    ! x. U+ r5 [" i
  322.     if(LPDF_OK != ret)" }9 m" E. O! A4 V/ k6 q
  323.         return ret;) ]0 F) {; t8 X, i6 \3 U6 D  l
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);
    0 i# q: O4 o& b* ]
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    + i# v, Z7 `4 k7 P+ L& ~- a" R
  326.     pdf->offset += length;+ d- L0 U4 d. L, n- r
  327.     page->length += length;5 ^8 G% J2 N! T

  328. 2 c% k$ I: I: m3 v, J1 m; u
  329.     return LPDF_OK;
    0 y: B6 ^( B8 N) T( D2 X  Z
  330. }. A( u  x, p/ Q: ]# D
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    & [$ P3 @6 V9 M. m2 }# D7 l
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,
    5 W/ W- [/ ~  S3 o7 l6 a# D6 Q
  333.                         const char *text)
      r7 g: C* s3 x( C4 c$ R3 V0 `& i
  334. {% k0 d% N6 W7 _+ }2 p: }2 U
  335.     return LPDF_OK;, V9 A% G! \( q; _* g/ V1 k
  336. }: V0 I1 m  f; @6 K. x4 O+ X: k

  337. $ Y7 L0 E7 H9 m* k$ @
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,# a3 b$ h4 \9 Y1 |8 s+ ~
  339.                          LPDF_REAL r,
    % u1 D2 Q& W  A' |4 a8 F
  340.                          LPDF_REAL g,
    6 b: L( ~& l. f' @$ s
  341.                          LPDF_REAL b)" Q. [& Y+ f0 H7 n; y5 |1 U
  342. {
    # A+ e+ n3 U& t( @4 ^/ }, u8 G, @
  343.     LPDF_INT length = 0;% V# y: O/ z* J& i
  344.         LPDF_UINT writeBytes = 0;
    7 k/ i& ~( k2 e% ]# ~& ^
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;8 ^' r  p% t5 ~- B+ Y5 m
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    6 M  x* x/ \# E9 e
  347.     if(LPDF_OK != ret)
    9 K) ], T! n, l, s$ d% j  Q
  348.         return ret;
    * D& u8 C* o/ v$ ~' m$ }

  349. ) z$ T- O. J. {! D
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);9 J; a9 @% s0 F
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    6 c/ U0 z1 g3 E* ^8 l
  352.     pdf->offset += length;
    % T  k/ Z4 V. o( L+ p0 ?0 h% G
  353.     page->length += length;, ~" r5 S& R: T' w
  354.     return LPDF_OK;
    % z  k4 k8 i% c
  355. }8 Q; e+ I$ e" F8 E) o6 t4 b4 t
  356. ( l6 I3 x' Z4 D! H0 s5 T* `4 t- h2 ~/ a
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    ) m/ N; g( I( J' i* \5 }+ R
  358.                          LPDF_REAL r,
    : W8 `& F* A* T
  359.                          LPDF_REAL g,
    3 k  m% S2 U, R/ F) x
  360.                          LPDF_REAL b)
    6 b3 r' x; T( t  j1 ?- r& r
  361. {
    / f) B' \2 {' A6 M
  362.     LPDF_INT length = 0;
    * Z4 m. w" h! B/ |/ ?4 E0 P4 b
  363.         LPDF_UINT writeBytes = 0;  F7 S, {5 y9 r5 w
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    : S/ \$ M6 ^% y. {. E
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);) \& x7 T. E( r* V8 [7 v1 T
  366.     if(LPDF_OK != ret)0 Z. L, A7 p2 _# i% z
  367.         return ret;
    & }% _  [( J5 @3 V8 H% d9 L' a

  368. 4 [" \5 t# \/ N# |3 ^" [$ r
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);% }5 |8 \9 I8 j
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);3 K% r! \! e1 ?! p* `+ V
  371.     pdf->offset += length;
    $ b+ Q: J0 m; F) ^
  372.     page->length += length;' @7 X" i; j/ Q# Z8 Y  E
  373.     return LPDF_OK;' h. `+ C! q4 I+ l7 x1 F: X
  374. }
    0 Y' {5 N  Z& q
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,3 d3 a+ \; y; x3 X
  376.                          LPDF_UINT16 x,
    ) m, T  E9 Z& V6 ~
  377.                          LPDF_UINT16 y)
    7 _, P6 F0 E3 Z: h: f  G/ c
  378. {
    / l: I* t2 d. l# l( W) D' Q
  379.     LPDF_INT length = 0;
    6 M+ ]: z2 L# j! D9 h
  380.         LPDF_UINT writeBytes = 0;
    # G! P$ E1 U3 j, T4 s6 ]  q. Z8 [
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    $ c: }! J4 ~$ @# k* h  Q
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);
    2 N) U( E0 I1 {" m5 u% }6 K7 b$ _
  383.     if(LPDF_OK != ret)2 T. D" Z1 }* n. \9 i# {
  384.         return ret;) t% ~2 Z. W; v: w, [2 j
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    , f% A0 T% ~- O
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    0 U1 v8 H# v6 X1 W4 g0 C
  387.     pdf->offset += length;
    : @6 F- T9 Z. T  U$ i, O! j5 B
  388.     page->length += length;2 J* C7 w# s4 m9 z- [
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    4 Z& F0 f2 [- L0 H2 _& w
  390.     return LPDF_OK;$ S# I2 y! A( C" i
  391. }7 i) p& O- \6 @
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    . H1 b0 @/ p6 J9 K: t  p: s
  393.                          LPDF_UINT16 x,
    # G& ?2 ]% G# B! }6 Y9 {
  394.                          LPDF_UINT16 y)! ~; T- n% I. N8 M$ j
  395. {
    ' E+ \, P! z2 m3 d5 D4 `
  396.     LPDF_INT length = 0;, b, g( M' r& c, @# V# f! T
  397.         LPDF_UINT writeBytes = 0;
    6 |; E: u$ {; I, d: ~
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;: X$ g( K$ S( j$ Y0 i% n0 V" a( M
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);7 E; x' r3 l4 E8 k$ Q
  400.     if(LPDF_OK != ret)
    0 T0 ^& y  U3 u' Y" u- h
  401.         return ret;7 S6 K! d6 Y6 V, M4 A% q( h
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);3 M, w6 e* G. s" V6 C7 N6 E
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; z' B5 [4 s& J2 ?, K
  404.     pdf->offset += length;; [. Q" J; g! Z2 @: b4 S/ W
  405.     page->length += length;
    7 \  v- Z' T% P- T% n
  406.     return LPDF_OK;
    : a* f! Y2 I7 v
  407. }4 X( h5 e. U$ \( |1 t3 r# Z; \
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)& `, k# F" h  G! A) V
  409. {
    . C) z/ k/ [& w7 J
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;3 x+ Y2 B+ P2 ]* O4 h, t
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);6 s* ~2 s) B8 A
  412.     if(LPDF_OK != ret)
    % U+ T4 n5 N( }7 {
  413.         return ret;1 {( o# [+ d# d1 u
  414.     LPDF_FPRINTF(&pdf->file,"S\n");7 M( B: H/ m* z+ d. h; `
  415.     pdf->offset += 2;, B' W3 r. M8 m
  416.     page->length += 2;* ~- o$ t) F6 W0 q+ g6 m- y
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;! [- d7 ]! B) K' x
  418.     return LPDF_OK;  V- `! ^+ _% \
  419. }
    8 o; B7 k5 E& |1 W3 B3 h5 ?! t
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    + j3 v0 w3 V* \, m5 i: D6 z! ]
  421.                       LPDF_Image image,1 x/ C  D  n2 c/ }
  422.                       LPDF_UINT16 x,1 ^' Z2 E. ]6 x# [  J: |  u. Y
  423.                       LPDF_UINT16 y,# _$ i& a3 H* l+ [/ i* B; z0 \
  424.                       LPDF_UINT16 width,, d4 _2 V  v: ^& g# G$ w7 ~* m
  425.                       LPDF_UINT16 height)
    ! ]; n; K. e. o, P
  426. {( r: G, a4 B$ k, [/ j+ f
  427.         return LPDF_OK;
    * m8 o. M+ Y/ W, N; W2 M
  428. }
    3 e) r( `  O* t! ?
复制代码

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

  1. pdf = LPDF_New();7 w: s& g4 I" B) O, [
  2.     page[0] = LPDF_AddPage(pdf);
    % [/ S% ?/ z# P  @0 C
  3.     LPDF_Page_SaveParams(page[0]);
    5 e; D0 E/ S# v& ^7 G- O+ N3 @
  4.     width = LPDF_Page_GetWidth(page[0]);  S- Z; D. r2 _; @
  5.     height = LPDF_Page_GetHeight(page[0]);
    ! ~+ g/ j# Z% w/ z7 t9 [( |. z8 g
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);$ T2 g* |' }3 p# c) w9 h( A. l
  7.     LPDF_Page_BeginText(page[0]);. N8 p2 ^" t! o
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);
    ) M& ?- {+ \" R
  9.     while(font_list[i])
    4 R) t& d7 {" l* N
  10.     {% N1 W2 v) _3 w7 X) W/ @
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    3 S" y5 d1 W; o2 u# Y
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");
    ; g" B* G3 g4 b: i' }( _
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);  r9 Q" i6 k4 V' s) v: T9 ^+ g3 u) r
  14.         i++;
    : N. k2 I; P: H& B5 q2 ~3 H: T* w
  15.     }" L' Y4 x; R2 s  |8 `
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);+ _. ^- T8 X9 b: ?- g
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());
    + g* d+ n6 V/ l# p- y4 [8 W: k
  18.     LPDF_Page_EndText(page[0]);
    2 O0 W0 A: L  H  [! |* k
  19.     LPDF_Page_SaveContext(page[0]);/ b+ A, _; U9 T' V7 l2 Y  i$ F" L
  20.     page[1] = LPDF_AddPage(pdf);2 X+ n4 Y& i/ Q" y# `0 s
  21.     LPDF_Page_SaveParams(page[1]);. n( u! T$ H, l  X7 L/ s$ u. [
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);
    , q& f+ e' b. u2 q. G
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    1 C3 L( a/ A: Z
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    # R0 l( T: y) u  d
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    " w; q  D1 f6 y) l/ V
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);$ j% B( p. w- H" n
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);  y3 g; v% F$ L: z. Q
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);5 Y/ s- ]0 v( m. i0 F3 V. ?
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);7 L' W; {( `) p8 i: L6 R# \+ H% _
  30.     LPDF_Page_Stroke(page[1]);
    ' p; q/ L) ~1 T+ _; P- C
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    " D( A  w4 u# n+ x
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);' H" }9 w# Y5 u8 I0 O
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    * Q$ D1 ]+ j# B& e" O: A
  34.     LPDF_Page_Stroke(page[1]);
    4 x8 P7 J( t8 l/ b9 w4 @+ B
  35.     LPDF_Page_SaveContext(page[1]);
    / ]2 Y" q: o3 E- n9 z& P
  36.     LPDF_SaveToFile(pdf, "/red.pdf");
    1 Z* E/ m+ ]" _9 k/ m' |5 o9 O9 c& V+ a
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    , Z+ T. f4 i9 K# `
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了) y9 I+ r! `6 y0 m2 ]7 z

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    % [. `( M, E- A: Y* I5 }  V) n

% L0 ^1 U+ f9 E4 J! n, P1 }3 q

pdflib_V0.04.rar

下载

6.1 KB, 下载次数: 456

pdflib库

点评

加密怎么处理呀,有没有大佬指点一下  发表于 2024-7-13 16:56

评分

参与人数 4 ST金币 +24 收起 理由
tanganrong-1584 + 5
g921002 + 8 很给力!
lemonjohn + 1 很给力!
wofei1314 + 10 很给力!

查看全部评分

赞 5 收藏 22 评论152 发布时间:2017-6-17 23:03

举报

152个回答
kiki.zhang 回答时间:2018-2-27 10:19:19
anobodykey 发表于 2018-2-26 22:55
% J0 J# ]/ V* C) E! B- N只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...
" a7 }9 N4 {" d  n
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
& g9 Z+ T5 y" t, w+ {$ f, O2 R首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
7 j8 u. K0 [! S9 \/ P
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思% B3 {6 ?- k4 f- K# A
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:458 t( L' {( W$ Z/ V  e1 g7 {. h* ^
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
& R* K1 I* h. p3 n9 U
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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
4 F1 m- x: ~) ]# t7 o厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

$ \$ P/ C" b/ f$ A3 t4 V& H这个还只是一个简单的库,实用性还是差一些的
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
) `" r' K5 G: Sff.h在哪里呀,我的是keil4.73版本,需要手动添加吗

; o/ N# d9 N8 T- H- \! @ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22; L0 n' ?( z/ n/ P8 D
ff.h是FATfs中的文件

* o1 [9 B2 }, d. n1 T5 n% l  O嗯,这个画线能改变线宽吗

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版