请选择 进入手机版 | 继续访问电脑版

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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 ! ^5 s+ b; E9 e. p# C

2 n0 M4 n* t* J2 O- D% U( 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__8 y& U- L* O% W8 V+ o; L6 ?- f
  2. #define __PDFLIB_H__
    - K6 K6 P- R2 s, w2 [

  3. # `1 ?/ g- w, ^" m5 C
  4. #include "ff.h"8 Y7 j! W9 j0 V/ D
  5. /*----- standard C library functions -----------------------------------------*/
    0 W  M5 m% m: J- l8 q6 H& ?

  6. / v, i; I; p$ S2 }
  7. #define LPDF_FOPEN                  f_open
    ( b# a" f: P& |$ F
  8. #define LPDF_FCLOSE                 f_close
    * {/ m/ F% z0 s
  9. #define LPDF_FREAD                  f_read. D' S- H* c: C
  10. #define LPDF_FWRITE                 f_write
    2 Y% b6 c' R1 A" Q1 ^: N6 B; ~
  11. #define LPDF_FFLUSH                 f_sync  m" m7 ?( L' j! H7 y
  12. #define LPDF_FSEEK                  f_seek
    $ f0 @+ o8 T8 @; K# L; w  O# o
  13. #define LPDF_FTELL                  f_tell. P: S& R. g: v. m: n4 W
  14. #define LPDF_FEOF                   f_eof- Z% d/ T, f8 ]5 t; m) F
  15. #define LPDF_FERROR                 f_error
    7 |2 Y5 J; L/ Q5 t# w% q. }' ^+ E
  16. #define LPDF_RENAME                 f_rename
    ; ?5 l( Z$ j, e' s: I
  17. #define LPDF_REMOVE                 f_unlink4 J6 r, k1 i( t
  18. #define LPDF_MALLOC                 malloc
    / _3 T$ F. J+ C* r6 f
  19. #define LPDF_FREE                   free
    1 p1 M  V3 m7 H
  20. #define LPDF_FILE                   FIL
    4 }; z7 f3 U2 R/ W- L8 Y: m
  21. #define LPDF_TIME                   time
    ! A  Q1 b/ N8 E1 U" u+ N8 J
  22. #define LPDF_PRINTF                 printf( j3 |3 W3 {4 f* g- ?( k$ `6 @
  23. #define LPDF_SPRINTF                sprintf
    & v3 s$ r8 G  h/ n. }
  24. #define LPDF_FPRINTF                f_printf
    3 L- ~( B& l2 s- M
  25. #define LPDF_VOID                   void/ w4 q0 }0 _1 s: [7 t1 r
  26. #define LPDF_SIN                    sin% N  o0 L; R5 k* j9 `; ~
  27. #define LPDF_COS                    cos
    ' i. k/ f" |: R0 s
  28. 4 E: V4 O( r) |* g2 C; q" t
  29. /*  native OS integer types */' |7 b8 H; P' U& r
  30. typedef  signed int          LPDF_INT;0 w$ w# ?0 l/ S" {5 p
  31. typedef  unsigned int        LPDF_UINT;
    : q( a& V- @; \9 A  U

  32. 5 n' k# C/ m5 u' z1 T, i7 A

  33. ) `" M3 w0 t- b) H
  34. /*  32bit integer types
    9 C' p" b# {! h! B5 C: h
  35. */
    & w  |( ~( {: O
  36. typedef  signed int          LPDF_INT32;) ?4 ^, U  p; L8 j+ W& Q
  37. typedef  unsigned int        LPDF_UINT32;9 d+ G* C9 w- m# D5 k; M
  38. 6 N3 v) V, [1 }' _, E
  39. ) k% S; f/ o; U  s  g
  40. /*  16bit integer types
    8 r$ U# \! B! y$ \' q
  41. */
    5 W% Q; \: V) z3 i7 g( X' N6 H! Q# j7 x
  42. typedef  signed short        LPDF_INT16;1 {. T' n9 Z0 c( Z1 h
  43. typedef  unsigned short      LPDF_UINT16;
    / K, u& ]5 o+ w
  44. + F/ K) B7 I, j* ]

  45. 9 o) n: p. G6 t
  46. /*  8bit integer types: u1 E3 k% h1 x6 D% c
  47. *// [4 l) j: E6 ~# s+ F; K9 v
  48. typedef  signed char         LPDF_INT8;  |$ u# K7 i( n
  49. typedef  unsigned char       LPDF_UINT8;
    " x# K9 @/ q0 o$ B2 q, E! l
  50. 5 w$ C" P  R$ R+ ]2 F- X
  51. / K$ R4 V; k! @* A; q
  52. /*  8bit binary types8 y9 @3 _& S6 j! H" ^! f
  53. */4 u- z8 ]5 _' M+ K+ g
  54. typedef  unsigned char       LPDF_BYTE;
    + v4 Z' b7 Q0 V2 V) @

  55. 7 J5 ?- K& O* Y" o, w% q
  56. , t9 x& I. X6 {8 A
  57. /*  float type (32bit IEEE754)
    # V" U- d" I/ ?( {, Q2 S4 b3 H$ y
  58. */" x5 C9 F! i! M2 C+ O
  59. typedef  float               LPDF_REAL;
    9 J: y; I) W$ ]: F. V% i  g

  60. 7 j& a" A3 H! Z- N$ C
  61. ; M5 s' @' s2 @
  62. /*  double type (64bit IEEE754)
    ) l7 P  W2 t  s: D0 S
  63. */6 M6 {3 V; c: N) v
  64. typedef  double              LPDF_DOUBLE;2 c* M: _; X( m2 X0 u0 A( Q, g4 H6 ^

  65. % A/ }! K$ f3 W. M, b
  66. % a2 ~+ \$ S; V* r0 E8 C$ g+ {
  67. /*  boolean type (0: False, !0: True)
    - H- @4 Z$ H* V/ s- O1 ?6 d
  68. */
    4 n' }' J0 Y  Q6 k1 I8 z+ L
  69. typedef  signed int          LPDF_BOOL;) f' P: m/ ^6 ~4 p7 K) W1 W+ R1 e
  70. 3 b* @0 U/ B  c: p; P
  71. # P8 q4 y+ h# I: u# N2 q
  72. /*  error-no type (32bit unsigned integer)/ C1 S5 [! ]5 ^' A/ g( M% I
  73. */8 L4 {% i& ^1 b6 M
  74. typedef  unsigned long       LPDF_STATUS;
    / p- |1 ~4 f5 S( U
  75. $ F, @& o9 H, @' L$ H
  76. #define LPDF_OK                     0
    / g; i& u4 w6 R) e9 j1 d% d; o2 }
  77. #define LPDF_FAILED                 13 A, g+ ]4 p4 ~! L. q2 A8 K. x

  78. - A- y; w& y3 D6 V% ^: }
  79. /*----- font state -----------------------------------------------------------*/
    ; M  X- ^2 r& T# h! P& U$ x* d
  80. #define   LPDF_FONT_INVALID                 0x00FF# d$ G6 L8 j0 d- I; H- z+ W# u9 l; }
  81. #define   LPDF_FONT_COURIER                 0x0000
    % n* S' O/ T" ]. ~5 F3 D: l1 ^
  82. #define   LPDF_FONT_COURIER_B               0x0001
    , p' R# G) y7 Q' T* R4 Q
  83. #define   LPDF_FONT_COURIER_O               0x0002% @) {- d; _5 c1 N8 B' g
  84. #define   LPDF_FONT_COURIER_OB              0x0003, `' D5 ?0 ~$ N9 l+ I# {0 o$ \
  85. #define   LPDF_FONT_HELVETICA               0x0004
    + \; t4 ]6 _6 G  T: l
  86. #define   LPDF_FONT_HELVETICA_B             0x00055 J" o5 G) |* n# q' |
  87. #define   LPDF_FONT_HELVETICA_O             0x0006
    # S+ l! I8 U$ u6 ~% V
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007/ m7 H, r. k+ J6 l, s, D
  89. #define   LPDF_FONT_TIMES_R                 0x0008
    ( S$ |4 c3 i# Q- O2 H0 q  p
  90. #define   LPDF_FONT_TIMES_B                 0x0009! b; Z5 `; r; |& @) |8 y4 f
  91. #define   LPDF_FONT_TIMES_I                 0x000A8 R9 _( u7 v; J
  92. #define   LPDF_FONT_TIMES_BI                0x000B+ R& \5 [7 W9 G0 ^* L
  93. #define   LPDF_FONT_SYMBOL                  0x000C
    - c; r; c6 A* {7 l* |
  94. #define   LPDF_FONT_ZAP                     0x000D
    , q6 Y! ^' \* @8 q& Z
  95. /*----- Graphis mode ---------------------------------------------------------*/
    ' ?% S9 ^. `# T& z' D$ R: @
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x00013 `( ^( P0 n" v) k: o! J
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002+ M9 N5 K; K/ X  C; B
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004+ K# {5 x; j  X, b9 U8 J$ V/ g
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008
    " {2 @2 k' p3 U6 @& P6 _
  100. #define   LPDF_GMODE_SHADING                0x0010
    4 T% c$ Y% _+ F
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020& d" l7 f/ l% k! i" Z
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040: @* Y5 l, w8 |) x, m! M5 t
  103. #define   LPDF_GMODE_INVALID                0x0080
    9 z6 |8 l9 s# k9 `+ S- N% L# M
  104. #define   LPDF_GMODE_OVER                   0x0100
    ) e/ ^, C/ d( \+ J' |

  105. ) e- R2 P( C  P2 U: D* P) Y( ]
  106. #define OBJ_MAX_NUM     256
    % P0 y" A& x5 i, }

  107. ! j0 s+ t" u5 U4 a6 \
  108. /* Page的结构信息是否需要树形结构 */) T2 X4 }+ G4 K1 j' h8 x
  109. typedef enum
    ( J1 G  s2 v! g7 v, V
  110. {
    + l. V* B! ?1 D( w7 @8 d" b
  111.     OBJ_info,0 G2 d: G0 x" V" l- P# F( n% K
  112.     OBJ_stream,$ M6 i, d6 U5 v
  113.     OBJ_font,
    " |! N7 u- Z; e6 ~* v& g9 y: s
  114.     OBJ_page,
    ' a) K9 V% Q6 o* u
  115.     OBJ_catalog,7 e+ F2 t/ f7 ~1 f
  116.     OBJ_pages,  u/ a* [) ]% W/ Y0 O7 {
  117.     OBJ_image,
    5 w# F2 Q3 R5 `
  118. }LPDF_ObjType;. s/ M0 o0 S9 \2 w+ J

  119. 2 ~2 s+ v/ \- `4 _! X4 k2 h" p5 x
  120. typedef struct0 o5 V) ]3 K6 x3 i* n$ n
  121. {
    0 [6 X$ G# z, C/ n- b* Z
  122.     LPDF_ObjType objType;
    0 _- g7 C- i0 M/ y
  123.     LPDF_UINT16 objIdx;  W9 @. }1 T- Z: _& f% V/ D
  124.     LPDF_UINT16 height;" A  F8 y6 F& X( z" ?
  125.     LPDF_UINT16 width;
    ! g2 ~, G8 |- b; [2 U: T
  126.     LPDF_UINT16 length;/ T) b0 x  ?" Q4 b7 c/ t
  127.     LPDF_UINT gMode;3 P. K  w: {8 Y" D
  128.     LPDF_BYTE fontType;8 |' Z0 u" V4 O& l1 u1 n# h
  129.     LPDF_BYTE fontSize;% s8 T3 d5 P; S" A% `8 Z0 @% E8 z
  130.     LPDF_BYTE pState;4 P- u, ?( I) d' P' y- o: x
  131.     LPDF_VOID *doc;
    ! a7 o6 _% S( |$ J
  132. }LPDF_Obj;
    1 n- y! ~7 Y( S- q! \

  133. 6 w, x% H7 @7 z/ s* F+ V8 N
  134. typedef struct
    * ~6 e8 R5 V" i- o( ^
  135. {
    $ i( ~7 p; b# v% \+ h! d
  136.     LPDF_Obj obj[OBJ_MAX_NUM];
    " N& p+ V/ P# q  r" |7 B
  137.     LPDF_UINT32 offset;1 _+ K* y& V" z9 `- a4 l( `6 a
  138.     LPDF_UINT16 objNumber;" Y  f1 s% Z, t6 ^* |3 V. T+ Z" J
  139.     LPDF_FILE file;
    + k% n$ Y7 p# K3 O: I
  140. }LPDF_Doc_Rec;
    . }3 ^* B1 n0 A

  141. 3 d9 G7 A3 N" ~
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    9 p4 J4 p7 g( t& J# H
  143. typedef LPDF_Obj *LPDF_Page;! T7 O  d0 a. v* ~) A, r+ G
  144. typedef LPDF_Obj *LPDF_Image;9 G; w& P% K' ?+ U0 c1 d# y; \
  145. extern const char *font_list[];1 M& U: C- n- M" T3 h
  146. /*----- LPDF Interfaces-------------------------------------------------------*/8 ~% ^+ B6 ~, `3 @9 K" Z: S
  147. const char * LPDF_GetVersion(void);2 k: w$ H2 D& d9 H/ E6 k8 e7 `
  148. LPDF_Doc LPDF_New(void);# Y* x) N3 ~7 y$ V( t' A
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);2 @3 w& l1 N( l
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);
    , ]! ^0 A  @0 S8 s! ]
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);
    5 R5 o# G) A4 B1 b0 p: S
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);7 x$ Z6 |* g. b8 l/ G( u7 w, @
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
      X2 q  ~; t6 a( a  K7 H
  154.                            const char *font_name, LPDF_UINT8 size);  [/ X1 z  J% H! p. w; k
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);: T9 N% k) S- o8 k  J6 O4 _
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);& u, C3 f( q) _" ]+ v
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);; z8 `2 ], u  Q& q- X: H0 h
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);# G1 M% _  d! b  S, e% ~# z
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    + ~! W9 P1 n- R5 s6 A' f  o$ X
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);- u3 ?) W4 c: x& Z( |
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    * Z1 @& F/ D1 X4 d- o( V, i: k
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);  R* W/ t0 T! ?& j( o( A( Z7 l
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);
    ! m, r+ p6 {: Y5 Q
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    4 H9 n: t* j/ d8 a, b9 x/ [0 J$ e* ~
  165.                          LPDF_INT x, LPDF_INT y);
    3 y6 H3 |/ c0 A2 N' }% l3 Q! x" m& x
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,   z0 e6 j6 ^5 B) v" `4 V4 Q
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,
    2 ]' _3 N: ^8 S. {
  168.                          const char *text);
    , \1 w) j* J: s* s0 h! o% q
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    * y& M/ b$ K' @4 \
  170.                          LPDF_REAL r,) q( p2 E5 _% g
  171.                          LPDF_REAL g,% y% t5 G5 Z9 a9 t7 q
  172.                          LPDF_REAL b);
    ( c& N, d( F  `" L0 p, m( O& o: l
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    0 ~4 n( `9 q: }3 Q
  174.                          LPDF_REAL r,
    - ?, y% S8 w* B& ~' W/ l/ f
  175.                          LPDF_REAL g,0 q; o) b. h' B3 K3 Y
  176.                          LPDF_REAL b);
    ; E! x2 f: Z8 Q$ N* Q
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,9 z4 V7 f& m4 C/ w/ g( R! _% z" F# E
  178.                          LPDF_UINT16 x,
    # l6 s. c2 q7 `+ W2 `
  179.                          LPDF_UINT16 y);, K6 ?" b. V# \
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    # q; S& J4 ~3 _( G+ W
  181.                          LPDF_UINT16 x,) {3 S6 r8 O$ ]$ r* O
  182.                          LPDF_UINT16 y);. T) y( I; V8 K8 j
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);0 Y* I, [" S2 j. M6 @& g. Q; e
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);7 x# Y8 p) s% v; p% ]
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    8 _" V; [. d& W# C% Y* }' j1 _
  186.                       LPDF_Image image,
    ' n9 T& o" k$ w, H
  187.                       LPDF_UINT16 x,
    ; `' T9 {( S" }9 }
  188.                       LPDF_UINT16 y,2 Y3 x) A6 _) x3 j3 k# y# j
  189.                       LPDF_UINT16 width,' A# g7 E3 E% }- D
  190.                       LPDF_UINT16 height);
    6 O8 o5 {5 I" n
  191.                                                                                         . ], ~1 A2 @6 E2 a0 i( o! ~0 V) z
  192. #endif
    , D: R, B# q9 ?# u4 w+ ?
复制代码

源文件如下:

  1. #include <stdio.h>
    ( |4 W1 Y1 X, o1 T9 X9 x4 f* v
  2. #include <stdlib.h>$ Y  m, b$ B1 I+ Y8 F) W* q
  3. #include <stdint.h>  x2 S1 r, b3 J
  4. #include <string.h>
    ! D; x+ R% H- t( d
  5. #include "pdflib.h": V: ~- @2 i1 X

  6. 6 R. ~; i, B) i6 E. N6 W& ~
  7. #define LPDF_INVALID_OBJECT                       0x1033
    6 P& _3 r2 T9 _9 t2 t6 ]
  8. - o; v) Q% X. q% h- N
  9. static char pdf_buf[512];% \/ E$ ~+ Q& ^2 T# i3 b
  10. 9 Y5 N; q2 Q5 q8 _
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"# ~% t4 |& Q' ?9 q
  12. #define LPDF_FILE_HEADER_LEN        15
    ' I& M4 L- h$ R4 y
  13. #define LPDF_BASEFONT_NUM           14! B; L0 H( Y; J+ c) R7 h, I
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    : G  g4 F- u% M
  15. const char *font_list[] = {. Z% d9 H1 [- A4 g% C! b2 B
  16.     "Courier",% A+ t. f& J8 X! B" @: F
  17.     "Courier-Bold",! c0 _: M1 j7 P
  18.     "Courier-Oblique",
    9 Q, W# x( B2 G# ?' f
  19.     "Courier-BoldOblique",
    ) @. x/ t! P. e8 o
  20.     "Helvetica",& F* V! q/ Q* R  W: p
  21.     "Helvetica-Bold",
    6 `# Z( l! z3 o, s& E1 h
  22.     "Helvetica-Oblique",
    ! F' G. Z/ ?( t# B& d7 B  J8 S1 _
  23.     "Helvetica-BoldOblique",) X7 L4 T1 N, S: k  j% {
  24.     "Times-Roman",' p- |! [% a9 F! d2 O
  25.     "Times-Bold",
    " _8 A6 a8 y+ A: d+ Y0 E
  26.     "Times-Italic",
    : ?# \' B  R) \9 j- U2 f3 u* }
  27.     "Times-BoldItalic",
    9 l/ F; m' p* r# x" A5 e
  28.     "Symbol",
    1 c# H, T+ b0 l5 n% {" R
  29.     "ZapfDingbats",' d( ]# L8 e3 _7 M" B$ g
  30.     NULL
    " @$ E( W% t( w! G
  31. };$ Y( i; q+ E6 X6 x. K6 Z

  32. ) l, T' P8 Z1 s4 M+ |. t

  33. 5 D! U- [& S/ s: ?/ W+ t  e$ t
  34. const char * LPDF_GetVersion(void)
    3 i: v# e( E' @. R5 y
  35. {
    - r. B& z. Y6 L
  36.     return LPDF_VERSIOIN_TEXT;
    0 a% B2 I" r2 N. u, E. i$ Y6 D; N
  37. }
    7 l& G3 c0 l$ K8 }9 x# |

  38. ! V, V& u/ J' a
  39. LPDF_Doc LPDF_New(void)! n4 ~0 W/ Z2 C# P
  40. {
    ! N* l( J' w1 D: h8 e- C' z) h9 v
  41.     static LPDF_Doc_Rec pdf;
    : k# t8 l/ V1 w
  42.     LPDF_INT length = 0, i = 0;) ?2 A2 s1 {7 n# a' A/ |. D
  43.         LPDF_UINT writeBytes = 0;
    . |7 V3 B. k3 H8 `( ?) n5 y
  44.         FRESULT fr;# K% O1 q7 I- F! B3 ~9 A
  45.     " k- o! Z: K. J# ?
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
    5 O; h, Y# k( m$ x1 X. |
  47.         if(fr)2 z: U8 e6 n- q9 B
  48.         {  q  d2 t- W9 \4 M+ [5 w
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    + M/ o) N6 l! e; k: w& P2 e5 F
  50.                 return NULL;; o* g3 L, g3 V( r- Z
  51.         }- p- X1 ?+ Y  J6 ?# S# O$ d
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */
      v: Q8 A  w. E" z& G, y: E3 b4 D
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;
    # P0 ~! e" X+ x
  54.    * I: R7 Q- J3 v; Y
  55.     pdf.obj[0].objIdx = pdf.offset;
    % A' o2 ^& Y. Y. }  f( O7 M
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
    ' c! @  \* R$ {8 Q
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    - F) v9 T/ _( Z9 |: v0 J' B
  58.     pdf.offset += length;
    ) b5 W: K0 x4 P; a+ |, T, ~; Q. c
  59.    
    2 A/ w$ l, ]; t6 ]8 \1 l
  60.     pdf.obj[1].objIdx = pdf.offset;: m/ o  _2 {( V' G5 ?
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"9 O9 H& `& f2 z* E  B
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");
    $ @& E9 d6 y+ S7 u
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);/ W3 B& g% \7 t3 e8 Y
  64.     pdf.offset += length;& G+ A6 z# I' P9 i) M
  65.     0 r8 M2 J0 c, v& }
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    7 h) i) o  G  k3 k! e+ ]8 c$ S
  67.     {
    , }- L$ C/ H. Y! [" B
  68.         pdf.obj[2+i].objIdx = pdf.offset;% f' h' Z# m; y; Y5 ~. g
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    ( E9 G) d1 j  q0 o9 T, j) D
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
    5 e+ `& X$ A3 P2 A4 r% @: l7 W: `9 B3 o
  71.                         "endobj\n\n",3+i,font_list[i]);& b$ `( G! \# z, I, W
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);& \( g# X4 I" |8 S/ h9 N* U$ Y! @
  73.         pdf.offset += length;
    0 B( [# k3 q9 N# K" Z  L- ?
  74.     }2 `5 F" q9 i- P! P  R* H
  75.     for(; i < LPDF_BASEFONT_NUM; i++)' v4 h: Q- c5 B9 Q* P
  76.     {
    ( [5 M* y7 ^4 x) L% L8 d
  77.         pdf.obj[2+i].objIdx = pdf.offset;
    6 A5 R" o2 m# C! J( ?* {9 I4 c
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    " x* [" F* d2 C5 g' @
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
    / z+ E: L6 J4 ?" ~* x
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    7 \$ V! D6 Q, j: W' k
  81.         pdf.offset += length;  y4 \6 [' ]% p$ F
  82.     }) h9 k: p7 k1 G+ g. N( j
  83.     pdf.objNumber = 3+i;
    8 p' Y" u( C  b2 J6 \# {" |& M
  84.   $ l) T* \! _% R& \/ H3 d' ^2 N1 \$ x
  85.     return (LPDF_Doc)&pdf;
    8 l7 P8 v$ k4 G3 k: q, i$ x9 Y
  86. }9 y5 G8 F2 o$ R  z- i8 I, L) G. S

  87. 6 F6 |" k; `5 K8 c& }" n7 ~
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    0 N  z4 T1 N) k7 D! N; n
  89. {
    : n  g3 T7 g/ R
  90.     LPDF_UINT16 i = 0, child_pages = 0;2 h5 m% u% q5 p. J; ^' {+ P" M/ C
  91.     LPDF_INT length = 0;0 R4 N3 P6 _, N* a& e; b
  92.         LPDF_UINT writeBytes = 0;1 z) s0 D0 w7 R$ m: b

  93. " n3 B4 c; j5 V
  94.     pdf->obj[16].objIdx = pdf->offset;
    0 p' }5 _6 U, t& r
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;
    7 d  S' C! f% i2 ^7 M+ `
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);
    9 C8 @8 p4 ?9 \( P" r% m) J
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ( H7 t+ q0 y! T# L
  98.     pdf->offset += length;
    1 d4 W. a/ {3 p/ R" y/ |0 g
  99.     for(i = 0; i < child_pages; i++)
    " ~. _9 M8 [) K6 e$ s) l6 Q" p
  100.     {, Y5 E& n) k& b9 k6 T
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);/ }. ~% i1 _. m/ z
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ( S0 {" {$ {1 f" T- [2 V1 [! S. f2 G
  103.         pdf->offset += length;4 t5 c. E, G% D
  104.     }
    4 Q! E3 ~! k0 h
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");
    * M' n1 J7 d2 o# p' E' H
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);6 A* Q1 D4 B6 y
  107.     pdf->offset += length;
    % _5 k0 H$ z# C8 L! v7 e7 [9 k
  108.    
    0 U1 X6 z+ y2 U0 b4 ?' [
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);0 u# b+ J6 V+ a, M  e  V) V3 r
  110.     for(i = 0 ; i < pdf->objNumber; i++)& a- y* n. n" h0 R/ q8 s: N; K
  111.     {
    " ?8 e. C' z2 @
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);. |9 T6 y3 u9 m* ?- a7 d* ~# a
  113.     }
    5 z# k% x0 S8 ]( 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",
    6 ^* n+ w+ T8 h. ~0 K1 i
  115.                 pdf->objNumber+1,pdf->offset);
    ; @8 R6 u' S. P
  116.     LPDF_FCLOSE(&pdf->file);
    ( r+ D  E  ?0 G6 \( U( v. X, J) I
  117.     LPDF_REMOVE(file_name);
    9 W( t( X: ^3 \/ i$ X1 c
  118.     LPDF_RENAME("tmp.pdf",file_name);
    9 J) p0 F9 G" Q. s
  119.     return LPDF_OK;+ t% q7 o: w; G/ L
  120. }
    8 C1 p& W  Y  ]

  121. + I! b6 R  L* U+ e& ], Q
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)
    , S5 w/ K1 Q$ T: J0 v4 N: I
  123. {
    / x9 D* P* M! Z
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);& [9 _0 A# \* a" _
  125.     return LPDF_OK;9 N+ u- w. C+ Y; B  G. N  M/ u
  126. }& I; D+ t9 }: ]9 }! B' ^1 v' C) |
  127. ) Y2 B1 O- r" ^
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)
    . S  ?9 U) U9 @/ |; h
  129. {
    " f6 R3 |# r, Z* {0 C% H
  130.     LPDF_INT length = 0,i = 0;' D- i) ^# u. [: o+ f
  131.     LPDF_Page page = NULL;
    : y: n: a# \) D+ Y( a8 t+ ~9 d
  132.         LPDF_UINT writeBytes = 0;
    " \, O- b# X: P3 a
  133.    
    : M" M9 s. s$ X1 ~7 X& k2 Q
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    . E7 z! [+ x& E! @- W$ w
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"% ~8 Y7 U; ?& Q$ x1 G+ d
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"$ e7 K8 t- I+ |  C9 T, B2 C6 ?9 K0 U
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    ! o2 t2 ]3 ^2 w# N
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);' j6 p& n. m9 A1 F* P6 R' f
  139.     pdf->offset += length;
    % p- U0 _( n) X% {
  140.     while(font_list[i])
    % H' D3 ~+ H  }4 v7 n
  141.     {
    3 w6 o5 \! N  p  m, Q
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);, ?4 ^: x2 [8 i
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);. o' l! i6 \5 e( n( r; p  Y6 M; B
  144.         pdf->offset += length;% S. J3 v4 F6 C2 x
  145.         i+=1;
    * b0 Y" g& U: m8 L; p2 C
  146.     }
    4 O! Q# X5 s' [+ E6 g8 f8 b
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");
    0 s; {0 g" q2 p. |- }2 N& U
  148.     pdf->offset += 4;$ ~5 k3 y7 |) W. H# }9 x
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];
    7 R4 r  A* l2 n5 v$ @) j
  150.     page->width = 595;
    3 B  r+ X1 [/ @) m% e/ ]
  151.     page->height = 842;
    5 J. W/ _3 Y' a' n
  152.     page->gMode = LPDF_GMODE_INVALID;
    / J8 ], @$ D$ ?8 h$ r+ m9 y! t0 ~
  153.     page->fontType = LPDF_FONT_INVALID;
    + ~9 I0 ~: M" c7 ]2 O
  154.     page->doc = pdf;
    & J2 y9 d% @9 Z; N3 B  G9 ~
  155.     return page;
    & S( K$ M% O2 ^9 K( Y1 I
  156. }
    3 i. m7 @; |8 q" J7 F0 Q, g
  157. : |+ W) r, @& h# R, B7 H, r
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)
    5 |- P7 ~  v$ W( b$ T0 S, o
  159. {
    . {7 v, L" i& \: v/ P# W
  160.     page->height = value;
    ( K! ]( Z8 Q+ _5 W
  161.     return LPDF_OK;: v  U8 m8 ]! c. ]3 h
  162. }
    . G1 D! R3 b: m4 E
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)" _0 ?  b' `6 E! k# i  k+ ]& l
  164. {
    - Y% a5 L: f; ?! E: f" r# X
  165.     page->width = value;  G) {' l4 `) p$ I' }2 P8 z. A
  166.     return LPDF_OK;. f/ ~. r* o* R0 c) p
  167. }
    / P& A/ W& c% g; a7 t4 d

  168. ; E2 |* L7 ~2 z3 Z; h; t) m
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)- i- Q* [" J/ z1 h7 e
  170. {6 `9 P8 w# Y1 V, C
  171.     if(page)6 I! d' _8 @/ z/ m6 e# ]1 ?
  172.     {
    . P# O) K6 H* `( B" F# L7 q7 {
  173.         return page->height;# ?0 {2 |5 a2 |& G
  174.     }) k( k: d( G+ Y% j: @1 T2 Y
  175.     0 G+ p& }0 {3 ^: V" J8 N! ^
  176.     return LPDF_OK;
    0 y3 y" q' A/ K' Y) I
  177. }( K3 g" G+ S! y" h( }$ l4 n) R+ a1 q$ i
  178. 2 \2 l8 O% q8 |
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)+ c. V. v; ^& `5 \9 K
  180. {
    $ H4 T& {; n. a9 F
  181.     if(page)
    + e# R; ~8 B) _1 M% n  v- b
  182.     {* w6 `: s9 o2 l+ _+ W8 @# q6 V
  183.         return page->width;
      e, J# ^4 F/ j7 J
  184.     }/ ~! m& ?( S8 h: q9 p/ l
  185.    
    + g9 ~( K; \1 ?
  186.     return LPDF_OK;; Z$ ?! z+ |6 h$ t
  187. }6 @) I0 s! d" x/ @/ f1 X
  188. & I: W5 ?# q5 j& {% r+ Y0 y
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)
    $ T& r1 K" z1 ^0 G! I
  190. {
    5 T% ]4 X& r" G+ _
  191.     if(!page)1 [6 `! B' k( J
  192.         return LPDF_INVALID_OBJECT;2 K! w1 _4 |+ v# B5 Q  t
  193.     if(!(page->gMode&mode))* Z1 y0 v" s4 \6 v$ n, m
  194.         return LPDF_FAILED;
    2 l1 u1 e9 s" [9 G1 k

  195. - w: w8 Y/ O5 D5 Q' j0 g/ b
  196.     return LPDF_OK;9 }1 v3 `8 }6 @5 H$ f
  197. }
    ' ~  `, s: g0 J# q" m
  198. ( @, G/ }0 y9 D( V6 r6 B  q
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    : a  \, l: V' q! F4 m1 O( M8 Q3 l3 G
  200.                            const char *font_name, LPDF_UINT8 size)
    ) h3 u5 f  b: B; m) I* \. W
  201. {
    : R/ S' N% |, K' ]/ s
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    1 F) }- z1 R/ ]% G7 u
  203.     LPDF_INT i = 0,length = 0;
    6 [7 s- @/ c8 \+ ~) ~
  204.         LPDF_UINT writeBytes = 0;7 w# s# M# a9 q, y
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    $ \! A" x8 k& M$ B2 h4 `0 ?4 q
  206.     if(LPDF_OK != ret)
    ; \+ U6 m; S! T' V- N
  207.         return ret;
    ' T2 p5 c" ], Y: C8 H; u6 q* B

  208. 8 X1 v7 B- }+ y- c8 D$ p3 l& g, z
  209.     while(font_list[i])( Z5 s/ _$ o# q4 i
  210.     {1 [! Z' D! S, e5 r
  211.         if(0 == strcmp(font_list[i],font_name)); D5 n- }' |5 o- E. r/ Y3 S1 b
  212.         {
    , _+ s! H( k2 V" I: u
  213.             page->fontType = i;
    : c8 q( q- _4 K7 S8 _
  214.             page->fontSize = size;
    4 p8 X/ f4 k' ^; `( d
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);
    / g6 }: b5 E$ N0 E
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);" ]! j& r+ b- U" ^* K
  217.             pdf->offset += length;
    0 m8 g* I7 E/ B9 W( W
  218.             page->length += length;
    ! Y! K/ I* M5 _; }( e: k
  219.             return LPDF_OK;; ~5 ]7 q! O* p' N. y" c5 Z% @
  220.         }/ o- ~, G# g/ J! _1 s; S/ Y# x
  221.         i+=1;
    ; C8 P; p9 ]' h/ _- ]& |
  222.     }2 K! E! A, w# N- I/ Q% Q5 m
  223.     : I4 m! s  S2 g& P
  224.     return LPDF_OK;. D/ p& ~! d" v. N
  225. }
    5 g/ S6 s4 o( L

  226. / g  i+ H" U4 R" ]
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page): G% o* E9 z# F/ h: [
  228. {
    : i8 f6 P' ]/ S& I+ M( |2 W
  229.     LPDF_INT length;
    # j* |" ]3 X( @+ n& k4 l, p
  230.         LPDF_UINT writeBytes = 0;
    1 m+ t# J# n5 T& y  Z
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;1 ?6 [* }+ K- f- ^4 a
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    " W3 H( e! B: B9 K, Z) D
  233.     if(LPDF_OK != ret)( q3 A* z# [# @+ ~- }& D# O1 @# o
  234.         return ret;$ g4 A* h' w+ T5 M+ J% D
  235.     ! m4 @8 N4 M* ^$ X
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */4 |$ E' e/ z5 Z6 d( Q
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
    5 f* |: J% A0 ?+ @' N" ]$ Z
  238.                         page->width, page->height);
    8 I4 f& _$ ~0 |# Y' k" T  V
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);3 G, h0 Y5 t, @  H
  240.     pdf->offset += length;6 J$ ~" x* _4 }. o% h
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    : g4 ]6 J" s! W+ \/ a7 u+ _% k; j
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",% T) p: K% O$ X9 ~, m
  243.                         pdf->objNumber+2, pdf->objNumber+3);! }* u' ~. J3 J( X/ n# Q( ^8 q
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);' c( r+ y& j+ ]$ t  P
  245.     pdf->offset += length;$ P; e  j. u% M; w! F$ |0 g
  246.     page->length = 0;/ K! @  a- P4 g
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;% K; @3 g; g+ {, C6 o
  248.     return LPDF_OK;
    + h5 W% Z% T& d$ Q0 O
  249. }
    ! I; f' y  h0 t; |$ _6 Z9 O
  250. * w2 I$ D$ H2 A: i
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)
    : @8 ]7 |6 G1 x4 P& c
  252. {
    & C0 t2 I0 Y- e( k, R
  253.     LPDF_INT length;6 M) o) H1 s* _9 x( Z
  254.         LPDF_UINT writeBytes = 0;$ I2 u6 `3 m# H6 l" z) v) ?% f
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;( ^4 X* b& u& A% M! f/ i1 c: }
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);' z1 `3 O* s( L
  257.     if(LPDF_OK != ret)4 S2 d7 f2 P4 o% w
  258.         return ret;
    1 K+ b* \, B# L) d
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    : [2 T6 g5 M6 T0 f( s/ y
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    : x0 L5 z7 R( X  H- o, a8 m/ R- e
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    8 q: K* H7 U, J
  262.     pdf->offset += length;
    7 V$ ]# L* H0 u$ m  e0 s
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;1 `/ I- g5 z% e2 E! C
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    % e' k2 z2 {1 m1 A2 h7 v4 s
  265.                         pdf->objNumber+3,page->length);; ^: B9 D4 m3 Q6 A1 G. R
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    0 v8 c! V: I1 A1 ~" }* M/ r
  267.     pdf->offset += length;
    ! t/ ], r( K" y- D
  268.     pdf->objNumber += 3;
    & X+ n0 C- Z' j! G
  269.     page->gMode = LPDF_GMODE_OVER;
    % V" v% L1 G9 C# [; H
  270.     return LPDF_OK;* m! R/ K! a# q2 B) V" p
  271. }
    9 J/ @* Y7 g" I6 g3 M5 O  |

  272. ; F1 k. J4 X2 y* G1 }3 w; ]! ^6 s
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    / J$ V8 N* x  |" p1 g4 F
  274. {
    , c. P* \1 I: e; `' J4 _) s
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    / l5 X- x; b5 p( w5 y
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    ; ?4 |. r, j# _% x1 \6 c& e
  277.     if(LPDF_OK != ret)
    - Z6 n- o4 A& `: l3 |
  278.         return ret;# p& K- }3 P) N- a7 g$ H$ ]
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    ' s$ R$ x4 _  t7 m* A+ w6 _3 {( V0 b
  280.     pdf->offset += 3;) t4 l: w0 u5 b  C
  281.     page->length += 3;$ b, ~+ }+ ]5 u: ]
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;
    ; T: g  d8 v8 \. P6 k9 H* m
  283.     return LPDF_OK;% z0 T* B0 ~% [) V; b2 c5 Y
  284. }
    , |8 Z2 ~* K2 A0 d9 }1 k
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)
    ) j& U% X& H) u# r6 @& n
  286. {# E! _* R% T0 h9 G' F
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;  X+ D( C* o$ r* h" [$ q& u
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    ( H. N) f; ?( d' }5 O1 m% e7 l
  289.     if(LPDF_OK != ret)& w: d5 C9 k  W4 F- {; B
  290.         return ret;
    4 k3 w! {2 Z/ T7 u% r2 i
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");/ f3 Z0 v. d# k1 s
  292.     pdf->offset += 3;
    ' {# }2 [7 J; F9 l
  293.     page->length += 3;0 z  [  d8 \7 k( K/ ]
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;% ^* d  `# o$ c5 u1 J( a
  295.     return LPDF_OK;- v, l: Q/ F+ z, m$ U% `3 m  w
  296. }
    / i8 i& |  D9 L8 A& Y' U$ {4 R

  297. . S7 a8 j+ J( J. Z
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)& p" o. Q) H, q' I& w  w
  299. {& B+ G" Q0 y1 }2 P' A
  300.     LPDF_INT length = 0;3 H6 _% {2 k1 b5 S5 n- N1 T6 |
  301.         LPDF_UINT writeBytes = 0;
    ) v( d8 _: |1 L3 j5 r0 g" y
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    - O6 E) I/ n, \0 x1 t" p# R: I
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);! m3 [) A4 Q, m( }; ~
  304.     if(LPDF_OK != ret)3 \& F% b# f. B
  305.         return ret;
    4 d; {/ a, \" _: I
  306.     if(LPDF_FONT_INVALID == page->fontType)
    * `! W! j( f/ A% ?1 k
  307.         return LPDF_OK;/ ~" I- R# `. k/ q, P
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);- Y5 K5 P- r, k3 M1 `" A
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);( O- w. B  W+ G; y
  310.     pdf->offset += length;; B9 r8 D4 J$ H0 r( X. N% R# Y" h
  311.     page->length += length;- b0 r; K9 r- T& |: x( g2 @9 q4 a8 \
  312.     return LPDF_OK;
    ! ~! O# X$ k# l7 X1 O  s! ], Z' t, w  p
  313.     ; d& y& w7 D1 j' x
  314. }' C- ~% M3 R  ?; T* i0 B! T
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    . c1 O* X. y+ I9 [
  316.                         LPDF_INT x, LPDF_INT y)% g1 K! ?$ a. h7 c+ n
  317. {
    6 N: q# W& z6 I
  318.     LPDF_INT length = 0;
    / \& L. W1 C& k+ t- [" `9 w
  319.         LPDF_UINT writeBytes = 0;
    % [  m/ @- m- q
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    / G% Q4 y8 C8 e8 f+ q
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    ( o+ [4 l1 n$ q3 g: S4 e  U
  322.     if(LPDF_OK != ret)
    1 `9 A* P' d, W, B0 c: X
  323.         return ret;
    9 r6 d8 Y* o7 D& y
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);
    9 K$ L6 z& _/ W" Z  M
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);! h; W& r! U% m$ a
  326.     pdf->offset += length;) X- p$ f: R( R* i
  327.     page->length += length;
      i, o: ~# o/ v: o6 k. q* w  _/ }
  328.   S$ p8 [5 d6 O* v+ ]# ^8 L
  329.     return LPDF_OK;0 Z8 O0 z# Z4 l9 k0 B
  330. }
    0 I3 D# D& O. l, a# J
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    6 |, h. N" [  N$ [
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,( Z6 ~+ f/ ?. C+ n/ r* l
  333.                         const char *text)
    % C- g: l$ r' |' M' P; P6 `
  334. {
    6 G3 K& n* `4 c0 A
  335.     return LPDF_OK;
    / A0 z& ^  G. c  Q7 o
  336. }
    5 }7 }' N( ?2 o

  337. 2 d9 @" \3 g5 Z; d$ H7 u
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,1 k2 I+ d+ V' G4 E9 M
  339.                          LPDF_REAL r,* m$ {( N& z: g6 S# W+ \5 }
  340.                          LPDF_REAL g,
    8 Z* w9 [2 V6 Z
  341.                          LPDF_REAL b)
    $ \; G6 F5 I& m
  342. {
    ' u; o3 ^2 P! J+ u4 b
  343.     LPDF_INT length = 0;
    1 n6 r. {$ O0 r
  344.         LPDF_UINT writeBytes = 0;
    3 c0 x4 r. g/ n; Q3 y9 U
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ; f. f3 `1 R6 N: v: a3 z# w8 n
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    / E7 n1 g. N$ W- d0 `3 ]
  347.     if(LPDF_OK != ret). V% q6 V, @# J. \/ H0 G
  348.         return ret;7 H6 ]7 w# i" h1 C* a8 t
  349. 4 T; L; }- R8 R6 {6 z
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    * J; B8 H# {0 t' C' w
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);8 I- F! V4 `  b2 A+ L$ _
  352.     pdf->offset += length;
    ; s5 e: _' G$ G
  353.     page->length += length;
    0 @6 N) s% E2 T$ A
  354.     return LPDF_OK;3 z" y0 {- I9 F. ~
  355. }. N) A4 d' i& z/ G: o- b  p
  356. ! L! ?' m, C9 C
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,* I  ~9 m, p( ]8 V- _0 Q
  358.                          LPDF_REAL r,2 v# R; P% W3 P. }% ]& i6 W+ L' s
  359.                          LPDF_REAL g,+ ?9 g) S3 f; I7 Z) ?$ f4 N
  360.                          LPDF_REAL b)
    8 e& B* i$ n* U- L4 _, U
  361. {5 r) H4 d' o$ k; Z" V; x& {
  362.     LPDF_INT length = 0;
    7 W0 ~/ L4 W. C0 E4 F: a- c5 x+ H6 S% }
  363.         LPDF_UINT writeBytes = 0;
    7 v2 c* L! i: Z; S: H- |: K7 d& w
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    - n6 b$ S/ _/ W% G. v; Y/ p
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);/ O5 _( \% m! T
  366.     if(LPDF_OK != ret)5 H1 b& j* `% p/ t3 v
  367.         return ret;. p0 q2 r: r/ ?( f
  368. $ F, o6 l4 H$ |9 Z" |0 D
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);2 X  L2 I! f) {. F4 O
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    1 y- n0 w5 j) c. }- c
  371.     pdf->offset += length;
    2 L; \6 m% m6 _$ `: r3 s: Z
  372.     page->length += length;
    * H0 S+ U% o" h! _
  373.     return LPDF_OK;
    9 q7 _% y- J0 C. y
  374. }
    8 v6 P2 N4 a+ s! X* D
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,; d, O" `- d- k9 s6 e1 U; {) l
  376.                          LPDF_UINT16 x,
    " O2 `! B3 n: T* @3 N
  377.                          LPDF_UINT16 y)
    ( p- v( m- T! P! v
  378. {
    ; [) {9 J, u; F3 `% m/ b
  379.     LPDF_INT length = 0;
    " s; m# @/ ]4 D2 ^2 h/ ^, c
  380.         LPDF_UINT writeBytes = 0;+ z" A( S$ \8 o
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;8 g" N4 T$ x" s( D
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);/ n" @/ \" [! c8 l
  383.     if(LPDF_OK != ret)5 Z4 o& G& F" i1 i1 \% O
  384.         return ret;5 J6 {, ]! ~5 i+ j0 J2 Y$ ]
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    8 @/ c6 R2 U1 f& \
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);# a& R4 d! ~- C$ O6 w$ t
  387.     pdf->offset += length;4 p1 e& Q2 o  n3 w8 |$ i  d
  388.     page->length += length;0 X' ~# Q6 Y8 z0 x4 v# [
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    0 L( Q) u2 S5 p# H
  390.     return LPDF_OK;
    / }- L8 L+ m2 O9 Y/ k# a' w$ d
  391. }
    : d4 l7 `! p5 W+ T
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,! k! h9 d! o" l: R- l
  393.                          LPDF_UINT16 x,2 l' O( [: M% C8 G  k- c5 z0 q
  394.                          LPDF_UINT16 y)
    9 W/ j, n' J  O/ S8 U
  395. {
    * q# q! o4 `2 Y
  396.     LPDF_INT length = 0;
    * J5 _! b* e1 @: `7 b
  397.         LPDF_UINT writeBytes = 0;2 P0 d3 r, E8 g  ^, a, R* c+ {
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;9 B3 k2 o  k3 }6 H1 N: B2 g& V
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    " [( X. Q  ^" x1 x! g
  400.     if(LPDF_OK != ret)4 e- w8 q% B. g$ [- H  U
  401.         return ret;, I5 u/ Y$ U* W# ]6 V7 @* M
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    ; @9 k3 y6 }' h2 D3 e4 z6 V; e/ |
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);8 f# S' Y  P- |& Q* }/ P
  404.     pdf->offset += length;
    2 V! J* i2 R/ b. ]7 V1 A
  405.     page->length += length;
    ' |7 B- m0 F& B8 G+ U, b
  406.     return LPDF_OK;
    $ P0 a: g2 V1 m; O
  407. }- c. N" F( W' ~' [1 s; k/ _
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)# p( h! G* j; M9 G# F
  409. {
    4 H" R) E. u3 z3 h
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;+ H" J" y4 D( z5 v' F" v0 w
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    $ }, h9 v6 l$ ~  b$ A" t7 {
  412.     if(LPDF_OK != ret); b% M5 `' g7 I
  413.         return ret;
    9 f: V, D5 @7 Q
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    ! X6 {! x: c; ~5 n! z) B9 m% e2 h4 E
  415.     pdf->offset += 2;+ ]& y) u8 n! J' y, K9 j
  416.     page->length += 2;
    , }& z: C' u: }: M' }3 \; U
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    % M- M. h' D" [4 R2 K
  418.     return LPDF_OK;
    & F. b% r# E7 e1 h; z, x8 ^" Z
  419. }6 o. \# t; ?1 L. ]/ s/ s
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    9 b6 \) F+ p+ V$ ~( w  k: }/ t
  421.                       LPDF_Image image,
    3 w* x' u/ W; K
  422.                       LPDF_UINT16 x,' L( C6 b6 }6 q9 Y4 ^* X
  423.                       LPDF_UINT16 y,
    4 U1 J8 a# W$ x. R2 O4 a; R
  424.                       LPDF_UINT16 width,. M$ P3 x: m5 R6 Y$ t! x
  425.                       LPDF_UINT16 height)4 H- l1 ]" X. f# z
  426. {
    + K5 s; o/ z- A, V
  427.         return LPDF_OK;
    3 p. O$ Q0 ?- h2 i& }
  428. }; F" q7 }% R5 H0 J: T
