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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑
$ M! j2 s% o# a' W" ?8 w' B+ ^# W  o9 U

主机环境: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__5 c. z# u: \& ~& h/ r$ s  s7 n6 L
  2. #define __PDFLIB_H__- B" E: B# {! |) }
  3. ' S' ?. B3 H# m
  4. #include "ff.h". }' ?. o4 }! c+ B/ }  M: }
  5. /*----- standard C library functions -----------------------------------------*/* E/ r: E! B% t* N, O3 P( p7 x, B/ Y

  6.   A0 a, f# _6 P0 G, K
  7. #define LPDF_FOPEN                  f_open
    4 t4 M# c! h3 H1 j+ ^6 }2 j
  8. #define LPDF_FCLOSE                 f_close
    7 m" j6 h9 L2 J5 d/ I0 B0 |
  9. #define LPDF_FREAD                  f_read/ a- l) M  A8 U8 U' X' R' ?1 C& _# E
  10. #define LPDF_FWRITE                 f_write
    7 c" ?: S# b2 e2 d! ^3 W& f! W
  11. #define LPDF_FFLUSH                 f_sync
    + f/ h$ |. y" `+ k7 ^
  12. #define LPDF_FSEEK                  f_seek( ^1 y6 x6 L1 X7 g- `( U% e+ Q
  13. #define LPDF_FTELL                  f_tell
    1 |) X! f! k# `4 P% j
  14. #define LPDF_FEOF                   f_eof# F7 `1 X3 l; D/ W, A
  15. #define LPDF_FERROR                 f_error8 F& ^, U7 A" L. J. |# _% h
  16. #define LPDF_RENAME                 f_rename
      _) ?! }) Y9 }4 J4 r2 {/ N
  17. #define LPDF_REMOVE                 f_unlink
    ) E3 Q6 ]  G% |7 t
  18. #define LPDF_MALLOC                 malloc  f% I/ ~! w; g/ N% T4 G% E
  19. #define LPDF_FREE                   free* j$ ~6 K) X# F2 E/ E* u
  20. #define LPDF_FILE                   FIL- k5 f5 e2 Y% F- J1 s% W4 N* u1 b
  21. #define LPDF_TIME                   time: V" q3 r4 ?& t0 |
  22. #define LPDF_PRINTF                 printf$ m* A5 x/ h/ a2 N
  23. #define LPDF_SPRINTF                sprintf
    ' ~0 t7 I: V) U& e$ Q' K& u. l
  24. #define LPDF_FPRINTF                f_printf
    , y3 _5 C, x# \! Y* z, T; D: E
  25. #define LPDF_VOID                   void
    ' P- {1 g& l2 Z+ ]$ I! B1 v9 q
  26. #define LPDF_SIN                    sin
    3 a7 h0 X; y9 H# Y" G- s
  27. #define LPDF_COS                    cos
    ( e" e4 j1 i) j4 N$ ^' U" x4 P

  28. , J( f, a. b* C, D  N
  29. /*  native OS integer types */8 V; H$ r% m% u% V
  30. typedef  signed int          LPDF_INT;
    ) H8 G1 l4 z3 w' ~: d5 ?
  31. typedef  unsigned int        LPDF_UINT;  R$ i6 t6 g( R, v. ]5 Q
  32. 2 `" X2 R0 z  I2 v

  33.   d% {' C4 n$ H- s8 h% A5 b
  34. /*  32bit integer types5 l1 ^& G" s: h1 Z, K8 W2 y/ M, v5 }
  35. */( y) U6 z" B$ O7 h
  36. typedef  signed int          LPDF_INT32;
    ) ~: S' q  F( w' K. I
  37. typedef  unsigned int        LPDF_UINT32;7 [  Q; h) |/ k

  38. ; ^) c" u! q! X! [; g# a- G, R0 e/ [
  39. # ^1 ~$ L2 ~4 H' v
  40. /*  16bit integer types
    6 s5 w% l2 F3 h& q- O2 C- S3 F
  41. */8 r0 _  r0 d9 F8 w1 B% \# @
  42. typedef  signed short        LPDF_INT16;
    2 y5 ~# e4 d: z9 F  J5 n
  43. typedef  unsigned short      LPDF_UINT16;
    $ ?  R- R- O0 G2 Z# r" \

  44. # w  I7 `2 K0 _# s
  45. & ?) w  C7 r- l8 l2 W0 w
  46. /*  8bit integer types
    $ ]5 T- u: {( [$ y' n) U, w  O
  47. */
    * }' @; j: _: g# P7 |
  48. typedef  signed char         LPDF_INT8;
    " b3 i  Z7 {. E' I7 e! c
  49. typedef  unsigned char       LPDF_UINT8;
    % b( o9 a( W$ m" I* ^' d

  50. . X' z& [" K* p0 j

  51. . h( Y5 `! H) R+ G, t$ j) k
  52. /*  8bit binary types
    + J9 K  s! p# a9 {2 G0 ^
  53. */
    4 Q/ N6 c6 D% a4 U" Z: \2 `
  54. typedef  unsigned char       LPDF_BYTE;6 |: R# C" `8 }; _" V' v3 u
  55. 8 ~. Q" a! b- |
  56. . R3 [2 H" ~0 o5 E  f' m" A
  57. /*  float type (32bit IEEE754)6 z8 ~, ~, N+ m1 i% k% u
  58. */
    ; o! ^; k5 ^, }5 H' b
  59. typedef  float               LPDF_REAL;) m# v' I: L6 I
  60.   f8 a6 r  ~4 V4 n- D" l

  61. , p2 y) t' t0 s) H4 x/ M: N
  62. /*  double type (64bit IEEE754)
    1 i3 L. J6 b) W6 X, `6 S
  63. */
    + @+ u& U# M- t, o/ z# W
  64. typedef  double              LPDF_DOUBLE;+ s& J6 D  E0 I' e! [4 @1 ?
  65.   j. G& n( n$ V" g! M

  66. ; e1 k3 H/ n* u8 \" l
  67. /*  boolean type (0: False, !0: True)
    : r$ }/ y2 d0 X4 B" j2 Q; F7 D
  68. */: h8 C5 w; |( h- k6 j
  69. typedef  signed int          LPDF_BOOL;0 g/ ?- W" D+ I) L' }4 M; o

  70. ' X& s1 Q# j. {0 ~1 [. x0 }! \

  71. 6 F& O$ ?7 @3 x: I
  72. /*  error-no type (32bit unsigned integer)7 i8 L* @; g/ ~) X
  73. */
    8 ]' E% A! J" ~& `8 D
  74. typedef  unsigned long       LPDF_STATUS;; t- Q/ }3 z! U8 }

  75. 8 t$ P4 Z# a& c' A
  76. #define LPDF_OK                     0
      {% T$ l; B' _9 ?# s, y
  77. #define LPDF_FAILED                 1
    2 U6 ]- G% L" |
  78. - y" z' \# n8 w9 z
  79. /*----- font state -----------------------------------------------------------*/
    / W; c! M5 ?2 u- Q  x& L" i/ M7 d
  80. #define   LPDF_FONT_INVALID                 0x00FF
    % a6 \5 s9 H2 x+ ^. S
  81. #define   LPDF_FONT_COURIER                 0x0000
    / _; W- @8 R: T& g" v( ~. v6 ]
  82. #define   LPDF_FONT_COURIER_B               0x0001
    5 ^3 u& ^+ h! U2 v
  83. #define   LPDF_FONT_COURIER_O               0x0002! k4 }$ i1 d/ m, w( _5 e$ H
  84. #define   LPDF_FONT_COURIER_OB              0x0003
    " i2 x2 }; [' c& c7 S, m; D" A
  85. #define   LPDF_FONT_HELVETICA               0x0004
    $ p" C; s/ U! F( K' V
  86. #define   LPDF_FONT_HELVETICA_B             0x0005
    ' ]- h4 f- I; r6 w
  87. #define   LPDF_FONT_HELVETICA_O             0x0006% `- l/ a8 p" U$ C: T4 P
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007# R, p! f8 s$ l7 `0 A% M0 a4 D
  89. #define   LPDF_FONT_TIMES_R                 0x0008
    2 P: e, s2 I6 ]/ m+ z
  90. #define   LPDF_FONT_TIMES_B                 0x00098 _* K0 ~; v' y7 o
  91. #define   LPDF_FONT_TIMES_I                 0x000A' W( u6 s0 y, A0 D9 V" F
  92. #define   LPDF_FONT_TIMES_BI                0x000B$ ?* \  L& u* U5 r7 O) y8 o
  93. #define   LPDF_FONT_SYMBOL                  0x000C" H& |4 `0 y( @/ l* i4 h
  94. #define   LPDF_FONT_ZAP                     0x000D
    2 P1 s' j3 h4 \, u
  95. /*----- Graphis mode ---------------------------------------------------------*/
    ! D7 t# {5 {# b
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001# S7 |0 G6 C5 w7 q
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002: @+ f. l! T" g1 m
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    $ e, m. J: O; g3 M
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008
    ' f) Y: A! a- b9 s: b, |, @, i
  100. #define   LPDF_GMODE_SHADING                0x0010
    + b1 C3 h/ X, a# d7 k
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x00202 |2 E3 z7 a; W
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
    0 D& B) y/ D  _- Y# n# _9 B
  103. #define   LPDF_GMODE_INVALID                0x0080
    2 k6 \4 T& n, K' @3 |
  104. #define   LPDF_GMODE_OVER                   0x0100& a& m- u5 k# d3 e) Y
  105. ' b( r: t0 X7 U2 Q& P
  106. #define OBJ_MAX_NUM     256& }) z4 j" N2 t3 T

  107. 0 _# b5 z3 r+ L. V9 W
  108. /* Page的结构信息是否需要树形结构 */7 @# `, q6 B, F8 l# |
  109. typedef enum 2 v0 f- J+ {3 G/ l# [- f
  110. {9 S: F' w4 K/ U% ~" N
  111.     OBJ_info,
    6 R" P& o) f" p* ?% ~$ r4 r2 ?
  112.     OBJ_stream,
    2 T, |8 s; n. d
  113.     OBJ_font,8 V- u# S8 c: Z- f
  114.     OBJ_page,
    7 _0 A# m% i- k( U" ?  M# ?: X
  115.     OBJ_catalog,2 ~' v- F( e) R# [
  116.     OBJ_pages,7 o, y, }1 o, F+ z: N# a8 J  M
  117.     OBJ_image,
    + z3 u# E5 E$ x& C  B$ v+ h1 v
  118. }LPDF_ObjType;
    7 z2 O9 D0 i7 f( O8 J8 y( ]- Q

  119. # v" }9 G& `6 n0 l
  120. typedef struct1 G8 _7 \& E1 A1 G6 h4 r4 F
  121. {, b: D: A- [- ~1 r+ w" H
  122.     LPDF_ObjType objType;
    # H, P* S# X( u, M" {, p8 n9 w$ G
  123.     LPDF_UINT16 objIdx;
      h' g1 P! m2 g/ {
  124.     LPDF_UINT16 height;
    . j5 U! l6 `) X6 I* o  a& \
  125.     LPDF_UINT16 width;. L' o- {: ]' [
  126.     LPDF_UINT16 length;
    : L+ S; e: n+ _
  127.     LPDF_UINT gMode;" l2 t4 q' L8 |( d% z
  128.     LPDF_BYTE fontType;
    ' _$ G2 v# k9 c, q+ F
  129.     LPDF_BYTE fontSize;
    ; X& o5 ], U- k) ^" ]
  130.     LPDF_BYTE pState;
    8 T- Y4 @5 Z: T; X
  131.     LPDF_VOID *doc;3 V( j- V( j5 {% P
  132. }LPDF_Obj;8 V9 T$ L7 V0 W" f4 Z
  133. - ~" t; B1 D* y5 c5 m, H
  134. typedef struct
    1 A: k8 G9 Q; n9 u  ]- Y4 t
  135. {
    , U, V1 k' L( Y. E( Z1 _# N! D
  136.     LPDF_Obj obj[OBJ_MAX_NUM];+ ]. H/ Z0 c. B5 H
  137.     LPDF_UINT32 offset;7 h/ b& U5 ]6 i& k; ?2 [1 c
  138.     LPDF_UINT16 objNumber;
    1 [# _; e& B0 B/ y9 ^! }4 O' k
  139.     LPDF_FILE file;& X2 ~6 N# `3 A: f
  140. }LPDF_Doc_Rec;1 ?1 y1 D6 F9 F
  141. & E  \1 s& k, ^: V
  142. typedef LPDF_Doc_Rec *LPDF_Doc;/ |) G$ }; H" f
  143. typedef LPDF_Obj *LPDF_Page;. _; m( {" h3 R6 ~9 ^
  144. typedef LPDF_Obj *LPDF_Image;
      S5 o1 a9 i% c7 E& h* Z6 W
  145. extern const char *font_list[];, O+ K3 _( P( r# [( |
  146. /*----- LPDF Interfaces-------------------------------------------------------*/; Z; ]' d1 Y, j5 `9 N- m
  147. const char * LPDF_GetVersion(void);6 i) w2 c, Q/ u8 v3 G6 m
  148. LPDF_Doc LPDF_New(void);
    ' Z- v/ E" W& O9 x* _/ E4 T
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);
    . D; q" y: C3 H0 H: p9 H. C
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);5 g% m( L1 H! \( X3 a$ m
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);( M6 |& `1 Z" z  Y9 L2 R
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);
    & F  v5 M! g% F' y& Q
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    5 ?4 o9 o& i/ T2 q+ y
  154.                            const char *font_name, LPDF_UINT8 size);
    ) L7 f- f" e  I! a
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);6 u' C* h$ }" q3 p: K, _: w
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);  ^5 ]! }% `/ {- r! L! ^
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);) X, N( Q. |1 ^" A* J
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);
    3 E, ^% I4 {* d' A) a
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    # j  @0 ^7 I- _% q0 y9 ~
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);. a4 Z1 a) y2 ?" r& H7 n
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);. i/ {: }) w9 |
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);* S& e" x5 b. @# K6 E
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);4 ?: J; a6 v' O
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    8 o( f7 n9 k! O
  165.                          LPDF_INT x, LPDF_INT y);1 {! m1 l; [$ a, F- ~
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    % m& w: O6 _& {4 I- S( e+ J
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,) J$ z& z% j4 K. `. O/ C9 R
  168.                          const char *text);
    / R% q- j% p6 n8 c0 r8 a; {
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,# Y# s; [/ X: C- t& O6 w
  170.                          LPDF_REAL r,, i2 j) e; ]/ P* @# M
  171.                          LPDF_REAL g,
    + m6 i  O% f0 E- ~4 I" C
  172.                          LPDF_REAL b);( A; w) \# t5 q0 J# w
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page," |1 Z, h+ o. Z0 G0 U/ s
  174.                          LPDF_REAL r,
    3 k- l8 s. y) v/ s
  175.                          LPDF_REAL g,+ P+ t2 w: \3 {
  176.                          LPDF_REAL b);
    8 v4 S7 h: \% o
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    0 Z# f0 q# x! O5 u: E( |
  178.                          LPDF_UINT16 x,
    / [8 R9 O$ |' V8 J+ L
  179.                          LPDF_UINT16 y);
    2 F1 i7 w# W# o. U" I
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    : i' |0 O% _: p( o7 l* c( r  a
  181.                          LPDF_UINT16 x,
    ) G6 c: r) f+ Z, Y
  182.                          LPDF_UINT16 y);+ x- [6 h, L( c- q4 u
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);
    0 F, P/ i6 [3 G! i9 \2 M
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);, b2 A9 b' j  m( Y1 ]
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    5 K8 j( f/ t, v  ?  k8 R, d3 E
  186.                       LPDF_Image image,+ D- R( _6 `# ^3 A5 Q* ~
  187.                       LPDF_UINT16 x,
    ; L3 h, G+ Z. w3 S
  188.                       LPDF_UINT16 y,5 d4 l3 w, k; M5 b$ ]
  189.                       LPDF_UINT16 width,
    * o* ~$ i' Q  T* n9 ?2 a
  190.                       LPDF_UINT16 height);
    1 D7 w- X7 y- ]0 _* I
  191.                                                                                        
    $ ]/ \! q; }" x) u2 P( B! _
  192. #endif2 l. p3 q5 M; g! J
