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

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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 / a; S* Q  c# i# g$ I) a: B

! S8 z: y4 s$ g( e- r. Y

主机环境: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__% q/ _. R$ n+ Z  y
  2. #define __PDFLIB_H__
    6 B: |; A* i  E( Z

  3. 1 V% K* }% Z: V7 y
  4. #include "ff.h"
    + F, g1 y& I5 n: @4 [) A4 D
  5. /*----- standard C library functions -----------------------------------------*/6 A9 N9 V" Y9 D8 m4 j

  6. 2 l. E" d& M$ g+ ^
  7. #define LPDF_FOPEN                  f_open  D; y# b) ?6 m; K" h8 Q* K, e
  8. #define LPDF_FCLOSE                 f_close, Q9 f2 S4 V, i% _) R
  9. #define LPDF_FREAD                  f_read
    9 f( X+ u, \0 |! s& e. Y2 }
  10. #define LPDF_FWRITE                 f_write
    * S. L  {/ Q  V3 @. d/ t
  11. #define LPDF_FFLUSH                 f_sync
    0 O' F! b- n- K7 Y/ l3 y
  12. #define LPDF_FSEEK                  f_seek
    & F3 l! @  f" K  s+ P4 f5 |
  13. #define LPDF_FTELL                  f_tell
    3 m& f# V# s" I8 {" v, Y
  14. #define LPDF_FEOF                   f_eof, z2 V1 H0 h+ _% [& ~7 p
  15. #define LPDF_FERROR                 f_error5 ]5 O  M' ?3 o5 A" Q9 P: h
  16. #define LPDF_RENAME                 f_rename
    , j* S; u* F+ ]$ M# r
  17. #define LPDF_REMOVE                 f_unlink5 H* d. Q# r+ c+ C  _* u
  18. #define LPDF_MALLOC                 malloc
    $ e3 l: p0 K4 t- N5 Q8 l
  19. #define LPDF_FREE                   free$ @; w1 C+ r5 ~2 g0 x& Z7 g
  20. #define LPDF_FILE                   FIL1 o) _" ]) f/ G" V/ @. z
  21. #define LPDF_TIME                   time
    % j. L; P  Q) d7 x. I
  22. #define LPDF_PRINTF                 printf
    5 C/ \1 r# R4 V7 q
  23. #define LPDF_SPRINTF                sprintf
    % z$ h' ]0 f/ c. c* P
  24. #define LPDF_FPRINTF                f_printf
    ' e% f: P( I- y: \! ^1 [; }! U
  25. #define LPDF_VOID                   void
    . W" f2 ^( s$ B: s" n3 F
  26. #define LPDF_SIN                    sin
    7 S1 f. S* [- p
  27. #define LPDF_COS                    cos
    + {) Z2 j5 y* S

  28. ! v0 e9 W9 t& g* q9 \: {
  29. /*  native OS integer types */
    # A- l9 p+ e7 A6 c: V% U
  30. typedef  signed int          LPDF_INT;
    ' w7 @3 a' c) T7 Y
  31. typedef  unsigned int        LPDF_UINT;8 Z, @1 c! T* X$ a4 V( L" {2 I

  32. $ g& r9 N. D- l, o1 Y5 p
  33. & i3 _9 K1 J! \( w
  34. /*  32bit integer types
      V/ x- I4 U, ~$ a5 |" E/ \
  35. */9 q( P$ L7 l) `+ e$ ^% a
  36. typedef  signed int          LPDF_INT32;* a; h4 ^$ a9 T4 ?" x8 Y
  37. typedef  unsigned int        LPDF_UINT32;0 T8 Z9 a5 m# H$ Q

  38. 3 w& t+ y& Z" w& H. G
  39. $ p% H" D4 e+ {6 Z0 p
  40. /*  16bit integer types
    & t! {" F  i$ O8 R$ g
  41. */5 V3 ]: W! k- l
  42. typedef  signed short        LPDF_INT16;
    1 m9 K, v* N. |* u$ Z; d: b$ j
  43. typedef  unsigned short      LPDF_UINT16;
    $ o& Y" m. `' Y4 s8 B# \4 U# G
  44. / x1 }( h+ j, D0 O2 H/ ?# j

  45. $ Y7 C2 `- @1 E4 {
  46. /*  8bit integer types2 G9 l- n7 `' N- c
  47. */
    9 y2 h6 Y% Y0 }2 ~% @
  48. typedef  signed char         LPDF_INT8;
    ' \; l# u8 Z( O6 v3 A9 ]$ h
  49. typedef  unsigned char       LPDF_UINT8;; J0 O+ m( l: z
  50. * m+ C% y* x3 d7 f  ^8 ~3 `
  51. 0 ^0 s( u1 q  W! v; A4 x0 c& ]
  52. /*  8bit binary types; k  |6 w( z6 C  z/ ?
  53. */! @7 J, C# O1 e% u' s
  54. typedef  unsigned char       LPDF_BYTE;
    " [2 q; S! ~/ I

  55. $ C" e2 O( l% y( G
  56. + W% ?+ G& Z. l9 T) m- O* Y
  57. /*  float type (32bit IEEE754)
    / C  }' U) `1 o- A7 X3 j
  58. */+ W, ]9 |, J1 |0 W( s. g
  59. typedef  float               LPDF_REAL;4 q2 [1 I0 y, [4 r
  60. 0 _& J' {  h. U# z5 Z

  61. ! y7 ], p# K0 r  i0 L
  62. /*  double type (64bit IEEE754)/ P& @. S; Q$ k1 R, g$ x
  63. */7 B1 M. K5 N% a. {7 f. o
  64. typedef  double              LPDF_DOUBLE;* U4 Q3 C% t/ {/ T
  65. % P% t, w( C5 F7 h. T, P' d

  66. 4 u9 e: a$ h1 G/ J3 F
  67. /*  boolean type (0: False, !0: True)" B: A0 ~- ?) H% E$ U: A
  68. */0 z6 d. F! {/ X# D- D: h
  69. typedef  signed int          LPDF_BOOL;6 h& _; n* b* D1 Q- c/ a. e7 i9 S
  70. - e9 M9 L/ T. p- R
  71. ! x% M! x: J& u1 U  w+ {
  72. /*  error-no type (32bit unsigned integer)
    % S9 t! Q; ]# V% u2 y
  73. */
    8 ~% p, o1 N" E) k# K. ?7 V
  74. typedef  unsigned long       LPDF_STATUS;
    $ L2 Q1 ^6 {6 r3 \( G# g3 Z4 x2 `
  75.   v4 a' R1 H4 b# w" K0 f
  76. #define LPDF_OK                     0' [* Q7 h- B% a6 V. d6 o
  77. #define LPDF_FAILED                 17 T' Q' w; b  ]0 c8 l% z- S

  78. 3 B( v! ]8 h  r% |
  79. /*----- font state -----------------------------------------------------------*/
    , _' \: \2 v2 H- x- n! v2 R
  80. #define   LPDF_FONT_INVALID                 0x00FF) o7 j5 p; N- B2 A5 g8 K# i
  81. #define   LPDF_FONT_COURIER                 0x0000
    ( l) T) E0 J! `' [
  82. #define   LPDF_FONT_COURIER_B               0x0001
    7 X4 c6 c) b- ?2 U
  83. #define   LPDF_FONT_COURIER_O               0x0002
    5 W. ]; G; h, r% W1 t( s
  84. #define   LPDF_FONT_COURIER_OB              0x0003
    0 c" B/ q- V+ m0 R
  85. #define   LPDF_FONT_HELVETICA               0x0004; x! {8 G1 D1 F1 I
  86. #define   LPDF_FONT_HELVETICA_B             0x0005+ w2 V) J; A$ i  ~8 I
  87. #define   LPDF_FONT_HELVETICA_O             0x0006% I& o; I; t& w/ {, `! z9 L
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007' Z0 P( @8 H( f8 t$ @
  89. #define   LPDF_FONT_TIMES_R                 0x0008
    6 K; S4 ^+ O% ^2 l
  90. #define   LPDF_FONT_TIMES_B                 0x0009' O3 M$ Z& E6 w5 I
  91. #define   LPDF_FONT_TIMES_I                 0x000A# ?9 @+ l  R& v* b
  92. #define   LPDF_FONT_TIMES_BI                0x000B
    ; r- Y4 K; |5 K8 w& h7 m# s  O
  93. #define   LPDF_FONT_SYMBOL                  0x000C& v  h( x- \) Z/ |9 y
  94. #define   LPDF_FONT_ZAP                     0x000D
    2 }& w4 |$ L0 ^( p8 F
  95. /*----- Graphis mode ---------------------------------------------------------*/+ A1 k6 w% r" C3 \- \
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    * ]6 E( p+ G; ]2 O2 e( p1 E9 U
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    : T% k' y& |" e" X6 }! d
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    $ b. S! G% z! j
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008* x- I& ]* X. G  B$ T
  100. #define   LPDF_GMODE_SHADING                0x0010
    5 J+ @: d$ b) E: v" m
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020- X, Q7 ?1 H  t* I6 c
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040  z% \& P# G1 y* l' S6 N
  103. #define   LPDF_GMODE_INVALID                0x00801 r' V9 Y$ |& m: \  t3 R2 c
  104. #define   LPDF_GMODE_OVER                   0x0100
    / K% P7 w2 v9 w4 C" B

  105. / ~  ]( L$ A3 X* q3 G9 Y
  106. #define OBJ_MAX_NUM     256
    & m9 ?9 `2 [' ?
  107. " m, \, [3 Y* _. I, f
  108. /* Page的结构信息是否需要树形结构 */; M$ ^- I! N9 u( y9 i9 e9 }9 ^; I' {
  109. typedef enum " U9 |9 U5 r$ F( l
  110. {, z1 }) m1 M* O9 i* j: K: x
  111.     OBJ_info,
    ; j8 D* [- i! B' C1 O0 A! m: r' a
  112.     OBJ_stream,
    - m! ~' m  x% v: G
  113.     OBJ_font,$ J9 g3 I4 p" G  y
  114.     OBJ_page,9 J# t, }0 @0 b3 o' k4 P1 g$ S& S6 m
  115.     OBJ_catalog,5 ]! K8 @) T2 P& g$ I  \
  116.     OBJ_pages,
    % V, v3 [3 B, P; A
  117.     OBJ_image,
    3 }: S6 M1 u9 j( N% d
  118. }LPDF_ObjType;
    * P4 n- M( W4 J. w2 y1 q; `
  119. & |( p) |: n8 L. S+ u& i6 x
  120. typedef struct
    4 h$ K9 X) N  v/ d2 R' y( l* D! ^
  121. {7 q+ _  H2 P1 D% V5 w9 Y' Z
  122.     LPDF_ObjType objType;
    7 ^8 k; @8 v' e* k! H3 Z9 m6 j
  123.     LPDF_UINT16 objIdx;5 S/ X: C% N" f" H0 K$ O% ~( N  J, ?) m
  124.     LPDF_UINT16 height;
    - T' ?, a6 o" B/ \" b" ^" R
  125.     LPDF_UINT16 width;
    7 X4 J, T# t% f! i$ @! D5 V' p
  126.     LPDF_UINT16 length;6 b; \7 [; N3 q" Y7 [: q
  127.     LPDF_UINT gMode;
    4 z: u" f' @1 D: i; C2 R( }
  128.     LPDF_BYTE fontType;1 q# F! D2 a9 s3 C# \
  129.     LPDF_BYTE fontSize;
    7 b% q0 f% g6 M, D  p! W: Q0 G
  130.     LPDF_BYTE pState;
    # g. k* e; a- ?/ `
  131.     LPDF_VOID *doc;
    ; J* V* n- H0 I3 g! ]0 [
  132. }LPDF_Obj;
    + ]2 `7 r4 F8 v: y  G: N

  133. - z, ]# H8 L6 i7 D" ~3 n# [, a' j
  134. typedef struct
    / X, v' y$ g; D; \. v7 w
  135. {
    9 f# w# M! j. m4 k6 s7 W' W) X! L8 p
  136.     LPDF_Obj obj[OBJ_MAX_NUM];
    8 D& l% j- T. \0 r, Q6 B1 X3 v
  137.     LPDF_UINT32 offset;+ R0 q( H0 e! ^
  138.     LPDF_UINT16 objNumber;% q* k  b$ n! x% T# p' B: ~/ q3 {
  139.     LPDF_FILE file;
      U: v. Y9 N6 H
  140. }LPDF_Doc_Rec;
    3 `0 j3 k, ]# o3 T4 i; ^

  141. 3 e6 g  O1 \- f1 o8 p
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    6 k1 j/ f8 f9 R5 x; f
  143. typedef LPDF_Obj *LPDF_Page;2 H3 d9 X# I' g
  144. typedef LPDF_Obj *LPDF_Image;6 U; C: E) b5 [2 H- [
  145. extern const char *font_list[];, n- h1 ^9 N8 U1 A- c
  146. /*----- LPDF Interfaces-------------------------------------------------------*/
    + z4 k+ d9 R5 J4 B, K+ f/ N+ X
  147. const char * LPDF_GetVersion(void);4 L5 u, g( h) Y/ j
  148. LPDF_Doc LPDF_New(void);
    " R$ C4 w# o9 o# C5 m
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);
    / V7 e( I; @5 a2 i( n" c
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);
    1 u) F2 M: h* ~- x' t/ a2 s1 _
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);7 o0 z  n" x* E: U+ _- a! j
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);  J; R, x- F0 ]* d# v5 q$ M
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,; E# T5 a4 h! V4 {
  154.                            const char *font_name, LPDF_UINT8 size);" [6 p1 b3 _/ E- B
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);  B+ I/ `9 Q2 s! [7 v
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);8 x, c; i( C, h
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);  g* m) O4 m' {# W; @
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);
    8 W1 {* z7 ^! j/ i# {
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    3 N& _: b, u; y$ b' [, W& i
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);5 Q- F8 W0 @4 f' V/ o3 c' W
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    $ s% u/ i4 }8 Z* V
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);
    3 q8 l$ V4 _9 x# B# K
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);
    6 B; d. W3 V9 ]
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,3 u6 L, M. s; x
  165.                          LPDF_INT x, LPDF_INT y);
    : S9 X9 {6 v1 k6 F
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    , O' x6 w% u7 e( w* J1 Z
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,7 k! ]/ [  I  i
  168.                          const char *text);
    % H" K* i% {- R. A
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    % L9 O$ [7 q8 K
  170.                          LPDF_REAL r,6 C+ T' L3 Y9 X
  171.                          LPDF_REAL g,6 _$ @) r' t4 ?! K( ?# l: N
  172.                          LPDF_REAL b);5 w1 f& n* u; m8 I
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    ( |6 ^, j' \6 K- K; s- r
  174.                          LPDF_REAL r,0 e7 N7 y0 ?- g$ @
  175.                          LPDF_REAL g,
    * w" _0 N+ Z- p# s0 s- [
  176.                          LPDF_REAL b);
    0 k- \/ g# s, K$ T7 q
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,6 }* t  X6 t" f, L
  178.                          LPDF_UINT16 x,3 p* x+ F/ r0 j5 W
  179.                          LPDF_UINT16 y);4 m% a8 w* i; r, o9 c9 i+ t
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    0 w0 |' m1 y/ N; Z. A
  181.                          LPDF_UINT16 x,
    - s5 O6 o& f; f& v0 t
  182.                          LPDF_UINT16 y);
    $ W) q: r  h6 a  x+ I4 z' ?# }
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);8 R# Q& e* G' J7 J% b# ~
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);1 \/ V8 N0 y- h
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,  `+ B3 j1 `5 J" \
  186.                       LPDF_Image image,
    9 B& ^1 M* c, W8 `
  187.                       LPDF_UINT16 x,
    * @6 W9 Z/ y" |% V5 h9 C3 X6 z
  188.                       LPDF_UINT16 y,; Y3 p+ X+ E+ Z% x
  189.                       LPDF_UINT16 width,- |- Q, r5 q/ k
  190.                       LPDF_UINT16 height);
    6 Y: ^8 E$ r3 O+ [' t
  191.                                                                                        
    ( j; I0 X( _& l$ \
  192. #endif
    & z% d0 }' k( F% `
复制代码

源文件如下:

  1. #include <stdio.h>
    , r% ]+ ]3 U; u) W% t% s# Z+ Y( x
  2. #include <stdlib.h>& E: G1 a' Y; H1 ~5 ?3 F
  3. #include <stdint.h>7 C* x) E" u4 o* P0 q& B
  4. #include <string.h>! V2 I2 x( r* P8 `) A
  5. #include "pdflib.h"5 g; n2 U# W: ~8 I5 Z6 a! C' v

  6. 6 b# J' W" y1 w0 a0 L6 e0 W
  7. #define LPDF_INVALID_OBJECT                       0x1033! ?% L' g0 g+ M/ v
  8. 6 f. ^# W  v1 l! {1 O6 J
  9. static char pdf_buf[512];
    - [! p6 W: K) O1 c1 W  Y" P0 P

  10. 0 K1 }9 V% d$ u/ B. \5 e& G
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"
    ! ^( ^' d) b$ I. z
  12. #define LPDF_FILE_HEADER_LEN        15( `6 r& f. N' u' Y) h" D  x
  13. #define LPDF_BASEFONT_NUM           14
    * k) a( l, H5 I- l. f
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";' [4 B5 a3 G, o" ?& V: a
  15. const char *font_list[] = {
    ( g$ \# z* D' V$ d' L% ?$ d
  16.     "Courier",
      |+ u6 v+ H' i3 H, m
  17.     "Courier-Bold",; G7 H/ j7 n; O: E. i# a
  18.     "Courier-Oblique",
    ' i' n* {. D& J& M9 A: N6 W
  19.     "Courier-BoldOblique",
    6 j& r: a* i; @  }* L
  20.     "Helvetica",6 d# [7 y( V0 a5 D' O
  21.     "Helvetica-Bold",
      u: t6 x9 B0 _; j2 B" t" x
  22.     "Helvetica-Oblique",- m4 g& q  u+ [6 ?
  23.     "Helvetica-BoldOblique",
    : w8 }: ?" n  f* ~
  24.     "Times-Roman",7 [7 h: |+ P, H
  25.     "Times-Bold",4 ~( X3 x1 O) K0 U+ ?. V# C) L
  26.     "Times-Italic",
    ' k( F& p/ w0 p/ ]5 V( b' @
  27.     "Times-BoldItalic",) ^# ?" U4 {- P! k' y) e2 D
  28.     "Symbol",! \9 D) P, b/ r9 d
  29.     "ZapfDingbats",
    ' `+ \, ]+ e. U2 k6 @
  30.     NULL
    $ o2 K$ K4 Z: D$ q
  31. };* b8 }6 h0 K! r, q

  32. 0 F2 U8 v* h. D+ G
  33. $ u$ ?% U+ O8 F* u, ~
  34. const char * LPDF_GetVersion(void)" L& ^/ m: o" h
  35. {
    0 \* u8 D3 J. g& B5 S+ U8 N
  36.     return LPDF_VERSIOIN_TEXT;
    $ n" b0 J/ D/ G- I# M
  37. }0 R2 j. q# u: G- \3 q
  38. 1 z& N9 K3 o6 o) d, t2 a# H5 D2 ]
  39. LPDF_Doc LPDF_New(void)' X) F% L' R0 y+ l* j# Y. z2 G2 |
  40. {$ T- V/ n3 @0 U5 v% i9 h7 Y, P
  41.     static LPDF_Doc_Rec pdf;
    $ l8 B7 _! j1 f2 N' Y
  42.     LPDF_INT length = 0, i = 0;" C/ m6 b0 {' `9 Q8 d* m4 ~8 {' ?
  43.         LPDF_UINT writeBytes = 0;
    , R2 [7 `; D6 h2 M$ a- g3 O) s9 ?; f5 L
  44.         FRESULT fr;! J7 s+ Y1 n, ?; x9 A$ Q6 n
  45.    
    + a2 _% J( N) u! v0 X8 q
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);
    ( E( r. q, W+ q; V0 g
  47.         if(fr). G1 h# O. X7 n. m
  48.         {
    0 V. C$ Y( j  ^/ j
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    0 Q! X1 E! {' f% @
  50.                 return NULL;- i# A9 F. y$ r: Y9 {! a
  51.         }
    " ~: m+ u+ o5 c8 F
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */
    8 k1 a" q- K7 z) f8 R% l
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;2 [8 N, i1 v6 i3 [
  54.    4 d$ Y& I5 H* E7 N, L5 `
  55.     pdf.obj[0].objIdx = pdf.offset;
    " u' i6 o. r: C# D+ a# @  c
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");; g4 G8 b& `, b
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);- Z- \9 w* q' u4 S2 N) G& h
  58.     pdf.offset += length;/ N0 T8 u6 Q  W1 x1 Z
  59.    
    $ y7 o+ M& I1 |5 _8 D
  60.     pdf.obj[1].objIdx = pdf.offset;
    & [, h7 N. `2 {' q
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"
    0 v% v# e  i& R
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");2 d6 d  G# t8 y, k& f* y
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);8 _7 D9 {! `! f! D
  64.     pdf.offset += length;( Z1 s- N6 o2 o
  65.     0 L- t  ?- p7 {* I
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    5 h9 y8 e- v; e$ V8 f) {
  67.     {% `7 u! u+ }0 e2 W
  68.         pdf.obj[2+i].objIdx = pdf.offset;
    : i( W7 E0 w& M4 [, g* U: j
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    : A8 J  F: v2 K# P5 L
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"& F' z) L4 y' r& F" H
  71.                         "endobj\n\n",3+i,font_list[i]);
    * B# @$ x7 |) a
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    1 s/ ], R( H% N
  73.         pdf.offset += length;! X) Z; C; q# Q8 f+ ~
  74.     }; t7 {* l; N% F6 i+ H& ?$ W& \! \
  75.     for(; i < LPDF_BASEFONT_NUM; i++)  z5 {; Z6 j. G/ w! }  k3 p
  76.     {
    : B8 }! c# I" Q
  77.         pdf.obj[2+i].objIdx = pdf.offset;. \0 k% c, P# N6 H' y* E7 M4 d! d6 k8 c' I
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n". @! Q" S7 o' k7 ]
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
    # q; v) `, S  G$ ^/ ]; W
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);8 [" Y! O* M8 a4 }9 ^
  81.         pdf.offset += length;8 X# I1 \: [2 t  B. q
  82.     }5 ^" N5 N! `2 w! L' f2 s/ o
  83.     pdf.objNumber = 3+i;4 _% L! Z  `6 @5 d2 M& f
  84.   ! ~3 o- D5 J# N0 E
  85.     return (LPDF_Doc)&pdf;
    " S* w5 _' n# o1 B! c& m  N
  86. }
    3 h) J9 L1 |8 E

  87. 6 R1 \% P8 E0 m4 P/ f' K, E
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    2 y7 `& V' A- s
  89. {
    / U( y5 @; W, A; \* h
  90.     LPDF_UINT16 i = 0, child_pages = 0;, W. j+ W) j" @; p" R
  91.     LPDF_INT length = 0;
    # p) T8 E# f( x. B9 @, }
  92.         LPDF_UINT writeBytes = 0;
    3 S$ n! _3 g2 D8 c* I
  93. 4 N' C. w/ g; d
  94.     pdf->obj[16].objIdx = pdf->offset;! W8 s; V( t7 ~1 ~
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;" j8 y1 I) T7 k( |4 W) }( Z! O! ?
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);
    ! ~/ L! R) w; f6 w' l
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    , R; g2 w7 S" }
  98.     pdf->offset += length;' `% B8 |; H  b
  99.     for(i = 0; i < child_pages; i++)6 e5 A7 B" h2 E# b# O6 e5 U
  100.     {
    + c! [2 Q$ s! s5 F
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);( P3 i2 i: [, a
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);& R: Q6 w6 |6 B* A
  103.         pdf->offset += length;
    " B( {5 _. x( ~
  104.     }
    % R6 N+ P6 E8 X
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");5 x  y3 H, y+ o
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);/ ^; v1 ?* t& m
  107.     pdf->offset += length;( b9 U/ t5 ^5 v5 X# j( s
  108.    
    : c6 K4 @* m% @4 S/ N6 r
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    - \* J6 p+ t' ]& X# _, A* T
  110.     for(i = 0 ; i < pdf->objNumber; i++)
    ( ^. W. l) C6 k2 F! M9 t' m
  111.     {
    5 `& T7 K: _1 x- H+ D$ t0 g
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);. H! G# m( B' u. q1 W3 q
  113.     }
    4 n: E  p: z+ o  q& O/ Q( z; e
  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",4 P4 o+ [5 Q! c- d& ?
  115.                 pdf->objNumber+1,pdf->offset);
    # e( a( ~9 W- j. H# M$ c: \# T' B8 E
  116.     LPDF_FCLOSE(&pdf->file);: M% z1 m! u% t1 q& c: l
  117.     LPDF_REMOVE(file_name);( C; J; h+ o) y
  118.     LPDF_RENAME("tmp.pdf",file_name);1 E& m, A; B/ q5 s6 D0 K' n
  119.     return LPDF_OK;
    ; P' R/ b' E0 T8 e1 R- G$ x
  120. }
    8 ~; M9 i, F7 L" z8 I+ g  F
  121. ! ^5 t6 M) @$ h: \/ c; v% W
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf); P3 D4 L1 E! T. C/ g
  123. {5 ]+ S+ o* r4 @$ R: b0 ?
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);; {4 R4 T! \! [; f
  125.     return LPDF_OK;9 Z  K/ `. b' k* _2 k0 w4 Q9 K
  126. }
    5 F5 i( \( m* R8 \" I3 a, F7 p- D

  127. 6 Y+ f- @* _/ I
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf): O' D7 {- n4 o" x
  129. {
    & y; l. [. C/ ~4 b  O: Y
  130.     LPDF_INT length = 0,i = 0;7 X1 w0 A- `$ e' r' A1 M: ]
  131.     LPDF_Page page = NULL;1 h! y, ~3 {% q0 K! S! ?
  132.         LPDF_UINT writeBytes = 0;
    ' A& f$ q6 w* ~. H6 J! M  {
  133.     , ]! l7 }  W; d) _% h1 |
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    $ A3 q) S; K6 l8 v; U
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"
    / Y8 h( g; u2 j8 h9 g9 F
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    : l/ |4 X! w( f6 s! k
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    0 a4 R, ~2 o5 y
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);4 |+ Z: I. V1 @( v, j3 t6 e
  139.     pdf->offset += length;- q3 \: Y+ Q4 u6 A, p# @& A
  140.     while(font_list[i])' s9 }1 p* i6 s7 ]& }+ q4 Z( Z
  141.     {9 M) O- Z0 t! W4 g9 h* ]' N
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);4 m4 F# T  ^, M- Z/ Y3 r
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);# A9 P( \! |- Y9 }2 E; `* B
  144.         pdf->offset += length;
    ! C5 S7 n4 N. R" G; d
  145.         i+=1;$ }5 K: @' ^( E* J  ~
  146.     }& @9 r" o% S! F/ t3 }* ~
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");% Y7 m5 q6 k4 H& x3 l2 `
  148.     pdf->offset += 4;
    / A! [5 |3 R* M. @) k* |) v* [
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];4 i& I' ]4 O( N; \- z2 _
  150.     page->width = 595;# g% n7 u) y( i, e: C# ~
  151.     page->height = 842;$ r+ m: l, f  e8 q3 G. ~% S' Y' m
  152.     page->gMode = LPDF_GMODE_INVALID;
    0 D2 @5 R" ?8 ~- a
  153.     page->fontType = LPDF_FONT_INVALID;! J# ^3 g" I+ y2 k% G
  154.     page->doc = pdf;( k; ~( A' J4 a! Z2 [  G2 e  r/ K8 G
  155.     return page;: V' Q5 h9 J, X1 g
  156. }. g  B$ m* g' e$ |$ h# G: e
  157. ) D# p: n. G! l/ V! c6 v1 W
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)4 z( J, ^$ ]' @& p4 J$ X
  159. {8 \. [; k& l6 I/ D4 Y
  160.     page->height = value;
    ) a" |; Q8 w5 `3 |& d6 e
  161.     return LPDF_OK;
    % U4 g9 g0 W5 y
  162. }
    , D6 C4 M" a, |& c' S  m
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    ! d( T" q" A5 N' R5 Z3 ?! D& _- T
  164. {) y2 e7 V# c1 e1 Y- J0 M0 ]% u
  165.     page->width = value;2 w4 p* F: O6 G( W& @9 w
  166.     return LPDF_OK;
    ; l, s; ~- l5 S" M6 {! M8 m6 W
  167. }: T: t4 F* ~. c+ ], k+ O
  168. ! S1 s+ I9 z. D" A1 A3 d+ V
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)' N5 C# a: Z; e9 _
  170. {+ b  D# L0 V( V( I  C  Y4 T) _6 k
  171.     if(page)
      }5 Y9 |8 h) T! q
  172.     {
    ; V" n1 P. K( g, h- ]/ Q
  173.         return page->height;1 L& V) _; P, V! \) C3 x9 J( }
  174.     }
    3 k7 q; |3 ?0 c6 R: U
  175.     ( {+ e4 X9 N! o1 o
  176.     return LPDF_OK;
    ( l0 p$ e# u( p+ P5 B* X* o# d. t
  177. }; J4 v) h# E( R9 K

  178. + _0 B6 Y8 P, H  H
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    1 y: r6 S2 S) C
  180. {: a$ }1 ~9 k; U0 t
  181.     if(page)
    - K& m9 E) R# X# Y' }
  182.     {
    1 s) ~; ]: d5 J' h5 }* n$ j
  183.         return page->width;
    & Z+ W9 z# }( J
  184.     }
    . Z) X# W% y0 c! z/ v" a' z
  185.    
    % Q( `0 l' n1 A6 `
  186.     return LPDF_OK;
    4 i( _" H% e/ y) I, U
  187. }) a& I3 @) e- |+ n( ~7 D5 m

  188. : r0 @+ {: y, ^6 A- d' U) D5 `, O1 u
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)
    , w) B' @+ V1 O' A7 B
  190. {
    & g" f! S& Y& g9 G0 x
  191.     if(!page)
    $ S/ v7 u# t  j( m1 N7 C+ j
  192.         return LPDF_INVALID_OBJECT;9 T; o3 f0 y* h. X& N+ X: q
  193.     if(!(page->gMode&mode))/ g( a+ x  `2 j5 D
  194.         return LPDF_FAILED;! |$ k* O9 ~- S- v# G

  195. + D1 Q3 r/ Z8 C- d
  196.     return LPDF_OK;
    ( V+ D) g# L+ w8 x* P
  197. }
    # c) I6 n9 _7 `* q# V

  198. ' q; C% q, N" F5 }. ~  w, v
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    & `, G! {' S3 ]& t* f
  200.                            const char *font_name, LPDF_UINT8 size)
    4 O* i/ E9 U; M7 V* @
  201. {
    $ K6 O; |2 |! ~8 u) ~1 C6 `  ~
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;/ \: q' T1 ^. ]: ?. {1 f" S
  203.     LPDF_INT i = 0,length = 0;
    # [8 y; q! r& A
  204.         LPDF_UINT writeBytes = 0;
    6 R5 {" l2 U' S9 g* j$ ~
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);/ v# P$ V- a2 j/ {* b1 I' }
  206.     if(LPDF_OK != ret)
    % Z  Z: ^2 P! Y# L4 {7 @
  207.         return ret;2 B. m6 P: `( c* j8 Q+ m9 U

  208. 0 B0 h" Y# N4 Z
  209.     while(font_list[i])8 h, A5 @0 f9 F
  210.     {
    1 g4 V( @  m0 o9 T& f: X
  211.         if(0 == strcmp(font_list[i],font_name))
    7 E! s7 O3 l! u, v2 J) \9 R; G
  212.         {
    9 q  i2 Z" g; b$ e
  213.             page->fontType = i;
    ' ~7 _. w8 X% V1 p' C7 w6 g
  214.             page->fontSize = size;# @1 g) ?1 l4 m  u1 j2 {
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);
    5 \1 L% M# c; _/ t) \& N5 A
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);% [3 c; M3 e5 _7 P. X0 i( }
  217.             pdf->offset += length;
    + j$ n  S5 K: A
  218.             page->length += length;
    * F' U. Q& F! P# q6 D: p3 S
  219.             return LPDF_OK;+ ?8 Y' M" S4 G4 O+ k
  220.         }
    ' t) R" n& W9 J/ I
  221.         i+=1;
    5 N; F/ D0 Y7 o
  222.     }$ g1 N# k0 @( N
  223.     0 k7 O" V( W5 Z, D* p% U
  224.     return LPDF_OK;
    9 T) ~, S  B, M% v
  225. }
    , N1 F0 `) ^: h
  226. $ n! w7 N4 i# t6 Y5 L8 e
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)
    # A8 j. }* q* i9 c- U& f& d
  228. {% l" {& i2 h4 E! F# c' Z. h! v: z
  229.     LPDF_INT length;
    * B" v' o6 L9 [
  230.         LPDF_UINT writeBytes = 0;
    5 B0 l( g, `8 J, H/ B: u
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;) H+ C: \: l2 V! d1 X9 \* ~
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);8 y' O# g- b& Z: _; f2 U; c
  233.     if(LPDF_OK != ret)
    1 y0 G  ]- e# D& o
  234.         return ret;0 w, N# l# r$ |
  235.     / \% l& }. e* i
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */& Y$ q! O# P. t$ K' x) L( o
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",$ }& b1 f* ^; ~! i- r
  238.                         page->width, page->height);' c: Z5 ]4 H0 h
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    * C7 P- n$ _$ R/ j# A
  240.     pdf->offset += length;
    # q3 ]) b" I- T
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    ) O. ~0 t( n) `7 v! s
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",
    9 o- \3 S$ ^! {* x5 ^& T1 c) a4 n
  243.                         pdf->objNumber+2, pdf->objNumber+3);& ]  Z- x& u4 u3 N* d) o
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);4 b: B* o; X. K8 q. q. ]
  245.     pdf->offset += length;2 n: ^, p8 M2 z0 z* _
  246.     page->length = 0;  A6 V, H; p2 ^% H- r; X
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    ) Z! C9 y) X8 l( y
  248.     return LPDF_OK;
    2 q9 [7 _# Y" I8 d* _8 U8 m
  249. }0 }* B# G3 r8 X; M; p

  250. ; V* ~) B2 r' u, n% T/ ?* \0 o
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)
    , c7 V6 ?, |* x/ y4 c) [
  252. {4 F% g& c) S5 N) }8 i1 Y
  253.     LPDF_INT length;
    ' v# Y9 w0 B, T3 E* e0 N
  254.         LPDF_UINT writeBytes = 0;7 w: {$ V7 O7 H" l- ?, t6 B
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;, Z6 f1 a! q9 Q- P  `2 E
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);1 m/ H. S0 U0 v) F" |8 |/ U# P( \
  257.     if(LPDF_OK != ret)
    % b; J; X6 K. v+ T8 S) m. _; f
  258.         return ret;. K9 y$ f5 F/ S2 {
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    / D: {& M$ h" f! l& M
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    , D- Q# e; i/ @# i* @1 W$ t% z
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes); 8 c/ q* F4 X+ o; y) B
  262.     pdf->offset += length;3 W: x# [- k! h- V6 y8 J8 e
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;
    1 Q: A) `* E9 x5 G  k9 q
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",( R' D, v; {2 C' d% K# K
  265.                         pdf->objNumber+3,page->length);& R9 j0 u3 r# L3 I/ L1 t1 ]
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);+ L2 P5 x( H# {( B( K
  267.     pdf->offset += length;
    0 P+ w) o6 q* J; {& C  j' O
  268.     pdf->objNumber += 3;8 K2 @  c2 s4 A  C
  269.     page->gMode = LPDF_GMODE_OVER;
    ; o) v+ }% p7 }9 I
  270.     return LPDF_OK;. Q! c9 j% g* s
  271. }
    8 p; s% Y6 j4 F/ L8 X2 Q

  272. : h3 f$ j7 l. a! B% t! Y9 h
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    # B# m7 F) p5 C8 s5 S" l
  274. {/ O1 I  f. b, W$ Q! s
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    9 u' x# V* X( D) t
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);3 p- n9 J) K, l3 k' c' T, w9 C
  277.     if(LPDF_OK != ret)/ _+ Z5 S- ^8 k( y4 P
  278.         return ret;
    * `$ |* E) j. c3 G$ V
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    2 K; Q% S" x1 @! d$ p* d
  280.     pdf->offset += 3;2 r: L8 @! U: y& Q
  281.     page->length += 3;& R# A1 ]! \1 {' n
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;" C# h& G: k. g2 l
  283.     return LPDF_OK;6 r$ s/ I( {% [' o% r% z. ]
  284. }
    1 q; l5 o- A+ y1 D$ x! Z/ u
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)# z* J0 j: y; n
  286. {
    1 s, H( R6 C$ R6 q, @/ F
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    . `3 _% I4 O9 i0 L' z, A5 R
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);/ P4 o5 y1 o( B1 n
  289.     if(LPDF_OK != ret)4 ?% ?+ ~; l& X: a! R* I
  290.         return ret;+ i% }: o1 l1 J; e3 E) b* M% L
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");$ E, H6 c8 e% c1 R0 m: m, H
  292.     pdf->offset += 3;
    # b7 {; I# @: b8 m8 U4 u5 ]5 E
  293.     page->length += 3;
    , q2 z6 f+ o% S
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;$ a/ l- u/ A& m2 z
  295.     return LPDF_OK;
    7 g) Q& _! l4 I2 z
  296. }: _; E7 d4 f0 }6 I) U, ?# B

  297. / ?& f8 y1 e; w1 W" @& T
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)8 ]' u, P" `5 p7 [) [( L
  299. {
    $ W: p  I, e$ _6 U8 D* e
  300.     LPDF_INT length = 0;1 L8 d5 |# y: |! D
  301.         LPDF_UINT writeBytes = 0;8 o- I3 @1 p0 F5 n, Z7 y3 N+ z% {
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    1 R" f% y9 h, P* }: t1 C
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);: |3 I+ O1 X. w5 Y/ @, I
  304.     if(LPDF_OK != ret)4 A5 Q2 k2 B8 I# R, x
  305.         return ret;4 y! `6 B; q* }/ N+ r
  306.     if(LPDF_FONT_INVALID == page->fontType); p6 Z# O: g& e; B4 \
  307.         return LPDF_OK;. R& B% }. M. r! P  z8 a
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);# {" N. t5 B/ q2 ]! |) M
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);6 A) u: s6 `# j5 _
  310.     pdf->offset += length;, f- O- L$ ?# _& \
  311.     page->length += length;' e0 @& [3 c0 ~2 C0 H; y1 Z
  312.     return LPDF_OK;6 `' b; L  B0 E: [& b
  313.    
    5 ~  _- z( o7 h. c) v
  314. }0 b7 K+ V5 X0 s% _
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    ( a, |- K, ?5 E9 }! X7 h* L: u$ ~8 t1 S9 p
  316.                         LPDF_INT x, LPDF_INT y)' P  w% U, H/ K
  317. {
    / _4 Y" q* y; d9 w: v
  318.     LPDF_INT length = 0;
    3 Q" j: G: a. Q$ i9 g( x7 g
  319.         LPDF_UINT writeBytes = 0;
    ' ]) M% D9 ?* G
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    8 u( Q) L0 l0 [+ W  z# R
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    ) p0 i( _) [9 w, q- J% N' C& T
  322.     if(LPDF_OK != ret)
    ( I8 k  R! \; Z/ s
  323.         return ret;+ H+ _) ~, V$ V  ^5 N2 B
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);3 R5 {2 I' r' X0 o" c8 S
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);. K2 O/ r# ~1 U# C; K
  326.     pdf->offset += length;9 h' @' Z& v% b6 K+ i6 i
  327.     page->length += length;& k1 c- D+ T0 {! l/ A

  328. 0 g! t+ Z6 L0 x1 B; C9 N, T2 t
  329.     return LPDF_OK;
    9 [0 M3 r! E% K! a
  330. }( G' {/ v# j0 ^- j# {% ]7 A9 l
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    5 \( q, k0 M3 j# b6 `' M
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,% }- F* E4 N  Y8 I8 m" v* E
  333.                         const char *text)
    8 _2 P9 c: ~' g5 ^* Z
  334. {
    / n6 J9 T& Q* X* _7 t2 e9 M
  335.     return LPDF_OK;
    * @9 h8 L) k/ W
  336. }6 e/ t3 G6 |2 R1 E2 v
  337. + a2 `  D5 ^8 r/ |# l
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    + P" |: s& G4 \/ V0 M
  339.                          LPDF_REAL r,9 |! l) g/ e! F) e2 M
  340.                          LPDF_REAL g,  H! d, a" [# N3 n: i$ T- G( d
  341.                          LPDF_REAL b)
    ; C% u3 V+ N& b% t- e
  342. {
    $ f0 m- q6 k! E$ `! a* O& V
  343.     LPDF_INT length = 0;4 I$ J: T8 {4 Z
  344.         LPDF_UINT writeBytes = 0;
    4 h& u& Q. o+ s6 X, f. `
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    # w2 F8 K) l! N# i, T& Q
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    . k( W( B# l7 J4 K
  347.     if(LPDF_OK != ret)) R9 b: B& M) P. Z# q8 w/ N0 i. H7 |" g
  348.         return ret;
    - T7 v" W: p; ]  q5 a# N

  349. 3 Q/ s5 y+ D# v4 a! C# }
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    : O- e- Y8 U7 V- P2 l1 y
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    * c9 A# I8 y* b5 `  N2 d
  352.     pdf->offset += length;
    . I" a. i; {( Y' n/ F5 B9 W$ ?
  353.     page->length += length;+ X: A$ Q' h1 |1 }3 ?
  354.     return LPDF_OK;1 j+ e- C5 P$ ^9 O. i
  355. }3 o/ ?4 r/ z2 X8 O) E

  356. 1 l- t3 r' D5 a5 A
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    1 K/ k$ V" a5 I
  358.                          LPDF_REAL r,( e4 \4 n' i! V$ m0 Z! j# S) T- A
  359.                          LPDF_REAL g,7 V6 o5 e( Q' X- `* s3 ~2 ?
  360.                          LPDF_REAL b)  d, @- k6 D2 i/ G" L9 Z" v' s
  361. {' c8 V7 ^* A  L6 U2 l1 U
  362.     LPDF_INT length = 0;( t9 _* V2 R: I! P$ U
  363.         LPDF_UINT writeBytes = 0;2 l7 G- M; B, K- ]4 c% I
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    . J. b  B5 l/ I+ \/ L
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);) Y! @3 @  k( k# X% v, T
  366.     if(LPDF_OK != ret)' L2 b" n( i; n$ h: }7 Q& R
  367.         return ret;5 T4 [# e+ F6 S5 @0 j' B2 S

  368. - T: v: s& `  f8 f
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);
    " p& T$ l; p6 X/ k* {% T7 g3 @$ u4 c
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    " S, x4 L1 R0 H  o9 A: m9 G
  371.     pdf->offset += length;8 d% o5 [( Y0 v/ H+ M- Q
  372.     page->length += length;
      }1 v, y3 x8 U0 ~) u! z
  373.     return LPDF_OK;9 \! X6 D. e  Y# f" E
  374. }
    ( E( G( z1 o$ @4 ~7 ^
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    8 q& |$ l/ D0 t0 I0 M
  376.                          LPDF_UINT16 x,  v; M- m: x( T  Z
  377.                          LPDF_UINT16 y)
    ( D$ {9 c3 H  R
  378. {+ p- \, i2 J( b, \
  379.     LPDF_INT length = 0;
    % V& Z5 _7 K+ R$ l! I+ G+ k/ @
  380.         LPDF_UINT writeBytes = 0;
    ) X2 e: K( ?, Z# k' M- |! h
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;/ Z) z2 v* H& {0 `. \( Q5 ~
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);
    1 i  p5 f9 c( {- G- z5 b* P3 u: A
  383.     if(LPDF_OK != ret)
    8 H5 A2 D) D% |3 T& r
  384.         return ret;
    # Y' x! V( Q, O- A
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    , b4 P, @! L4 u3 K* W- e' q
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    - X7 c* H( E( ~* ?' e. E
  387.     pdf->offset += length;( f2 h1 U: w* g, ]# p
  388.     page->length += length;6 J  z" u9 w  H0 t8 l
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    ) d, ^* q6 J; X
  390.     return LPDF_OK;! d1 m! I6 H4 m: A7 o4 d1 \' i4 ]
  391. }
    / [$ q( r! {5 y
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    + S5 {* }1 |+ H& W0 \. T  I- i! t
  393.                          LPDF_UINT16 x,1 v# ~1 A! m+ b$ q9 [1 ?
  394.                          LPDF_UINT16 y)
    4 W+ `! q2 K# P; C( t
  395. {" O( g. t1 f# {7 L% Q
  396.     LPDF_INT length = 0;
    ( v3 n" q* D0 [
  397.         LPDF_UINT writeBytes = 0;
    ! r& Z# P/ g4 a% n- z- P$ n6 M  r/ d
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;6 Y( f0 L" H6 L. |+ K# E4 F
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    / F8 h; o: Z( H7 i
  400.     if(LPDF_OK != ret); v; F2 T- G! d5 N- d( g% v" ~
  401.         return ret;' v' U! E" S9 c: \
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    ! b, e& @6 S& [1 R. e$ `
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    2 c# C& Y8 d" _" X2 L
  404.     pdf->offset += length;
    ' [  h: J3 U  [8 j" r
  405.     page->length += length;8 X! L8 X& R! R* _. p# G9 q
  406.     return LPDF_OK;
    ' ~7 _: S: E, Y0 F% B4 W
  407. }
    0 X2 g& N  }! j1 l; p( u
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)
    7 }# ?9 [2 H* A8 K/ M
  409. {
    ) N  z; S* [  }0 \& e
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    4 ?( k" t8 N1 J5 v3 N
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);, G4 H, ~. Q5 t; U, O& _& L8 q
  412.     if(LPDF_OK != ret)
    " L1 G/ N$ v( X; y- W- B
  413.         return ret;5 C$ L% t4 B# d/ @6 [
  414.     LPDF_FPRINTF(&pdf->file,"S\n");
    % `7 b6 K3 V1 }
  415.     pdf->offset += 2;9 F' l* g. G( Q; P$ X
  416.     page->length += 2;7 o9 z$ X4 C% t3 F9 R$ q8 s
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    8 X' N) X% z7 s" o
  418.     return LPDF_OK;8 C. \+ `; ]( p* A$ h' U
  419. }7 j5 k2 I' A; r6 C3 ~
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,& W3 ~# c( n$ s( t/ P/ L1 s, }
  421.                       LPDF_Image image,* y7 x8 K0 g  W( F& o+ C4 H- U/ K
  422.                       LPDF_UINT16 x,) [, U$ v6 |& y* R* l$ e1 j
  423.                       LPDF_UINT16 y,
      E& G3 I& [6 [  j# y4 n
  424.                       LPDF_UINT16 width,
    + I3 r$ _- x0 s4 q+ G6 }
  425.                       LPDF_UINT16 height)9 \: Z. n7 W1 g4 c% [0 E
  426. {
    / ?* ~3 j+ T3 q, N
  427.         return LPDF_OK;
    + q5 a3 I5 p$ Y$ }
  428. }8 t- E' G4 y; y# c# s
复制代码

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

  1. pdf = LPDF_New();9 i0 C  r0 H% _* {! Y% s
  2.     page[0] = LPDF_AddPage(pdf);
    4 m, {: H/ j& ~
  3.     LPDF_Page_SaveParams(page[0]);
    ' x2 f# F- O) J
  4.     width = LPDF_Page_GetWidth(page[0]);
    ) ~9 ^7 y+ B3 e# Q! n; [2 y
  5.     height = LPDF_Page_GetHeight(page[0]);9 `8 e3 H  L% j. L
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);# f/ _7 }& ^8 z- i" v
  7.     LPDF_Page_BeginText(page[0]);
    , q& T1 \+ g4 Z5 G+ x* ~" u" L. [9 H
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);: N+ t6 G7 U" D# W. W8 i
  9.     while(font_list[i])1 P( i7 o  X7 P) p; K' P
  10.     {: v% D( j7 G- W  q" x0 ]# I7 ^
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);5 k& T( n9 s- p" N4 H$ @
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");
    ) R. _/ Q/ a& M. @/ D
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);
    $ y* Y+ X6 b0 I5 L" ]/ c
  14.         i++;
    - W" f9 m4 @. M: `: N
  15.     }
    . w  q& u/ H+ y* H9 C4 a* F, p
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);
    ' u' L; c4 D: |
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());
    3 B* I' l" w9 ]% x, J0 Y: m
  18.     LPDF_Page_EndText(page[0]);
    % p- r# y8 B$ h6 {  Y, s, y( ?3 G
  19.     LPDF_Page_SaveContext(page[0]);
    8 n( A4 ]$ |( f
  20.     page[1] = LPDF_AddPage(pdf);" b/ T4 U, w* T0 e
  21.     LPDF_Page_SaveParams(page[1]);# |+ ]- P  P6 n) U+ O
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);
    2 Y6 _# H  B7 ^3 y" x+ j
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);5 M, }4 |* @1 y( {( [
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);/ @/ g& u! _, L+ J( e
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
      e1 a. k. {4 b3 Z9 J
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);4 `3 ?9 }/ }. |! h- T$ o+ K2 T; J: e
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);3 Z8 p% ?" U% m: i
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);( @4 D$ R, R2 u# T* F# a8 M
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);5 O" q* _+ V4 q1 ?/ Q  p
  30.     LPDF_Page_Stroke(page[1]);
    ( G5 D0 i) `% ~' i$ k: n
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);* s9 R( [" m! Z% w. d) g9 l$ t
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);1 T, a, y4 ~6 f/ h3 L" ?
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);* y9 c4 h% O7 c8 h% h
  34.     LPDF_Page_Stroke(page[1]);8 D0 B) W4 |+ ~: o
  35.     LPDF_Page_SaveContext(page[1]);
    ; U+ j7 ]2 a) g& {; L
  36.     LPDF_SaveToFile(pdf, "/red.pdf");
    " I) O% X6 t; {: Y. M% n# J- D
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    , l8 `! u% z3 T0 R/ _8 x9 z
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了+ Z7 L3 n7 f! h) r0 S+ E0 p0 i# g1 {

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体% W; F% c7 R5 N* C$ ^: M

: k, k) c* e7 r& D4 Q1 x9 ?: R

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:559 i5 E" p4 |0 y. @
只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...

  n; `+ D! J, z3 B4 L7 U4 ^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:337 ?# G9 C/ g2 {
首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...

9 E2 @& Z' `- |66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
8 |3 j5 G" x$ ^$ H8 k2 v
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
4 `$ J3 H3 K; S6 t/ ^* }7 k4 d看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...

" n5 O! M4 C/ c6 a& l' {这个我也还没遇到过,只是之前看到有人问这个,所以看看
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' _  Y4 k+ Z2 U# Z4 c
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接
* A+ |; N! h0 f* ]' F" J* t& k
这个还只是一个简单的库,实用性还是差一些的
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
/ Q9 g+ J5 X3 B" W4 ?; r0 yff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
* K5 ^/ L4 f$ E: y1 a8 P2 n" [% q
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
  j8 e. h+ E: C4 Q$ }ff.h是FATfs中的文件
4 B. b* c5 |8 }$ g- n' F2 B/ N  m
嗯,这个画线能改变线宽吗

所属标签

相似分享

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