复制代码

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

  1. pdf = LPDF_New();  w$ L) U( ]+ z' Z& N+ a
  2.     page[0] = LPDF_AddPage(pdf);- V' `2 f9 {( x
  3.     LPDF_Page_SaveParams(page[0]);5 ?7 S7 O* Z  T. B2 p6 L: p, U
  4.     width = LPDF_Page_GetWidth(page[0]);& Y$ |+ B5 [; U7 ]* w' k( u) Y
  5.     height = LPDF_Page_GetHeight(page[0]);
    * b* o% [3 \/ i9 c  f0 P
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);4 P5 G( X7 ]1 v0 b& V+ V
  7.     LPDF_Page_BeginText(page[0]);) I9 c" |* M# v1 R  L0 A+ v
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);6 d# z( s! e5 v2 D5 k* Z
  9.     while(font_list[i])6 I3 A8 s9 y+ }$ P. e
  10.     {
    9 ~) z) K! Z! l9 o! |0 e/ @
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);0 p, E" G# x- z
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");* V2 T7 M$ A# {+ ]( ]. {- m
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);
    ; p- @6 V) i1 T$ d# o: J, a
  14.         i++;
    / X' H- E+ S- g% u0 B
  15.     }
    ' V2 y* ^) i& z: Q
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);6 {( h3 `, E8 {
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());; a$ s3 W8 U! C
  18.     LPDF_Page_EndText(page[0]);
    3 z. l8 [. ~: Z4 ]* d$ W
  19.     LPDF_Page_SaveContext(page[0]);
    + u- \8 L0 s) ~
  20.     page[1] = LPDF_AddPage(pdf);- [& a" B- O1 `* A
  21.     LPDF_Page_SaveParams(page[1]);# J9 x) \: ~, Y1 W& |
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);: K! }" F! h' s3 ^5 Y6 S
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    , F  ~$ z) o+ c- j# O3 `
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);1 k. d. C* C0 W- S! ^3 ^
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    8 |" ^: Z8 w  Y/ [
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);" B) |( Y9 l$ [) U8 K
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);
    ' _- Q0 l4 M* _% ^9 A7 H. k9 m
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);
    , x# k2 s# V$ ?; O/ |$ ]( m3 \+ D- z
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    * |% [: A% a! A7 W. i
  30.     LPDF_Page_Stroke(page[1]);
    & I- W1 f, g+ B& w% w( h7 E0 r5 W
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);0 x' W4 k9 t) {- w, V" J
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    9 `& {5 i1 d) h/ D7 M% C
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    & f' ]" E+ `5 w8 U  @5 z
  34.     LPDF_Page_Stroke(page[1]);! ~0 s9 v2 h2 K" V
  35.     LPDF_Page_SaveContext(page[1]);
    & ?5 E1 ~/ Q: f4 y% x8 W+ g3 I
  36.     LPDF_SaveToFile(pdf, "/red.pdf");% B8 V! n; f- ?$ ~( ~: E8 z8 }
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    5 P) `/ p! i+ x- V9 N
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了
" H6 `+ W0 M; X/ p) N

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体( U5 d1 x9 j: K0 |' r' ~7 a5 M
+ Z3 q" `/ b& B1 J# n. 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
9 }) ?' ]6 l$ v! z0 K$ T4 Y1 p只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...
3 A2 A/ E; t$ p6 ^
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% P- ?6 z& ^3 s, g; @6 {3 ^+ r
首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
. ^! k, b2 K) n% F+ d/ |
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思3 }+ ?% a0 @: I
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
$ K8 L$ g/ y% |% @7 n8 j看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...

- N+ ?7 h& C5 U3 _9 @% \这个我也还没遇到过,只是之前看到有人问这个,所以看看
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
- e6 J% ^" ~: x1 k: z7 U8 A厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接
1 U: ]. ?% X* g
这个还只是一个简单的库,实用性还是差一些的
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
9 k5 \2 a3 [" c3 J( O8 Jff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
4 L( r6 |4 _3 l
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
. F5 d# b1 P4 j" M8 d/ Fff.h是FATfs中的文件
: U5 A4 e) V/ I1 }+ Y% |- b5 m0 m8 T
嗯,这个画线能改变线宽吗

所属标签

相似分享

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