复制代码

源文件如下:

  1. #include <stdio.h>- H5 o) B: U5 J3 A9 y% q3 o7 F
  2. #include <stdlib.h>3 w' f: l& u+ x, k& K% I5 ?
  3. #include <stdint.h>3 j& h" w7 W7 X1 w0 S
  4. #include <string.h>6 ?6 z$ z# S& C, N9 P. p
  5. #include "pdflib.h"+ i- X$ N1 k; ~5 P/ h
  6. 2 w8 i0 t* G/ h
  7. #define LPDF_INVALID_OBJECT                       0x1033* J7 N3 T4 n: C  {8 v5 s- V9 `

  8. & A5 a; |( C2 C" B. `" v, w) L6 Z
  9. static char pdf_buf[512];/ g  r# Z8 f- V* t, I
  10. 6 b  H! \, n+ H7 q& _
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1") w; {* |3 }1 O! c, N
  12. #define LPDF_FILE_HEADER_LEN        15# e5 {% q0 Q7 K7 _0 d
  13. #define LPDF_BASEFONT_NUM           145 B. w2 u6 b  l. U; s3 y% X% U3 P2 ]2 }
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";! ], p; D: H$ B8 \. m
  15. const char *font_list[] = {: Z- s+ v! G3 f5 \
  16.     "Courier",
      J3 F1 ?5 X* Y
  17.     "Courier-Bold",
    * D( H; J- V1 i7 K
  18.     "Courier-Oblique",. K9 N* `% X% h
  19.     "Courier-BoldOblique",
    ! E! p- {: A- P) O
  20.     "Helvetica",; a1 G7 k3 h7 I
  21.     "Helvetica-Bold",
    * h- D  q3 i8 N2 S
  22.     "Helvetica-Oblique",
    / z7 @7 d' r: }3 M; Z! l3 N/ v  [' W
  23.     "Helvetica-BoldOblique",+ g" X3 y" a4 |1 T8 g
  24.     "Times-Roman",. I+ A. i5 c+ J4 l+ `
  25.     "Times-Bold",
    . ?( m5 D6 x) f' o# t8 [
  26.     "Times-Italic",. V# [  [3 q. y% j1 ^$ y5 l
  27.     "Times-BoldItalic",# X% v3 }* H7 C1 Q0 M; D! i
  28.     "Symbol",
    ; Y1 q& O! V6 Z5 j# m8 E8 o# s
  29.     "ZapfDingbats",* g. d# @9 M+ i& q5 k- C
  30.     NULL$ ~9 F  X$ U8 I) m# \0 O$ G( X0 q; O
  31. };, p7 B1 q6 M7 x9 p' n

  32. ! t, H4 h& I; k/ e/ _9 i4 r

  33. 3 n, Q$ `3 `! x7 N* F8 V  j# C
  34. const char * LPDF_GetVersion(void)
    * w0 \3 F7 [/ Z1 `
  35. {
    - p0 z7 U6 O4 K$ M$ j! N
  36.     return LPDF_VERSIOIN_TEXT;
    ; m9 B7 P* D. u% \% F( D
  37. }' `! h& @8 w+ D5 K8 T: m/ w

  38. $ C& n$ r4 G* Q8 J6 `; @5 p7 B: O# p' S
  39. LPDF_Doc LPDF_New(void)
    / L% W. ~0 p# K' q% C5 [
  40. {
    " f  i; m3 Y" N* M
  41.     static LPDF_Doc_Rec pdf;
    ( {" J, r: ?$ ?+ f- L) ~
  42.     LPDF_INT length = 0, i = 0;
    $ h8 V4 p- X2 }: t) V5 [
  43.         LPDF_UINT writeBytes = 0;  T. F- V& S2 u- ]
  44.         FRESULT fr;
      Y: X: F4 Q- T
  45.    
    5 P6 ^8 ], R* R/ V7 y/ b
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);/ t' t3 F  `  h8 P
  47.         if(fr)
      `% A0 q9 J' B
  48.         {
    ( I5 @: D9 x; J! F, p  w/ N
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");. f, a' ?2 p2 I" y( m7 K3 |
  50.                 return NULL;) }$ S9 U8 `# q, i5 f
  51.         }
    9 s# `! N0 T8 b# }$ h
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */0 f' x) o- q  y% n" x
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;6 \6 n: R8 t! E6 e$ A. w
  54.    
    3 U. _0 }+ I' ~0 ]
  55.     pdf.obj[0].objIdx = pdf.offset;9 v% X2 k/ A7 T4 `* u: X( y
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
    0 K  L: K4 Q* @
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);5 p6 b8 K! K. t/ i; y
  58.     pdf.offset += length;( Q* A3 y1 @4 G0 y7 y
  59.     & m5 O' |$ `4 R+ I. V6 t
  60.     pdf.obj[1].objIdx = pdf.offset;' E/ o, Z' o) R
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"
    ) M: R2 z3 H! z! l* P
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");$ {& Q+ _/ a* V5 b* v+ L
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    + u# k1 r4 I, ?8 T8 Q  t( s1 S
  64.     pdf.offset += length;
    / r* t6 A" S( {2 l( D  e
  65.    
    ; B6 Z7 Z- X7 E2 L1 V" z9 V  v% H
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    2 C( q* h3 M- M9 a/ [$ A2 \* Z
  67.     {  s; y9 h6 Z4 b* m, Q
  68.         pdf.obj[2+i].objIdx = pdf.offset;' h. m0 f' Q8 ]$ M( D* K5 @, w
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"2 D/ O! D7 o7 T3 K3 \, ?
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"2 M6 Q" h. R' Z  s' x: E  @: w
  71.                         "endobj\n\n",3+i,font_list[i]);- K$ j" j- ~) V) v4 D
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);' k/ c6 @4 z2 m8 L
  73.         pdf.offset += length;* c4 {6 v7 p: V' d
  74.     }7 {5 `; J+ r" }3 k1 o$ f7 b0 H
  75.     for(; i < LPDF_BASEFONT_NUM; i++)
    , S# L! \/ W" o
  76.     {
    ) a& Q7 g7 b  @
  77.         pdf.obj[2+i].objIdx = pdf.offset;) V' Z5 h! }6 n% ^1 Q: H1 ~
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    0 N6 }4 q- D: @
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);* l0 L) C: E. f2 L
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);; E' e' P6 K$ C7 ?  W4 p1 t
  81.         pdf.offset += length;
    $ M# h7 T+ `* t
  82.     }
    ' h1 Q" |: c! x' x
  83.     pdf.objNumber = 3+i;. l7 }( O4 F( `9 `8 }# S+ x  @
  84.   
    4 O1 w$ _1 z/ a/ R/ ]
  85.     return (LPDF_Doc)&pdf;
    " S4 [( w9 c/ ^/ V+ O9 C
  86. }
    & {4 _8 P) J' \! D- r, b
  87. . m# E" J/ Z# [3 N: j7 I8 E) V- {1 u
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    ) N, J- m# a) ^+ s6 ?, A
  89. {, W+ e& A: c' e7 E# m+ M! T
  90.     LPDF_UINT16 i = 0, child_pages = 0;
    , ]: u# ?% T: N+ \1 \6 A
  91.     LPDF_INT length = 0;& B8 n( @7 |' F* \
  92.         LPDF_UINT writeBytes = 0;
    % U+ h/ g! W& `0 D. d

  93. ! C* k7 M% \  P3 s& X/ e0 i( f  x
  94.     pdf->obj[16].objIdx = pdf->offset;
    + |$ x  |" b/ {0 q0 {1 S. Z  e
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;
    2 I  u, f5 P0 p! [* K* u2 z
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);$ h. ]7 t9 a$ j+ Z, p; ~$ d6 k
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);0 i$ o* d! y9 j; R8 p
  98.     pdf->offset += length;
    # g3 ~" q% m& b: A$ P, H# B
  99.     for(i = 0; i < child_pages; i++)2 O( {# B7 d7 U7 t1 k6 t
  100.     {7 ~8 K/ u& Q+ S1 n
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);; S7 K" s7 c. D; F2 M$ P
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);( h) s! h& K4 h% y; {3 h
  103.         pdf->offset += length;
    4 `  T' Z7 }8 u+ }5 T
  104.     }
    6 k6 z% T) }, u* ~* u9 y! T$ u
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");, d. ?- q' G0 ^% q0 M" U
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);0 E0 `- y( @" ~; [/ j8 O
  107.     pdf->offset += length;$ E4 A; x9 L) f* b* N
  108.     . P4 R6 t- l- W& W
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    9 k6 K8 n. K  y
  110.     for(i = 0 ; i < pdf->objNumber; i++)8 C- T# l& r5 L) n' I0 h9 H. z
  111.     {
    3 b$ S; w# F5 ]" W. {
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);" e$ Q& R! {/ X$ W
  113.     }
    0 G. s' z! N1 v/ f# K' g6 z( Z
  114.     LPDF_FPRINTF(&pdf->file,"trailer\n<<\n/Size %d\n/Root 1 0 R\n/Info 2 0 R\n>>\nstartxref\n%d\n%%%%EOF",
    8 L) A: J4 k5 _$ T
  115.                 pdf->objNumber+1,pdf->offset);
    3 A* j+ _0 N2 U6 [
  116.     LPDF_FCLOSE(&pdf->file);0 C0 f9 S9 ?' p4 ?+ _
  117.     LPDF_REMOVE(file_name);
    8 e" g  I! q9 o7 S6 |  f: i+ A
  118.     LPDF_RENAME("tmp.pdf",file_name);
    2 W/ \  C% u) L. y2 L6 }% P; U
  119.     return LPDF_OK;
    9 J, M- K% M5 J" ^4 Z
  120. }4 Q. R+ `! r; }, |7 c6 C
  121. 8 _$ f1 B* u% b8 C; g  s6 u
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)2 g- }' M: F( f* C$ {9 H3 a
  123. {# g* ~" d( s/ A0 F
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);
    % l$ v7 y5 S  Y! p1 p" G
  125.     return LPDF_OK;% }' q. b3 q- h! u
  126. }
    3 O" H+ R) Q- w& r5 q9 O" y$ X

  127. 1 Y% g" U; g7 T& M
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)( N4 K4 A  A0 \1 K+ q& p) [- Z
  129. {+ a0 b! |5 L+ E" c& c
  130.     LPDF_INT length = 0,i = 0;
    * E8 a4 g6 Q& t5 p7 @0 t
  131.     LPDF_Page page = NULL;
    - K% I$ U6 I# ]+ c: d% O8 m
  132.         LPDF_UINT writeBytes = 0;/ y3 H/ {0 c8 U" p
  133.    
    ! X- G8 q+ V  h* ^) @
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;& n' e& D' m9 N
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"
    ( I- t1 `: m9 t/ W
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    ' [2 v5 Y- d2 y. F; r$ E3 ?
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    ! z" @, N3 q- i' m$ _- h
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    % g% w% e. J7 d2 M( }9 u
  139.     pdf->offset += length;
    : o( o) N7 ~# p# a# R$ F- C) H
  140.     while(font_list[i])0 f; c4 p/ }# K" N; F" k- G  f
  141.     {
    - P4 [- }) `2 A# N4 ^; {8 \/ E' d
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);9 M+ i! R8 g! F
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    " Z0 r/ P; e& t0 O
  144.         pdf->offset += length;
    / I, m1 ?! g) a4 g! Z3 U# e
  145.         i+=1;
    - I- ~/ @8 [. c/ R% V
  146.     }5 i0 Q1 |2 H3 r
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");6 s; f) }* b9 S$ F; S
  148.     pdf->offset += 4;
    9 A5 q5 g& a6 [% D
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];- M5 x/ u. u0 w' N
  150.     page->width = 595;; f2 S# }- g* q' b" ~- O. K, x
  151.     page->height = 842;
    - I/ [! f  e8 B
  152.     page->gMode = LPDF_GMODE_INVALID;8 C$ O, o5 c5 f% A% A( ?
  153.     page->fontType = LPDF_FONT_INVALID;
    + w, h/ T7 P; i' h
  154.     page->doc = pdf;
    % |% T% [! e# H1 w
  155.     return page;
    ; Q$ c( Z, R2 {3 {3 I9 q7 d
  156. }
    + V& q9 N3 o5 |! I0 h2 c- a/ j. U
  157. 1 j5 r. K4 J# j5 S
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)
    " _3 O' X  h) f
  159. {
    " m) o( V6 t* O8 K
  160.     page->height = value;
    ; r5 n1 w& R5 y
  161.     return LPDF_OK;
    & M" i+ z) S% n; [1 }
  162. }+ Q# Q$ i& B) c
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    6 D8 c) x! j$ ^& @, }
  164. {
    3 x: d+ ]0 b: S/ H/ i
  165.     page->width = value;
    0 `/ K# t- h* a" x* \
  166.     return LPDF_OK;9 O* h0 X1 U" |" u' E  S
  167. }; Z! u3 C+ g) K( Z% E

  168. 1 Z( d% I% @' _( {% @3 u
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)
    % b, G0 w. Q% y& ?* {' [/ F2 a% g1 V! X
  170. {6 |) f* m1 p/ W4 R0 f
  171.     if(page)& P( @. E2 t: k3 J6 V
  172.     {
    : U; j& ?0 m3 |$ ?/ b" k" x
  173.         return page->height;
    0 Z" ?* E9 t/ b) B5 |
  174.     }( A+ q: M  ^7 H# j0 f& Z( ^, Q) i
  175.    
    - p' F: w# {4 X% d
  176.     return LPDF_OK;
    ) ]+ S4 ~9 K: L- s
  177. }
    - W8 p" S% r4 i! c
  178. 0 g( b6 }/ M$ Q7 A- d# B* S2 c. D
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    " G0 s8 l5 P) w& R
  180. {
    8 R+ n! O: s6 ^; g' o
  181.     if(page)" T+ c5 w$ j; }8 R" E9 ]- l
  182.     {
    5 Z; i' M, [7 L% r- c8 V: H6 G
  183.         return page->width;
    8 d+ {( M4 V* \8 x/ W1 X: s
  184.     }
    " z6 w0 d9 t8 p" s; p+ x3 ?
  185.    
    ) g8 E7 E& t& h* o: @
  186.     return LPDF_OK;7 y: o2 o9 q) U2 ]+ g7 {( S, L" T9 B! ~
  187. }- N+ o% [( O- C, j3 s

  188. 9 @7 O' n  h- [. K/ D& A2 e$ ?! p
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)" j* Q% H2 Y9 X5 {: q/ b5 Z$ X
  190. {2 t) }  ]3 ]% x: J
  191.     if(!page)7 C0 ?1 j2 p* c( [. w% w
  192.         return LPDF_INVALID_OBJECT;
    6 _5 G9 g7 G# B& P) q
  193.     if(!(page->gMode&mode)); z/ e2 ]" z; T
  194.         return LPDF_FAILED;2 u8 Z4 G. ?7 N9 g7 j% o8 c
  195. 3 X* C0 s% z! F1 A( e. E
  196.     return LPDF_OK;
    8 d* Q6 `1 W* t, g- e  h2 Y9 I. q- Z4 s
  197. }
    $ \" l/ B9 l. A/ P3 Y0 v/ P

  198. 0 t, m- M4 D/ k% ]$ k$ u6 M) A
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,/ V+ K& Z  a; J- u2 N4 y
  200.                            const char *font_name, LPDF_UINT8 size)' \4 Q: w' ?% G5 s. Q0 N
  201. {
    + X+ `2 T; X9 n- v% T
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;9 t  y2 S! ^* T0 P/ c3 F2 D
  203.     LPDF_INT i = 0,length = 0;# J/ v9 P) j6 R& w" \- p+ c! G
  204.         LPDF_UINT writeBytes = 0;
    . D7 [$ Z6 B8 [$ Y4 x5 b
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    % z- ?# ^# P+ Q. t3 {
  206.     if(LPDF_OK != ret)) E+ S4 C- E8 [/ x) Q# X% P9 k+ d
  207.         return ret;9 y/ O4 \4 R; z. ^* ?8 j# _+ ]4 u
  208. 5 w0 v9 ^& z' u' u* h+ e" P. C
  209.     while(font_list[i])
    7 ~" v1 J5 p5 v/ z
  210.     {
    . F4 d: ]" ]& M5 f$ q
  211.         if(0 == strcmp(font_list[i],font_name))" w) t1 I1 k: O3 m1 v) E% E! P3 u
  212.         {6 h7 \) o6 X6 A
  213.             page->fontType = i;) g6 W; R) d: o2 F2 a
  214.             page->fontSize = size;
    7 c; u% O! N1 n
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);9 |4 C3 Q2 o$ `2 W
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);3 V2 a: b. q- j& [
  217.             pdf->offset += length;( o$ m7 K% L7 M' ]
  218.             page->length += length;4 W! d; q& p) J9 \; p
  219.             return LPDF_OK;
    2 U, @' d/ G1 ~2 ~5 N9 v
  220.         }
    , y% ^& I0 C0 _7 D
  221.         i+=1;) d  T' H" a" A: l$ E
  222.     }& ]( m0 z% \8 l3 T* }! ?
  223.    
    0 C' j2 @& g7 L; t  B
  224.     return LPDF_OK;
    + X: w) [  ]" e, |' w  ^6 D$ n
  225. }
    ) p4 H3 C7 O* B$ k  T/ n, `
  226. , c& x2 t) u9 P& l4 @
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)
    : u5 l  k; S6 S( M! [7 r# f
  228. {3 `3 L, M$ G( @3 @
  229.     LPDF_INT length;
    5 D7 ~$ s5 o7 a' z. n, l
  230.         LPDF_UINT writeBytes = 0;
    4 g& o1 C2 `) c$ e0 k
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;4 v8 Q+ x: W2 L9 `
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    * r. s" R  X7 s
  233.     if(LPDF_OK != ret)
    ' a1 j0 k! [. c- ~# Q- z2 \# P
  234.         return ret;' j3 u/ g8 v) B5 \
  235.    
    0 R, T+ Q$ S; X; P  {
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */8 S) e! v/ k% Q* G  p
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
    5 F4 Y$ k$ A0 t6 t( t# _
  238.                         page->width, page->height);) y4 Z# @- G7 m! t5 z
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    # l# A, K3 n4 ~' |
  240.     pdf->offset += length;3 U' b8 R2 q( K9 Q8 o* G
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    ( ]4 m3 D4 w+ ?3 U
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",8 f% _! u+ d7 u; L
  243.                         pdf->objNumber+2, pdf->objNumber+3);
    7 m1 W% `5 d0 d9 `! h4 M' U
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);6 M6 Y- J) x1 _( b6 L( s) D& V* I
  245.     pdf->offset += length;( T, S/ x; s% M6 D# N0 q
  246.     page->length = 0;7 Y( Z) E, F6 @: |# G$ l
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;8 M# |- s! i- c: F  @
  248.     return LPDF_OK;
    5 G: K$ Y6 H1 x6 r  i1 }% f+ g
  249. }
    - X/ M8 b( L* n# k, [

  250.   {3 M0 d4 t) }4 B' s
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)& k5 o; _  u* N/ o/ ^
  252. {( e' }; a- U$ b( b1 s' {( m) ^
  253.     LPDF_INT length;
    / S' ^3 n: s  w; I" L- I1 z
  254.         LPDF_UINT writeBytes = 0;
    ) B* W3 b, a2 y2 C$ A2 ^  B
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;( n; {5 w  M0 Q( |; ~  `& O
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);3 Q* Z2 W; f# s/ r8 `0 u# K8 m
  257.     if(LPDF_OK != ret)
    2 w$ k" t& _6 v, ?. o7 O% @( q
  258.         return ret;$ x! l6 ^! r; q, Q5 n
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    % n" x  v" g1 g  J* G
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");8 V; U1 A0 f$ s3 ]. E" i
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    9 \$ X6 d* K+ M1 C$ k
  262.     pdf->offset += length;/ ^  E% Z4 N+ v* G6 q
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;5 l  H: e" S! D0 e$ Z) i
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    ( i- u* e/ w9 M5 u0 I
  265.                         pdf->objNumber+3,page->length);
    & Z0 a/ ~$ k- X8 Z
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);+ g( Z5 ]2 u5 L" Y: B+ Y
  267.     pdf->offset += length;( {0 \; R, N/ K! Q: ^0 n9 S
  268.     pdf->objNumber += 3;
    : ?/ @- w, `; _6 ?, o( E
  269.     page->gMode = LPDF_GMODE_OVER;
    . U' w, h! [3 t4 h* Q5 ^$ V
  270.     return LPDF_OK;2 l6 s- Y' e! k# }* G
  271. }/ V# U: n0 z% t3 X# `
  272. ( N4 G. {3 E2 k! e7 A0 E
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)3 c/ T7 w1 B+ w8 U8 H
  274. {+ j) q& T+ N7 C
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ) U; B, l0 J7 t5 p2 X) a
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    ! L  p7 @5 }+ j/ i: U
  277.     if(LPDF_OK != ret)
    $ ?9 x) C8 f3 u" C; K
  278.         return ret;% Q/ d1 _4 d9 N! x" m
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");- `& C' o; k+ }! V6 r5 I
  280.     pdf->offset += 3;
    3 G" ?2 X0 b1 i, g
  281.     page->length += 3;5 C1 A$ N' S* {9 F9 d6 j, B! C% Q
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;* ^4 W. ~. I6 O9 Z$ G' [6 N' ^6 c
  283.     return LPDF_OK;
    * @1 z1 \2 @, x$ O
  284. }
    9 u2 r4 d( E: \- b$ a: S
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)
    6 y0 w! n# Q( x4 F4 I/ c" ]
  286. {
    $ l- _1 M* ]0 F! M  K0 b) e
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;+ d, ^% |2 \+ j
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    , f" h- u4 E  I2 W
  289.     if(LPDF_OK != ret)4 U+ ?2 a2 R% g2 w. k
  290.         return ret;
    ( j8 N" e4 i  F5 e, A, _
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");
    ) W) @: D5 I' r2 E# o2 e
  292.     pdf->offset += 3;
    ; ~1 @+ f/ g% \5 V
  293.     page->length += 3;) y- S( j; Z' V5 ?
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    : V/ L; s! n$ e2 e2 [- n
  295.     return LPDF_OK;
    0 V  Y& ?9 ?7 i' ?+ G1 H5 N
  296. }; r# N, |% d5 _6 c  Y+ q! Q

  297. 0 ^* v: n8 \8 K( G8 M
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    ' q1 J3 g2 {5 d5 q: Z. z
  299. {
    4 g; B4 q# @2 _4 r* v% q
  300.     LPDF_INT length = 0;( p1 ^) D! O+ K4 k1 `3 M
  301.         LPDF_UINT writeBytes = 0;! V5 h" f4 q+ T3 x
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    3 j' ?- v& j1 c% @- ^- O& I% ~
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    6 G4 p0 a9 K& X+ O
  304.     if(LPDF_OK != ret)
    . {% Z7 e% Z5 H5 X4 Y2 P' h4 u
  305.         return ret;
    0 u9 |% X& U; `+ g
  306.     if(LPDF_FONT_INVALID == page->fontType)
    0 ~7 }$ u/ I" @0 L- _
  307.         return LPDF_OK;) j! \$ e+ H$ ^# K9 i* j
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);% {4 B7 e$ u& |- f- i
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    1 W0 Q; ?8 t0 B  F& n
  310.     pdf->offset += length;
    . O9 Q+ W0 M: T
  311.     page->length += length;
    ) V6 E( T# m: ]
  312.     return LPDF_OK;  G) D0 j0 Y" W! \( P6 O
  313.     / Y2 H" C$ Q/ y3 @7 z
  314. }
    + N; c2 q  `, a, y# R# v% @+ e
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,6 p( I: H  d4 }8 }$ R+ i( c
  316.                         LPDF_INT x, LPDF_INT y); ?. N( S- u, n
  317. {: j: m( K+ @& l
  318.     LPDF_INT length = 0;
    * \  g) ?# [: B+ E
  319.         LPDF_UINT writeBytes = 0;! O% I6 g  X& k, u1 g" V
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    , t5 |' {% M; j  k) S1 [
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    9 e$ t# k4 l, H+ P
  322.     if(LPDF_OK != ret)* g# k- m# P/ r$ a5 j4 k5 E& ?/ I# z
  323.         return ret;
    $ ]" A4 o) N' r8 J$ j! a
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);- p9 _- r" v7 S, @1 X! N% R, I
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    & U2 h) n, I9 ]3 X) {" C3 k
  326.     pdf->offset += length;1 Q! h7 u7 J' Z) ?& |; }+ |3 {
  327.     page->length += length;
    " F  E, o, q) D. l$ c. |

  328. # g( G. Y; y4 P
  329.     return LPDF_OK;
    3 u  n/ f! l; R! w6 v6 n
  330. }
      X$ E/ h; P3 C0 W4 S
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, ; C5 f8 y. q7 n: {) z5 Z& w. e. v% S
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,# ^8 C7 h+ o: d  w( k; t5 U; y; k4 Z
  333.                         const char *text)$ b% M$ Q2 z0 b3 n; v- s1 ~. R
  334. {3 c# S* q% z/ t3 ~6 [: R# S" m
  335.     return LPDF_OK;
    0 }. M* p5 {/ Z6 `! o- l, l
  336. }0 W4 F9 r' v* g& ?+ A2 N( |3 x# t" F5 p
  337. ; i. F+ [. K" A# J1 p' X
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    5 y6 E# A3 z2 _3 b
  339.                          LPDF_REAL r,4 l* E1 V* W& C& Z
  340.                          LPDF_REAL g,
      {4 m/ X, l4 B6 ~- O( _! J
  341.                          LPDF_REAL b)5 o# }/ L, Y  P) I" m9 Q1 p2 k& C
  342. {; e/ B  I  m  u4 g
  343.     LPDF_INT length = 0;
    % j, Q/ a/ U9 B& P4 {
  344.         LPDF_UINT writeBytes = 0;5 b9 _0 c5 [% g. Q* L4 v9 _
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;, s: n2 u% q5 e1 p3 u2 j$ m0 }" A' s
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    1 v2 H, c! }3 p, a1 f4 T1 F
  347.     if(LPDF_OK != ret)
    3 W2 w: d! [, p
  348.         return ret;
    6 q6 T6 `( D) H2 V0 d7 T

  349. 8 j- E# z  _& E7 l7 K" n8 f2 X3 ~
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    ' U+ R3 m7 B, y4 P: H
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    / O+ D9 Z1 [$ B2 G
  352.     pdf->offset += length;
    0 t) Q. r; z0 \" W
  353.     page->length += length;$ {) f- Q0 E( Q
  354.     return LPDF_OK;
    8 U+ v4 U; Z( P. H0 q
  355. }
    ' A2 ?$ Q& G1 b& O) S; Q- {6 b. q
  356. 4 Y, b8 e: y, K& ~
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    5 I  @; M  x" ^8 @' v
  358.                          LPDF_REAL r," Y' P* K. p: w: L1 [; y) n
  359.                          LPDF_REAL g,
    . H4 F- X+ N; g3 L% u; @
  360.                          LPDF_REAL b)
    ' _: i  A/ y; t7 b& j
  361. {/ c4 a/ a  j+ U  v) I; c
  362.     LPDF_INT length = 0;- {! s- Q; e3 L& q1 n
  363.         LPDF_UINT writeBytes = 0;- L3 l" d; R% a
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;: L6 R$ A4 n/ r/ c! h% C
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);4 d$ G8 z. W' k  ^$ M  }9 z  D. d
  366.     if(LPDF_OK != ret)
    5 ]& i4 R. ~$ d" `9 s5 U2 D
  367.         return ret;
    * U6 o& m; F" n

  368. 6 ~6 v' ]. a) k, g
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);8 a( ^5 ~! a" h. F1 M
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);- S# f, O8 \* w' `! G/ e
  371.     pdf->offset += length;
    * m5 d8 x$ C9 W- i/ F4 U# h
  372.     page->length += length;
    9 {4 ]/ H% q4 r. e! \
  373.     return LPDF_OK;
    / e7 s/ w% s: X
  374. }2 g  n; ]7 E7 z9 X. e  e
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    5 y8 y" N+ f% Y# D& D3 ~! ]
  376.                          LPDF_UINT16 x,
    - Q# F% D* U! w* Q
  377.                          LPDF_UINT16 y); u) h( s5 A/ S# z3 ^* F# v$ M
  378. {
    ! K9 U1 d0 ?$ N' H8 Q! C$ ?
  379.     LPDF_INT length = 0;
    9 {" j! M- I4 E9 g( C6 W8 K
  380.         LPDF_UINT writeBytes = 0;+ L3 i: A3 e# a! z3 G% r" v
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    + u" x" F& y( i+ g. J2 q/ z+ H% ]
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);/ ~% f* t. k3 C  {8 v$ f# Z# \* q0 P
  383.     if(LPDF_OK != ret)% u9 M/ s' B* W9 X, G# M0 D. I& J
  384.         return ret;3 y& B" o  \# B* q- \' D* K2 t) H
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);6 w) G+ v6 y. Z. v
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);: |8 G- }& @; _# w
  387.     pdf->offset += length;
    1 d) d3 M5 C- @
  388.     page->length += length;
      {. @4 o3 ~3 g' l$ n( L
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;- e6 a- X& B7 Y1 S
  390.     return LPDF_OK;" L7 m9 c+ l. ]( `: o- @4 W
  391. }
    6 J0 H2 R3 I* Y/ B
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    5 L4 m" q, Q3 B8 \3 O
  393.                          LPDF_UINT16 x,
    ( h' C/ N2 p; l
  394.                          LPDF_UINT16 y); r3 ?0 Z( l) j2 z- k% l; W
  395. {2 ]$ V8 U( h8 F' A7 G  ?2 W0 H0 y
  396.     LPDF_INT length = 0;& S4 r' l' A- G" f6 `, O8 U
  397.         LPDF_UINT writeBytes = 0;
    - o3 S5 z& P" ~$ J* k5 l  ]
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;+ ?* @6 R$ N  z3 j) X0 w9 @
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    ( m5 ?/ E2 u' c9 ]( T8 w
  400.     if(LPDF_OK != ret)5 U7 c" x% I3 @8 G
  401.         return ret;
    5 T) w) a* E! Q! W3 j% j/ c
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);- d8 j' Y& Q5 \  W! I% Q" s1 B; _
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);, Z$ P% g1 x+ V5 W/ J
  404.     pdf->offset += length;* {1 R: ?) w/ _
  405.     page->length += length;6 Y0 |0 }+ |+ d6 B
  406.     return LPDF_OK;
    % R, ?- a% n7 ~! L4 w
  407. }
    + _3 G) `) E' l# J7 ^( L% o' G
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)5 R( T' @7 P1 ~- M+ w1 ], [! E
  409. {" s  \( {# T! j3 ^6 ~0 E5 R: L5 K% o
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    3 m8 d2 U  s+ s9 j' ]  J% H
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    / P/ j/ a/ i- E6 w, f: D8 b
  412.     if(LPDF_OK != ret)
    # i( M( X& v8 @( U$ J; {
  413.         return ret;) e' p0 G. P0 z6 J
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    2 N1 O4 K' ^- P7 c1 B: Z" \1 h: q
  415.     pdf->offset += 2;1 {/ W5 o# t) b7 A" g9 a4 Q- P
  416.     page->length += 2;
    & c/ y5 X; y) ^& O9 r
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    " h; E" j# e: _7 m
  418.     return LPDF_OK;3 E$ e  g: a3 w" u! c& B) q" [
  419. }
    3 X! g5 n& J5 p& @8 u4 g
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,' H5 P+ C! \( s/ F/ N
  421.                       LPDF_Image image,/ l3 o* m- Z) k8 G" q8 \1 A% @
  422.                       LPDF_UINT16 x,
    $ g4 \3 M* ?% p4 l5 P5 w( X
  423.                       LPDF_UINT16 y,5 E3 c% i/ v- ~7 @1 q  ?- [- {: `- {
  424.                       LPDF_UINT16 width,
    4 g$ p  ~/ o3 e/ z
  425.                       LPDF_UINT16 height)9 G5 x! ^. `. g* C1 b
  426. {( q( y7 k; l2 r2 o0 h
  427.         return LPDF_OK;9 s) N0 X4 v  Z! ^7 P
  428. }! H/ S: _2 t0 q. D) c7 l- W; Y
复制代码

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

  1. pdf = LPDF_New();
    - U/ Z$ Y4 Z  T; M# b) z/ u
  2.     page[0] = LPDF_AddPage(pdf);
    / \! P# G8 [0 ~" ~) V- k  F* @
  3.     LPDF_Page_SaveParams(page[0]);' v" i; {" m' ^/ J
  4.     width = LPDF_Page_GetWidth(page[0]);
    6 ^7 \; _5 |7 b4 e$ M* S
  5.     height = LPDF_Page_GetHeight(page[0]);* ?3 W! o( ^2 g
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);
    6 Q6 }: }2 }9 b$ s1 L, U4 W
  7.     LPDF_Page_BeginText(page[0]);% w6 n3 t& K* u/ t1 W
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);2 O' D7 p! c; V  k7 g* ]% g( ?  N
  9.     while(font_list[i])
    + S! G7 K# s5 u% E: @
  10.     {8 }/ H# x' z" o, Q# t; r$ z
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);  P/ v. I0 L: u
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");
    " |& O" I# [4 h3 ^7 h9 t
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);3 E0 a/ E) M" m8 I' l
  14.         i++;2 r9 i% v, p& c- j
  15.     }
    9 Z8 E1 ^. J. n. h2 H- r% [6 N/ f
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);
    ; p( e) ?; S, b- k4 M- _
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());
      }+ g4 ^) {" _
  18.     LPDF_Page_EndText(page[0]);
    % X8 x1 x' ^  H. F; D3 J# T
  19.     LPDF_Page_SaveContext(page[0]);) s& R( Y- {/ O# [4 U- ~6 Q
  20.     page[1] = LPDF_AddPage(pdf);
    5 X( c& |. [& d  A1 t6 X# `9 Z+ F) D
  21.     LPDF_Page_SaveParams(page[1]);1 O# F& T1 l- ?1 q
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);& b( |' p2 ^% K) T6 H: u- ~
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    % \$ i& w; u" k6 P6 M% \
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    : K6 M& l% p% B+ E! y' d+ J2 `3 m
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);! H6 ?* p3 C' H- i2 r0 H
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    ( M9 Z5 K0 }. x+ |5 B
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);- j7 M$ w$ K$ b0 d! t
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);: O! K3 z/ Q, v; A) C& y( N( T+ f
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    ( a; J$ r9 m+ ]
  30.     LPDF_Page_Stroke(page[1]);
    ! l1 A1 ]5 Q( w
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);5 ?8 L7 O$ r# S3 L1 }
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    9 ]& c+ z- [1 ]8 |' K$ W
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    , C& p' ~! F6 y" L9 c0 _% K
  34.     LPDF_Page_Stroke(page[1]);
    : {7 X- q$ h' F; w* R  V5 ]
  35.     LPDF_Page_SaveContext(page[1]);
    7 X9 Z/ c) N1 {& j$ c0 @; d
  36.     LPDF_SaveToFile(pdf, "/red.pdf");
    $ m( c3 S; n5 e  Y! I8 o
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    4 U8 Q1 X! K$ z3 \  ]# n% S3 F/ s
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了
+ a3 W- j+ h6 ?! o6 C' w

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    1 @7 C9 `3 `: z' R

: x3 y8 B( p/ |

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
1 v) p9 T# {6 B* c3 p6 q只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...

3 f- ^& K* j( R9 DLZ,我怎么没看到有添加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/ a' ~3 Z& ?6 y5 X2 P& l7 Y
首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...

4 H' B# @5 [9 O, `9 X9 V/ H2 s$ l3 m66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思0 n2 T3 f1 B/ ~6 I) h9 j
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
: _* r8 W# C0 @; P2 F看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
$ u) M% W- b, ~  s
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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 t, [3 m! [5 e, T: U7 s7 }厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接
: M' A7 O: ^8 o9 y3 v
这个还只是一个简单的库,实用性还是差一些的
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
3 o0 a  f" R, w" J1 U6 xff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
% U2 w" Q  h4 q$ ]
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
% x0 ?( ~/ f" B. H$ R! C0 pff.h是FATfs中的文件
2 d$ T) Q8 r' r. a
嗯,这个画线能改变线宽吗

所属标签

相似分享

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