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

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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 ( P7 w- w2 o( v. z4 ]

- ^. r7 `. J6 b0 P) L7 s

主机环境: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__
    % r9 K( H1 w: i) A* I+ p
  2. #define __PDFLIB_H__: N& X, c1 i- u$ S

  3. $ g9 x: W/ s# G& n+ k( q. y- L
  4. #include "ff.h"& Q/ H/ z! m( p- ^- S
  5. /*----- standard C library functions -----------------------------------------*/
    3 V& q( k8 T! U

  6. 2 M1 Y& I/ g" \
  7. #define LPDF_FOPEN                  f_open
    3 S/ O" p8 Q4 a6 N2 n1 _
  8. #define LPDF_FCLOSE                 f_close" }* w; g7 T' o6 D3 `
  9. #define LPDF_FREAD                  f_read: U2 P; L0 s& z" d( ?, n' b% H. \# i
  10. #define LPDF_FWRITE                 f_write
    ' L9 n3 B/ d1 Z
  11. #define LPDF_FFLUSH                 f_sync
    0 n# A: e/ K( ^0 V' H
  12. #define LPDF_FSEEK                  f_seek5 G; h' n" R: l7 e% n9 g( V
  13. #define LPDF_FTELL                  f_tell
    + f7 c; q( W' }. Q0 ]4 @
  14. #define LPDF_FEOF                   f_eof
      v  T5 P+ S; U6 o' T
  15. #define LPDF_FERROR                 f_error% K( f7 H" N5 m% Z: A( p
  16. #define LPDF_RENAME                 f_rename! e- x. v" Y- U3 J" p/ Y
  17. #define LPDF_REMOVE                 f_unlink
    1 Q: i5 \( v( v* A0 K5 _
  18. #define LPDF_MALLOC                 malloc# @0 U4 r/ n( r. m/ m4 p; C8 V9 k
  19. #define LPDF_FREE                   free  L( G$ N; b5 H- _
  20. #define LPDF_FILE                   FIL8 K( u# S* ~: X* f% e& j$ A
  21. #define LPDF_TIME                   time* V* `2 j, O1 y5 G3 J- u& |/ W
  22. #define LPDF_PRINTF                 printf* z9 i4 B5 ?' u' N3 {( `- d9 j8 P
  23. #define LPDF_SPRINTF                sprintf
    9 K; k$ T- c8 h; k8 ^8 Y, p, X5 c
  24. #define LPDF_FPRINTF                f_printf
    ! m; T* @# _/ L& q. ?' f/ [, y
  25. #define LPDF_VOID                   void; z4 F' f+ @' F# s, X' I* W
  26. #define LPDF_SIN                    sin) D- b% p/ i4 m% v9 f6 Y1 C
  27. #define LPDF_COS                    cos
    2 h& v% y: h; G- S" t  @! S

  28. 0 G) u2 V. J' ]$ T) e+ l" W: o
  29. /*  native OS integer types */4 j* l# j# A- U
  30. typedef  signed int          LPDF_INT;
    2 d$ _, J$ D/ ]* X9 z- q
  31. typedef  unsigned int        LPDF_UINT;3 q$ }* k6 M' o) _7 G

  32. . V: _5 G* ?- q0 h- x

  33. 7 [" h( q2 Z) ^# y
  34. /*  32bit integer types
    # C: Q, S8 L- F0 A# f( D, T( K
  35. */
    - ?5 Q. _" Z8 V5 P+ Z+ e$ k" o
  36. typedef  signed int          LPDF_INT32;
    6 v5 w$ ^( _1 }4 A! ?9 i0 ^
  37. typedef  unsigned int        LPDF_UINT32;/ Y3 l5 c" p: E6 B4 I5 d# T6 w/ U3 D

  38. & h" ]. T2 b6 f+ G8 s

  39. ( V0 \0 g6 X  Q+ y; A
  40. /*  16bit integer types/ T, h/ v# }+ k6 l
  41. */- J2 }2 k6 F9 Y. `  E8 t
  42. typedef  signed short        LPDF_INT16;
    6 q$ V% g9 x4 y! g( P+ |6 M: P4 n
  43. typedef  unsigned short      LPDF_UINT16;
    & {1 K- A! s  A4 \: s

  44. + z. N9 W) p  Q( M' w; j5 }2 q
  45. ! I6 W% n8 V" q
  46. /*  8bit integer types0 j& n6 H9 E4 c( r, |% d5 |) W9 m/ P+ q
  47. */0 e! L$ p, S5 ^9 \
  48. typedef  signed char         LPDF_INT8;5 x4 }4 @$ p9 Q) Q
  49. typedef  unsigned char       LPDF_UINT8;
    : O2 O  \. S3 S8 w! h
  50. % |( G* q7 p/ P  B9 l+ r' p( b
  51. $ e* [3 h4 B: w
  52. /*  8bit binary types+ v+ A9 a+ H+ U& M
  53. */
    : o+ j  o; d, \. ^+ x  V
  54. typedef  unsigned char       LPDF_BYTE;6 Z4 o# w& X1 z
  55. , B3 N+ Z, m  a
  56. & I, S" {% W8 q7 j9 S5 h$ f" H
  57. /*  float type (32bit IEEE754)! ?7 R# e8 P0 d: Z# j2 Z* J/ M
  58. */
    ; r( B" x/ c  z4 P0 T+ b5 R8 q
  59. typedef  float               LPDF_REAL;
    / x8 q5 V7 t) O5 N+ ~
  60. ; X) I. Q( G+ O- Y' m# x- L  h
  61. + H( M' ]+ N! a, O$ p
  62. /*  double type (64bit IEEE754)
    , i0 d! p; O& @) f( Y
  63. */
    / F8 O/ f3 e, ^3 Y/ _, \$ p
  64. typedef  double              LPDF_DOUBLE;/ W/ x. C, _! \4 l" B$ Y
  65. 6 U# u% {1 @3 l+ m! b3 p  R0 W
  66. 4 P3 H! M% K' k/ ?$ D+ Y; ^
  67. /*  boolean type (0: False, !0: True)
    ; J& q5 r0 ~( y
  68. */: c6 z" h% \! Z' @+ D% Y
  69. typedef  signed int          LPDF_BOOL;
      E+ w. ?$ ^1 S/ r

  70. ! u1 W$ H9 l: W

  71. 6 q( j- g+ i9 x- ~
  72. /*  error-no type (32bit unsigned integer)2 i4 J1 p' D" F/ s1 ^6 l
  73. */
    ; s7 [+ p& r! r- ?- m0 i& o
  74. typedef  unsigned long       LPDF_STATUS;* l5 N. g1 H: R/ @( Z- v$ ^5 w

  75. $ D" d* I3 d* O; F) b
  76. #define LPDF_OK                     0
    / v( g/ y/ T8 ^4 [, q- x
  77. #define LPDF_FAILED                 1
    ; M/ a( k5 e1 v; `) d; Z% z

  78. , j) d) {6 Q4 Y& @- U
  79. /*----- font state -----------------------------------------------------------*/, B9 \, Z2 E' ~4 W
  80. #define   LPDF_FONT_INVALID                 0x00FF
    ; j+ C' M% i9 L( o/ l/ P
  81. #define   LPDF_FONT_COURIER                 0x00009 k' C$ T! [& b7 R9 f& A
  82. #define   LPDF_FONT_COURIER_B               0x00013 d) Z  [2 e) ^! _
  83. #define   LPDF_FONT_COURIER_O               0x0002
    3 Q8 P5 r5 k' I1 r$ ~# N' m
  84. #define   LPDF_FONT_COURIER_OB              0x00038 M* k/ ?- n( \) p
  85. #define   LPDF_FONT_HELVETICA               0x0004% ]8 X& }' ?: v; s: W  B
  86. #define   LPDF_FONT_HELVETICA_B             0x00050 q, W* G; V1 Z( u0 e
  87. #define   LPDF_FONT_HELVETICA_O             0x0006* S3 Z4 [& Q' C6 E( ]5 Q
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007
    - a+ g8 a" C- r4 ]- _1 V' }
  89. #define   LPDF_FONT_TIMES_R                 0x00085 l$ o3 p, I& F3 j- `: U
  90. #define   LPDF_FONT_TIMES_B                 0x0009: D3 }9 d: B: K+ F7 @
  91. #define   LPDF_FONT_TIMES_I                 0x000A) o" K% W1 _4 L  X. _9 u- l0 N
  92. #define   LPDF_FONT_TIMES_BI                0x000B% ?8 W" R2 \7 k, ~$ J" p
  93. #define   LPDF_FONT_SYMBOL                  0x000C: G6 k/ u: `+ U2 v2 f
  94. #define   LPDF_FONT_ZAP                     0x000D
    3 Y9 `& t8 ]" \# T1 o4 [" D
  95. /*----- Graphis mode ---------------------------------------------------------*/
    ( A+ r. w5 |% C& S: j
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    - N* U5 M0 q7 d3 \5 B4 `2 t: ^
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002( g  @- b" @0 h  b
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    1 s( z/ @3 w+ T# @. F* m2 p- q
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008. V0 g* M: U- ~; Z
  100. #define   LPDF_GMODE_SHADING                0x00100 T4 T+ s4 U- F
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020; u6 D) N1 }6 {# c: C
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x00407 A1 G5 t9 P+ C. q+ t% s
  103. #define   LPDF_GMODE_INVALID                0x0080, _( C; Y1 Z9 Q! g7 j9 O6 z
  104. #define   LPDF_GMODE_OVER                   0x01003 p- r! l7 J. h' v! s1 G  r3 J

  105. # `4 G7 c7 n0 Z& C& I/ q5 J
  106. #define OBJ_MAX_NUM     256
    7 K% ~! [( d$ t7 i2 R

  107. ' u% z# N$ {1 n5 ^; G
  108. /* Page的结构信息是否需要树形结构 *// a- f7 y& b: g0 a
  109. typedef enum 6 g, f$ {0 Q' r3 P+ n( a+ y. f
  110. {
    $ f2 t0 I; n7 h2 q9 e8 L6 q
  111.     OBJ_info,
    9 V- p2 u8 {, L9 o8 m. p& K+ T: X
  112.     OBJ_stream,2 ^' i. R# f* y5 Y$ g2 L
  113.     OBJ_font,
    5 m' B9 Y# C# D2 L! u3 J
  114.     OBJ_page,
    - D0 A- [* _8 E$ _6 l
  115.     OBJ_catalog,
    - B7 R/ v9 B5 ?' V! ~3 F
  116.     OBJ_pages,% F# D! U/ V4 Z- d
  117.     OBJ_image,( s" q3 j% B' a
  118. }LPDF_ObjType;9 [6 j( A2 s+ u# W
  119. ( v$ b4 M% [- v
  120. typedef struct3 ~+ \* |4 c, o; w' ~6 Q; z% S9 s
  121. {
    - m" C1 [: ~9 k# h
  122.     LPDF_ObjType objType;/ M0 m, S8 `& |7 ~/ @5 n* M  W
  123.     LPDF_UINT16 objIdx;
    " Q6 U( a& I2 a' s5 k2 h
  124.     LPDF_UINT16 height;% }# J. t4 y* W0 E* a
  125.     LPDF_UINT16 width;
    ) }' r  S" y! L) I: [
  126.     LPDF_UINT16 length;( V/ W; Y: B- |. I' ]/ @, x
  127.     LPDF_UINT gMode;# r, {6 I! X6 K3 I4 S+ O+ Z
  128.     LPDF_BYTE fontType;
    + N) ~9 ?* H6 ]% b  ^; W# N3 I1 w) d
  129.     LPDF_BYTE fontSize;
    1 M& o" b7 P* i2 h/ p
  130.     LPDF_BYTE pState;
    6 E6 C6 `' T1 x
  131.     LPDF_VOID *doc;( l1 {5 T- g2 `& B# s+ F
  132. }LPDF_Obj;
    * I0 `: A9 w" f6 q, s# K/ r5 Q
  133. ) D8 o' |2 y& x7 y9 A
  134. typedef struct
    $ g5 A* y- S+ d; h) F7 ~) b" `- k% [
  135. {
    , O( \/ F( Q( m& V8 U1 v/ D9 k
  136.     LPDF_Obj obj[OBJ_MAX_NUM];
    $ Y8 V- m( u  t) W  I4 S
  137.     LPDF_UINT32 offset;
    2 U: U; M& Q7 h: o) b+ `
  138.     LPDF_UINT16 objNumber;2 ~* ?* K% w3 J1 {0 Y* {! w
  139.     LPDF_FILE file;
    : m5 i5 V3 u/ ]1 Q9 k0 K
  140. }LPDF_Doc_Rec;. y7 W; F9 h5 I
  141. / A1 }- {7 C4 S0 K
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    : [1 K# P% d0 `6 \' t
  143. typedef LPDF_Obj *LPDF_Page;
    * X0 A4 [- b- M7 _: S
  144. typedef LPDF_Obj *LPDF_Image;
    4 t6 {/ i2 G: ~
  145. extern const char *font_list[];& B* C6 }; ^) V
  146. /*----- LPDF Interfaces-------------------------------------------------------*// G  P: w3 S" H( w& R  \
  147. const char * LPDF_GetVersion(void);
    3 g( U1 m8 w+ I) v/ u
  148. LPDF_Doc LPDF_New(void);
    ! u5 [  e( o' ?
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);
    % _# ?. Z/ C, L1 w5 S
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);
    $ o1 j" x0 V+ a
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);; O4 K: T# y4 o" ^) k% X
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);
    . `" |+ |0 N# f; E
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    9 X( ^9 e# f1 `" S; j6 t; |3 ~
  154.                            const char *font_name, LPDF_UINT8 size);
    : F. v6 W: U6 G, A& @9 j1 v: n
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);: O2 j5 a$ U6 R
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);
    ( J9 I1 q" J/ G3 X3 G3 z8 u
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);
    # v9 f$ F" I4 g$ M
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);" E) W! C  j; s6 J* @3 e: F
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);! F( v. c- c2 `, ?) j# }: B# W# S' V
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);( u9 w/ w* a1 b9 ~9 N. [
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);" M3 |) P+ ?7 r* A
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);) N$ ?7 g* R6 m( S
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);
    2 L- D/ Y  W* f0 ~: G5 v' M$ M
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    , u' O: `  I* _$ J& ?$ S
  165.                          LPDF_INT x, LPDF_INT y);
    ( A8 R% Q; U# t" S/ a) W0 {: g
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    + q  m% x% e& W3 i
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,
    8 @. e) ?- }' n/ D! N' D' ]" `
  168.                          const char *text);4 N) t* P/ L8 ]2 B7 F; W  H
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,& Z' D- c1 f) U* X
  170.                          LPDF_REAL r,/ l! {3 I$ q( v/ e" K1 T. z, h' f
  171.                          LPDF_REAL g,1 t, ^& ~6 W) `& P5 \  ~
  172.                          LPDF_REAL b);
    6 _6 I  a5 U) D% p+ P, Q& `
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,/ Z' v1 N8 z) N2 z% i1 o, b  k
  174.                          LPDF_REAL r,, {9 f2 a2 F& I: ^% Z# h; C6 `
  175.                          LPDF_REAL g,
    1 ~, s1 I2 O% O& s( e
  176.                          LPDF_REAL b);
    1 V, z/ b9 k" C$ s5 ]
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    1 V& {4 `/ g2 c4 W6 P
  178.                          LPDF_UINT16 x,3 |4 F# U+ |* P4 T# s
  179.                          LPDF_UINT16 y);
    * o% P" U  _+ q5 b) q
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,8 T" W% @* d! U/ P" Y  F6 r1 P
  181.                          LPDF_UINT16 x,0 J: _2 l  ~8 w) g
  182.                          LPDF_UINT16 y);: R  @8 R1 X. c. G6 A9 ]3 u. H
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);! \$ `9 g3 j1 i+ C  Q
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);& [+ c8 U- m8 }0 X* S
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    % _$ M$ B3 X+ Z- ]: T. \) d5 n6 \3 e
  186.                       LPDF_Image image,; {! r$ Z0 p: w5 f
  187.                       LPDF_UINT16 x,9 a: f6 F% R2 [3 x. r, o
  188.                       LPDF_UINT16 y,
    : Y6 a# w; I  x7 m% L
  189.                       LPDF_UINT16 width,/ S) f) ?# ]6 _
  190.                       LPDF_UINT16 height);+ V' v, P0 D5 h" v2 T
  191.                                                                                        
    9 }3 _& M7 ^/ z2 y
  192. #endif
    ( w$ ^( d0 k, v$ Q3 r
复制代码

源文件如下:

  1. #include <stdio.h>
    " x( ?2 m* e4 T0 u* s' n
  2. #include <stdlib.h>
    1 w7 L" u/ G# X4 H( C
  3. #include <stdint.h>
    ) K6 l  F& a& i. Y0 Q, I: `
  4. #include <string.h>
    . n5 W1 D3 L, b4 C5 c1 A
  5. #include "pdflib.h"
    % x# `4 X3 J! P- o6 b; w
  6. & ^6 e2 L# Z0 Z; o9 K/ I
  7. #define LPDF_INVALID_OBJECT                       0x1033* h: c7 T) x; G# Y

  8. / K! j5 c; ~7 ^
  9. static char pdf_buf[512];* s0 H: P: c9 [1 G8 R

  10. 0 e2 e1 g& r5 N) a+ U( X
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"% r4 e1 p# ~5 d# P2 q% B% _' ?
  12. #define LPDF_FILE_HEADER_LEN        159 @3 c5 a0 U, Q" |6 \1 y
  13. #define LPDF_BASEFONT_NUM           147 }+ ~! \% h! K( Y; g3 R* A
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    ) Z% ^) @+ C2 n; l% v- X
  15. const char *font_list[] = {
    : P, j# V4 O  r
  16.     "Courier",' e6 P- L+ Y) Y# T
  17.     "Courier-Bold",: J8 O! b6 g9 W9 ~6 u/ [
  18.     "Courier-Oblique",
    , c9 P4 k: W. i
  19.     "Courier-BoldOblique",6 c( A( `5 L6 C8 Z9 X2 U+ p
  20.     "Helvetica",
    5 ^% g' ?. r7 {# S0 K7 {7 \6 ~  U
  21.     "Helvetica-Bold",' F) Z1 K% p8 G, T' c! T. S
  22.     "Helvetica-Oblique",
    1 U- y! c( G5 o3 ^
  23.     "Helvetica-BoldOblique",
    5 g7 I$ Y& Y  q" G6 c
  24.     "Times-Roman"," c6 }, E& q2 R( c3 K5 r
  25.     "Times-Bold",, H0 ^& r) [$ O5 C9 \" d
  26.     "Times-Italic",
    3 K6 z" O: M" L6 I# g$ ]% Z7 l
  27.     "Times-BoldItalic",
    $ ]& k- F4 q7 S1 E! `
  28.     "Symbol",
    ' f6 e  U% L. V/ M7 Z
  29.     "ZapfDingbats",
    ) V$ V6 h7 [% _4 P: Y  U. b' i
  30.     NULL9 W. l7 j9 H% }$ e
  31. };# ?' p3 k$ U; ~6 r+ D

  32. . G' L3 Y" b% L4 B
  33. ! _& ]" O' w6 a$ \0 T  ~
  34. const char * LPDF_GetVersion(void)
    & f5 H& L- p# N2 S
  35. {. H1 S2 y& `- x
  36.     return LPDF_VERSIOIN_TEXT;
    & t9 z# l+ @. B; g4 Z, s
  37. }# `  U$ S8 A. D5 f( |* t
  38. + ^6 a; [% z# f, X) L7 C* w5 U  o
  39. LPDF_Doc LPDF_New(void)
    " v, n8 r* H& I# f2 h5 D
  40. {# R& G5 V' b/ d8 [
  41.     static LPDF_Doc_Rec pdf;
    $ ]) B% o6 C/ f0 m& j# c5 g' a) v
  42.     LPDF_INT length = 0, i = 0;
    1 z, [( L4 @: m; t1 A9 {
  43.         LPDF_UINT writeBytes = 0;
    * G( Q2 x9 }) t$ ~. G. O
  44.         FRESULT fr;% b& O5 \+ U1 R) F/ d0 F: D$ ]
  45.    
    ) {9 S: G: t3 T2 J- F) q! S! l
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
    $ K4 G7 I/ N$ u( U/ L6 F; y
  47.         if(fr)- N/ V" f: A( y% c& u
  48.         {$ h5 }2 O- Q( |( A# o. s4 j
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");6 R/ V! U3 }  E+ h( }7 z  t
  50.                 return NULL;+ P' ^6 t$ [, e
  51.         }' U$ U! U1 V+ k, V; }
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */- e8 y' a8 [. u3 {; f; n
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;# o/ Y$ H9 ]' ]5 q) q$ \
  54.    
    ! b) ]$ s, `* y6 e, o
  55.     pdf.obj[0].objIdx = pdf.offset;
    3 l2 ?5 n% m% ^" M0 k) u! A
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
    % C4 K/ E0 b1 g  o2 Z  l% @
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    " i- [( f. t3 l: X" r! @5 Y
  58.     pdf.offset += length;- k* P5 _- f; }, I7 @
  59.    
      ^# M& |' H9 Y" s# Z5 r
  60.     pdf.obj[1].objIdx = pdf.offset;
    , _- S8 j7 u0 N/ ^# N7 \
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"" y/ H5 c9 e. |6 ?- W% [" J- K9 I
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");6 C+ G3 y4 h: M( Q  s' \3 E
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    : M/ F; |5 p0 x4 v5 o1 ^
  64.     pdf.offset += length;. U. {" u1 A8 C3 [: K
  65.     2 ~4 {2 D$ D& M
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)2 t% P) o, |8 y+ ~$ K! g9 Z
  67.     {) E1 O& a& T0 G2 q# ?9 C; y
  68.         pdf.obj[2+i].objIdx = pdf.offset;
    / I; n- K: Q1 |5 M
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"6 v# E7 p! W5 ^. v
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
    8 i- C+ a$ ^  p8 u& A
  71.                         "endobj\n\n",3+i,font_list[i]);' Z- ?* P( F. k+ n7 p% j* C1 E) `) o
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);* f4 O& ^. h" v
  73.         pdf.offset += length;7 B# O8 b7 o) A' Z
  74.     }
    7 Q& c' G; p# b$ X( [  s# c
  75.     for(; i < LPDF_BASEFONT_NUM; i++)- d4 J/ n, f9 P0 P* {
  76.     {
    . z' M% v7 H! ]: ?1 e/ W7 r
  77.         pdf.obj[2+i].objIdx = pdf.offset;
      e% G: v: i/ ^9 o/ M6 j* F
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    . P0 B/ u; I  O
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);# ^' S) t+ P& z& p
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    / l! l' b' w4 `' |5 y$ B5 ]1 k- f
  81.         pdf.offset += length;0 H( V" y3 X7 a4 c& |
  82.     }" W! `- e9 G( ~; k$ j/ I6 z
  83.     pdf.objNumber = 3+i;/ _: y1 o6 E2 P8 I$ s+ s
  84.   ; T- A% j5 x8 k) e
  85.     return (LPDF_Doc)&pdf;6 O! J: N: Y$ ], l& E# f
  86. }  w& f$ ?0 O0 L8 ^" n) a

  87. . t0 a4 o( |" M$ |. b
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    2 r+ N, f5 q: p. J7 k6 K& }
  89. {+ m$ R% E6 `7 B  }
  90.     LPDF_UINT16 i = 0, child_pages = 0;
    1 @) A- q' X4 ?" Q' v/ g$ \- y) H
  91.     LPDF_INT length = 0;
    $ ^- T) H7 n8 C  f4 H6 @  Q0 t1 A
  92.         LPDF_UINT writeBytes = 0;
    - X9 ?; x) ]+ `$ |, n$ G

  93. ) k1 ]- F9 n8 g( c2 N' o
  94.     pdf->obj[16].objIdx = pdf->offset;
    4 L* k. t8 L; v$ A( }$ }" B
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;/ x2 z9 [: H: w5 X% f: E$ e& ]
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);
    $ t  _" H. [7 o- D. j
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);- T7 N6 D2 M+ o* `$ c# O
  98.     pdf->offset += length;
    : ]' m- G% U3 {0 N6 `# |: C
  99.     for(i = 0; i < child_pages; i++)
    3 [7 ~3 R1 U* ^3 A
  100.     {
    & `* t6 {9 a, l
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    & g2 u7 a0 Q3 d( {3 r- Z7 J
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);  T0 F' j9 L, {. F* V
  103.         pdf->offset += length;
    ; `5 [# r; h: u/ V
  104.     }
    3 v  ^8 t* N: k/ {3 B" }
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");4 N: `8 t4 w" g4 V, C: K
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);( X3 {' a1 C5 N6 k" b
  107.     pdf->offset += length;
      y# i% X# s" e  e, C
  108.     . Y; G" a7 s9 r. z* H
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    ) a) ~$ j0 L3 Z' h  @
  110.     for(i = 0 ; i < pdf->objNumber; i++)7 L+ C1 `( ^9 g# a# y& D) B  C
  111.     {5 e* m# H2 D, I" G; S
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    2 z8 c8 |' e9 c8 v8 B: L* f9 F
  113.     }
    , v" E. _* N8 N7 n6 a8 [
  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",
      d+ d8 H9 a9 A3 m8 ^3 j) `
  115.                 pdf->objNumber+1,pdf->offset);. U7 m1 l+ @# X0 ^7 e1 Z$ t
  116.     LPDF_FCLOSE(&pdf->file);
    6 e; ~3 F9 `8 t8 z3 G/ A
  117.     LPDF_REMOVE(file_name);! W4 w3 [0 J+ F* ~$ C. }2 R* }
  118.     LPDF_RENAME("tmp.pdf",file_name);( w5 U3 m8 \/ O# x
  119.     return LPDF_OK;) K. v, _7 e9 W3 u4 v
  120. }
    & K& b+ |* ~# b/ N0 Y/ E

  121. 7 `+ ^- n& E- x4 M& Z& R' Z
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)/ l. P: t) H0 B. Y+ d6 ]( R- }
  123. {
    # G$ A1 v6 q- L/ `" G: f  ~8 d
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);
    / X: w" Z# |- H7 S) a
  125.     return LPDF_OK;
    ' A/ \: r0 {, |7 X8 l+ i2 F
  126. }
    : O3 C9 w2 U# |( t* ~" x) ]

  127. & J, l0 W& K# Q
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)
    2 j1 [5 @. u8 H, U1 a4 n
  129. {
    ) I7 x. A& j9 E1 s" s
  130.     LPDF_INT length = 0,i = 0;: O. A. ~# R  A
  131.     LPDF_Page page = NULL;
    % J- L5 ^+ M, `; [
  132.         LPDF_UINT writeBytes = 0;  G% P% L; R% P& T  d# Y) i
  133.    
    0 r& Z& u% h( e0 k
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    8 L2 ^' m2 F& j1 b! `0 Q/ r
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"
    $ g; M2 e+ ^$ g% U. n
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    8 l( y6 U- o/ n4 o+ m( j) `
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    $ a4 c: r, N* U2 D0 N
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    5 p+ O* f" K$ y7 F% i7 K( _
  139.     pdf->offset += length;6 I5 R2 @, h! Y* D
  140.     while(font_list[i])* J8 s7 n$ _) B. Y/ C7 T/ q/ m
  141.     {1 b5 \+ Q3 ^" z5 W  ^8 P. v1 H- r
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);! G' s+ @2 G4 c, n0 b4 i
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    $ B8 _9 Y+ o1 Z( Q
  144.         pdf->offset += length;
    8 ?# s8 o6 u9 S/ v% c
  145.         i+=1;  K7 i! j& L, ^4 c
  146.     }0 M4 d$ y. y! O' O! [) m) p( m
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");, J, C* a8 `9 c" g! e6 j* @" W* l
  148.     pdf->offset += 4;; \0 D. U& C! O9 T" s0 m  }+ V
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];
    7 G0 H' ^2 f7 E, n
  150.     page->width = 595;0 Q: x+ |+ p5 W6 F. ~
  151.     page->height = 842;
    . c7 C' }9 R" T* N9 P
  152.     page->gMode = LPDF_GMODE_INVALID;) {  S4 Y! ]+ E  X* F1 o2 |3 U
  153.     page->fontType = LPDF_FONT_INVALID;$ Q9 Y1 C6 i7 y8 t+ p9 w' W: Y
  154.     page->doc = pdf;
    ! _! n8 w. U* m2 ~& |" b
  155.     return page;* k6 k2 |- E% k& _5 i5 O
  156. }
    # K6 J4 U4 K; d* B' {

  157. ' V! n# c/ h* b4 }. n' M
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)
    ' A! D& n" o" P8 v" S# b8 P
  159. {
    + D) C  ~1 R. v+ _. Z
  160.     page->height = value;
    3 Z9 w3 t4 j5 a
  161.     return LPDF_OK;
    4 D( s: l3 h9 U3 M& C( [
  162. }5 s4 W0 ^2 X. D  d
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    : b9 E( @5 j3 ?# l/ `
  164. {7 m5 M- S) L  E" Y8 T4 ~0 C$ F4 ^. g
  165.     page->width = value;
    * b7 R5 ?& B( a2 ^- Z2 l
  166.     return LPDF_OK;/ G; b/ i& k* ?
  167. }. }! ?9 \( F4 I2 R( k( ~3 _

  168. , F3 g$ [* {* C/ S
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)+ q  o" k" d& `$ U8 w. m) B
  170. {0 i- c5 [$ @2 G$ k# |
  171.     if(page)& w/ V+ Z7 f$ u0 l
  172.     {& N3 D$ b# v8 A, Y. L- K+ \
  173.         return page->height;
    - J& `+ V' P, ~0 i
  174.     }
    4 p, T. A$ c* j* R' r7 @. G4 Q
  175.    
    + Y+ b9 j) y. }/ g8 I# d' z1 _
  176.     return LPDF_OK;
    . C# }+ W% N2 W: ~7 b5 _' K0 C
  177. }
    7 D7 A, m3 O& S7 |

  178. 8 E  B+ e; `2 {5 E  F% [7 V. \
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
      I0 o+ f- ]5 B; N+ n" E) o
  180. {
    + J. C! A, E7 c5 P
  181.     if(page)1 c% D( R. _( {2 T( ^' u5 K
  182.     {5 l3 b) F$ g% l$ v4 N/ N
  183.         return page->width;( R; i/ P7 ?, i; s/ b
  184.     }
    / B- Z  ^3 m, {9 n0 j) q+ u
  185.    
    7 w$ f0 y1 w* I' q/ T+ c- w
  186.     return LPDF_OK;
    7 e7 [& u: }( t' x% b3 C* c
  187. }
    ! ~; T* h& j$ J% j. T; W9 X5 G, B
  188. - R" l& `8 p5 ]  l/ h; {
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)9 m% F6 j/ F- o% V
  190. {
    . t0 E6 L- l$ j" S, A1 t: D( o
  191.     if(!page)" m3 H; a: w" \! N5 A
  192.         return LPDF_INVALID_OBJECT;- D: D# b6 L7 B" H- S. K. T
  193.     if(!(page->gMode&mode))& {" L, L* o5 \. M+ b* f8 K+ J2 P
  194.         return LPDF_FAILED;
    ; F0 }/ m2 O8 c9 t: g
  195. - b, m+ u: a9 a- t1 I% e
  196.     return LPDF_OK;
    5 U( i* U$ m- W
  197. }
    7 B, r/ F2 p/ b, j9 \( v  i2 m, X

  198. ; M4 ^/ {6 J' n2 c) r: p/ q
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    ( O( L2 E9 T% A
  200.                            const char *font_name, LPDF_UINT8 size)
    $ m9 N/ Q& T% k. K
  201. {3 g  Z3 X' [! R$ \0 `8 M3 S
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;6 D7 v( n( l, B+ T) v; U! @7 Q
  203.     LPDF_INT i = 0,length = 0;
    " `( G5 e8 Z6 `: N) ~
  204.         LPDF_UINT writeBytes = 0;4 Y5 k+ ?9 ~7 \( t
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);) k9 p: u- Q0 V% G% c
  206.     if(LPDF_OK != ret)' g+ z8 N( L. L  c
  207.         return ret;
    : {% f% E" j4 d

  208. , |3 L0 C* f0 w0 L
  209.     while(font_list[i])
    $ w0 p: q2 S' @5 _+ i/ k  c% I7 l
  210.     {
    " e$ j" K# v- q, V' L6 C7 {9 O
  211.         if(0 == strcmp(font_list[i],font_name))# C; s4 R  [2 o2 r
  212.         {
    7 d" M: _! h8 Y/ S
  213.             page->fontType = i;
    : s" w3 E3 V( K+ n2 d
  214.             page->fontSize = size;
      D/ i3 b  V  z! d( f
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);5 R  c+ q2 C, i! \
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);+ n$ O+ C/ _4 e0 U' Y8 R9 A7 ~- L
  217.             pdf->offset += length;
    # U3 k6 u/ q2 ]$ [5 f
  218.             page->length += length;+ b% c* a+ e9 g+ r9 I7 w
  219.             return LPDF_OK;. Q5 e6 l! O& _& W6 p/ }0 e: s
  220.         }
    ' v3 {& F  w& s3 y% g2 u$ [
  221.         i+=1;# ~6 k4 O$ W* X8 X9 F. p
  222.     }
    / ]/ g! K3 u1 g8 k: f$ J, E1 }
  223.     # J( w4 ]$ M/ }
  224.     return LPDF_OK;+ F) o7 ^( d$ G
  225. }. r4 X2 ~, a* g; a3 W9 F& ]
  226. / h+ w4 {+ O9 T$ h  x
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page), u( \5 P5 x9 J2 R, ^8 e! `6 o
  228. {3 R6 N& z1 ^6 G  @' G
  229.     LPDF_INT length;
    6 `& U' W4 m: r) m- |3 X" c
  230.         LPDF_UINT writeBytes = 0;
    7 W0 u: w6 k9 }# W! C  k) T
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
      ^& g% }6 L+ ~
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);, e) }7 [' p8 z. M
  233.     if(LPDF_OK != ret)2 _& F$ U/ w9 @; C1 u) P$ Z: }5 O
  234.         return ret;& |) u& _0 g+ ]
  235.     ' Q% f( I0 v: ^" r9 B  c: t, J% g
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */* I+ T  B1 J% ]
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
    1 @  b, n# h6 Q2 d" `1 @
  238.                         page->width, page->height);
    + E& a( _% w2 L1 J: V
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);! m# ?# d) s4 {6 Z' z$ {
  240.     pdf->offset += length;
    % C+ ^+ }- N+ C- e( f# H, p5 B
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    * o" _6 h0 N& Y0 `
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",
    - o9 E/ X7 p. |) s
  243.                         pdf->objNumber+2, pdf->objNumber+3);! p6 A. K. t( _3 Z* ?) t  q1 S0 |
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);+ d* Q$ ?: j4 h) N
  245.     pdf->offset += length;$ L) q+ v# [7 \& c1 Q  w
  246.     page->length = 0;+ s) y( l" h5 \- c
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    6 ]* F7 \3 K& y5 Z  c; @( n
  248.     return LPDF_OK;3 Z5 ]! Z: R/ Q* J
  249. }
    6 v2 H' M9 ?0 u% N' \- k

  250. * S7 ~% q2 |, r& @; }; W; v, t
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)
    , Z8 B0 g) U- }8 r; E
  252. {
    0 T  ?# p3 o8 ^- x9 U
  253.     LPDF_INT length;
    # D" m2 [2 N9 b; ]/ ?% r) x
  254.         LPDF_UINT writeBytes = 0;
    & M( k. y# s. y) N1 d% B  G: v! y
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;! [$ w1 a; U) l; @8 m
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    9 L& @! Z7 G+ R  ^1 }+ j4 K- _. e
  257.     if(LPDF_OK != ret)6 d1 U& C4 Z0 j, i
  258.         return ret;
    * P& T& ~; p/ t/ e* o
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    ' U! H7 v& f9 |4 q4 ?
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");$ o1 k" v& o  R8 j) X7 K
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ) K- P( q6 f( |
  262.     pdf->offset += length;
    " p/ y, {$ w0 Q$ M+ G/ {' [
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;
    1 {) Z$ F- c8 W9 d% j
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    # K; ]% i% H- D
  265.                         pdf->objNumber+3,page->length);( R9 T, a  L6 Q( {5 m
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    + Q" V: E& @4 c: j
  267.     pdf->offset += length;& g; r1 a# K9 |6 h9 m/ Q
  268.     pdf->objNumber += 3;2 p- N" J- |( u3 _! a+ K
  269.     page->gMode = LPDF_GMODE_OVER;# \# E) f' s) J/ x6 Z, {
  270.     return LPDF_OK;/ `+ N" a: }* P! ^% x$ s" p
  271. }
    ) `/ M& d$ M2 T- H% P" `/ U3 g

  272. ( y* ?4 ~- w0 M& H( ~) R# S
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    + e  Z. O( S2 ?! V% L# e1 Q( q
  274. {
    6 G/ U; M; u7 @  C  q8 o9 q
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    $ y* o& Y: q- ^- |
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    + |* E8 q3 j& a  ]( y) N. g
  277.     if(LPDF_OK != ret)
    : F% ~6 b6 F4 u$ F7 v0 H1 |) ]
  278.         return ret;2 r+ V! J% }7 h+ C4 C2 {/ d
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    6 W( x" Z5 g9 D
  280.     pdf->offset += 3;3 ?8 I+ H% Q0 k; n( K; N
  281.     page->length += 3;4 U- R- W& @/ H( R+ h& m4 B
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;0 r6 O9 l/ k& \
  283.     return LPDF_OK;
    - d0 ?) R) i8 y( N3 B$ D: j/ [; w
  284. }
    - H$ M  S! a( Q# [
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)
    ! N' m/ w3 J0 R
  286. {
    ; g& N6 x' O9 C- y
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;! d7 ^+ h' g3 U: o6 @! i1 ^+ ~) Q& O
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);, R" V2 v3 W* v: c8 y) j
  289.     if(LPDF_OK != ret)
    ; v! o4 P9 q5 }; [
  290.         return ret;
    0 @3 v+ r- K7 {- U) }$ M) W
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");3 Q( a" L& F! x) A
  292.     pdf->offset += 3;/ |& M  @. G/ y" t0 `+ H( o/ J
  293.     page->length += 3;
    ' d" r" B* w' Y
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;: d8 d, e' b" h# H9 Z
  295.     return LPDF_OK;, \0 G% N2 s8 x; d: }$ [7 i
  296. }* s2 T1 s& U% n1 V" A7 W

  297. 0 @2 B; f  Z) e' m! [3 X
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    ) B4 ^/ F' }1 P2 I
  299. {" b  Q# ^/ s& H9 @, _$ d
  300.     LPDF_INT length = 0;% F& F5 ~2 ]9 F* D  F
  301.         LPDF_UINT writeBytes = 0;  z. G8 Z8 G( P/ t7 w0 @$ A" M
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;6 o9 d; e. I3 `/ Z, p
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);' H' J2 j9 |6 I
  304.     if(LPDF_OK != ret)4 G1 {# M% e% F, ^5 a- E
  305.         return ret;8 i& Z$ m) \5 P
  306.     if(LPDF_FONT_INVALID == page->fontType)- }2 b# U" a( k0 d- ~9 j* h/ l* o
  307.         return LPDF_OK;- I$ N4 P$ R) @- ?7 @0 ^( ?& q
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);) R% B- `# W) b3 k
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    2 n+ [) I7 l  _
  310.     pdf->offset += length;
    ( w: z. w% m  i4 W: p8 V
  311.     page->length += length;
    % f/ u; W! l( o  [8 Y5 a: l
  312.     return LPDF_OK;  [9 c- }' m& B0 r5 G! Y* f
  313.     + T: Z6 W7 X* @1 k
  314. }7 z. R, d/ o, ~9 z
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,, ~$ t- y" @7 ^+ V8 a
  316.                         LPDF_INT x, LPDF_INT y)7 G  g8 R0 b, y$ V# n
  317. {5 }0 G9 ]$ b- [5 ?  E" n+ f
  318.     LPDF_INT length = 0;! Q" @5 W, `: h2 H$ M/ P6 h
  319.         LPDF_UINT writeBytes = 0;
    ! U; d; w" [# i  Y, I0 t9 ?6 w8 n
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;2 g: c8 W, `; r, a& n! }
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    & z. ]5 `; w1 _7 C4 K; U' I2 Q
  322.     if(LPDF_OK != ret)' z  n8 T# X5 y% \) w
  323.         return ret;
    & O0 b9 d$ e* {: `
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);% L- D; x1 x& x2 m
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);5 ]  r' s0 `  R1 k% @, ~
  326.     pdf->offset += length;. f, O6 ?1 J1 X# _
  327.     page->length += length;
      m) u; Q) Q8 Z# U! [; F

  328. & Z- P2 ?$ _5 F" @$ L+ P0 q- E
  329.     return LPDF_OK;8 A  c8 c) J+ y* D. I% r3 @9 V
  330. }& u/ Y2 t# D+ \* N* h
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, ( H& x. g2 X1 y+ j2 B
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,4 O" c; t- K3 Z. n
  333.                         const char *text)2 r5 @) ]3 W" S1 W3 P. N
  334. {
    : M& _+ N, q2 D& r. l
  335.     return LPDF_OK;* {" u+ `; P  M, z, a
  336. }
    2 E1 w' F4 u4 p$ K% u) O& u
  337. : \4 B' v7 X/ _8 [) m* Y/ o
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,. s% r: u: I5 D# q! U1 f  ~
  339.                          LPDF_REAL r,
    ' Z, u  ~" j6 @& H( ]
  340.                          LPDF_REAL g,
    / k" a) K% t9 B; ^+ _
  341.                          LPDF_REAL b)3 W; T* y# Y# Q) S
  342. {% k4 F8 q( d* y0 V/ [6 S7 N# w. G
  343.     LPDF_INT length = 0;9 }: f! c7 k. V
  344.         LPDF_UINT writeBytes = 0;+ P0 i, s8 N- ?. C
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;3 h1 M8 k9 t" J8 Z8 J: D5 b8 m
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);5 }" ?# z' o( U  T! `. ^+ ~
  347.     if(LPDF_OK != ret)/ A# P7 n2 u* a1 }: Y
  348.         return ret;$ G/ V( z2 g1 @% F, L: R3 S
  349. + U8 a) _+ w6 n6 ?
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);, h8 i/ Y6 Y& B# _) _# B
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ; D1 j% k4 q+ i% ~& B+ H: S
  352.     pdf->offset += length;+ Y1 K5 [& v) y9 z7 u
  353.     page->length += length;
    5 V- \- |( A% {- B  t: A0 K
  354.     return LPDF_OK;
    ) Z7 G% J- q  z9 t9 @/ _1 [: q
  355. }1 Y* P8 n" h  W/ j' y

  356. , j* Y7 [+ {, Q5 W
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    ) @$ X& i5 |9 o& L  V2 c$ D4 r' y, W
  358.                          LPDF_REAL r,( n8 C; {4 J: W9 {. |
  359.                          LPDF_REAL g,! N% K# Q0 [6 K( F8 H9 G
  360.                          LPDF_REAL b)4 E$ h9 T1 M7 T  l+ E2 q0 X6 Q
  361. {
    + h: r) u5 e( o  e% z: L
  362.     LPDF_INT length = 0;
    + I9 T% z4 d+ H* q! @5 W6 v
  363.         LPDF_UINT writeBytes = 0;" U' E. L% n3 I0 P, e- a
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ; b1 c* ~& q1 d
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    $ K4 P( I: p+ a) k' g$ d( A
  366.     if(LPDF_OK != ret)" A0 r$ n) ^+ B9 _0 R2 o- g+ S, v
  367.         return ret;: ?8 F, {! r. }3 w, b. }5 }

  368. : G8 N* r# j; J+ t, B
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);
    8 e3 X/ g0 s0 k, L
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);+ c# @7 [: v& t- ~
  371.     pdf->offset += length;! f& Z0 N$ v& m5 c, D
  372.     page->length += length;2 t2 O! ]/ ]6 S2 S
  373.     return LPDF_OK;& D2 q0 J$ C  h( T( P
  374. }
    6 B  o4 @3 Q0 q- W6 l. `
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    ( g3 c# a/ W/ L0 }! l
  376.                          LPDF_UINT16 x,
    6 X) k4 |9 q. ~
  377.                          LPDF_UINT16 y)
    / a0 {2 F/ s# z0 K/ E
  378. {, _) f% v) B) @, t3 O/ u
  379.     LPDF_INT length = 0;
    ! p) Z. A6 r( l2 p
  380.         LPDF_UINT writeBytes = 0;  f; S) r% c- Q8 n
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    . X  I8 T0 U* k% S/ B
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);
    6 k; z0 S1 v5 O; A3 e5 G9 ^0 G
  383.     if(LPDF_OK != ret)
    ! l1 H3 c. h& k- m
  384.         return ret;
    " A. b) q% Z3 N, r2 H
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    2 w8 U* T& O1 I
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; x) o  o+ n1 |! A& E; _- c- I
  387.     pdf->offset += length;
    2 W$ e0 w0 @' I  x/ T4 }/ j+ t; k
  388.     page->length += length;# ~  f- y* Z* C7 j, v
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;/ x/ w& V  o/ {9 J+ ^) B
  390.     return LPDF_OK;# x( n. J! U) O# D3 n7 U0 f9 d
  391. }
    / z* W: W, p% c$ g) ~# l
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,' b) c9 c/ V. y2 C
  393.                          LPDF_UINT16 x,% |- X8 ?5 ]+ |! a# p
  394.                          LPDF_UINT16 y)0 Y) [- @+ G9 N
  395. {
    1 p# O- z& p' Q- A* G
  396.     LPDF_INT length = 0;
    # n, ~2 E7 L; V
  397.         LPDF_UINT writeBytes = 0;* ~$ }) w9 ^6 y, f# F. {" F  V( ]
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;4 p3 X  N0 N+ c8 J; m
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    5 @  D; R$ Y4 g: N  o! x1 u* C
  400.     if(LPDF_OK != ret)6 O5 q2 S' x# v7 P) ], h
  401.         return ret;
    % {# a3 g9 U/ \
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    / g4 o+ U" d2 w* z& \
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    & {% W  F7 D" E: h) n# y
  404.     pdf->offset += length;
    ! R) S- g) n& P! ^, ]- L( D
  405.     page->length += length;7 S! z5 h  d' ~2 k
  406.     return LPDF_OK;
    + C5 o: z/ g& {) d) H+ U
  407. }& M( [2 r5 g3 q; K7 G0 `+ k) z1 \
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)1 X' n* Z0 C6 ~. X/ `, q- `9 b
  409. {& Q% G5 D) c( L: `& u9 d
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;/ v  @3 ?" l  G
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    ( J0 v4 n1 S7 b$ ^. [4 E& Z, T
  412.     if(LPDF_OK != ret)" R* H5 A5 f; x) ]2 p5 N# P( ^' E
  413.         return ret;
    ) q/ b  e% q# s$ M  V  R5 @; C% W6 v
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    5 o8 k4 R6 G5 S! [4 @
  415.     pdf->offset += 2;
    - W$ x2 ~/ S$ I5 P* z
  416.     page->length += 2;
    - x& N  s8 M) A5 W, F
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;& M+ A! V/ T6 ?8 D! y7 {! a0 A
  418.     return LPDF_OK;) ^& Z% u8 ~1 W3 ^+ c) L" T% [
  419. }7 i- q: Y* R& i' s: H
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,) k. I, j" X2 b
  421.                       LPDF_Image image,; }4 R, j3 k$ g& w* J; B
  422.                       LPDF_UINT16 x,
    " `7 \+ N7 V6 Z# U7 }
  423.                       LPDF_UINT16 y,
    2 Q+ V. H& H8 z! P$ S( t4 `6 ^
  424.                       LPDF_UINT16 width,& I- H6 b' k2 N- y: E7 r/ b/ Y
  425.                       LPDF_UINT16 height)
    $ X% \( m2 F, `+ |% T
  426. {6 s$ F& I, p% P9 J" o3 l
  427.         return LPDF_OK;5 H7 [) h" d3 F
  428. }
    9 h4 M9 u/ ^/ U( e
复制代码

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

  1. pdf = LPDF_New();
    . k$ p0 B5 I$ y2 ?8 y1 v
  2.     page[0] = LPDF_AddPage(pdf);0 l! Q; L3 x+ e( \. U  Z
  3.     LPDF_Page_SaveParams(page[0]);
    0 }5 Z" F/ r, B
  4.     width = LPDF_Page_GetWidth(page[0]);
    / j! r& U% P( P* o1 Z2 i& `( K
  5.     height = LPDF_Page_GetHeight(page[0]);$ y- ?) @# D' m$ s0 D
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);
    9 n' U) a% i; Z8 I( x2 ^; {* V
  7.     LPDF_Page_BeginText(page[0]);
    - g  E1 r- Q0 p( d: E- h# j+ {
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);
    , l' C; e/ ?" y% u& N
  9.     while(font_list[i]): Q8 `# \+ y! }! Q
  10.     {$ c# D9 u& U+ F8 g; [& U  W( h2 P
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);) t6 \( z5 i( _- r9 R
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");6 g& e: @6 `5 Y, q' o4 `* {9 n' |+ t
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);8 p; k5 j' @6 P; n% Q; H1 ^! D
  14.         i++;
    3 {! A. a3 X  u6 [; e+ j% F
  15.     }5 f, w& Q8 a3 c# B, s
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);
    9 T5 e7 V' ]( z3 w1 r
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());
    ) Y* C. H3 ]; x' p0 }5 `5 V3 t. h
  18.     LPDF_Page_EndText(page[0]);
    5 E" W0 y8 w0 L+ g0 Q) W' F
  19.     LPDF_Page_SaveContext(page[0]);5 H3 Z! r! `5 ]' P0 j; C
  20.     page[1] = LPDF_AddPage(pdf);
    5 h5 V2 |1 O2 S! |- C4 {
  21.     LPDF_Page_SaveParams(page[1]);
    " o8 S1 J0 V9 H1 I- v) c. K9 @3 o0 I
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);
    : Q- |1 S9 I. l0 n
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    5 \$ Y7 e9 N4 r
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);# X4 h; X* \1 b, I& U7 S& ^% _
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);0 j& ^2 Q* E9 [9 ~
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);0 g  r' h0 Q, N* z9 I9 f4 {5 Q: Y7 F* V! R
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);
    ) }2 L& u8 _: l: O) ^
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);$ F' t" [) \! x( F* _
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    , D3 w! x' ]6 X7 E& K
  30.     LPDF_Page_Stroke(page[1]);9 k! c8 _- w) h, P
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    % Y8 |& v% G% i* r  \  ^9 Q/ D
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);$ Z  v" i: Y$ H& N( I1 X
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);+ Z, {5 p3 N6 P  B
  34.     LPDF_Page_Stroke(page[1]);
    / Y6 n3 B) |' Q# n7 p
  35.     LPDF_Page_SaveContext(page[1]);, e8 c2 m: P/ S
  36.     LPDF_SaveToFile(pdf, "/red.pdf");, E* U- l) q- k( l; y
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    $ d# d2 f* `- c3 n
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了8 i0 l: S$ U4 E8 X; V0 G: q

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    7 O; x& s) ]* [1 U9 E! ]

1 n' E! r+ b3 `0 }1 Y! z

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
+ j* H5 J* l) e  N1 v只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...

$ r2 ^/ m1 A. t8 g" G. s/ y3 [) ILZ,我怎么没看到有添加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:334 G6 w5 a7 T+ @1 Q6 S3 S: \" t
首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
2 x3 `! E7 }7 }  ]8 t9 w! @- C
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
0 Y5 J7 R* Z3 @. I0 S* e5 v
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:458 S3 m0 b7 o* A& p$ Z/ y$ c* l
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
( Y, Q+ q+ W; ^& I0 c
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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
  \- n( ^1 V. f3 i: Z4 R! w7 @厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接
  {) K$ |. V1 |& g' J) j* e- O
这个还只是一个简单的库,实用性还是差一些的
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' f1 E+ `& Y$ @" Y! c5 r" q* ?2 P7 M$ {
ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗

$ t# J( l8 D& y3 p5 \, l, p  l$ Hff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22  ?: z) C  W0 _4 s. x1 I  P6 L/ b
ff.h是FATfs中的文件
: W' r# f. N$ I! Z- o* g1 D: ?
嗯,这个画线能改变线宽吗

所属标签

相似分享

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