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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 " j4 ~4 |8 E( \+ o' ^
6 i% I/ f; s$ \. `; h+ w

主机环境: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__
    4 m8 D2 W" j# ^7 Q+ }+ B# D% o: U6 r
  2. #define __PDFLIB_H__
    " p8 ?3 p% t) ~# B1 M+ }3 H% `5 s
  3. 7 J9 X; w( X* D9 b
  4. #include "ff.h"
    % g: n0 u: W7 Y9 X
  5. /*----- standard C library functions -----------------------------------------*/
      n6 K8 B# v) o. a+ L' F: \6 b7 d
  6. & V2 g. a& n3 l, f* C1 u6 [
  7. #define LPDF_FOPEN                  f_open
    : q% j# X, E4 o; R, Q$ B+ S% y
  8. #define LPDF_FCLOSE                 f_close
    ' U# n/ g7 k6 A2 A9 U: M+ w8 M
  9. #define LPDF_FREAD                  f_read0 u& r+ c. q# H3 I9 S5 f
  10. #define LPDF_FWRITE                 f_write, m% ~! {  j" V- q' c0 L+ |
  11. #define LPDF_FFLUSH                 f_sync2 }7 J  w9 a3 E* B6 t- J5 X
  12. #define LPDF_FSEEK                  f_seek
    5 [! l3 `4 Q  U) x! i! Y( _
  13. #define LPDF_FTELL                  f_tell0 `- y( b( N) N7 Q0 s
  14. #define LPDF_FEOF                   f_eof
    6 h2 F$ x& R$ l/ v7 C
  15. #define LPDF_FERROR                 f_error
    1 k$ F! Y& Q4 Q6 p, [2 K
  16. #define LPDF_RENAME                 f_rename
      a2 d. _5 G' t, u
  17. #define LPDF_REMOVE                 f_unlink# W& f  |  w& w. ?7 I$ v  q
  18. #define LPDF_MALLOC                 malloc
    3 J! z5 ~2 M+ R5 t7 }7 ]& C8 d
  19. #define LPDF_FREE                   free
      D0 }+ {- z" R; ~6 I
  20. #define LPDF_FILE                   FIL
    4 O7 f# ], [: Z
  21. #define LPDF_TIME                   time8 j/ E% e9 U  s3 A3 l) M2 j
  22. #define LPDF_PRINTF                 printf
    + m, M% F& P- C" _; K
  23. #define LPDF_SPRINTF                sprintf3 T+ B. v6 i2 h, f+ V8 b+ [6 {) ~7 b
  24. #define LPDF_FPRINTF                f_printf6 r  q1 {* V7 l- `5 D
  25. #define LPDF_VOID                   void
    ' W) n  _/ K0 s
  26. #define LPDF_SIN                    sin0 A  M( O. T) o, D8 M$ i
  27. #define LPDF_COS                    cos
    ! e5 t( X$ ]* K; g1 N) `' L& ~

  28. ' e# }: W4 t+ M" V
  29. /*  native OS integer types */: \; G& P0 e0 Y2 l) g- q6 Z$ }
  30. typedef  signed int          LPDF_INT;
    3 L& w7 t/ G8 q
  31. typedef  unsigned int        LPDF_UINT;
    : y/ j4 M2 k1 U/ X1 `+ H

  32. , x' Q; `5 G' w/ A/ n
  33. - x1 h  x4 v' \" }' i
  34. /*  32bit integer types: l! d( [4 S9 n
  35. */5 G3 z& {) o% L" a/ C+ U. I
  36. typedef  signed int          LPDF_INT32;
    . `( e. h- T7 M* Y& M
  37. typedef  unsigned int        LPDF_UINT32;. U% @9 a# n# c% C

  38. 5 t8 G0 Z5 r3 O' r2 s, ^
  39. 3 S1 _( \% l1 U
  40. /*  16bit integer types
    8 G: @& p4 y8 @' I. n
  41. */
    ( H. D6 Q) c+ M8 D
  42. typedef  signed short        LPDF_INT16;
    / ?/ W5 O  ^* ]# C9 l# ~+ S
  43. typedef  unsigned short      LPDF_UINT16;
    , \! s  e3 G; Y* D+ O: a

  44. - }% q! m5 Q; A

  45. ) C* n+ e) i4 A! K
  46. /*  8bit integer types: O3 v: n( o. E) y7 `
  47. */
    * Q# p$ Q  ]5 @2 a* K
  48. typedef  signed char         LPDF_INT8;( s& p& L- c& B6 F; n( @* o( r! ^
  49. typedef  unsigned char       LPDF_UINT8;
    0 K8 e- }/ ~5 n! Z; ?, @% z
  50. 5 t2 O7 e# ]  o. I

  51. 9 _2 ^( y) K: Y6 {6 r- n$ B; w( ~
  52. /*  8bit binary types
    - p% L9 {' ^9 Z' {+ b8 ^: a
  53. */( M8 ~/ I, p7 P8 @
  54. typedef  unsigned char       LPDF_BYTE;2 F2 v5 H- I7 H4 V

  55. 1 \  V9 U0 }& O) I5 z
  56. * O1 k  @3 n; D) T) m4 q
  57. /*  float type (32bit IEEE754)
    / }" f- o, t# Y
  58. */+ q- z0 L+ K, ?) B0 I
  59. typedef  float               LPDF_REAL;9 g/ |9 w: `( d2 ^0 v5 _
  60. 1 A' x& _% H. z8 D" a. v) S7 e$ b6 n
  61. 1 N9 b: C% {; x( w) f9 Y
  62. /*  double type (64bit IEEE754)
    1 Y8 u7 h& q& G* D. L  Q
  63. */8 c9 R3 ?# b3 ~# a
  64. typedef  double              LPDF_DOUBLE;- l# _8 h2 E/ ^7 ?6 i

  65. % Y6 S9 v; p$ O7 c' r# \2 U5 z

  66. ( y: S' Y+ M9 g* V3 f" e. K" C% ^
  67. /*  boolean type (0: False, !0: True)$ h/ H' d9 ?# U
  68. */& s0 N# K0 ~# |! H  O& Y- P0 G  n9 w
  69. typedef  signed int          LPDF_BOOL;
    + C% V4 p+ _) K- J+ i
  70. 4 r: D( X. G, T2 n! Y1 Q
  71. 7 w9 J3 O9 g4 c4 f
  72. /*  error-no type (32bit unsigned integer)
    - R- d1 B6 u3 _! Z2 V
  73. */7 x: U  I3 V. ^
  74. typedef  unsigned long       LPDF_STATUS;
    , c0 |  b$ _9 J
  75. 3 }# t$ y2 W5 X
  76. #define LPDF_OK                     0
    / i& V0 z" ^: g! X
  77. #define LPDF_FAILED                 1
    - j3 B+ j& B, T' e4 \4 L% J6 R
  78. 2 j7 u9 T6 i, }, I
  79. /*----- font state -----------------------------------------------------------*/# b2 E# l$ m* B: }7 E) P2 G
  80. #define   LPDF_FONT_INVALID                 0x00FF
    4 ?0 B: |1 r1 x2 ]/ P; C2 ?/ M5 m
  81. #define   LPDF_FONT_COURIER                 0x0000% d! y* k3 S4 j0 d- l6 ^) q& L
  82. #define   LPDF_FONT_COURIER_B               0x0001
    - D; W: w' c5 p
  83. #define   LPDF_FONT_COURIER_O               0x0002
    4 v" P4 A& T! `
  84. #define   LPDF_FONT_COURIER_OB              0x0003/ }! B' j% R& }: w5 N& B7 [) r+ ]
  85. #define   LPDF_FONT_HELVETICA               0x0004
    9 D* e1 U% N! w2 J! L
  86. #define   LPDF_FONT_HELVETICA_B             0x0005
    ' N4 H& ]- G7 i) s: w
  87. #define   LPDF_FONT_HELVETICA_O             0x00066 g2 U- V, B) w
  88. #define   LPDF_FONT_HELVETICA_BO            0x00072 N# J! N2 O; ~: L4 o0 B
  89. #define   LPDF_FONT_TIMES_R                 0x0008- C% |1 e) I$ A7 u( Y
  90. #define   LPDF_FONT_TIMES_B                 0x0009; g) T; |' V6 Z6 `; o9 D
  91. #define   LPDF_FONT_TIMES_I                 0x000A
    / {7 O0 d/ q9 ?* J$ A
  92. #define   LPDF_FONT_TIMES_BI                0x000B* H4 I/ u" Y) y# i# R8 P; e, ~
  93. #define   LPDF_FONT_SYMBOL                  0x000C
    * w( H$ q$ m' d. ~  E* z% J
  94. #define   LPDF_FONT_ZAP                     0x000D4 ]& _2 g4 j: }$ u, D) X
  95. /*----- Graphis mode ---------------------------------------------------------*/
    9 v* Z2 b: f% W: E7 ]4 ~  U1 i6 d5 R
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    " i7 Z* |, m# W+ r: `
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    & N" L- f6 E! @$ s9 r
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x00040 P; Z  l) D( `' o4 U, Z
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x00080 f9 l% S' m) L; {8 N; \
  100. #define   LPDF_GMODE_SHADING                0x0010
    1 g) U/ E5 [" V  z0 A( \
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020* ^0 ?4 Y2 r' x' c# g
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x00402 p2 J9 Z$ r8 }9 H9 z$ |7 D
  103. #define   LPDF_GMODE_INVALID                0x0080) j) W' l  }- j2 i9 H4 k6 S; N# @- h7 A
  104. #define   LPDF_GMODE_OVER                   0x0100- A8 k( i8 ~* I: z; O- X: N

  105. , y' T/ ~! I. Q& Y$ g: @  z
  106. #define OBJ_MAX_NUM     2569 ]3 q0 {, _) c1 E; C# A

  107. ) {4 w* j: x" h) \' ?* }( _
  108. /* Page的结构信息是否需要树形结构 */8 ~/ p- n3 P- ^
  109. typedef enum 5 H8 B4 q8 Z5 W* m% V6 W# Q
  110. {: ^; B5 I/ j/ g3 L2 R3 {. n
  111.     OBJ_info,
    6 o2 C1 n+ F" o
  112.     OBJ_stream,
    2 o0 G- @8 O2 u" h+ a' G1 h0 a  d0 x
  113.     OBJ_font,0 J2 G( b2 ~& g0 _1 _3 S  Z; S
  114.     OBJ_page,
    & {* \& J5 P/ Q6 u
  115.     OBJ_catalog,
    + Z5 ^* \+ w% a, [! P3 v& w4 D
  116.     OBJ_pages,
    % f4 u0 f7 e1 Y: S5 F
  117.     OBJ_image,8 G" u, f( i/ }7 L- m6 r4 @
  118. }LPDF_ObjType;# f+ R% \8 ~/ }1 [
  119. 1 O5 \" \: y0 d7 ~9 B
  120. typedef struct
    ) Z; X, z* i' }8 c. |5 S
  121. {
    4 F, S8 b$ I2 V
  122.     LPDF_ObjType objType;
    8 j- c  H$ y% @9 g. K6 ]/ F
  123.     LPDF_UINT16 objIdx;3 N5 \0 R  K% I) Q
  124.     LPDF_UINT16 height;
    $ j" T" d$ n* e, V( D( M4 r7 y
  125.     LPDF_UINT16 width;0 l" F" `8 ~3 V$ w; `+ E
  126.     LPDF_UINT16 length;5 U8 ?" ^: h6 \+ H, l: R5 [7 X
  127.     LPDF_UINT gMode;" O! Q. q8 Z8 c5 x
  128.     LPDF_BYTE fontType;
    ; ~) l+ \: y9 m- q! b/ \, I: [1 C0 }- Y
  129.     LPDF_BYTE fontSize;7 N- Q* A8 w4 L5 u" j4 [
  130.     LPDF_BYTE pState;: n3 q- F2 \  A' A, o" @! ?
  131.     LPDF_VOID *doc;
    $ r) `; Z& J$ a. ?/ X$ k# e1 g
  132. }LPDF_Obj;
    % z5 _' w4 u" ]  @: r* z$ ~8 v3 {

  133. . Y* m+ S2 |8 T. B* J% i$ {
  134. typedef struct, k7 w$ t( f9 Y& m& c/ \4 u
  135. {
    % I- j( T6 R; u6 r+ p9 L+ C
  136.     LPDF_Obj obj[OBJ_MAX_NUM];; w6 Q) {) G! s0 J6 ~/ y3 s
  137.     LPDF_UINT32 offset;# n- g: F! `+ a, @3 U
  138.     LPDF_UINT16 objNumber;# m+ E1 t5 d3 N" w& ?, k, D, m% N5 ?
  139.     LPDF_FILE file;; O% Q2 X; l3 x* a' s  H. d5 {: F# O5 a
  140. }LPDF_Doc_Rec;
    ' D- k" M/ q8 J; m
  141. 0 `& `, Z% g/ R9 G  @; a- d; j' d
  142. typedef LPDF_Doc_Rec *LPDF_Doc;$ ~% x9 g3 B$ g) J8 g
  143. typedef LPDF_Obj *LPDF_Page;7 K1 T9 b( v) I+ i! q1 r  ?
  144. typedef LPDF_Obj *LPDF_Image;
    ! \. c9 q3 ]1 ^6 {" X4 w# [
  145. extern const char *font_list[];
    ; P0 L( ^- |% k" @- B1 p
  146. /*----- LPDF Interfaces-------------------------------------------------------*/2 @) I& \" ]" d6 x
  147. const char * LPDF_GetVersion(void);# k6 X( x* v8 \$ K9 A
  148. LPDF_Doc LPDF_New(void);
    * f# L8 ?8 r7 F
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);# C  b' \0 G& Z( U- S& ~
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);3 t5 M! |. Q2 g9 x2 x' p+ Q; O
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);: a7 Q' n6 |8 m7 u' f* |; k
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);
    % ?  E1 k- I* h" I+ O: ^0 R
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    7 N, l+ U0 T2 X) [- p
  154.                            const char *font_name, LPDF_UINT8 size);- ]. h' \/ Z  X. d3 W& W
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);
    3 i) }. Y2 }. ?1 t+ V5 u
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);/ H5 W: h, ?' |* R# Y! Z
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);
    7 `; R$ _) W4 _: g
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);
    % v7 w# q1 `+ j$ y; @
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
      R; z/ d( r4 ]) s, R
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);
    0 ?. M. T9 i- d* m/ r" D! L
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);9 w: D% ^4 o* q, d- C; a, M
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);& M6 I& p& f* D  ?  Y
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);6 F& a- L. ?0 `( e
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,4 L+ e" k9 y3 R+ K4 D
  165.                          LPDF_INT x, LPDF_INT y);+ M2 C4 b8 v* W' P' ]3 @% h  W
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, ; v; v; U5 P# S# p; a- E
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,
    % \$ O! ]$ d/ e$ Q0 @0 g# a5 J
  168.                          const char *text);
    & M9 `$ {% s- x
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,; l) x4 d- |& D: H
  170.                          LPDF_REAL r,
    % B) S& l; w) q6 @; W  }
  171.                          LPDF_REAL g,
    0 f5 ]0 E" B  u3 x3 ~4 q5 o
  172.                          LPDF_REAL b);
    6 [: D7 x) R- |" N. I( m- y
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    4 F" d7 u' |6 K0 N/ |
  174.                          LPDF_REAL r,- F% Y5 D" Z8 g+ R- c1 p7 m' E" R8 D
  175.                          LPDF_REAL g,
    ! F/ r5 v& W: }5 u9 n
  176.                          LPDF_REAL b);
    * _8 o7 b+ }, _% }. O9 x3 Y/ R2 h# e
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    . x/ f) u; W: \8 w0 }9 i3 P
  178.                          LPDF_UINT16 x,
      A) y( w/ |" |! q4 z3 B
  179.                          LPDF_UINT16 y);/ @- {; R7 F" z+ e# W2 t" D# `
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    1 q& f) Y+ a& Q* z
  181.                          LPDF_UINT16 x,
    9 d8 `  X0 `$ c* a0 f
  182.                          LPDF_UINT16 y);
    : |( u! `7 K8 _, ~
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);3 ~+ @! ~. H! f% U9 p0 s2 k
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);
    4 U  m5 m/ L* t; Y
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,# M+ A- V! U6 t9 f2 \
  186.                       LPDF_Image image,
    8 D4 O% @6 ^. {, h+ q
  187.                       LPDF_UINT16 x,
    ; n+ R8 c- B* F9 s  M/ q* t, C
  188.                       LPDF_UINT16 y,/ N! f# s, H+ A, S8 X0 j
  189.                       LPDF_UINT16 width,: O# C; b0 D4 H7 q# e
  190.                       LPDF_UINT16 height);4 ]$ C/ i$ O4 F- i% ]* M
  191.                                                                                         ( _2 F1 J( i5 |
  192. #endif
    / S" ^' O- F1 U* t
复制代码

源文件如下:

  1. #include <stdio.h>3 H, }. D& L* u6 U$ u# }8 l2 p' @( f+ {
  2. #include <stdlib.h>
    2 x# Y5 \* q% C3 s
  3. #include <stdint.h>
    7 k/ q  j. w# h' \
  4. #include <string.h>! J& n2 Y+ r2 u2 S7 ]+ S
  5. #include "pdflib.h"" O2 b. s) _7 k8 F7 B# T0 Q+ ?$ P
  6. & t, z9 @5 t9 ^% M) z* g
  7. #define LPDF_INVALID_OBJECT                       0x1033/ q4 R; v6 s; {, C2 t4 e/ Q

  8. * @% f; R6 w1 U. O  F$ x- {" `
  9. static char pdf_buf[512];( I: `7 W# a; N% D/ ?6 t
  10. & q* p. H+ r3 f" U6 k
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"
    " N" {+ e/ ^) }* k( _5 H0 _
  12. #define LPDF_FILE_HEADER_LEN        15
    # }1 m; ?2 h! o& K' x; ]$ f+ R
  13. #define LPDF_BASEFONT_NUM           14
    1 d0 f/ @: L; l( o
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    # _$ d9 g6 O8 Z0 X2 ^1 L) ]
  15. const char *font_list[] = {
    + q2 }2 |! g& V9 ?
  16.     "Courier",5 D3 j& P: a  V$ X' s5 ~
  17.     "Courier-Bold",
    / g( t7 e" o8 f8 o/ D
  18.     "Courier-Oblique",+ H, u7 M0 d6 T8 P4 V
  19.     "Courier-BoldOblique",
    5 K  ~2 f! M+ I' Q. Z
  20.     "Helvetica",5 ^8 {% F9 m- M/ [% M4 {
  21.     "Helvetica-Bold",& R( P1 m+ W8 Y  T
  22.     "Helvetica-Oblique",  P0 G9 `* m# ]" H- F
  23.     "Helvetica-BoldOblique",+ z* _% k+ h* f
  24.     "Times-Roman",* n* _# v& T1 J% d) W
  25.     "Times-Bold",0 Q! U. P9 j7 x. w, i/ ]
  26.     "Times-Italic",! C5 z; v1 o" E2 _: H  W
  27.     "Times-BoldItalic",
    2 U; n: K) W% W" R3 B( C2 q) O
  28.     "Symbol",. \' o& R8 O% t' b3 u: P
  29.     "ZapfDingbats",% y+ y& K4 H4 E7 V/ Y
  30.     NULL% h( ?% J0 Z# W. u# n
  31. };
    2 |: p1 H7 @* |$ |  L' q: S/ c

  32. & }! i; }$ \! f' j, l: p  C
  33. 3 R& D' c3 q3 G! s% U
  34. const char * LPDF_GetVersion(void)8 E! V7 X1 d! t0 N- C7 n% n6 o
  35. {
    2 ^  k6 e* A: v" c. t5 p
  36.     return LPDF_VERSIOIN_TEXT;
    - }- n7 a5 ~' [! R
  37. }% r0 O8 }2 N% R$ u- ?0 j( t

  38. : l) i1 b- E. ?0 A7 I# {; @: G7 H
  39. LPDF_Doc LPDF_New(void)
    ' [3 {$ K0 T( `/ N6 P+ C' j
  40. {) ?3 `$ i" {4 v1 x. `; m
  41.     static LPDF_Doc_Rec pdf;
    1 ^& T. e; ~' T' d2 i/ G2 Z' }
  42.     LPDF_INT length = 0, i = 0;& o4 z6 _% c% ?9 V# p) @# V
  43.         LPDF_UINT writeBytes = 0;
    / R$ D# c; m9 r. Z( r' I
  44.         FRESULT fr;
    : J7 c9 M  i7 q3 U* P
  45.    
    ! Z9 h3 M1 y5 @* z9 Y
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);8 H+ U% C4 v* G9 ~
  47.         if(fr)
    . J" K) n& C+ l2 }& ~
  48.         {& N: `6 r# R' w8 W7 }8 v  F
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    , a) n# j. Y( Q) b8 A
  50.                 return NULL;- ^% p; l; ~) p1 v
  51.         }
    . c: O3 e8 a$ w1 ~6 y9 S& V" o' o
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */; @: d$ |% s3 }+ U' P2 W
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;
    9 r3 x% Z7 l, g* U! U1 s9 e
  54.    3 M$ d* u  r$ U
  55.     pdf.obj[0].objIdx = pdf.offset;
    $ }4 r2 Q+ w$ U) a+ Z
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
    $ Y) Z& [% P" G. l9 @
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);7 z; E0 F8 R' }+ R; \4 I$ Y
  58.     pdf.offset += length;
    3 r9 P/ u, c0 `9 i) e; P$ l
  59.     + u1 j& L& Y% S' v. Y
  60.     pdf.obj[1].objIdx = pdf.offset;- x( x  X, u# E, Z+ ~9 ]( u
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"
    3 H" \1 R5 T: \
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");
    7 a; F! z' w1 p
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);( D* I2 h- z2 h: w
  64.     pdf.offset += length;6 m. H4 Y4 r# M/ j+ a( b- `
  65.     8 N/ m* B5 X* K4 Z
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    ! {* [1 j9 ~( q( N
  67.     {- X8 {' f0 G/ F- z
  68.         pdf.obj[2+i].objIdx = pdf.offset;( B3 `3 J! _  I1 P/ k0 g
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    0 D* \7 ?& {$ S" h
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"/ @7 a( w( F% P/ p( P
  71.                         "endobj\n\n",3+i,font_list[i]);
    9 s0 C+ e8 s) W4 _  ~* v
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    & p: j6 t5 O! n( V$ @# N( |4 t
  73.         pdf.offset += length;
    7 h6 J7 P7 L4 i9 Q3 t4 g
  74.     }2 K% u# T* O6 a
  75.     for(; i < LPDF_BASEFONT_NUM; i++). F% s  a/ c7 X* c6 ~% @
  76.     {. {/ L4 M! [' g1 s) j
  77.         pdf.obj[2+i].objIdx = pdf.offset;
    ; b/ g! Q' I( g7 ]
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"7 v4 s& s& P& J% u2 j* v
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
    6 ^# ]# A) V7 [5 r! }! g8 V! R1 x
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    2 g' o% S' f0 U
  81.         pdf.offset += length;4 j) Z  G: q+ ~6 ]8 S
  82.     }
    3 [% k) p% H+ e+ a# h7 `
  83.     pdf.objNumber = 3+i;
    " i; K! i. F4 Q
  84.   
    5 }$ o. b: \6 _! @9 ~3 ^& k+ Q) F
  85.     return (LPDF_Doc)&pdf;
    : m$ q+ h9 d5 n3 c0 _: C2 c  D
  86. }
    3 r. l; W0 y" D

  87. / x: Q7 d4 e  W3 N
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    ) P. y/ t) r" S* C3 c5 U& ]2 o1 W
  89. {3 Y9 y) D- v8 T3 m6 X) x
  90.     LPDF_UINT16 i = 0, child_pages = 0;& a* {3 J  O, f, q* a2 X
  91.     LPDF_INT length = 0;
    + J; x& r- \$ G: M0 z/ w& J
  92.         LPDF_UINT writeBytes = 0;
    2 Z0 g+ x0 f: N' t/ e
  93. ( E  m* T. _' f: p1 `+ m& `: Q! T
  94.     pdf->obj[16].objIdx = pdf->offset;
    3 m8 R7 X- J0 b6 e( I0 ?% G
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;7 g/ S. ?% N- f3 g2 o
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);
    ; _* A4 \+ p' A7 ~" [
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    , a4 P3 k+ ]5 w/ j5 `7 x
  98.     pdf->offset += length;
    ( Y0 l/ S7 o- V
  99.     for(i = 0; i < child_pages; i++)
    2 i& X7 y8 B" u5 k. @% Q
  100.     {
    ) @/ b* N) U: I2 i9 d3 l2 |
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    - _7 ~% T5 m6 t& j
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ! A2 \% y/ d% Z" b8 W" K/ M, G
  103.         pdf->offset += length;' |6 e+ N' D/ y, z; S% `; b; M3 v* {6 O% ?
  104.     }5 x3 N0 A, A9 W
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");. C3 F$ e- p( m) |, `! Q
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    6 D9 Y& Y% |0 R8 n
  107.     pdf->offset += length;
    % {/ [, G' W5 F. V" w! I
  108.    
    4 ~/ l2 z  N2 s. u3 Q5 u: ^
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    0 T- }- p& a/ i! @4 W* o( a
  110.     for(i = 0 ; i < pdf->objNumber; i++)/ ]. z: j% h% w1 s5 E2 _9 T& s
  111.     {
    $ j' t2 w) n1 L3 B0 i" r& \# B
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    ( Z' d- q$ w3 s& u
  113.     }
    7 g( f9 W. ^3 b5 O' |  @% ]' S. R. |
  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",/ E' x6 y; p5 Q3 L9 h3 ^& r& ^
  115.                 pdf->objNumber+1,pdf->offset);
    9 s( @. K) O" P: {& E. `9 s) q
  116.     LPDF_FCLOSE(&pdf->file);
    & ^0 t- ?* T9 I, F6 S3 M
  117.     LPDF_REMOVE(file_name);8 s8 L% M& }6 R5 P* [) h* K2 ^/ E
  118.     LPDF_RENAME("tmp.pdf",file_name);
    9 T, u8 Y5 w( J5 M6 w. i/ I5 B
  119.     return LPDF_OK;
    % p- S/ N: D" }4 \
  120. }
    3 z; g: v/ d. r, H% z/ `
  121. ! ]9 w$ t3 |. Y  S- i* z
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)! A( V  I& Q+ g8 r1 ^. {& C
  123. {! q+ ^% B$ o5 i) o: x
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);
    * T6 F8 z, m+ Z1 `8 r! H. B! ~% Y
  125.     return LPDF_OK;1 k. F* u! R+ v
  126. }
    + |( s+ a) m1 P2 M
  127. 4 R3 f: p& p' E( r
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)  P  N; q* }2 \; U' J
  129. {
    4 E0 k( o, f. n  P* M
  130.     LPDF_INT length = 0,i = 0;
    ' {  m& Q4 A1 {) a! o
  131.     LPDF_Page page = NULL;9 W. ?& `+ z; n4 ~8 r- F8 e
  132.         LPDF_UINT writeBytes = 0;
      k3 M+ j/ e, @$ ?9 z1 S; m
  133.     , v- o: |3 k7 V
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;  S5 L4 w% d7 p5 Y7 K1 D% c+ T/ ~
  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 c  {: t6 z. c. a( V, T1 \6 @
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"7 c8 Y  V- W" {- e5 _  _
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);4 _/ `0 N' \; Y5 v, F# q8 L
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);( u$ [  Q% r1 r/ h4 {, [% j4 Q
  139.     pdf->offset += length;
    & P( e+ N/ b6 |# E% ?
  140.     while(font_list[i])! |. q0 h- }3 l  L
  141.     {
    . y- O, H, M( e& x5 C& x' X8 s
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);
    3 q6 v7 ]- P. D' V& T
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);- o) {4 }: ^3 S( j! y
  144.         pdf->offset += length;
    # P" N( {( _% n, Q  J8 V3 ]
  145.         i+=1;: {! o3 q  m- Z" u) t
  146.     }
    % @& e- q" M* a& [8 a
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");
    , P$ M9 e- ~: P
  148.     pdf->offset += 4;: C( k# C1 ?8 j% G1 \  k
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];6 Q' A. W; u8 ~8 z% f6 Y( O
  150.     page->width = 595;. R" [0 W# G0 c# e3 @) v  x
  151.     page->height = 842;5 n, t! `+ ^; o2 F8 O
  152.     page->gMode = LPDF_GMODE_INVALID;1 ]6 H6 V' h; O7 g8 M2 @4 f8 T" W
  153.     page->fontType = LPDF_FONT_INVALID;( Y1 R- D* h2 q0 u# O' Z
  154.     page->doc = pdf;
    4 X% A7 V' u# Y6 i
  155.     return page;* Z4 |' H8 ^( W" u" S. f
  156. }% R6 C, y3 [9 C* U  x

  157. 9 i* Y  k2 H% r% ?' e
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)
    8 p1 b/ y5 x. G
  159. {
    ' h# W4 V  Y- K$ ?( {, u
  160.     page->height = value;& p  A) Z! N3 }# h) c
  161.     return LPDF_OK;1 D6 k: q0 K) \# L( H) y
  162. }
    0 v- S3 w5 S# g* ?: o
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    6 A# Z) S+ o0 w' c
  164. {' E3 q. |- m4 b
  165.     page->width = value;8 f' x$ L7 u. d# Q7 U$ a+ ?* K
  166.     return LPDF_OK;
    & x  @3 b2 j; P. {; Z3 H
  167. }
    # N3 h0 ^/ N" J2 s, i) F4 k

  168. ; a. ?8 ^" Z, w& t! q: f. g
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)
    7 w% a* u5 M3 b6 E( `5 o' A
  170. {
    & @4 P: [* R+ c
  171.     if(page)( E4 |) e3 L: ]0 Z
  172.     {
    # E9 O% n, J6 c
  173.         return page->height;6 l+ l4 j) N& _9 g, w
  174.     }; A' J$ Y" p# ^
  175.     ! ~" h+ G% [5 O8 b6 K. Y9 n
  176.     return LPDF_OK;# u: C9 i0 g9 g6 @% {( A4 s! @
  177. }
    7 T# r/ d; {- m, e; ~4 w

  178. 3 P  ?: G% q: N1 F8 z) ]# q
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    , I9 a+ B4 b$ G) p* {
  180. {$ J7 T/ ?2 F4 k4 h  ^
  181.     if(page)
    & A" J7 V; e; h; I
  182.     {
    7 g7 j3 L7 F) w4 n3 ^  ~& \
  183.         return page->width;$ j/ Y* ?) L: f/ [8 w
  184.     }
    . O- i  R2 r3 M: Y  w( H9 ?
  185.    
    # C- e$ [  H- k* j5 ?9 k. Y: I  X
  186.     return LPDF_OK;
    2 c0 w) g+ D0 t8 d, E  [$ d" T6 W
  187. }
    : R2 t) X  S8 p6 W  l* Y3 E

  188. . x3 x3 b6 ]; X
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)
    1 r8 V5 X& L8 \
  190. {7 k6 H6 O' A+ [, v
  191.     if(!page)6 ?. P4 K! E; i! |  i+ v' |  ^
  192.         return LPDF_INVALID_OBJECT;: [' r* [. n) y9 X- S2 g
  193.     if(!(page->gMode&mode)): ?1 P6 V& J7 N
  194.         return LPDF_FAILED;9 T# m; ]& I  t6 e7 \; F6 {* l1 g
  195. / e) p6 `% D; u; E/ e3 p7 L$ I
  196.     return LPDF_OK;/ L  l. K6 N( N$ ^) d& G' n% \; N1 r
  197. }
    , L- i! O4 |- X- Q0 `" S) ?
  198. % N8 T1 ^; P+ u  i9 g7 F1 I# x
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,& t+ r6 [' f( w8 [3 X
  200.                            const char *font_name, LPDF_UINT8 size)" m, U; [2 U7 I( T  [: m
  201. {
    % R4 ^, L, u6 B8 \! u
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;+ y5 W6 J5 Z% r8 _) S# c8 A. t
  203.     LPDF_INT i = 0,length = 0;/ `( o9 g( S5 [9 W( q
  204.         LPDF_UINT writeBytes = 0;
    1 A; @7 u1 W6 g9 c( y7 P
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    ; P) t5 t9 a3 w& Q; J) C. z
  206.     if(LPDF_OK != ret)
    ( I* [& i0 ]/ B; l1 b' ?$ H# ~2 x
  207.         return ret;8 p5 m3 g6 `8 O* t3 z" O6 x" }
  208. 7 f- s; B- R* I) S' x. k
  209.     while(font_list[i])
    # K8 f+ S3 B+ W( Y) ?( M
  210.     {
    5 w* e& c5 Y3 `
  211.         if(0 == strcmp(font_list[i],font_name)), x/ T4 ~0 V: b; p( n' w
  212.         {2 w1 C: L6 G5 x% p9 E( n
  213.             page->fontType = i;' E/ G5 w) N' [( W/ N
  214.             page->fontSize = size;
    ( I7 o2 A8 a/ \# o+ s" }4 }+ t
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);
    % X7 u2 _8 e# O: l
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);7 Z# k  k' G  I+ h. c: N: ~
  217.             pdf->offset += length;
    0 \1 y) y  l8 J7 `
  218.             page->length += length;
    . s# L8 I8 P' ?. o$ T. f8 Y4 c" n
  219.             return LPDF_OK;
    $ t6 c1 q  ^7 S
  220.         }
    . I9 [- z  F7 b1 w, h  c
  221.         i+=1;8 g4 n3 O  o& q/ e; U- J
  222.     }) z  n% k$ }/ s/ M* G
  223.    
    ) s& V5 U5 N9 B" _
  224.     return LPDF_OK;
    , ?. I! w9 f& p5 e, y- |, z/ }: z
  225. }
    ; n- _3 w+ u; g* b
  226. ) H# ?' \! u* P2 d) x
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)
    % x* s4 L" h$ E6 o
  228. {
    1 ~9 b: _2 Z$ l- R- o9 F
  229.     LPDF_INT length;
    $ T" v" d: S' C" v7 G. ~6 w
  230.         LPDF_UINT writeBytes = 0;
    7 C& B0 x/ H  F: |! e* l. m! {
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;0 p' C8 A( C- S; K6 ^, B9 R9 A
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);( a) {% b1 _  h8 g( P
  233.     if(LPDF_OK != ret)
      c; Q/ p9 j8 y4 K& p
  234.         return ret;' Y9 F6 @9 t9 r. E* `% |& T3 j
  235.    
    + [- X) |) o0 f& _
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */( y7 y0 s3 ^3 A7 m+ g
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",5 w$ C* s  u; z+ i% G  a8 {2 W
  238.                         page->width, page->height);
    0 Y! e$ B( Q+ A  S9 Y0 L0 O# I
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);! q9 ^# u4 p1 A, D
  240.     pdf->offset += length;, {8 ]: v0 B+ d8 b. g* C" T/ \
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;2 |6 |+ b4 K2 o* f* g
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",
    0 l: h; ~8 C3 d  J3 k7 G' C
  243.                         pdf->objNumber+2, pdf->objNumber+3);
    + i( M1 z; @: \
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
      T: }8 l% n9 T: \7 m
  245.     pdf->offset += length;
    9 ?8 p* Y+ d; v1 x& N/ R/ ^6 ]1 X$ G
  246.     page->length = 0;
    $ R+ q( J5 j: o2 B" H7 _/ T
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;2 F( m8 }( u) K
  248.     return LPDF_OK;
    ; ^4 x3 r) G8 ]: g
  249. }
    5 [& s7 d2 [! n1 Z4 j: S

  250. % l$ E9 `4 v$ t! Z7 l9 t' n
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)
    ) |: K$ X% k- q3 q6 C
  252. {1 t* k' N( Z9 a
  253.     LPDF_INT length;
    6 r( A$ F! h& E# a3 N8 E5 c
  254.         LPDF_UINT writeBytes = 0;1 F$ ^  n! E! u/ @7 k
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    + ?: r9 ]1 u$ _# K. G
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);' f" p% w5 a7 S: d+ J) H
  257.     if(LPDF_OK != ret)# G5 [8 x! }% Y! I  z+ {( g
  258.         return ret;3 |* v& `2 A. D4 }! y
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */( |7 p( z/ i" i5 L  u7 z% m
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    - |& b% K# O* [# J5 U/ H
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes); . x3 |& }# J& G2 L3 q! s2 e
  262.     pdf->offset += length;
      d; v+ F3 Z5 ~9 l4 Z
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;& x" W8 ^: U% \7 E0 _3 [* E, v+ F
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    " a& ^. W% G5 P& C. |6 ~5 e# s5 s
  265.                         pdf->objNumber+3,page->length);
    , p4 J7 G0 E; D0 E! Y- I' |0 ]
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);: x* F  r9 J4 w9 m% p3 I& H
  267.     pdf->offset += length;
    % W+ H: Y9 |0 Q. ~
  268.     pdf->objNumber += 3;& l; P& `1 p* l9 S6 X
  269.     page->gMode = LPDF_GMODE_OVER;$ J: R# q" a0 o: b) ^: T) C
  270.     return LPDF_OK;
    / {) ~+ z7 j) J6 C
  271. }
    5 \" U8 C' Q  R  G) \+ X8 ?, v( o

  272. 4 a0 W7 r6 K6 j0 T  E( _, e5 u
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    3 h. K/ X. ]3 Z
  274. {, x. `2 r9 M& N+ N" J0 P
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    & Z( ~0 p" f' c7 e3 A1 k
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);9 n$ ?/ u2 r0 [$ l' y% B+ w+ A
  277.     if(LPDF_OK != ret)$ {8 [$ q, T) h4 H  e3 w
  278.         return ret;
    9 X  g: p8 R% S' T  R
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    . v* H+ b. S3 ?1 C
  280.     pdf->offset += 3;
    6 c* U/ M( z5 |
  281.     page->length += 3;
    , N+ u' [/ K$ W
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;
    % s7 t5 S6 b& U7 n  J( P
  283.     return LPDF_OK;3 }3 z; |6 v$ E( @
  284. }6 E$ O; @& _" s
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)
    $ [5 X8 _8 k, A+ D( x+ Y, f
  286. {
    2 e4 g3 {! O7 b5 i
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    / _  d/ _+ Y2 l# u
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    7 Q4 H. \- T+ `/ w% R4 K) N
  289.     if(LPDF_OK != ret)) q! Y! D3 F) U9 |: K4 P
  290.         return ret;
    6 V" X% n8 ^. Y/ _$ T3 m* W4 n
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");9 M7 H& }, O! @
  292.     pdf->offset += 3;4 P' _/ h# c& }
  293.     page->length += 3;6 r. @+ a* X0 t' F
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;+ f+ H+ [  W% i7 d) V% p. T
  295.     return LPDF_OK;5 C* }$ D# O" d1 q# x7 S% ]
  296. }$ Q# Z' d. d' T: q9 j1 j
  297. ( ]8 `/ F" a/ k
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)) Z* o  q4 r) E. T: C( ^! n0 E
  299. {
    + l1 g- [/ g( r% Y8 Y
  300.     LPDF_INT length = 0;* b& L2 m; A: _0 V- e
  301.         LPDF_UINT writeBytes = 0;9 H4 T3 v9 d) F2 H8 O4 K+ _
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
      b# C6 k/ j8 N( |- s1 N0 i+ S
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);9 ~& X6 b3 \6 r6 E, b5 f) v
  304.     if(LPDF_OK != ret)
    $ @$ w; [1 B1 L) |7 [# B  B- ]
  305.         return ret;
    ' h9 C4 \3 {2 z. H( R7 H: O0 y
  306.     if(LPDF_FONT_INVALID == page->fontType)
    3 }+ F. a, R4 D8 W" Y9 F5 y
  307.         return LPDF_OK;
    ! ^) u2 r* L3 B6 H; H. r
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);0 T: U+ X0 o! ~2 V+ k- F9 v
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);$ e. {# [& R1 ?: t. l+ [
  310.     pdf->offset += length;
    % B2 Z! q# B/ a- m+ u. ~
  311.     page->length += length;
    * M5 R0 c2 w& e1 y) b- S. S, x
  312.     return LPDF_OK;7 a5 d  t9 B3 H! h  i! Q3 o, h
  313.     ' f3 n) t7 e+ M% Y8 m
  314. }
    , B7 N' W' K7 j0 o4 e% S
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    $ Z0 d& \. t$ p. Q4 }
  316.                         LPDF_INT x, LPDF_INT y)
    , m) J. R0 O: ~: T# o) V( j
  317. {
    $ {1 u2 P  B  L7 V
  318.     LPDF_INT length = 0;
    8 l4 f1 T! Z# C" D" ~) m0 n
  319.         LPDF_UINT writeBytes = 0;
      f1 |# }+ H  o9 T* d
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    / W$ Q! J. Q2 M9 i7 ~6 s# m3 z
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);# X& O4 B4 a* q0 q& G
  322.     if(LPDF_OK != ret)6 @! J( M( J$ i
  323.         return ret;
    " J5 y  P" k. o9 M& R+ t2 z" e) [
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);
    2 m3 N% c! A( h$ i  [/ Q
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    4 f' x. H6 I# s4 r4 g% S3 W1 w+ w( I
  326.     pdf->offset += length;' W# o, c( u. N1 e# i6 w8 A6 b
  327.     page->length += length;8 b5 U& w! T; R3 u' m) l
  328. + @1 f0 x/ f. |' J* F3 r/ b0 \: |
  329.     return LPDF_OK;
    1 p3 P( o3 |7 T8 _
  330. }
    * d- A1 l* G0 N$ j# \
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, ; o, m0 ^' n, L4 k! x: ?2 \# ~
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,5 D* P2 G; t( |" W4 G3 T: f
  333.                         const char *text)
    3 I) \+ W, T; X
  334. {
    $ E$ [0 j2 _) B' ~% @- W
  335.     return LPDF_OK;
    * @$ i8 W' W2 w
  336. }
    / O- e  h# L/ [
  337. / ?3 l* o4 i& X" s4 Q+ Z
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,+ h9 B% Q' W( X6 M
  339.                          LPDF_REAL r,
    * G1 i9 R- Q9 L4 R% \- t$ W
  340.                          LPDF_REAL g,1 V1 ?# x* t! a; U1 k+ O
  341.                          LPDF_REAL b)' ]8 k9 `# E5 c' w- k: C  i9 s& C
  342. {
    5 N' R( O- i; F5 U! k& p
  343.     LPDF_INT length = 0;- _4 H% i9 s9 c) y6 s' }9 ]$ C
  344.         LPDF_UINT writeBytes = 0;# _; R5 u; L. u/ p* F
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    " A4 |" C! U- U$ d1 E3 z* H8 U
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    $ d6 v  C$ i" ~; N! ?4 w
  347.     if(LPDF_OK != ret)
    9 F5 |0 _4 G. C. s5 ^4 b. y
  348.         return ret;& S& ^* R/ M. |: P6 O
  349. & |, H* t+ u) `8 [$ e7 p
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    6 f( A" m" m# O: I( z6 Q
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);) o- J: M  L. r7 X  t8 S
  352.     pdf->offset += length;+ S9 F1 J8 L: X+ P/ Z6 o
  353.     page->length += length;
    3 y$ A1 H$ ?% S9 a
  354.     return LPDF_OK;# }% \; |/ i& A! }$ T
  355. }
    1 \+ P& g# ]3 ?' E! Y6 |

  356. : R$ B6 p: `( G" {, F+ P! E
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    ; X) T& U) V+ K5 r2 J1 c
  358.                          LPDF_REAL r,# D8 ]9 i& v  {- |5 {
  359.                          LPDF_REAL g,
    5 P' _: J2 N2 Q& R, `4 Z% D
  360.                          LPDF_REAL b)2 y( N  ~. \/ I) R: k6 k
  361. {
    : v, s% r1 y* r( Z: ]( T3 K
  362.     LPDF_INT length = 0;7 o# {' a- Y0 l& [; Z& Q
  363.         LPDF_UINT writeBytes = 0;
    3 A! x8 D9 R0 x
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;- X6 T( d5 M& ]6 L" I
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);; h2 F5 P7 @/ i1 z: z- C# s
  366.     if(LPDF_OK != ret)' A# @, E( u" T. G, ^7 i1 K
  367.         return ret;1 Q8 U" v  C7 A

  368. - n) n( ]; y1 q' [+ x6 l5 }1 p
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);
    " J9 n8 h8 z0 }% |* [
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    # P# u: b! h0 H) o# X2 O
  371.     pdf->offset += length;2 d! i4 G' l  y& T
  372.     page->length += length;
    * M5 O/ m- P9 q* d8 L- c3 W
  373.     return LPDF_OK;
    8 H2 O4 y' g+ ?# x. S$ o# a+ m
  374. }
    ( O* Z5 |3 `+ ~9 f+ C' O
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    2 V7 a/ S. @( l1 B8 y0 F
  376.                          LPDF_UINT16 x,& q; ?* W7 N" K$ G) f6 ]  Q
  377.                          LPDF_UINT16 y)
    # p: ~5 D; d5 M2 p
  378. {/ b' O% p, N& w
  379.     LPDF_INT length = 0;! ]; T, V3 m  j4 z# e' o0 B; ~2 z
  380.         LPDF_UINT writeBytes = 0;' a' f4 a9 B+ i6 _5 g
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    5 ~) X+ g+ M8 ?) t- c& F( T
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);
    7 X( c! @& M9 i; \' R) A& {
  383.     if(LPDF_OK != ret)
    " r3 o" m1 O2 C- L( W7 @) F
  384.         return ret;
    # {; _& Z% b. d5 a  p# s6 [
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    7 s: ~7 @* \$ p- h7 b# H) R1 U
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    2 H1 v% @6 d2 D6 o/ n* g
  387.     pdf->offset += length;2 a& s, Q) p8 q5 l' ^2 v2 h1 m
  388.     page->length += length;
    : ~; P( z8 w6 \% A  i$ B0 j# E
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;7 c: U4 ^9 t$ B
  390.     return LPDF_OK;& x- @: o0 w6 J$ ^- L9 P
  391. }( J5 M+ A7 }4 X- S+ G  d
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,+ B6 ~! f- F3 _5 S) O) t1 w
  393.                          LPDF_UINT16 x,
    8 F$ t1 z3 U: F/ u/ C5 q5 _
  394.                          LPDF_UINT16 y)& {$ Q  ]$ V) X
  395. {; I" e: G+ H4 {
  396.     LPDF_INT length = 0;
    ' a8 e0 c* U0 h
  397.         LPDF_UINT writeBytes = 0;; |" s$ X8 c' M  `+ g& Z1 F
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;6 V  c& g! V4 ?* W  m
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    $ _6 _. j; P; ~1 P' h/ B( l# D) W9 o
  400.     if(LPDF_OK != ret)  \  \' h( s9 Y% ^* p% Q" o
  401.         return ret;
    ) O) B/ Y) }7 m2 Y+ j
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    2 s9 [  k% ?; t9 g
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);' p) H5 M* z2 c9 Q# Q6 V+ r
  404.     pdf->offset += length;! x% z' n: n$ d, }/ G
  405.     page->length += length;+ `2 b$ ^% z% F6 X
  406.     return LPDF_OK;# b: x; w& @& L% L: I
  407. }% k5 U$ a5 o9 y
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)
    ' ~5 ^2 O5 k5 }' A9 Z6 r4 \
  409. {+ k. J& M+ u4 b. x
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    & \) B# K/ R3 _3 {0 u
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    : `5 w0 Q% k' ]0 q" o! R
  412.     if(LPDF_OK != ret)- v3 Y2 @: R. O. G
  413.         return ret;9 `$ j) N! L# r5 l/ e; p
  414.     LPDF_FPRINTF(&pdf->file,"S\n");6 U( Y- W. x# s$ |2 ]
  415.     pdf->offset += 2;  t6 d- R/ Q7 x' t9 ?/ N
  416.     page->length += 2;
    ' G& Z2 G+ n( j  A  s
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    5 a. N3 J- h, W  h4 d/ o
  418.     return LPDF_OK;
    & F* |6 l. _% x4 s/ H; o
  419. }
    , `, r5 y& H* o) c/ Y. [
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,2 c3 l9 B8 o7 f# }9 j4 d* p
  421.                       LPDF_Image image,
    9 A, |) U2 h! v  b- A% g6 H
  422.                       LPDF_UINT16 x,
    0 I- i, Q' D- q0 U0 j! ]* I
  423.                       LPDF_UINT16 y,
    ! P' P& L0 F+ k9 ]
  424.                       LPDF_UINT16 width,
    8 L$ O! `! E8 k8 W3 A8 {# v1 |
  425.                       LPDF_UINT16 height); [: J9 V) ~5 T
  426. {4 t) I$ N& H" S6 o, f" O9 h
  427.         return LPDF_OK;
    " S, n& [: x, f$ |8 M7 e
  428. }# f' D$ B4 k% A/ R/ x# x1 q2 H
复制代码

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

  1. pdf = LPDF_New();
    + m3 f6 J: o# l; W
  2.     page[0] = LPDF_AddPage(pdf);
    . Z; y# l0 @, t5 v8 F$ P
  3.     LPDF_Page_SaveParams(page[0]);. T+ W. N& O& _5 `! M" y
  4.     width = LPDF_Page_GetWidth(page[0]);/ }; I4 Q" q' K# ?: J. m" K
  5.     height = LPDF_Page_GetHeight(page[0]);
    4 s. u- _* H' w' K
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);. ?* T2 [0 s$ u$ A8 a
  7.     LPDF_Page_BeginText(page[0]);
    - O1 [. h+ t* L
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);  h2 w- \+ K& S; x# p
  9.     while(font_list[i])
    6 \# G8 H2 F0 }" U+ L5 X+ p
  10.     {% L, w' d5 u6 ?+ s( o1 |
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    ( y& l# s! C! X9 T1 e, h+ L
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");+ S' Q( L7 {$ u. u5 U
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);/ ]% c, m  r( O" E
  14.         i++;/ H: t' B( G. R  \
  15.     }6 s7 k2 s$ C- s! j
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);  _% ], S* ]1 q2 Y$ ~
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());
    ; F7 d; g# i) _) H% p  U4 Z
  18.     LPDF_Page_EndText(page[0]);% U: m8 J5 D1 I! j/ M
  19.     LPDF_Page_SaveContext(page[0]);  w/ F' W" N  m2 |' c, |7 S( y
  20.     page[1] = LPDF_AddPage(pdf);
    8 H. i; y( z* d  p, ~7 i" v
  21.     LPDF_Page_SaveParams(page[1]);
    / X0 o- x; v, o
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);
    ' B4 @$ G2 m0 J2 X
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    8 _6 P# d( H4 j) x& B
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    ) Z- s' q. N, n. b! j
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    : j2 C0 |% e0 B: S4 n
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    0 d; [% Z3 G8 Z; y* S2 e4 b! Y5 F: X" Q
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);
    , a# }. N( z% W
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);6 A5 x+ D  V0 }% g& C/ n8 G* q
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);  N* c6 l( F# V3 z4 O9 b
  30.     LPDF_Page_Stroke(page[1]);
    ! u- p0 c" t8 J4 R6 Y
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
      Y" I9 U) r1 ]# S$ ]
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    " ?1 ]7 q/ E9 e/ f
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    % s. F# W8 q7 K
  34.     LPDF_Page_Stroke(page[1]);3 r/ E1 x+ q+ T1 j- w* N
  35.     LPDF_Page_SaveContext(page[1]);! b* C: i1 l  Z! O: n, Y
  36.     LPDF_SaveToFile(pdf, "/red.pdf");7 X% a' P3 ?! V9 L. b6 n4 O+ q
  37.         PRINTF("\r\nCreate pdf file success!\r\n");( W5 l7 H6 u1 u3 X) D2 ^8 ^
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了  C( {1 A8 i6 t9 _$ z* r

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    - @0 a. d4 S- K0 B" q) q
. B% o3 b- W. V6 m3 T& S$ D8 H# }

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:558 C7 d3 x( ~$ l5 C
只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...
, D* q  L3 }: l5 r' @" |+ t
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
% z* G8 L3 s. Q! z/ C首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
( ~& A4 N3 q1 x
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
2 k& d; k2 N: m1 p' d9 s: C
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45: m0 w+ c: I% p! P/ F- S' n
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...

5 }" c# i5 W9 h6 l# @7 W6 g9 {这个我也还没遇到过,只是之前看到有人问这个,所以看看
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, Y( Y5 s0 p5 p9 B* o
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

4 e! K8 M; `7 ]) z! X$ V: ~/ k% }. T这个还只是一个简单的库,实用性还是差一些的
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; d9 s, O" F4 z3 z; \: `6 T
ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
/ L! T* C, r* g6 ?
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
$ w. Z! B  i" T7 [" z% bff.h是FATfs中的文件

3 V9 w0 b3 o$ k! }1 G' N# J嗯,这个画线能改变线宽吗

所属标签

相似分享

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