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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 ) d6 X9 @+ F/ q2 ^
2 r: L  V, H6 G

主机环境: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__6 |' A, c" p. W! e2 `! |5 i
  2. #define __PDFLIB_H__
    4 S$ E& U# X+ N4 x$ \

  3. : s- v3 ?! ?% d4 o) k
  4. #include "ff.h"- g- u! X2 A# G5 e6 t& T! _/ w
  5. /*----- standard C library functions -----------------------------------------*/
    , F+ o0 k/ w9 w8 s2 r3 D  }

  6. " y3 P, _& r' Z1 b( G
  7. #define LPDF_FOPEN                  f_open
    & m! {( N7 ^1 f$ m( n$ u
  8. #define LPDF_FCLOSE                 f_close
    * Z6 j3 k2 [+ }) c* K! Z
  9. #define LPDF_FREAD                  f_read7 m! M0 Z9 w8 ?3 o" q; \
  10. #define LPDF_FWRITE                 f_write
    - b% y+ n( d$ ]
  11. #define LPDF_FFLUSH                 f_sync. s8 C0 o9 C" N$ l; C' b# l
  12. #define LPDF_FSEEK                  f_seek6 W; v/ a: {/ O0 m
  13. #define LPDF_FTELL                  f_tell/ C# y* O6 [* v) L( {) h
  14. #define LPDF_FEOF                   f_eof2 A1 J0 ?, ]2 B4 Y
  15. #define LPDF_FERROR                 f_error4 c+ [. B0 F& q7 Q9 V  k% ?7 X, ?# n2 o
  16. #define LPDF_RENAME                 f_rename
    5 ]6 m6 U; y: ^- e
  17. #define LPDF_REMOVE                 f_unlink
    8 ]8 G; V) `( A: I7 ], V' H
  18. #define LPDF_MALLOC                 malloc
    9 W, ~5 E2 F6 s+ u0 W7 \" i
  19. #define LPDF_FREE                   free
    5 U5 I  q, h+ y1 c3 r  k
  20. #define LPDF_FILE                   FIL5 a# p' u! W1 B4 P8 K! A  A
  21. #define LPDF_TIME                   time3 e) Y& s: h8 k  d$ t* d- n7 A
  22. #define LPDF_PRINTF                 printf
    - _6 I" n' {. f, J8 c
  23. #define LPDF_SPRINTF                sprintf
    5 P+ v3 @; e- E/ g) v( ~8 w# T
  24. #define LPDF_FPRINTF                f_printf& t. j$ C9 o( i1 w/ b1 _
  25. #define LPDF_VOID                   void  l* ]7 C) ?0 x. J2 K
  26. #define LPDF_SIN                    sin2 M3 M. G; |* y) [) G" l6 M
  27. #define LPDF_COS                    cos. J, n2 `% m% _' t% L5 F: i

  28. - J6 A# V! A: n8 u6 j9 j
  29. /*  native OS integer types *// A$ c2 G( w7 K3 W/ N, ?' F
  30. typedef  signed int          LPDF_INT;3 v6 b. ^8 e" `8 E2 ?# d" Y9 `
  31. typedef  unsigned int        LPDF_UINT;
    / o2 t: u7 P6 ?1 R! b# B
  32. " I  K1 u/ [/ F3 O

  33. - K* E. J% {8 d* \% S* ?6 W
  34. /*  32bit integer types: c9 @5 P8 ^+ K, R
  35. */8 ^2 L7 S% y7 V
  36. typedef  signed int          LPDF_INT32;& j7 s& n7 m/ ?& I& A9 ^1 ]
  37. typedef  unsigned int        LPDF_UINT32;
    # v2 o0 p9 `4 `) o$ j, E

  38.   f$ M$ g' I9 O9 L) }

  39. ; U  n6 }. M* R& O& d6 f
  40. /*  16bit integer types
    * \& v6 k3 J# V0 [# c' w
  41. */' ]( v/ b3 G6 m( f
  42. typedef  signed short        LPDF_INT16;
    0 U! @/ b* h4 r/ D/ O  r
  43. typedef  unsigned short      LPDF_UINT16;
    4 L& z( R, D/ h; ]* v3 I5 }) v

  44. " L' n# K5 ?' q5 K1 v! v

  45. 1 y4 l4 V  J8 Q1 [- x% [6 h
  46. /*  8bit integer types  x8 [, S/ v* i( |4 Z' V
  47. */# }/ O$ y: y3 X$ W  f
  48. typedef  signed char         LPDF_INT8;) n% O- w% U) w- N- ^- I6 A
  49. typedef  unsigned char       LPDF_UINT8;
    ( P0 Y0 j6 N. k9 ?) n, z

  50. 0 e8 P6 c! W6 _  |
  51. 2 }3 i0 |6 N# f( L' T7 j( z
  52. /*  8bit binary types. x6 m! ?# x5 a
  53. */+ q7 C/ ?( w1 R; T2 Z9 G9 [' A
  54. typedef  unsigned char       LPDF_BYTE;, ~: F6 R0 t% h" `7 `$ r: j

  55. % [% U7 }3 i, d9 p, r

  56. 4 M9 F$ I8 ^: i2 I6 Y" J
  57. /*  float type (32bit IEEE754)  D7 N3 ?! r, }$ G# g+ Z( b. v
  58. */
    0 c$ z. u8 o# |3 c9 n
  59. typedef  float               LPDF_REAL;
    6 y  g: s% U: \% o

  60. 4 b. |6 C8 e+ A" g+ |* p
  61. 4 V( H& x# ?  \4 R3 l9 K, G
  62. /*  double type (64bit IEEE754)
    % u, u  M6 |, y5 g( @2 v' ]5 u
  63. */2 S6 R, z  @- m5 C2 n& d7 R
  64. typedef  double              LPDF_DOUBLE;4 T7 ?* {, U# I8 f
  65. $ f3 l3 l  X$ V4 `
  66. 1 w4 g" `$ W! a7 o8 a- s& H
  67. /*  boolean type (0: False, !0: True)
    . ^% U/ Z1 p, n4 r0 y3 r
  68. */( k. W5 i; D5 }
  69. typedef  signed int          LPDF_BOOL;' y" i# l" U! n: Z" B

  70. 9 {% p8 k- a0 `. a3 I1 Q/ z
  71. 4 J! F! r# z1 l1 E. k
  72. /*  error-no type (32bit unsigned integer)
    4 |# L+ R0 T) [  m
  73. */0 l* P6 p5 N& ~9 \: n
  74. typedef  unsigned long       LPDF_STATUS;+ k  t: e; R" h. P; I

  75. + }  b. r+ \8 E. c' O9 ]" j0 J
  76. #define LPDF_OK                     0
      B2 x6 t2 H3 c9 o3 H7 z3 f
  77. #define LPDF_FAILED                 11 P4 n; z' ]7 c

  78.   W6 @0 S3 c% [# s
  79. /*----- font state -----------------------------------------------------------*/" Y# z0 J4 U5 p# T
  80. #define   LPDF_FONT_INVALID                 0x00FF/ ?$ g5 N8 x  q, n. b4 R
  81. #define   LPDF_FONT_COURIER                 0x0000
    ' [' q" v+ o) I2 J4 Q  h
  82. #define   LPDF_FONT_COURIER_B               0x0001
    : Y" K& }  f* V: P
  83. #define   LPDF_FONT_COURIER_O               0x0002& n) x/ U4 U$ L" V# X8 D
  84. #define   LPDF_FONT_COURIER_OB              0x0003
    0 Y  k( _0 H" L6 y
  85. #define   LPDF_FONT_HELVETICA               0x0004& x( P' w: {* c4 H  E
  86. #define   LPDF_FONT_HELVETICA_B             0x00057 D: n/ X) I- t( r
  87. #define   LPDF_FONT_HELVETICA_O             0x00061 S4 K7 s$ r( m7 \6 d! M
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007
    . c3 [+ R) y, Z7 Q0 m
  89. #define   LPDF_FONT_TIMES_R                 0x0008
    * j8 ^5 z9 g4 y8 P: w% h' v2 G
  90. #define   LPDF_FONT_TIMES_B                 0x0009
    % a7 G) c0 B0 W4 R7 A' k. I
  91. #define   LPDF_FONT_TIMES_I                 0x000A: h* ^9 ^$ T' d4 F( q3 V
  92. #define   LPDF_FONT_TIMES_BI                0x000B) }" p! ?1 y8 l& r4 W- _
  93. #define   LPDF_FONT_SYMBOL                  0x000C
    ; L$ P  i) F7 b6 y; y  v  a% m
  94. #define   LPDF_FONT_ZAP                     0x000D1 d; ^7 `+ S- n: R& ?! m) f
  95. /*----- Graphis mode ---------------------------------------------------------*/( h8 k$ p1 X# V. b8 h0 \% M+ N3 C
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    ; \: N9 \  F0 O+ D% O3 B+ o
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    . Q& I( X. @3 r9 T0 C
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004: H& E2 N2 Q  T) G# Q
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x00087 J: u& O' k- h+ L" a1 b, G! Z
  100. #define   LPDF_GMODE_SHADING                0x0010& e  w0 \' h7 y8 t! d% [
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020
    : A* b8 Z. j5 o% V
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
    ) c) ?& ?2 K" s) w
  103. #define   LPDF_GMODE_INVALID                0x0080& i/ M- c8 _# d5 d8 s
  104. #define   LPDF_GMODE_OVER                   0x0100
    , m% \. V4 c+ b$ Y# e- U9 h' r
  105. 6 n) L# x; t9 l: [. {, m( q7 @
  106. #define OBJ_MAX_NUM     256
    " C( D8 f5 U) ~# f2 q% I9 ]
  107. / `( s. i$ m+ g9 w
  108. /* Page的结构信息是否需要树形结构 *// b2 U- Z& }! H
  109. typedef enum
    , w4 i8 W( T0 P6 e) p( v. }
  110. {2 A/ L: i7 q- U! ]9 `6 K, C0 r
  111.     OBJ_info,' c: B* t% G2 O
  112.     OBJ_stream,% A1 J9 w5 ]1 z
  113.     OBJ_font,
    ' \/ [' b! e8 z5 r
  114.     OBJ_page,& |, E* v+ H8 y  Q  L- K
  115.     OBJ_catalog,( I9 F" Q$ N# O% r9 U7 W! R
  116.     OBJ_pages,2 [1 d5 e7 s) y
  117.     OBJ_image,2 q, m! o' _3 ^& D
  118. }LPDF_ObjType;
    ' p; P1 F/ T: w, j; o
  119. $ G- h* O6 l& U. u  H0 P- s5 [0 d  e5 l
  120. typedef struct
    " L' Y  A1 i7 c* I
  121. {- J. E+ x, {/ D% r/ ^
  122.     LPDF_ObjType objType;( O* P: W" A9 b/ d5 Q) P5 L! L) @
  123.     LPDF_UINT16 objIdx;( d6 u; B4 ~( {8 i
  124.     LPDF_UINT16 height;) S: d& Y3 T% V+ Z7 g0 @
  125.     LPDF_UINT16 width;
    % p4 |/ O+ C* k1 |8 d3 v5 K4 |
  126.     LPDF_UINT16 length;3 n0 i( r* [0 f8 t! m% H
  127.     LPDF_UINT gMode;6 }' E4 E# I; B5 X+ G- Z
  128.     LPDF_BYTE fontType;
    / w: h8 H- q5 y3 A
  129.     LPDF_BYTE fontSize;
    + x( A) p, i: L- _' _
  130.     LPDF_BYTE pState;
    ( {: u: ^! ]4 c: C- ]" H$ X
  131.     LPDF_VOID *doc;
    ! L$ l1 [$ E; ?" d/ I% W, {8 ~/ ?
  132. }LPDF_Obj;
    # v. c8 x- X6 E$ S6 o, U

  133. 4 k# v1 w6 a+ u7 ~9 n
  134. typedef struct4 H* b6 H$ {! U3 ]) W  }) z) Z
  135. {
    1 `. Z2 s6 T8 L$ @8 g, t6 L: U
  136.     LPDF_Obj obj[OBJ_MAX_NUM];
    $ I- s% ^! V' I- m/ r' I4 ?# r
  137.     LPDF_UINT32 offset;
    ' G9 I# {, z: Z) _  q4 C
  138.     LPDF_UINT16 objNumber;( f  L' b* k( _; L  \
  139.     LPDF_FILE file;. `8 \3 x+ G, u: U1 l
  140. }LPDF_Doc_Rec;2 _# g7 T) {" g% _# Y6 r
  141. : r/ @% T( N& \: s
  142. typedef LPDF_Doc_Rec *LPDF_Doc;. l# O" C7 O# q" _0 H1 f
  143. typedef LPDF_Obj *LPDF_Page;
    9 ]: `6 F5 Y5 k
  144. typedef LPDF_Obj *LPDF_Image;( D, a" x% S4 o) ], P0 Q4 {8 I
  145. extern const char *font_list[];
    - [% c+ ^, F2 F) {6 U/ s9 H8 e
  146. /*----- LPDF Interfaces-------------------------------------------------------*/
    , j  d4 L: j  F9 [$ z- q
  147. const char * LPDF_GetVersion(void);
    9 y2 E5 c6 P7 X/ Z7 ?( o* O
  148. LPDF_Doc LPDF_New(void);4 T5 L$ b- k, t# ?9 K( \
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);/ Q& I/ J6 Y9 ^0 K9 _) U3 H
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);7 _0 ]5 |! S, ~, y# G5 z7 K
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);, D% e: e# ^# K% u% [0 D! ?$ m
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);% e4 h! n6 v; Y& l! |
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    - Y' c3 O2 K3 G' E+ K
  154.                            const char *font_name, LPDF_UINT8 size);
    % T5 g" q& d/ t& l$ e/ A1 p/ E' I
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);
    $ ?) q* J$ g) q  A2 O6 z% g. W
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);' a' M+ |8 \+ K( Y% y# ]" V9 ?& M
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);: `( G/ M, f9 X% h" q/ ^
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);
    8 ^/ {5 S" a* w+ y2 n7 |
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);: I1 M: v- N6 G/ e9 @
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);- _/ T. ]6 D' {/ }6 n2 @2 {
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    7 B; j) b; Y; G# G2 g
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);
    1 S' f$ {& `9 {# n# _( c
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);
    . M! ~+ u' g' `" Y
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,3 Z& b/ m$ N# e9 A
  165.                          LPDF_INT x, LPDF_INT y);! _: {  V5 _3 e
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, 1 M2 Z6 j; d6 J( v1 l
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,
    $ b2 P) q3 h# D# l6 b  m
  168.                          const char *text);3 O1 |. E7 U% q% g
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,& y6 t! T& x. u0 B# x
  170.                          LPDF_REAL r,1 n4 v& x. ^& Z1 p
  171.                          LPDF_REAL g,
    . h# B7 y: P3 ]( Q) v
  172.                          LPDF_REAL b);
    8 R; c0 G3 M) p5 {
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    0 }+ t  z6 G; j- E, }$ K
  174.                          LPDF_REAL r,) @1 y( ], V6 |# [
  175.                          LPDF_REAL g,
    2 H: a- d/ F: ^7 l
  176.                          LPDF_REAL b);
    % A+ p! `8 F# P2 n% f8 W
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    9 y. Q' W+ B. O5 G, a
  178.                          LPDF_UINT16 x,1 m4 j6 W' H5 |/ I) l7 P4 `
  179.                          LPDF_UINT16 y);$ H! \1 |9 n, Y
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    9 N' ?1 v: Y$ L0 W
  181.                          LPDF_UINT16 x,
    / H2 k2 c/ [/ l. E1 R9 {' ^
  182.                          LPDF_UINT16 y);
    : K# _9 X1 V. H% u: w
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);
    : c) x, X* i8 q0 O, ]& M2 k
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);% T5 g' F( k0 K7 N
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,  o, y. L% q2 i$ P* v) `8 ]2 u
  186.                       LPDF_Image image,. g/ X* |% V' a1 Y  a* ]8 A
  187.                       LPDF_UINT16 x,& R3 _& V, U' @
  188.                       LPDF_UINT16 y,! w$ a! x9 V7 O5 H. T
  189.                       LPDF_UINT16 width,
    3 d0 j  q9 y1 k; n  b: @0 Z
  190.                       LPDF_UINT16 height);
    . @& B0 I5 B6 t! X% l
  191.                                                                                         ' q3 ]7 E$ Q* y8 }# {$ F9 N( T0 M7 W! i
  192. #endif
    : f3 c9 F4 I$ M- T- [- p
复制代码

源文件如下:

  1. #include <stdio.h>% d+ ~" ~+ ~+ v6 \
  2. #include <stdlib.h>2 j( W. L, u2 L+ s/ N1 Y! P
  3. #include <stdint.h>/ o; S7 j& E1 V5 v( l
  4. #include <string.h>  q) J: K* h5 u$ u! F
  5. #include "pdflib.h"! `, d" h  J0 G9 \: G+ }
  6. 9 W% `" h( k! i+ w' G
  7. #define LPDF_INVALID_OBJECT                       0x1033
    / d# @5 X! q1 P+ J( L) x8 Y% {% A' E

  8. 3 e- C6 q  a- w: h* J6 b) \
  9. static char pdf_buf[512];* V& y4 C) M0 {# m# c" d+ `
  10. 3 w" J" U+ i, a% m" V, c
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"4 V. _) s6 S! F
  12. #define LPDF_FILE_HEADER_LEN        15) S# ~& f8 S0 U* J2 [
  13. #define LPDF_BASEFONT_NUM           140 _' b  }5 o  J! a
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";
    0 A6 z, l1 `/ A) W6 w
  15. const char *font_list[] = {
    . q; V/ c- t( f
  16.     "Courier",
    3 z' t- Y! J& Z
  17.     "Courier-Bold",5 Q# b/ I" w# d9 X: ^5 O* |0 W- I
  18.     "Courier-Oblique",6 ^6 v) E) G5 H( b
  19.     "Courier-BoldOblique",! o* k. i; p4 u9 y- ]
  20.     "Helvetica",
    + L( K9 ]7 {" `1 e- ^: e2 M2 L- U
  21.     "Helvetica-Bold",
    1 |$ p! N! z) q
  22.     "Helvetica-Oblique",
    % z/ C+ }. C) [% w% `! z
  23.     "Helvetica-BoldOblique",
    ) _+ C% ?  Y2 H2 c# s
  24.     "Times-Roman",+ |5 {# i  [/ ]9 p
  25.     "Times-Bold",( p+ l2 Q8 z1 G0 I4 S2 o; d0 l
  26.     "Times-Italic",
    ' j+ ?  B9 C5 t- Z) j8 S
  27.     "Times-BoldItalic",1 _/ \; E+ n/ n( _( @; [
  28.     "Symbol",
    & p! e5 D" J) I! h1 b5 G8 x; c, f
  29.     "ZapfDingbats",6 h0 J9 \7 c+ B  _* t
  30.     NULL
    $ i1 P. s% H. y9 j  z
  31. };
    4 g6 J' {' f9 Y+ j
  32. 3 I- z2 j% ~" D2 C: O/ V

  33. . @" R) O: S3 R+ T8 J
  34. const char * LPDF_GetVersion(void)
    % j- O9 X$ ?# j$ F
  35. {; [9 Z0 N2 h: `" Y0 W
  36.     return LPDF_VERSIOIN_TEXT;2 W' ?  K% ]/ P+ y; p
  37. }% m1 |! n* u. h5 W* h' N- k+ m) e+ j

  38. ; \  L9 T# k' y# x0 }# }/ a& R5 I
  39. LPDF_Doc LPDF_New(void)- T! H3 u! v: L) H+ g: u( W
  40. {1 V: E6 D$ L. d
  41.     static LPDF_Doc_Rec pdf;
    * z* V3 R' g, C+ B# t) c
  42.     LPDF_INT length = 0, i = 0;
    : v. D# q3 z( k& R
  43.         LPDF_UINT writeBytes = 0;
    " \" s( }0 U% s4 z
  44.         FRESULT fr;
    4 k2 j7 G' b9 V  r
  45.     / u9 F( i3 G4 c( i9 d: q- v
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);) T9 ]0 K5 ]% A6 n6 r* K
  47.         if(fr)
    4 A" k! z2 h2 E
  48.         {' w5 C5 g  a$ p& I$ ?
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    6 H( K. ^% y  O& ~5 o  {8 s9 g
  50.                 return NULL;
    4 W- R1 z* E+ m
  51.         }
    4 Q+ m9 F- J9 V/ W) C. q. L% E" k
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */& t( _3 N4 v' e! }2 _% l
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;
    & d3 _# v3 B3 I  D, k
  54.    
    2 X% B. @8 _8 U) v% |( W/ I
  55.     pdf.obj[0].objIdx = pdf.offset;+ Q2 l- W6 D  h; D2 R8 v7 B
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
    , N. n: w7 f! I2 X: v0 L
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);0 R6 S1 k6 l# |3 f9 y* q7 p
  58.     pdf.offset += length;
    - N# }0 M6 D' U
  59.     6 }9 b- i# E/ v: x
  60.     pdf.obj[1].objIdx = pdf.offset;
    " `% I& T' T$ T) s& N# j5 x
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"$ z9 ^0 A3 b5 i9 }8 q8 o
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");# s. u+ v, k6 E8 M
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);' [0 ]+ d& C7 d) ^  n/ }  v+ u
  64.     pdf.offset += length;& Q, m/ K& C3 X: L% g' o- D4 c
  65.     4 N3 R- a( b) d' q+ r* G6 a
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)
    : e9 n3 Y1 [" v. M8 l( a7 f0 U
  67.     {" T" ?4 K0 C7 v# z
  68.         pdf.obj[2+i].objIdx = pdf.offset;
    # _; n- c) k' A( q
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    + I$ z* k: T4 D/ r8 Z% m4 U  a! k0 W
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
    1 @/ `, r$ @: b- E6 G
  71.                         "endobj\n\n",3+i,font_list[i]);5 C# T# @( Z# i7 P; F5 A5 u5 v
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);0 D  Q/ l% O- a, q, `. _2 T
  73.         pdf.offset += length;
    % N  x+ k( u; L0 h6 p
  74.     }! c2 k* W1 w$ c, h, j- |' s9 H& _0 W
  75.     for(; i < LPDF_BASEFONT_NUM; i++)
    0 U5 Z, ?4 [. r) S& D; U9 C
  76.     {
    ; O7 \' D9 n# b% A: z6 U" v
  77.         pdf.obj[2+i].objIdx = pdf.offset;
    1 b1 D8 k3 Z/ s( r* f, V5 C  H
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
      @' F, `7 L  v2 ?: ^$ j5 p, E
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
    & [7 S6 k9 q* J7 B2 _
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);# i, @" I4 O; i' H* z2 p
  81.         pdf.offset += length;1 P) A9 G; E6 o$ L' E3 D3 I! \+ N
  82.     }. X: g" R6 v3 e
  83.     pdf.objNumber = 3+i;1 \; N+ @' V( V' x" h2 K$ K4 K
  84.     ~1 K$ }2 w) m( }1 f% R& |
  85.     return (LPDF_Doc)&pdf;
    1 _. ?& L' V1 @' L; N  }$ Y% |5 K
  86. }7 d& w9 X5 }! [4 o9 ^4 M
  87. * C& }2 ~* Q4 g0 J( f: [$ K
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    - W6 R0 v2 J  w3 E* G1 u* I
  89. {8 _6 n6 S: `$ ^( ^
  90.     LPDF_UINT16 i = 0, child_pages = 0;% S, t9 [" O8 D. o% i
  91.     LPDF_INT length = 0;
    ! C9 w& `) T8 |8 b1 V3 G+ W" |) H3 U
  92.         LPDF_UINT writeBytes = 0;0 _( r5 b, c7 z5 d& K

  93. ; x; \  e9 k; i
  94.     pdf->obj[16].objIdx = pdf->offset;
      l8 B* c2 V  h
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;
    ' L' U% z6 b; u
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);
    ' L. F+ P9 M/ S- ^
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ( ^! M5 {2 O; R& Z6 z
  98.     pdf->offset += length;
    ) t0 y7 ~& B) v% r( k9 {, U
  99.     for(i = 0; i < child_pages; i++)- {( Q7 J: _8 \$ [
  100.     {1 B) [( j. M9 e+ O! X
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    * D, K2 c2 Q9 N0 j2 F$ T
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);: ^" e, i+ C+ O0 U; L2 M5 G, O8 k
  103.         pdf->offset += length;4 c5 C8 L) s% |' ^
  104.     }2 s% a+ o$ Q& G8 a. R" R
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");: b6 V" o& \# L5 O5 z+ n7 R
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    3 I* b, \! g( y3 u  t
  107.     pdf->offset += length;
    : M8 n, D# {' ]" X" [4 O
  108.     : c# H9 H+ W+ o5 _. w5 v
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    / M  X/ g& h" {
  110.     for(i = 0 ; i < pdf->objNumber; i++)
    ) p  ^% z- S# P
  111.     {1 l3 Q0 i9 a3 j" K
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    6 `' P1 y; |5 U0 o7 h, @" p
  113.     }
    6 x! M2 P) I1 o3 k8 E, Q  k! j  ^
  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"," A0 T/ f( G) e( a6 ^
  115.                 pdf->objNumber+1,pdf->offset);1 x0 E# P' s; W& [3 @8 k' f  E
  116.     LPDF_FCLOSE(&pdf->file);6 r6 [/ O) d$ X% i( L
  117.     LPDF_REMOVE(file_name);: j4 i$ ^- ]. n1 ~. e6 F! [" }
  118.     LPDF_RENAME("tmp.pdf",file_name);1 c% C' M9 g. f" U& ?7 N2 q, l( @
  119.     return LPDF_OK;6 {8 H& p: w6 Z9 F$ {
  120. }; N& T* I3 j" |1 Y
  121. 9 Y8 n& ]7 n* U4 P& g( C
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)2 B. S8 O. t; [; ?0 S* V
  123. {* u' ]; d6 |3 r! _: Z( V
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);
    " w6 h/ `* A3 [2 b7 U
  125.     return LPDF_OK;
    1 E) V( {+ a: r: t( e
  126. }
    3 c5 I  v0 E1 P% k& O% n/ m1 I, J# k

  127. ( h& }" N9 g( w3 J* J4 I( T" I
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)# T! S: H1 p# s/ ]3 B8 i
  129. {& P. r' B$ o2 b# o
  130.     LPDF_INT length = 0,i = 0;
    8 S* K, `; }, o) Q+ J6 y2 }" k
  131.     LPDF_Page page = NULL;
    0 r) P  ~; t8 }
  132.         LPDF_UINT writeBytes = 0;4 h2 W. C9 v$ P( t
  133.    
    # t) s" u- M8 h  ^
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;. V2 @* S1 G1 B$ U7 p; 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": E' n) F0 O0 O6 w5 k
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    $ O# Z" h- K3 J# l5 n
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    * @" N% W% K2 f4 ~: [* c
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; E& e  A( z6 [8 e
  139.     pdf->offset += length;
    + E/ M: h/ P7 d% R5 p5 B
  140.     while(font_list[i])9 D; I- g9 j9 u+ y6 l1 s, D
  141.     {0 p! V; z) b% D* Y6 Z9 @- M# J0 }
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);5 q4 f% G6 g7 ~2 |
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);0 _- Y- N) U2 y+ k5 Q. d5 \0 B( U
  144.         pdf->offset += length;! t0 W7 k9 w$ Y# J" m
  145.         i+=1;* }8 u% v: {7 ]  h9 X% G
  146.     }3 K2 ^3 ?5 j2 E- ]7 |# M# O5 u' O
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");
    * D. v0 W5 U, ]6 }- g1 D
  148.     pdf->offset += 4;" o+ w! q+ Z4 X8 G$ @% ~( T) F
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];& s& w, V8 C! }
  150.     page->width = 595;
    7 L3 W# h: c0 V
  151.     page->height = 842;
    - d% a, v& J; i, ?, d
  152.     page->gMode = LPDF_GMODE_INVALID;9 v8 v% M7 |: |+ f, h5 K3 c2 r! A
  153.     page->fontType = LPDF_FONT_INVALID;4 Q& t1 F" {) D6 X3 [; w. d- Q* u
  154.     page->doc = pdf;! F( |+ q( ]9 [% }& [
  155.     return page;& u7 C4 ?) @7 T  I: J5 }1 S# v
  156. }* R. w7 p) ~3 M+ D1 e5 ?4 L

  157. ' c3 t( E3 x; X3 Q6 b# s* p
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)  ~0 f9 G! [% N) e
  159. {
    " S' e8 C# h' D7 |5 X
  160.     page->height = value;
    : S) U, `9 v! I7 D1 I
  161.     return LPDF_OK;- ^: x1 d) r% V" G
  162. }3 C1 C# R7 r& I# I' |
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)
    " f: _* C# }' T  X% x$ u
  164. {8 c& p2 i. A7 {2 O3 X
  165.     page->width = value;
    + Q5 e( V7 b5 ^; O% i6 q
  166.     return LPDF_OK;9 \- ?# R9 I" [
  167. }
    2 P  R% P; `: H& p2 ~
  168. 2 I$ l3 E* h2 x# f/ a: g. ?
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)9 U7 Q: m4 c# h" M7 R- m6 g9 b
  170. {& K! @  E% T2 Q' j5 H% K+ X. D3 _
  171.     if(page)
    & b/ B) P) {) ?$ a% c7 w. z
  172.     {
    . \0 w/ z* L: h8 u& H
  173.         return page->height;
    2 z7 f2 A, s  e! R
  174.     }
    " _0 ]$ U. t5 v9 D$ C- V' \
  175.    
    " X, V5 X8 R" r' D+ l" F2 B6 S
  176.     return LPDF_OK;* p2 c# L7 Z6 J- h2 Y
  177. }
    ! O/ |4 Q# o# i$ P$ u

  178. ) t5 u1 I6 B1 p3 r  n1 U2 ~
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    , ^( ~; U  \- z/ P: x3 X, N$ G
  180. {
    % v% h) k' P9 o+ `0 I
  181.     if(page)
    ! }' B2 h) H! X2 `
  182.     {2 G' T0 C2 K4 h" [/ {7 a  y% X. b
  183.         return page->width;0 ]$ Y; {6 I$ @
  184.     }7 m3 i+ o% t8 c: M' N
  185.     . x$ U& I; D- P9 e5 w
  186.     return LPDF_OK;6 G7 [! V: z; [' z( E8 L
  187. }
    * S. g$ s' j3 H- ]1 v' K: x

  188. ) m7 M4 h: o2 y1 V
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)5 L+ a( L. @- V/ ~9 e
  190. {: [! R$ c8 g/ |, ~9 K
  191.     if(!page)
    ; T+ m$ m7 z" x+ s. c
  192.         return LPDF_INVALID_OBJECT;
    1 C. P# j2 P- x1 X1 W' ~- _/ x
  193.     if(!(page->gMode&mode))
    " ~7 ^! [: d; B# P. a7 Q( L3 |0 C
  194.         return LPDF_FAILED;9 ^4 C- j6 }9 X# c  U; T8 y

  195. $ G, }6 v+ m; Y: l  N' M3 D0 U2 O
  196.     return LPDF_OK;& m& ?8 X! q/ T; A! _4 ]
  197. }
    % b* {3 z2 ?% A; w
  198. 0 L! Y! F" V& d
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,: G4 q, _* ], t- d1 m* |
  200.                            const char *font_name, LPDF_UINT8 size). ?0 w4 j3 M% C8 I/ S
  201. {
    & @2 _$ ]- G/ v* y
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;$ ]. a! v5 V, o, r
  203.     LPDF_INT i = 0,length = 0;+ |$ O; `6 ]) T  B/ z5 i
  204.         LPDF_UINT writeBytes = 0;
    7 q$ \' ]: s) x; b
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);9 ~, ?, b: m* O9 F. H
  206.     if(LPDF_OK != ret)1 E9 f  p+ x1 I# e' X
  207.         return ret;
      B7 ?9 `. f0 b* ~/ _# a

  208. ! M* \0 n0 P1 ?: w* R2 Y  t# t. ^
  209.     while(font_list[i])0 I1 ]1 O0 P" r& V. H" z
  210.     {
    3 T* U1 s8 \1 n! y" ]
  211.         if(0 == strcmp(font_list[i],font_name))
    - J7 W* a4 e" S! A2 Y+ V( p
  212.         {
    " b4 h- Q4 V9 k' e% H4 n  P, F
  213.             page->fontType = i;
    6 q+ y" b& x; P4 p4 r
  214.             page->fontSize = size;' c, D1 G  u! \
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);
    1 l5 F% z. ?: a0 b
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);" u1 e, e+ |$ S
  217.             pdf->offset += length;
    1 v* S+ Q( V8 N8 B4 i( S3 S2 [) v
  218.             page->length += length;
    0 _- `  f% o% S& w! R1 O  w, c
  219.             return LPDF_OK;, B' S. i, i: Q8 T0 B
  220.         }
    4 ]+ z& d( {8 U" N; d
  221.         i+=1;
    2 ^' [% X/ d) u. A4 `
  222.     }
    0 \2 |4 a0 w$ ~! n3 K
  223.     2 S) S2 u6 ]6 T1 `
  224.     return LPDF_OK;" ]' _8 ]$ I# G% r* o
  225. }
    3 H9 s' K- M5 L  A

  226. 2 p! i1 V$ D7 v4 r) h0 `: R: K) e
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)
      V" D' ?6 k$ R7 {- [4 J
  228. {3 Y1 O/ o5 y2 Q, U' k
  229.     LPDF_INT length;
    , h+ C9 ~+ E- H. v' S
  230.         LPDF_UINT writeBytes = 0;
    ' j* c- u0 A( ~3 w
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    0 D- t( |! @' z
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    " L9 I3 p/ z. l6 @4 {: v
  233.     if(LPDF_OK != ret)
    / n# ^6 V3 Y6 M" n" j- F) K
  234.         return ret;: j6 ?% Y, a. f7 a( d  d
  235.     ( \! u& t$ z$ Y4 v
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */
    5 U! j0 [4 J, j" L) o
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
      n/ H7 Q& s/ G. x1 p  A8 \% t  g
  238.                         page->width, page->height);: j( x: |$ W, X* J/ G
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    " r" K2 m9 c8 W2 Q# ]. p
  240.     pdf->offset += length;' l- V  p8 a7 p4 n
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;
    8 w) y* O/ w' u0 h
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",- R7 D, d' Q% s, b( R5 ]
  243.                         pdf->objNumber+2, pdf->objNumber+3);
    5 z9 U" U/ K% f; j
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);( n, C$ x. }) [' O; U! F1 i
  245.     pdf->offset += length;% _/ m  c4 k* c( h$ X( ]
  246.     page->length = 0;
    " g1 t2 P+ {3 U) q7 ~
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;( Q- t3 I5 m; L# u9 u  F  j, a
  248.     return LPDF_OK;* u0 W$ R: J& v$ a1 X
  249. }
    4 `! r' M; h; R% |

  250. " P/ S7 G% B, j( J) J' o. X
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)( G" }( o3 V6 @, p2 z( d2 ]0 ?
  252. {6 g5 S' y: B$ E5 z+ r" G
  253.     LPDF_INT length;, c+ F2 J4 I: u1 c# o+ Y  p
  254.         LPDF_UINT writeBytes = 0;" X( Y- m$ p1 L. S3 i5 }
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;0 X0 \+ h! m8 {9 P
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    2 D+ _! `/ F: o% c
  257.     if(LPDF_OK != ret)8 ~2 b% h% h9 ?/ b( K/ U- \2 a  z
  258.         return ret;- i% S" A( e9 C% q
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    $ O3 G4 I) E' Z0 G- p! K
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");' }0 t" x( ]. j* [
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    " S( Z* Y4 e( D8 ?
  262.     pdf->offset += length;0 X+ \9 b( S! _, {: u
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;' ?5 v; \' T" O* q& Y
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",* Q$ ?# J0 A' r( a% ]3 L9 M
  265.                         pdf->objNumber+3,page->length);7 z1 \" `/ {6 b* e- x$ v
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);! C% i% t' }4 V
  267.     pdf->offset += length;
    4 P# ~" C$ ~' B# D' h7 r4 e+ Q* T
  268.     pdf->objNumber += 3;
    ' U; n1 T4 k" b5 u" O
  269.     page->gMode = LPDF_GMODE_OVER;+ b' A/ M' d+ U0 t+ e. q8 a, A
  270.     return LPDF_OK;
    ' @* L3 O, i% @- E$ u, `( B+ S
  271. }6 P1 B) l. j& `+ J: N
  272. ! C9 A+ R1 N) t) h) n  P8 j
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    4 H1 ]5 w0 e/ [) E. F+ n1 h- _
  274. {6 @/ j* y* r* ^, _- _( X2 M
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    + y+ u+ H2 l8 {  K
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);  s6 \$ }5 `4 Q  l) W
  277.     if(LPDF_OK != ret)$ [" ?3 o5 }0 ], o: d8 [" Y" y
  278.         return ret;' J, v1 b* w$ t- }
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    8 Y! D/ {) h  a
  280.     pdf->offset += 3;
    ( B* N% J9 \$ k4 X" v2 m- U
  281.     page->length += 3;
    & X1 n) V: {, m2 |8 F+ C% S& ]
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;+ {8 f) K/ [1 V" s0 X; @
  283.     return LPDF_OK;
    0 n; R: M& A! U
  284. }
    ) n) `0 a5 e& w9 ^6 {
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)$ y1 H1 n; O) W) ^' ^' m. ^
  286. {
    , i3 Y) l# u) C* s" |3 E& e! l
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;( L5 S# h; c+ M; {, s! L
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    2 d8 N$ d( ^* V, z0 n
  289.     if(LPDF_OK != ret)
    4 U2 k7 I0 Y% E, Z1 r: R' {6 p/ i9 j
  290.         return ret;$ G8 F- Q5 E  p. C+ y
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");- ?4 q/ l9 {* K  p% |3 R
  292.     pdf->offset += 3;
    2 u( L6 K! G/ [" {, @
  293.     page->length += 3;
    7 s* p7 [; P1 \( n2 Q
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    & y+ |6 m0 S5 r% o/ V. r
  295.     return LPDF_OK;# h7 ~, @+ j! s& c- M) o
  296. }
    : N6 U5 v. q2 `9 K
  297. 6 T$ I( d' @! x& L, Z0 F9 }
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    ' H  ]* ^2 G0 w; m, U# L
  299. {
    $ H' M- K/ R6 j8 l& e; c8 E
  300.     LPDF_INT length = 0;1 y! P0 s/ U1 t
  301.         LPDF_UINT writeBytes = 0;$ N0 a$ X3 L/ w
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    1 c$ v7 [' m& s6 J2 q" U
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);7 R$ g! `8 B9 z
  304.     if(LPDF_OK != ret)
    . ?1 C" g# f: f  {1 a$ ?" v
  305.         return ret;, V, {( t; E! {* W6 X  `5 N
  306.     if(LPDF_FONT_INVALID == page->fontType)
    7 L  d. E" s+ ~2 p0 s4 G
  307.         return LPDF_OK;
    % b0 R+ j. j( s8 b
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);( L0 a- l/ F: b( Y5 E9 v' m
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);& L* r5 A' B' K# q5 D& K) T- t
  310.     pdf->offset += length;* @0 l$ L5 X4 [  t9 O( N5 H
  311.     page->length += length;
    . w( u1 G* Z, @$ M4 \  M/ j# I
  312.     return LPDF_OK;. d. ~5 }! \( ~4 ]( Y, N* E
  313.     2 Z3 w: W9 M+ w0 V
  314. }, V# e8 X7 q) r- h8 }& u* H
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,
    * _- f8 ]5 w& \# w
  316.                         LPDF_INT x, LPDF_INT y)
    + F& n( z/ B  T' o5 \5 R0 q# V; J
  317. {2 [# X7 C2 Z9 h% J# P& v* C% D; V) L
  318.     LPDF_INT length = 0;
    8 z* K) U$ |. @) E7 U0 f$ p
  319.         LPDF_UINT writeBytes = 0;2 G& D# ~9 W' X6 `
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;5 X3 u2 C! v9 q; r" F. b- y: Z% j
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
      B& F) H" m. J5 v% o9 S! m
  322.     if(LPDF_OK != ret)- g+ a1 r7 D) R; o0 Q# R
  323.         return ret;
    9 r  Q$ U  g- ]: Q
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);" Q1 ?7 ^' _  S
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    7 }0 O9 o* j: x: @  W; c
  326.     pdf->offset += length;! o; G5 D$ s" c
  327.     page->length += length;
    * H/ d$ p/ B8 e/ C: h, t" Y1 P
  328. + }  z3 l& k) S6 m& a+ v# O
  329.     return LPDF_OK;
    . \  S9 k$ X6 H9 \2 W5 ]8 X
  330. }, S7 D1 k2 E/ Z7 ^
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
      e2 Y0 e% ~. Q3 p7 w/ {
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,( N2 k( e% R0 l1 q9 g
  333.                         const char *text)5 f' ^& L" b+ k! x+ b
  334. {
      c3 |" |- K3 ^! {) S
  335.     return LPDF_OK;
    & a7 P9 K# f6 ?# W4 O
  336. }
    , h" V3 U1 |7 k" v

  337. - T& w8 N" J- O$ j+ m2 E
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    # `: [6 M4 @9 v9 ~$ I2 X
  339.                          LPDF_REAL r,8 y7 M8 \; H9 m9 e; S5 [7 N) t, a. n
  340.                          LPDF_REAL g,
    4 j9 J0 G3 a# l0 m1 e
  341.                          LPDF_REAL b)
    ( T$ J3 A& @" R* N* ~: m
  342. {' D. Z2 B2 F0 x$ @" ^8 y& u
  343.     LPDF_INT length = 0;9 h/ `% `( e6 y$ X9 j
  344.         LPDF_UINT writeBytes = 0;" m9 q" Y" t% H8 {/ R
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    + l# N5 D8 z) q% J& _+ \
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);$ X9 }! I: x0 P/ i) `6 D+ K& I
  347.     if(LPDF_OK != ret)  c; Q3 k; m+ P( O  q
  348.         return ret;
    0 ?. t' R+ h8 r# Z8 I' m

  349. , i  h2 D& C! Q/ h/ z- X! C2 r0 T& b) s
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);8 l* F- i0 M9 G2 {
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);" n7 Z) O( r. r. z* C7 Z
  352.     pdf->offset += length;# f. \, u5 b4 [. W
  353.     page->length += length;8 W2 i, N, C! s0 {3 p. P6 P$ U" e
  354.     return LPDF_OK;
    1 W7 z6 H! S, _8 O0 Q  |1 K
  355. }
    $ L& ~5 e. K& C! w; y3 D; M7 X9 D
  356. . J: j7 N+ O+ ~: \% ^2 f% `( z! l
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    $ R) y8 u# L2 y  q9 m* d, q
  358.                          LPDF_REAL r,
    * F- _/ \7 T0 Z
  359.                          LPDF_REAL g,
    , ~/ p& L4 J4 ^& _6 Q) b
  360.                          LPDF_REAL b)
    4 J: Z# U$ m! r5 _4 e! P- |
  361. {! ^, ~" z* Y- i. a  N
  362.     LPDF_INT length = 0;+ E: n3 I. U+ C6 ?' c
  363.         LPDF_UINT writeBytes = 0;# w% q/ J7 u- Q  I  q& l+ {
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;- L2 I" T" Z- u4 [& R
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    9 U5 d) a! z( I5 |) S, ^& j
  366.     if(LPDF_OK != ret)+ J" M! Y$ d. H: Q
  367.         return ret;. ^& F  e8 {9 J# i9 {" S

  368. * @; \' n+ ?) G4 K! B9 i- \. F
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);
    ( S! E. g5 ?: A. m
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    * P$ ]7 U0 c' f, f$ G
  371.     pdf->offset += length;
    - Y4 @, E# F' {5 K, d( _; }7 [
  372.     page->length += length;
    $ z* P# E. ?. c* a
  373.     return LPDF_OK;& c4 u7 @5 [  u
  374. }
    $ ~$ l) F1 y' k* ?. |/ T
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,$ i: x; h& H0 L! w
  376.                          LPDF_UINT16 x,
    $ W  ^6 {+ ~4 r8 T# {
  377.                          LPDF_UINT16 y). E# G# E. G: n; E( H% I2 r
  378. {
    0 U% c' Z7 o! w! @  A% A
  379.     LPDF_INT length = 0;) ~- q4 ^& b, f! k" k! {8 s0 G2 E
  380.         LPDF_UINT writeBytes = 0;
    * A) r/ T% v! x( d: q1 T
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    - Y; [& U2 n* |- E* N4 P
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);
    4 D2 x5 s5 O9 A3 [5 d
  383.     if(LPDF_OK != ret)
    9 p/ d# @! E/ }: ?1 \
  384.         return ret;7 T5 J, R# u  }9 f" b
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    ( W+ Y- ~) H; {+ `6 H
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);8 P0 A7 M% Y1 Z9 [5 |! o' `4 M
  387.     pdf->offset += length;
    + @! `5 {# e( i3 n  Y
  388.     page->length += length;
    ( N- r* c$ S: n
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    + R% H7 Y' \+ i: D
  390.     return LPDF_OK;
    3 I& N  P4 R7 N. a' Z* f2 `
  391. }
    " N6 c5 o+ K- b, H/ b
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,% `7 O% M& H' J* N( A5 J- m; v
  393.                          LPDF_UINT16 x," g" A: d/ }- O$ F. G
  394.                          LPDF_UINT16 y)+ ^% H1 v1 D" y* N$ \( X
  395. {2 R. [: G  u7 {4 F% N2 w
  396.     LPDF_INT length = 0;1 m* ~8 b" R9 \$ M0 O0 x! ~2 a7 D
  397.         LPDF_UINT writeBytes = 0;- m4 U/ D: G6 J; n0 D+ a
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ' P- U& n2 F3 a9 I6 ^
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    " j3 M; s$ h5 S# {7 W2 F8 P5 P
  400.     if(LPDF_OK != ret)0 P% L9 v- r1 @7 \+ r+ H( p, @
  401.         return ret;
    7 l& C) ^3 p! l3 s- Y/ [
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);, G$ T) p5 K) I
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);2 x% c# o8 T! s$ u  |' L
  404.     pdf->offset += length;  S0 K5 b6 w0 v+ d! Y
  405.     page->length += length;" Y. F2 X0 G; t, O4 P
  406.     return LPDF_OK;% }* b) A# Q# Y& y% x9 C
  407. }
    # o) h3 x$ ^2 J( j0 ^, h
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)
    6 p5 k* z+ }* Y! C( n
  409. {
    + d' D4 u* O. r* }9 z: _& z
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;4 n' I; x8 @! K6 @8 B$ a
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    + m  J, f; Z4 b5 q/ G
  412.     if(LPDF_OK != ret)* s' K. a0 R2 D* D- D8 i9 H
  413.         return ret;
    2 h% }7 W  k) z0 X1 [. p
  414.     LPDF_FPRINTF(&pdf->file,"S\n");& X5 N" ]: Q% h3 `4 V+ X
  415.     pdf->offset += 2;
    ) X3 |0 E; X$ _+ G  w; @: n
  416.     page->length += 2;# h" F/ g& y6 D  F
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    . K4 k0 }9 \5 \7 u% H) L, x
  418.     return LPDF_OK;* m; \; x+ T, y0 [# z% S1 j' r* p" P
  419. }
    1 R; M* A$ X8 A) t9 N0 T
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    , G4 c& i5 I* k* T
  421.                       LPDF_Image image,1 B4 M0 W5 w9 }, r# p4 a+ A
  422.                       LPDF_UINT16 x,
    7 d/ P# {- L2 r# P/ m
  423.                       LPDF_UINT16 y,: P) G  ?! d) c+ G" \
  424.                       LPDF_UINT16 width,
    " i' d/ y( Y9 n7 Q* o- _
  425.                       LPDF_UINT16 height)1 r, Q# [. u# b. H  y/ X
  426. {
    # s* N( g$ A% o+ \8 b  l' e
  427.         return LPDF_OK;& M, Y: H4 K- H) A& S6 L
  428. }
    ( [7 E  x" C' k6 F* k+ I
复制代码

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

  1. pdf = LPDF_New();
    9 R. }0 g( J) K" X9 c
  2.     page[0] = LPDF_AddPage(pdf);
    " ^# F& F4 y1 f$ H$ ^7 ]
  3.     LPDF_Page_SaveParams(page[0]);
    9 o. \; A% A+ x; ]9 U2 B. a8 R  R$ v
  4.     width = LPDF_Page_GetWidth(page[0]);  l: G% s; s* w( ?7 _
  5.     height = LPDF_Page_GetHeight(page[0]);  ^3 ]5 L  Q8 B( G  q' Q6 D
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);
    / Q% P; G. f2 s" ?. V
  7.     LPDF_Page_BeginText(page[0]);3 A% n/ G9 ?% Z9 {0 r: V4 @& X2 ?
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);% j* d6 W$ n0 l# h% o: u/ P
  9.     while(font_list[i])
    6 X# g, \- b! Y! j- F  V# n, U( t
  10.     {
      b6 ^7 B1 ]+ q
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    " o! y: I  l: L3 T0 t. x
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");1 y# v) O- ?4 Q/ `
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);% v3 R% H8 O% ^1 u0 x# A( N* Q
  14.         i++;6 L# V# F, L- O  T  h! T
  15.     }
    # i' n" y% R  l$ W5 X, Q* C: v
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);( u& K$ y6 S) ~6 \
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());: F' h; X: K/ e3 P
  18.     LPDF_Page_EndText(page[0]);5 A+ Z" r+ q6 t- {) `( T) S
  19.     LPDF_Page_SaveContext(page[0]);
    ( A$ Z  z6 @/ {
  20.     page[1] = LPDF_AddPage(pdf);
    ( [0 L0 m2 p0 b  |2 B; b! J! D
  21.     LPDF_Page_SaveParams(page[1]);& |/ O4 ]- W$ w: A4 v
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);7 x8 O8 {! {% S% n( a2 m
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    7 t9 E& ^: c: v! n7 n& q. ^
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    + i) W) I( ?  b/ @" z
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);$ }% j/ n$ L7 l3 K/ D
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    4 W" b7 X3 y4 i4 L9 T8 f
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);
    % I8 o* }/ q- k$ I5 a
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);, m# H' b. w2 t
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    % E& n, l. Y7 e; d
  30.     LPDF_Page_Stroke(page[1]);/ f) e" \' P& L
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    % n7 w: X5 x' i
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);% |0 `' ^. H* E
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    2 v9 m1 ?! d  X
  34.     LPDF_Page_Stroke(page[1]);9 f. ]4 Y2 m- T3 d! N6 Y
  35.     LPDF_Page_SaveContext(page[1]);
    1 O* N# k0 V; i; I
  36.     LPDF_SaveToFile(pdf, "/red.pdf");
    2 U7 f1 u! y; w; N
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    " {" r+ t% q6 {7 X
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了
( _6 K& ^. N1 e8 P

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体2 u: D" u6 i2 K* m2 t8 Y
0 J- K5 f, d" L- x4 |9 ?. W0 t

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:550 _- Z- j% c7 J, v; Y! A& Z
只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...
" c! N/ q& D2 W* I
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
, u$ B9 C/ t7 F& R# y首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...

  {  u* C! m# O! \66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
) q- {! ?' O% W1 H- S+ B
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:450 X/ @5 j7 p* V: h+ h6 S+ N: a* o
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
6 J6 R1 P% u2 t; x& ~8 |
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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! d3 W4 d3 A6 b" B/ Q" Q5 d% |厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接
3 e: h- ]- U% h5 ^
这个还只是一个简单的库,实用性还是差一些的
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
7 ~' Q) H  `) [" t6 r3 t1 mff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
. L& x# x; q3 A* M  _
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:228 X) w( m, F9 Z: }+ u* t- b! q
ff.h是FATfs中的文件
& T3 t( w% ?! B3 S1 U
嗯,这个画线能改变线宽吗

所属标签

相似分享

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