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

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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 5 x! v- n4 N, q* U

' m& H' U. o, d* b

主机环境: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__
    ) ^, W8 ]$ G, G5 o4 @) h+ x, I
  2. #define __PDFLIB_H__
    ; C8 t) T) y- q
  3. & `0 H0 i' C* n8 ?6 m% C3 u
  4. #include "ff.h"+ Q) D7 A! c9 P# I$ R5 l& x6 L* u2 U! R
  5. /*----- standard C library functions -----------------------------------------*/
    0 C0 h, F- y* {

  6. 8 d  {/ @3 u  U' T9 s* U- b( {5 _
  7. #define LPDF_FOPEN                  f_open' W' a% L/ ]9 S1 f3 ^8 o5 F
  8. #define LPDF_FCLOSE                 f_close
    , s0 m) r$ w  P5 b  Y7 }& {
  9. #define LPDF_FREAD                  f_read) T- R6 V. R9 Y: `
  10. #define LPDF_FWRITE                 f_write
    ( D/ V- ~( {0 B* A1 F  p
  11. #define LPDF_FFLUSH                 f_sync
    7 C" `! z* b. y2 ^, p8 e
  12. #define LPDF_FSEEK                  f_seek7 _! z: C5 ^# @! S: ~1 j
  13. #define LPDF_FTELL                  f_tell
    2 q$ F! [8 U7 u) W& W
  14. #define LPDF_FEOF                   f_eof
      F; Q% w$ S; L
  15. #define LPDF_FERROR                 f_error
    1 I( q! V: w! |6 ^: A( A, N
  16. #define LPDF_RENAME                 f_rename
    ' ^  Q' F5 G4 [
  17. #define LPDF_REMOVE                 f_unlink" B3 I, }5 F  F( {* y( u
  18. #define LPDF_MALLOC                 malloc
    9 H: F9 S3 V: _* z! j% C. T" O
  19. #define LPDF_FREE                   free$ a5 v2 Q# U; O. l
  20. #define LPDF_FILE                   FIL
      K5 N, _4 X' ~0 r: `3 R
  21. #define LPDF_TIME                   time
    / |: K  ]% b6 ^  F' p; i
  22. #define LPDF_PRINTF                 printf- h* E1 F3 x2 z: g) B
  23. #define LPDF_SPRINTF                sprintf
    % d$ K6 \+ w3 G+ P: Q9 w: R3 O6 R
  24. #define LPDF_FPRINTF                f_printf( K7 N) U& N$ K! @8 E# l& y+ V3 a
  25. #define LPDF_VOID                   void
    5 d( f3 e+ `4 P  O% {- M( |, t
  26. #define LPDF_SIN                    sin' L' ?- B* t9 Y
  27. #define LPDF_COS                    cos
    ' y6 j$ I1 U8 j
  28. 9 ?8 o; \: p' g
  29. /*  native OS integer types */! q( X" l% n7 B5 |& T+ M% n- A& b$ v
  30. typedef  signed int          LPDF_INT;- b7 V" G) @8 i( o3 R
  31. typedef  unsigned int        LPDF_UINT;
    " z7 s* z  h6 D% d
  32. 5 z' R! Y! C! ]# p( x9 w
  33. ) y4 d! n( Z4 m
  34. /*  32bit integer types
    , C- ?& W3 {# i7 ^. t. N* W
  35. */# g: [' y. X% L
  36. typedef  signed int          LPDF_INT32;: v4 O2 ]' G0 U1 C
  37. typedef  unsigned int        LPDF_UINT32;
    . v6 n7 _6 q) K: i* q/ i( _

  38. ( h4 [& ~+ P& J3 G6 n

  39. ) }3 V+ Q4 P, P  L! u! A
  40. /*  16bit integer types
    . Z. f! x" @9 v$ q5 n6 I$ s3 R
  41. */
    $ V) ?% A) k; e1 A6 f  R7 B
  42. typedef  signed short        LPDF_INT16;
    9 h" i( {- T5 X+ C; e+ d/ v# l
  43. typedef  unsigned short      LPDF_UINT16;+ m1 s3 c& x8 b
  44. ( r, }. k# s* ], J3 o9 ^
  45. ( V, e; v8 j6 L- b8 ?1 @; D* [
  46. /*  8bit integer types: g3 ~4 K& a3 p9 }9 H: F6 R0 I
  47. */  b9 q/ |$ B9 }% H# D0 w# Z2 N0 }2 ?
  48. typedef  signed char         LPDF_INT8;! _4 a: `6 D' Q, b4 f! F" I3 B$ ~
  49. typedef  unsigned char       LPDF_UINT8;0 T4 E  W) r9 c: Q, X
  50. " A8 t8 K4 J8 d
  51. 3 b( u0 o7 Y4 F+ X- k6 e4 B2 ?
  52. /*  8bit binary types: b9 V! @/ L8 L0 d- C& M
  53. */
    2 _& h3 O& d8 Q0 Q9 o$ w4 |
  54. typedef  unsigned char       LPDF_BYTE;
    " U& A, q, {5 Q9 p: Z8 z

  55. " S7 o3 P2 ~0 ^1 [+ M2 W* t5 R( M

  56. ) k8 D: O+ l5 d) o. S- L$ E
  57. /*  float type (32bit IEEE754)
    * t% ?8 u, N! t, q
  58. */0 i1 n& I8 w0 e" V) L
  59. typedef  float               LPDF_REAL;  O1 y% t3 y% ]+ Z6 |

  60. - L1 M2 f+ v+ A* k- N& T! h

  61. $ ~0 q' `  @5 ]+ @6 A
  62. /*  double type (64bit IEEE754)
    - l5 `3 J5 a% R2 W
  63. */
    4 N6 R  Z( N+ b3 ]8 X9 n
  64. typedef  double              LPDF_DOUBLE;
    % H' }: J  y- u- u. @  Z

  65. + b3 }/ s$ S3 M
  66. , ~7 H9 r5 K; g% N/ o; u! @
  67. /*  boolean type (0: False, !0: True)+ d2 Q( ^& A: k7 r6 W; \+ g
  68. */
    . O& _, n! U4 i& j7 k: s3 z9 R  v
  69. typedef  signed int          LPDF_BOOL;. N' y5 u+ G5 n: h4 |0 Z  b

  70. 3 i: d1 h+ K! u+ H, G

  71. 4 h% ]! S2 R$ K
  72. /*  error-no type (32bit unsigned integer)
    . N  F4 K3 _2 l8 s7 z# w
  73. */
    4 R( a7 }2 H* b& U! _- t
  74. typedef  unsigned long       LPDF_STATUS;# t# t- L- O7 t) k

  75. ; y% Y! w" s) O" ?  x
  76. #define LPDF_OK                     0
    . L' R% n% V; t+ c5 Y9 D  v8 N* N
  77. #define LPDF_FAILED                 1
    ' \1 @8 z, }* S0 V+ p
  78. 4 n; L3 B+ r4 R2 t
  79. /*----- font state -----------------------------------------------------------*/
    9 J- p& G% x. j5 i
  80. #define   LPDF_FONT_INVALID                 0x00FF
    & m' M7 ^) K+ u# O& n' A" _
  81. #define   LPDF_FONT_COURIER                 0x0000  _( d( q9 @4 e$ V* R' {( L
  82. #define   LPDF_FONT_COURIER_B               0x0001. a" D# I) w; d7 T+ Q
  83. #define   LPDF_FONT_COURIER_O               0x0002" C2 x7 c: p$ z# J: N5 Q. s
  84. #define   LPDF_FONT_COURIER_OB              0x0003
    ) a- F$ d; `) ]# W* M
  85. #define   LPDF_FONT_HELVETICA               0x0004& j! M7 v) W& i0 w
  86. #define   LPDF_FONT_HELVETICA_B             0x0005
    2 |2 E8 U. m' I7 |: l  |8 o- W
  87. #define   LPDF_FONT_HELVETICA_O             0x0006+ D: b* w# i3 F7 h0 B7 ~; J/ u
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007
    1 T; Y7 o. |/ y5 B* q
  89. #define   LPDF_FONT_TIMES_R                 0x0008! u$ U7 S" |8 B7 x$ g, f+ e4 Y
  90. #define   LPDF_FONT_TIMES_B                 0x0009
    " J8 h6 N7 M  H! O, I3 v; P' i- s5 `6 c
  91. #define   LPDF_FONT_TIMES_I                 0x000A; F! h4 x6 P6 f8 j# Z) Z
  92. #define   LPDF_FONT_TIMES_BI                0x000B3 _1 o% n% X: S
  93. #define   LPDF_FONT_SYMBOL                  0x000C* S- q1 {' u2 V6 G& H
  94. #define   LPDF_FONT_ZAP                     0x000D( y4 p' Q* E& U% F# N7 V; U8 b" m
  95. /*----- Graphis mode ---------------------------------------------------------*/' y  q& P2 G) r% B
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    3 N' R$ u: t- ^
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002
    - B4 Z" k7 Y6 x& g
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x00044 K2 M# J( `0 F% d6 t. }
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x00088 C+ U* V: T$ ^2 C0 \7 `' S
  100. #define   LPDF_GMODE_SHADING                0x0010
    ' T, f$ `% c) e) X
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020& |5 b. r. m- ^3 K
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
    % V1 c  U$ h) e+ C: e2 t3 ~8 Z5 P
  103. #define   LPDF_GMODE_INVALID                0x00801 @) v& ?/ b& n, v' X
  104. #define   LPDF_GMODE_OVER                   0x01007 g3 k  Z6 c* i2 J5 K/ G

  105. ' F% D& ^0 R% }( u
  106. #define OBJ_MAX_NUM     256( r' O! R5 G1 Z# ]. ^
  107. ; P, e) B- L2 ?& q( H# R8 S- C: N# u
  108. /* Page的结构信息是否需要树形结构 */9 u& _6 Z$ Q% z- ^; g
  109. typedef enum 5 i" ~& v4 ~1 @3 C& Z6 g
  110. {' i* i. ~" ~! G; C" y. H
  111.     OBJ_info,
    1 U6 U# q+ u4 c) C
  112.     OBJ_stream,
    ' \0 ^4 C/ V. e4 O0 x) I
  113.     OBJ_font,) {- {) ?- f& R7 I- f1 B
  114.     OBJ_page,
    4 L2 b/ |- o1 j! w0 Q2 c
  115.     OBJ_catalog,
    ; {2 w* C8 D& z1 s; k7 H$ p
  116.     OBJ_pages,
    5 u2 D+ e- E7 k9 n1 |/ U& D; R
  117.     OBJ_image,2 L1 W' S6 \! ~% K& S% q
  118. }LPDF_ObjType;1 N2 ]9 j6 s  Z; r# `! X
  119. 5 M6 {% A/ B+ n  P, T) Z
  120. typedef struct* O4 n, n/ y3 j
  121. {' D5 }) x0 \# c; U( X# k0 s
  122.     LPDF_ObjType objType;
    + R# e3 F' S- q0 ~# R$ g0 q! c
  123.     LPDF_UINT16 objIdx;
    + W+ ~: m3 m, I) W$ p- p
  124.     LPDF_UINT16 height;1 g/ E% Y- E/ h5 m
  125.     LPDF_UINT16 width;
    8 R' }! R8 Y. I& O- q' r: i( i; w
  126.     LPDF_UINT16 length;$ D6 D3 Z# I) F- k4 Q
  127.     LPDF_UINT gMode;3 }, |) y" q; @6 w/ N
  128.     LPDF_BYTE fontType;) K6 e* f6 g; D; o; c- ~7 P
  129.     LPDF_BYTE fontSize;2 r) P2 ~; w8 l8 H
  130.     LPDF_BYTE pState;' W# l: N, y! W6 I0 D+ n) _5 \
  131.     LPDF_VOID *doc;7 n, s4 q& F6 @& Z
  132. }LPDF_Obj;# l+ f+ `' E% F$ e0 r
  133.   |1 P* Q5 h+ Q3 |/ K- F
  134. typedef struct
    & p+ k+ a# {. V
  135. {
    + o' A) k8 b7 u4 j
  136.     LPDF_Obj obj[OBJ_MAX_NUM];$ X+ ]0 f4 F' v0 r2 ^9 T
  137.     LPDF_UINT32 offset;, f. |& p! p) l# z8 J0 ?$ f
  138.     LPDF_UINT16 objNumber;
    - D1 R7 ]( G9 N- A
  139.     LPDF_FILE file;
    ) b: d" z8 y- u& U6 m0 B
  140. }LPDF_Doc_Rec;
    1 }( x- i/ H+ A" s% G, l
  141. $ |$ m+ R" y5 |
  142. typedef LPDF_Doc_Rec *LPDF_Doc;5 q. H) r' |0 L3 h$ L$ O8 J
  143. typedef LPDF_Obj *LPDF_Page;8 D" r! }$ u1 V$ C
  144. typedef LPDF_Obj *LPDF_Image;
    ) h) y& F2 \5 A* j/ A" c, H: ^
  145. extern const char *font_list[];# U+ f0 Z9 x! W: b" h% k7 v
  146. /*----- LPDF Interfaces-------------------------------------------------------*/
    ; P4 t; c0 U  v
  147. const char * LPDF_GetVersion(void);& J& ~; A5 r; f
  148. LPDF_Doc LPDF_New(void);/ p5 _$ y# M2 R% E/ k" I/ @1 r2 l+ \/ t
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);
    + f1 n  I- {0 ]; L
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);9 w4 c5 x" B3 \, h
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);
    7 I  |, F9 Q" K" h1 r) B
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);0 g) k, D5 o% h/ l+ A
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,7 L& [1 W/ i7 o1 q2 G. c
  154.                            const char *font_name, LPDF_UINT8 size);
    & F5 w( _2 m1 V$ q
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);
    0 H- T* A, c/ T
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);- Q3 ^; I/ R: w9 J$ d
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);
    8 g& o/ V4 q, E; U* j- z) W
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);3 }9 ^* b0 f9 P& ?
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);
    & U9 j( N6 d, n
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);" h* ^6 v. k- n* y4 {" r. y
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);
    - X, F/ q8 x3 @# E! P
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);
    5 L* c" Q( [3 `( {7 d7 c  q
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);: z1 }" ~, \% j- B+ h
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,0 R3 h4 Z* o4 T% c
  165.                          LPDF_INT x, LPDF_INT y);: y  f0 Z5 C+ s3 G$ F0 w: `+ {
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    6 _% }0 Q2 U( ?. T% G6 D. {; T
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,7 Q8 `2 }/ G/ y' k6 r! w0 R3 [
  168.                          const char *text);3 W, M$ l0 N8 N- n( Y( L
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    1 s' P+ F) @; ?' C
  170.                          LPDF_REAL r,) \" _4 |( E% s0 O; \- S( E# \' j
  171.                          LPDF_REAL g,# F1 }+ m$ L7 V0 V; Z
  172.                          LPDF_REAL b);
    $ j! Y! q! ~) \& E! s$ F
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,% \$ {0 ]+ W, Z5 F1 A1 d" k
  174.                          LPDF_REAL r,
    # ^  [( M  N% J7 d/ I- j5 @  _. c- x
  175.                          LPDF_REAL g,
    4 j0 G- I3 n& l* z1 j! a: N
  176.                          LPDF_REAL b);
    7 Q$ v7 {" _- m" u, T
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    " f/ k: P5 {8 Z) m6 I# W: ?4 |' |
  178.                          LPDF_UINT16 x,
    ! z6 w# G$ C1 l; N
  179.                          LPDF_UINT16 y);2 R4 [) t$ e* x# S3 M+ k! X
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,8 [. |3 W0 d* \
  181.                          LPDF_UINT16 x,' _7 H) m: s: q) o+ E
  182.                          LPDF_UINT16 y);
    6 q6 l1 V- i3 P3 ~( i8 u! l
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);
    & S: Z5 M3 G3 d7 S8 F
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);. w0 E7 ~. N( X# }
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    8 }. W1 C2 ^! A3 o& n- N) m
  186.                       LPDF_Image image,
    # j. r. R- s; w/ @# }3 e4 F
  187.                       LPDF_UINT16 x,+ p3 Q$ E6 a. }8 [$ H; U; k6 y
  188.                       LPDF_UINT16 y,
    * c: V3 ?8 ?+ [) h) K; ^
  189.                       LPDF_UINT16 width,0 J9 g$ |0 z2 f) @0 q  E- p
  190.                       LPDF_UINT16 height);7 l) N& _0 {9 B0 J, Z
  191.                                                                                        
    " i" P2 b* V& u0 z& ^( U5 F
  192. #endif( G, k+ A, l; d- g$ b3 ^- x/ B6 l
复制代码

源文件如下:

  1. #include <stdio.h>
    0 N9 e1 U8 B' S. r, R0 I
  2. #include <stdlib.h>4 M) n6 ^- F6 z) w" d6 t+ O! Q
  3. #include <stdint.h>2 P) O; ~+ s& W" J. G
  4. #include <string.h>  G1 O$ k% M+ U' n$ ^/ ]2 n, z
  5. #include "pdflib.h"
    # f1 H& @( u% z7 j: u9 d. p% s5 s

  6. ) m+ j- `. E$ n. b; u+ ^
  7. #define LPDF_INVALID_OBJECT                       0x10337 b: T4 [- F' k! k# g

  8. # h. j* ~: @% Y. _# e/ Q
  9. static char pdf_buf[512];
    $ l+ w; E  f/ I* q
  10. / l+ j5 _! ?6 ]
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"! D( m: j* t/ z+ j' ]
  12. #define LPDF_FILE_HEADER_LEN        155 t+ _) m! w& c. b
  13. #define LPDF_BASEFONT_NUM           14
      Q" N' @* s3 _) ^/ m* `: q
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";3 c( H! J7 h6 U0 i( q: {
  15. const char *font_list[] = {
    + [' c' @) @. e' h* T2 O
  16.     "Courier",  u5 O7 Y- R" z# a: c3 F' l
  17.     "Courier-Bold",
    , b8 G6 i. Y. C
  18.     "Courier-Oblique",3 ]& M: e- d1 s6 f/ l
  19.     "Courier-BoldOblique",
    ; ]+ M* b/ |6 v' m& ]
  20.     "Helvetica",! |. Y: D' z. z& j9 Y% c! Y
  21.     "Helvetica-Bold",
    ; t: ^, t1 {/ U* e: x6 _$ c5 Y! L
  22.     "Helvetica-Oblique",
    6 P* G  l3 i2 y% c* G) z
  23.     "Helvetica-BoldOblique",
    . z. n$ f* ?: a. x3 L3 S& B
  24.     "Times-Roman",
      p1 W! T: N3 [) q5 Q7 ^
  25.     "Times-Bold",5 P& }; A/ |% ~5 v  w0 ?7 Z
  26.     "Times-Italic",
    0 x0 K3 v: w5 m" f. e) M
  27.     "Times-BoldItalic",6 P' `+ U5 y) q3 ]2 t
  28.     "Symbol",- B) W' M) h; k# ?/ z9 D
  29.     "ZapfDingbats",
    - ]: V4 A: ~1 t( Y+ E
  30.     NULL- @2 J) c( d0 u* d5 ~% q, [
  31. };
    " C! p. U" _" _# R3 v9 \
  32. + A; v7 c( R( R! y  b% \. U( O  E
  33. 8 o, f- c5 x4 h1 o' S5 `
  34. const char * LPDF_GetVersion(void)
    , a: v+ C2 X! c1 }
  35. {( P! T# @8 h9 `3 Z! X
  36.     return LPDF_VERSIOIN_TEXT;* `$ L- E. g2 w% {8 r) ]2 f' [
  37. }% [# s  c7 E: \
  38. * }# L7 g- r- _# c' Q% a
  39. LPDF_Doc LPDF_New(void)# s' ?& K5 q: V7 v& D) r2 J
  40. {& U( D) a1 G4 J% N/ I
  41.     static LPDF_Doc_Rec pdf;
    8 K; X  `7 f. I" O# @( e0 _5 s
  42.     LPDF_INT length = 0, i = 0;
    - p6 B7 R3 ]4 k' h: V7 m- X; ]- n
  43.         LPDF_UINT writeBytes = 0;
    1 u4 ]/ z) w3 m4 g/ F# `
  44.         FRESULT fr;! i4 l! t, ~, ~/ u; s
  45.     # b1 K2 w0 w) U; L" z
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);- J3 l5 o" z: r8 A& c
  47.         if(fr). W9 p+ z3 ?+ z9 j# |" ~8 O* O
  48.         {
    + Q3 D: Z5 x& b( ~! K  k" w
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    9 I( a* l% L; @! `
  50.                 return NULL;$ z, E# Y4 X, \( ^' [
  51.         }
    5 W0 u- `! `1 E
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */
    ) j" i9 t/ w/ v* R
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;1 T2 w9 }+ @) v' ^& u
  54.    
    ( @2 [, ]# Y0 [$ J
  55.     pdf.obj[0].objIdx = pdf.offset;$ U( C5 b4 G6 O' I& k5 b
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");
    - t: a8 U$ [# l5 }& c6 |
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);6 z+ b) T; [, S5 w
  58.     pdf.offset += length;( ~, c% x( L" l) n3 I
  59.    
    ) l3 ?) Z+ C" L
  60.     pdf.obj[1].objIdx = pdf.offset;
    " s& E! {( ], _% Z! O' R
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"
    3 W! [. L3 Z, R6 m! e8 _
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");  |, e; y6 [. J6 P% g
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    ! b5 ^4 B+ W* @9 t9 C( H5 w( b
  64.     pdf.offset += length;4 R0 i1 ]! O# m  o5 b; I
  65.    
    5 g* b8 b: J5 s
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)" |1 r: X6 O* T; p
  67.     {1 |1 M+ P, h; n( t$ v( s! V
  68.         pdf.obj[2+i].objIdx = pdf.offset;
    # D" y+ r1 _* T  f" c
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    - E, S) \5 G( q. y" I
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"
    7 ~* N, B+ b( F6 d6 F
  71.                         "endobj\n\n",3+i,font_list[i]);
    * B' P* i6 X; u) ?* |" N
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    - [1 I4 C% L/ n% j& X& a$ O3 e* D) t% D
  73.         pdf.offset += length;3 y3 q7 C! i% l
  74.     }
    3 b  p4 I3 a% O' h% q( ^  S( U2 L2 }
  75.     for(; i < LPDF_BASEFONT_NUM; i++)2 r- v6 C( Y' b, ?% r- j: Q
  76.     {
    5 N$ k; B* u% w# G) T
  77.         pdf.obj[2+i].objIdx = pdf.offset;
    6 F9 ^' F! f. n( {/ H7 {
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    4 d4 w: w' d- M- n& r) T7 A
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);
    " @& z6 @8 k" ?* _$ K. P
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);- x/ C' h# u( o9 G: S! A
  81.         pdf.offset += length;- _# ?- Z' p- L' Y, e
  82.     }4 L+ E) j5 [& a* w" O) J4 a' |
  83.     pdf.objNumber = 3+i;
    3 h7 C! g/ m9 T$ a3 r
  84.   
    , D$ |  x9 r# o/ o& X
  85.     return (LPDF_Doc)&pdf;, r" k0 o9 L( U& @
  86. }! \- n9 M8 ^5 {$ n* O& A3 ?/ F/ ?

  87. 3 p2 |1 I1 P; X" |' Q( c
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)
    2 X# d! D" m7 B7 R
  89. {# g9 \" c9 s  B
  90.     LPDF_UINT16 i = 0, child_pages = 0;" M/ \- [! Q3 s  k( ]6 L' c1 k" W/ l) i
  91.     LPDF_INT length = 0;  g( y0 X+ c9 Y( G, s( \1 i
  92.         LPDF_UINT writeBytes = 0;
    5 }0 C  T$ g7 R" l( ]! r
  93. 6 L+ K8 e- G; {
  94.     pdf->obj[16].objIdx = pdf->offset;
    * l6 A6 k; u) D  g2 u7 r
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;
      a& j$ n" Y- k" Q  b
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);7 y2 w( N# ^: h1 E  M! o5 @
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    . {" t9 W6 t/ b0 l) v" r
  98.     pdf->offset += length;: t8 v* Q) D( {; ^, L, h3 W
  99.     for(i = 0; i < child_pages; i++)3 V/ x" ]9 s5 r, ^2 j7 {
  100.     {) n8 s2 @! H- C* u
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);
    ) n) c/ F5 O) x) _
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    + e' v) S$ ^  A
  103.         pdf->offset += length;9 K  D9 H* i; t8 }, X3 Z- G3 j
  104.     }
    . I: g" f% O2 P0 u: r, w
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");- t6 [; C: g! G. X+ _: }3 v
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);1 a. O: g4 `+ G) c: }/ s, J
  107.     pdf->offset += length;0 u& s8 W/ s" L( q6 B
  108.    
    $ D+ ^4 `8 [, G0 I0 U
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);
    - J7 J* t' Z# N4 z$ v0 @2 Y, g
  110.     for(i = 0 ; i < pdf->objNumber; i++)
    6 Z  n5 b5 Y% A, N- h
  111.     {; s0 @" R! _+ v2 I
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);
    4 t' d# k" b2 F# @1 s
  113.     }
    9 t& ]1 ~' r. a* R1 V/ 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",3 D& N& F( x% L; Q
  115.                 pdf->objNumber+1,pdf->offset);! s& w( _/ u1 p4 K& R9 P5 b
  116.     LPDF_FCLOSE(&pdf->file);' ?" y6 N: F! q
  117.     LPDF_REMOVE(file_name);6 W4 f3 M" }: L( P1 w3 q
  118.     LPDF_RENAME("tmp.pdf",file_name);
    ( x5 B  A7 E) _# w. |
  119.     return LPDF_OK;0 _7 B1 U% I* f" C& `
  120. }- [# f1 _5 v3 C

  121. * y, I& a; R, h3 ?6 u& m$ k' A7 \
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)9 e3 `! b2 F4 V  a/ a, H
  123. {8 _9 }  @9 X) C: t
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);, e3 {- T% A2 Z, I- _
  125.     return LPDF_OK;
    5 y. @( C9 ?+ K8 E) D5 X1 e5 o
  126. }8 N: x$ g2 S3 L' W  G- ?
  127. : {+ p" N7 T  H# i2 W* O5 t1 S& k
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)- C$ `5 \. w0 e+ ?7 T$ ]& \
  129. {
    ) S# k9 [) g1 k, k2 h! [
  130.     LPDF_INT length = 0,i = 0;7 ~9 z/ e8 t* Y( w! c, R3 Z) B
  131.     LPDF_Page page = NULL;
    . Q9 L% A. ]8 y
  132.         LPDF_UINT writeBytes = 0;
    ) a0 C) M" P& K% I1 v! `3 R
  133.     ) l1 d9 P- m# z5 Q$ u( F" e( k
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    9 i" {2 k8 o' t, M
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"
    ; {- {" q& I7 N4 e" V0 L
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    7 z( w0 C9 M* z
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);
    ) t6 w- I* g* q' c0 d
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    $ [2 }& L1 |! K8 f8 u  J7 G6 D! t
  139.     pdf->offset += length;3 \! a. ?2 L) c1 {7 f  m) F  H
  140.     while(font_list[i])* y& j5 `/ b0 G/ t1 Q
  141.     {6 @! v$ H* [) }$ b
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);# s$ }# ?( Y. y
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);# Y7 K: \* E/ \. V. L9 B
  144.         pdf->offset += length;
    7 e$ q' w3 W8 S9 D& y$ n
  145.         i+=1;# o& w- z1 P5 f7 t
  146.     }' j. }3 {9 d5 }" m
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");
    - q, a0 a  a  ]& }- J5 ]  j& e
  148.     pdf->offset += 4;# W3 S5 R; T+ s* c) c3 E% |% ]. v
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];' W- H  }5 x( S' Z7 a- S; b( L
  150.     page->width = 595;
    & T- T4 d  ?6 ~# ~
  151.     page->height = 842;/ S$ B" j3 z1 {( l! w
  152.     page->gMode = LPDF_GMODE_INVALID;$ k2 S& v% l4 s& O& w9 T
  153.     page->fontType = LPDF_FONT_INVALID;
    8 ], A: E3 E) ^3 c8 g1 d$ V
  154.     page->doc = pdf;
    ; _7 n/ m5 a' v1 G+ G
  155.     return page;
    1 U/ |4 N% |/ r4 k) v! ]* o; x9 [
  156. }# C! _4 B: V' e6 s  W$ ]
  157. ! x( r1 |' x. h+ X. ^
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)! B3 c" {2 U! @( I0 d- e7 P+ ]: Y
  159. {5 Z2 ]3 O: w; t- ~7 s( Q5 @
  160.     page->height = value;6 ^1 K# V  z4 @9 h+ N3 x
  161.     return LPDF_OK;
    : z3 D4 L( v% ?; ~9 t/ K
  162. }$ m) }6 K5 \4 A  p  i
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)) `5 p2 ?, C6 H
  164. {
    - y6 e8 F3 s; D* y, k( }' ~
  165.     page->width = value;* T0 `9 b" Y/ x+ U
  166.     return LPDF_OK;
    4 }, r+ Q3 ?# P
  167. }
    ; r2 U0 I6 n% v: s

  168. 6 |7 P: X  l0 e0 K* [  d1 z
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)5 m) e: t# A  g; K* Q$ l9 p
  170. {
    4 a& K" r; l) c& d2 Q$ Q8 n
  171.     if(page)
    * i) S0 n9 K0 }4 Z
  172.     {
    , ^7 h% `  R( V5 ?6 L
  173.         return page->height;
    2 }% o0 G8 Y5 e9 L4 L+ @4 X
  174.     }
    . h0 `5 Z% Y* C2 e) k- e: P* T
  175.    
    : X" _# H9 X* f- A1 Z4 h' q8 p
  176.     return LPDF_OK;0 ]3 Z  o6 s. l# q4 l
  177. }
    ; l9 R  P7 ~9 ]- x/ _# l2 W3 n
  178. ( {1 ]" H0 s6 U2 }1 X( g' }
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    ( W2 R! G3 a3 A% D( s6 @: i' J) I
  180. {8 H4 l: L# D7 p  e
  181.     if(page)" n. i: Y/ k) R1 f0 f/ u( b2 b+ v
  182.     {, G7 ~# R0 \( J2 Q
  183.         return page->width;6 J+ f2 A" k7 M) v7 x" d
  184.     }# J0 t' H0 D" J" v
  185.    
    6 |3 q0 R1 N4 v; c$ G! Y; ^, ^0 N
  186.     return LPDF_OK;
    4 _1 S; b# `: [2 H2 G
  187. }( K9 e' V2 b0 o9 [6 _, P, M

  188.   p* {$ r& `7 J5 f8 C8 ~, Z
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)5 U) q5 E3 D- r
  190. {
    , f2 M) h/ [- G$ R
  191.     if(!page)& S* A! [; c' c( ~' R
  192.         return LPDF_INVALID_OBJECT;
    ! `* r. o! d" Q( H$ Z, @; e
  193.     if(!(page->gMode&mode))/ ^- n; |, w8 p
  194.         return LPDF_FAILED;* y9 `# b) b+ Q: e

  195. ) V0 Z% ^6 O7 o- Y" ?7 a
  196.     return LPDF_OK;6 Y( W! l: R/ ]5 h; _3 p
  197. }
    : X, ^5 Z& r+ n3 L; V  S
  198. . R% g% F0 R6 z5 Q/ n
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    : k( i; l# H4 `7 q! H  m& j
  200.                            const char *font_name, LPDF_UINT8 size), J7 H3 o4 s* v8 _" U
  201. {
    2 `* U9 a& t" L$ O$ x
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    " c+ i, |0 W4 ^8 {7 b7 N0 g
  203.     LPDF_INT i = 0,length = 0;* t" K* _% y4 k' z) m0 d2 w  D1 j5 Z9 V
  204.         LPDF_UINT writeBytes = 0;1 w5 r& l3 n) M0 V
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    1 b" K8 h2 P/ T+ A
  206.     if(LPDF_OK != ret)2 F2 T) f6 K1 v# Y! a
  207.         return ret;
    . d5 y  ~- N4 J, `( h: C

  208. + s$ l, i- m4 F5 L# D$ I8 O
  209.     while(font_list[i])$ U( p% n" ?8 C# k) ^9 Y9 Y, G! `8 A
  210.     {
    ! ?+ z0 o5 U3 a$ b7 \, g
  211.         if(0 == strcmp(font_list[i],font_name))* U- X: [' h4 Q6 R# t& g6 M* }
  212.         {0 A, M% f' D/ e8 X
  213.             page->fontType = i;6 Z' z/ }! U7 ]0 B( U8 e
  214.             page->fontSize = size;
    # b5 ^# `) \8 Q0 h2 g  t" d& h
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);9 s; W) J7 v/ F0 R6 q7 j/ j0 _
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    8 B6 V/ R) |, [: F! E
  217.             pdf->offset += length;: W% e* E% _( D' d9 A
  218.             page->length += length;
    6 N: @; i- l1 M1 ~8 c" r. `( K0 J
  219.             return LPDF_OK;" E6 J( ^$ @* g
  220.         }
    - O. k+ ]* ]# W8 ?: _* p
  221.         i+=1;( L; F( b% f0 ]# m8 |1 o( c3 U( x
  222.     }" P0 u. `) h9 s
  223.    
      T. ?* M8 T* v0 M- s; H3 n
  224.     return LPDF_OK;" b! N4 I' V/ c, H: [- O
  225. }
      e. N* W1 ^# p6 Q# t' I. u$ g) O
  226. * C% h/ G; \/ ^. X
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)
    6 P/ ?' {- n# i4 d9 _
  228. {
    4 g- I  Q4 o4 D, X2 i# b( Q; W
  229.     LPDF_INT length;
    # n& M/ |4 a* `
  230.         LPDF_UINT writeBytes = 0;
    3 }" q. F( s8 ?
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;# D/ j+ u; Y/ L( E) W: D+ N
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    7 s2 _- E/ K" Z9 O" b7 @: e
  233.     if(LPDF_OK != ret)0 |! A8 T! }/ X2 Q  o6 V
  234.         return ret;
    4 {& d! Q) C: p/ k" O* N
  235.     * t" k7 k  \$ ^8 s1 B5 u4 ?0 f
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */
    2 N# k% g( p& @, ?+ R3 r$ \8 d) E
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",
    + w* |) [+ A# [  j2 g/ o  p
  238.                         page->width, page->height);
    / H+ C# I8 D$ W, Q  ?
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ) H6 w) e% A" F! Q/ Q4 L* s
  240.     pdf->offset += length;
    ) F/ ~! S0 K& X/ G) w6 m  H
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;  [3 B- j( }# S
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",5 ^/ _7 D8 z/ x0 x0 k
  243.                         pdf->objNumber+2, pdf->objNumber+3);  u2 f4 i% N7 O, g4 K
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);: ?2 E8 Z& V* f9 P! X
  245.     pdf->offset += length;# i* G! H4 G/ s0 i, _0 ~3 a
  246.     page->length = 0;
    0 R6 W# S7 o; e* Z' m6 v
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    , X% Y6 k, D* v& s4 L. v3 T- A
  248.     return LPDF_OK;8 u, b) O2 \( ~" {$ u' G2 _$ K0 r- f
  249. }
    7 o+ L4 I; a: S( I: O* b( _5 s

  250. 0 s. W2 E4 h1 _% D1 m9 K
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page)
    # U' L! e) @/ `% g" I8 I' \/ @, V( F, g
  252. {  B' q* K/ z; P+ ~4 Z- B  N
  253.     LPDF_INT length;9 u* |+ O/ ~% x/ U
  254.         LPDF_UINT writeBytes = 0;. ^$ N  [8 |7 P7 v, K4 v7 Q" X
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ! P6 ~# `- t. V
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    8 B* x! a$ _/ ~1 y+ e! o4 R
  257.     if(LPDF_OK != ret)& t  y; I; ]) |6 h+ W
  258.         return ret;
    * b! V, h& K3 z" [
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    1 l0 r9 r* N5 r$ Q4 o. m
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    % Z# f) ?% d' I( y) ]- X
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);   h% @( h! `/ |' q
  262.     pdf->offset += length;" M3 T9 b7 D' u% |
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;
    * `  y2 |* [  p$ y! L- l7 X
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    5 r. C; [3 c/ x+ O* a' k
  265.                         pdf->objNumber+3,page->length);, j. K5 g/ o% ~
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    % S4 \! i, X, ^: ~. ~7 ]9 r- D
  267.     pdf->offset += length;
    / B, q, I# |5 |( x9 e
  268.     pdf->objNumber += 3;2 I! p3 T' w  @! }* s! l( {
  269.     page->gMode = LPDF_GMODE_OVER;; s5 O" I. M0 k$ `; a) [* J& {: Y
  270.     return LPDF_OK;1 K  U) T* a! e% m' k+ Y$ v. ^( p
  271. }5 @. G! ^$ Q+ T  [

  272. ( p; n2 z4 M7 `3 D/ U$ U
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    8 x' _( l$ u8 U, t- [3 i
  274. {
    8 [/ n) q6 V+ M5 K
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;& T. K: h- t: K1 e
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    - a8 s+ j# K3 j1 P3 t
  277.     if(LPDF_OK != ret)) A+ ^! M+ P8 b; d
  278.         return ret;
      ?& z2 {4 b8 O' K6 {
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");
    ; c( l& [, @0 i" D: W& I' k9 G
  280.     pdf->offset += 3;0 T% ?  Z* ~" a3 i
  281.     page->length += 3;
    . r5 C6 z( w/ |, _: ?) j4 v
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;
    ( \3 t& u. o  [- c4 \8 p/ B
  283.     return LPDF_OK;
    * p( H; g# k! P9 i4 Q
  284. }
    ! o% s# D: M. ?! E+ u
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)* p1 \& c, n5 c5 n+ I- J& b
  286. {
    * k, V1 v! c+ \! E/ \$ }
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    0 s! ?9 i5 z7 E. C# Y
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);+ e: w) ?4 u) @" @/ [2 C% L
  289.     if(LPDF_OK != ret); c' S; y( u# L; u5 Q: A' {3 N
  290.         return ret;
    4 z/ b  M" w3 M6 K
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");
    ) B. x. u+ Z; Y
  292.     pdf->offset += 3;
    . Q: X, P* b& |  \& r; ~
  293.     page->length += 3;
    % b! W8 }7 |" J* S8 I" _
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    ) S9 f4 a3 v4 G. ]9 X/ `
  295.     return LPDF_OK;# T, {. \5 r# [+ @0 a9 F( M
  296. }0 Z' c& y  i2 C
  297. - E8 l, ^! O- }% v  R3 \; t
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    9 u, o+ x; G0 v4 U( ^) F, r
  299. {
    8 \0 R9 B5 S5 q0 N( \
  300.     LPDF_INT length = 0;7 U: z: q; P+ u: `
  301.         LPDF_UINT writeBytes = 0;
    + i" G* \" ?! M. H" O: U# g  m
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;: v! C9 J& D% B0 w- J
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    ( }8 W) n+ Q4 R) v3 V1 k
  304.     if(LPDF_OK != ret)
    - b' q- b. b+ `8 S  X0 `
  305.         return ret;
    : h4 {5 b, C! G6 B; }8 [& q
  306.     if(LPDF_FONT_INVALID == page->fontType)& {3 L1 R& F4 k3 l9 e8 @) C
  307.         return LPDF_OK;
    9 }9 n- Y4 a) m9 ?
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);
    ( ^5 L3 U% p: u
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ! f. X& ?. \6 D  i* s) Q
  310.     pdf->offset += length;1 _( h% a0 j/ \+ X% J
  311.     page->length += length;
    # c7 l8 h$ T: a. \
  312.     return LPDF_OK;
    2 b. d0 X# O) _9 c( a0 O: X
  313.     1 O* j) u) g: t
  314. }5 r1 S# b, ]; m1 k  G8 A7 _
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,; X: T* R7 @0 ^& y9 Y3 ~
  316.                         LPDF_INT x, LPDF_INT y)7 N9 ?' t8 v: `8 f6 N9 ]
  317. {9 u) d, k% P/ ]7 K
  318.     LPDF_INT length = 0;2 P/ }  e5 o1 I  e9 M+ x
  319.         LPDF_UINT writeBytes = 0;- G8 R  z  n; g5 ]0 |
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;5 z# e* K1 l2 w- v
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    * f. P* Y" v8 G2 P, I, o( H3 m
  322.     if(LPDF_OK != ret)
    - C; z; G! a, S, Y* ^1 ^3 D
  323.         return ret;  X; j+ ^/ t  Q4 l$ |( ]
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);5 L* |4 N5 Z- {- V- P" F
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    " w4 \1 ~: A8 }1 b% x" i4 `
  326.     pdf->offset += length;8 g( s8 _, r' x; q$ ^( f4 ]
  327.     page->length += length;  a- E' D/ p0 U7 t/ G
  328. ( n( r  B. g, E( S
  329.     return LPDF_OK;* e4 p( c2 j( G0 h
  330. }+ @. x( w, h) `0 q: k4 o. x; ^( B4 y
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page,
    0 z6 `% K3 `  i1 N
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,
    " F( l  x" i9 x# M, H6 F
  333.                         const char *text)! j2 y' d% k& s
  334. {& }$ r. c! V! S0 T, P
  335.     return LPDF_OK;0 F5 P3 B6 z% u( I' l
  336. }- Q: [7 G' P! k/ x
  337. + l$ j$ M  @* r1 k6 |
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    0 B0 Q7 ?* G4 f/ U0 E
  339.                          LPDF_REAL r,2 ]& F) m& D3 C$ Q
  340.                          LPDF_REAL g,
      i6 {8 G2 _+ s  h8 B
  341.                          LPDF_REAL b)
    , _/ u3 m% s) V. ]
  342. {
    * x/ q6 Z9 q) t" W. G% b/ Z
  343.     LPDF_INT length = 0;( \6 U$ g, l9 ~% t
  344.         LPDF_UINT writeBytes = 0;
    / Y# Q9 r+ N- P
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    " I! V' M7 |/ g1 e1 G& h) ?
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);  M* p! Q) A% l# ~0 X
  347.     if(LPDF_OK != ret)7 r: y( R6 w$ c; o4 F
  348.         return ret;8 X3 t  G9 h- W! d$ y7 R3 ~4 u
  349. 3 l4 A4 X! k/ s4 M% a7 p; R
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);  ^! Z% Y/ H( d2 a2 E6 y. M; J! C
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);  l8 x) q( v! K: b
  352.     pdf->offset += length;
    7 l5 a3 m+ d- B. r
  353.     page->length += length;
      j% n4 U9 {/ u- g
  354.     return LPDF_OK;9 l' {2 m2 S6 n
  355. }
    # v. o2 A9 Z2 W9 l0 J) E

  356. ) B& S7 i. l! V5 W% ^/ |
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,/ C9 S# \, g2 R! [( {; m
  358.                          LPDF_REAL r,
    4 w! Q4 |9 `& @9 V: i
  359.                          LPDF_REAL g,, k  j7 }, @5 [6 L" F" r
  360.                          LPDF_REAL b); _# r% R! Z3 V# ]
  361. {
    ; r2 O- L! ^/ z9 J$ Y! R
  362.     LPDF_INT length = 0;
    * x- i. ]2 ]5 G: I. R
  363.         LPDF_UINT writeBytes = 0;
    , \2 @$ G) o( t5 ^9 ~/ r5 Z
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;/ ^& ^. G) P1 X
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    2 s% [/ n2 O1 g$ q! K
  366.     if(LPDF_OK != ret)" Q# C, {' R4 @' J7 _" z
  367.         return ret;
    ( z" K& Z5 H" U1 n1 Z: ]

  368. ) G4 B! b/ i* L" I  q
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);
    . M/ u) [, t2 `0 B) C
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);9 j% {% ^( b6 w+ `4 Z1 f/ f' v
  371.     pdf->offset += length;, i6 P2 j; ?+ \! M. e/ a, d5 e
  372.     page->length += length;
    % {7 e1 v: n* P- }, o: G/ D2 N
  373.     return LPDF_OK;, x- b$ ?% K/ d+ d
  374. }
    8 c0 o; T8 u4 b
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page," n% t; m% U- _" }. N
  376.                          LPDF_UINT16 x,) \2 H( M& r8 Y( o
  377.                          LPDF_UINT16 y)
    * ^  ?6 A' D) _* e, T: \0 ?
  378. {
    ) F% \) d: O) I( M' q' j$ K
  379.     LPDF_INT length = 0;
    7 N7 p/ @% a1 W' z. X
  380.         LPDF_UINT writeBytes = 0;, b, o3 K7 p" O4 D- n- v7 {; n# ?8 F
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    5 q6 |5 p8 i. ^/ I
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);; F3 j: b! e5 t- l
  383.     if(LPDF_OK != ret)4 G; Y8 [" R# _3 k% U
  384.         return ret;. g: e4 Y& |6 V0 h8 h2 u
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);3 W: V" W$ k2 ]
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);) y& r1 [2 {" f* H5 g
  387.     pdf->offset += length;
      a( T& j! S; t: O5 W2 M1 g
  388.     page->length += length;
    ! g" H& I* i) j
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;
    . M$ ^( S  ]# R+ ~6 y/ x  S/ {* I
  390.     return LPDF_OK;* u% {9 h3 A% v5 K" e
  391. }
    - u, d8 q) G* O$ \9 |, Q
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,
    ! k) n) R6 T- z3 a
  393.                          LPDF_UINT16 x,: L# P8 y7 `; V  T4 a& v
  394.                          LPDF_UINT16 y)2 T$ `# q% z1 P
  395. {
    1 D/ V( N. R% Y- m9 ?$ I
  396.     LPDF_INT length = 0;4 q2 t; J4 A- Y+ a9 {
  397.         LPDF_UINT writeBytes = 0;- C/ Y# u- P3 c! v6 W& k* s
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    , [1 }$ e2 N7 L2 J3 u
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);* L; r( J/ Q6 n7 K* b+ f, Y# N
  400.     if(LPDF_OK != ret)
    , I. d/ R, I& S$ _5 J
  401.         return ret;
    - y4 A  _+ e, @; t+ h  b6 I
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    5 U& g0 V/ |6 N' i. m; V+ f" R
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);& |  H1 A* x  H2 H- _3 P$ G
  404.     pdf->offset += length;2 s2 P2 w1 w( Y5 h" Z# D- B" n
  405.     page->length += length;
    ! l) \' H) T2 ~/ G: m
  406.     return LPDF_OK;
    * N  g  d" w9 Q6 Q! F
  407. }; C! B& z" d; S' s$ H2 {
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)9 _% @. }  i0 k: E' x
  409. {3 V" C, d+ @4 a
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ' u+ [. |. X: i0 L: s( c
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);! t" R$ P, `5 n+ j  F) [# @
  412.     if(LPDF_OK != ret)5 C( V8 ~! a% x' \* H
  413.         return ret;
    . e" `' @( N& b3 x
  414.     LPDF_FPRINTF(&pdf->file,"S\n");0 n2 g; S9 ^  V' P' G
  415.     pdf->offset += 2;
    , Q3 P1 L# r6 C9 C
  416.     page->length += 2;0 y( i  F/ e  t8 e/ k
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;
    " S9 k& M! _7 r% W% K# ^) S. d+ `
  418.     return LPDF_OK;
    * [# i6 q3 w. c& e, Y
  419. }; C% m" b0 L  e  y3 `
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page," j3 n6 K8 U$ a/ }
  421.                       LPDF_Image image,* R$ K4 ~. o3 t/ J. f' X& f! d+ W
  422.                       LPDF_UINT16 x,
    + L/ C! q, O$ O! g
  423.                       LPDF_UINT16 y,& Q! ~) F. C: g) b2 E6 B
  424.                       LPDF_UINT16 width,
    8 H' s6 L4 F# ^6 x
  425.                       LPDF_UINT16 height)$ K3 y( T" v0 r3 t4 Q; X
  426. {
    # ^* p& v$ \; I5 F7 U& h
  427.         return LPDF_OK;, ^( G8 x  ^5 ^3 _
  428. }
    ! U  K9 e. Q. l. Q: H5 C2 b! [! ^
复制代码

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

  1. pdf = LPDF_New();1 [7 Y! e- s9 v) M
  2.     page[0] = LPDF_AddPage(pdf);4 i0 @* i7 {6 Y% x" ]' D: v
  3.     LPDF_Page_SaveParams(page[0]);: D: [- L  x$ ~+ F" Q
  4.     width = LPDF_Page_GetWidth(page[0]);
    2 `5 u9 y4 o9 L4 M" M
  5.     height = LPDF_Page_GetHeight(page[0]);
    + X* x7 N- V& f) l3 N: I
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);
    9 N8 m5 p, U% W9 s& k6 ^6 V5 C
  7.     LPDF_Page_BeginText(page[0]);
    9 W% w) c2 h* ]6 ]% ?
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);( i2 P6 F- s- J. D6 ^
  9.     while(font_list[i])
      a) m  [# ]( E/ R  k& @
  10.     {
    ; N1 `" E$ H- U" r1 T
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);" M3 H/ n2 E% @0 j' L4 b$ x! ^
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");0 Q4 P- \4 W0 Q# M! x5 A. d
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);
    5 {& t( t* q# i" D
  14.         i++;  g% e: m+ p/ X# O# a
  15.     }
    . Q* `' a, O" ~( q! P% ~
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);  [# f+ e. N2 G! w) i, O" u) ?
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());( J: C9 s  B% [3 E* a5 j# o
  18.     LPDF_Page_EndText(page[0]);% O. l  D! @9 U2 r9 b1 d
  19.     LPDF_Page_SaveContext(page[0]);
    1 I( E$ p& ]+ K$ E5 e% N% c& t% ^
  20.     page[1] = LPDF_AddPage(pdf);
    ) E) C8 n' r3 O5 z6 T
  21.     LPDF_Page_SaveParams(page[1]);1 u/ S3 G. r* [! u( y" O& J: x
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);
    , g1 Q1 N9 x! F' J+ |7 D& e3 [
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    % Y* X$ q/ @6 C7 j
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);  @1 X# g) Y0 m0 W+ [- d
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    ! i" \" R! h4 f. r) K% f$ A
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    6 ]9 P2 n( w8 F! N# `4 h% ]; g6 T3 e
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);
    - \: T' y& _5 t$ A
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);
    . d* @% }: C2 R- o  ^! B
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    + w# R1 z4 u$ q! o3 t7 U8 y
  30.     LPDF_Page_Stroke(page[1]);
    - a! ~% U( s+ R! O
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    " w  F# e+ a3 H- I8 n/ r* L8 q
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);
    ! e+ o) ^1 z: U4 ?4 N
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    & a" a: h$ S4 x0 r6 i
  34.     LPDF_Page_Stroke(page[1]);1 z9 c3 |2 a' W" D
  35.     LPDF_Page_SaveContext(page[1]);, j) n9 h9 K5 ~' l7 {& ]* H1 H
  36.     LPDF_SaveToFile(pdf, "/red.pdf");1 r$ ?- B+ J. J3 y) u/ C' r1 y
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    5 }# f4 ]6 X% G" }5 u
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了% Y! M. L8 t4 h+ `

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体1 }: ^# ]7 [) `, j. d

9 C! `$ i1 Z- Y: L) V4 S: }

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 P6 z7 m9 F4 v; V: r
只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...
) j! r6 y  Z" z) [* z- A3 v
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
! s) r6 b) u( H! L首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...
0 B' e  L( U4 K+ f/ L
66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思
5 G9 k1 |5 B* w! _: n- l4 D' I. j
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
, B  G4 A' W# o9 U看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...
4 c- f! [# O: S& ~
这个我也还没遇到过,只是之前看到有人问这个,所以看看
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:449 i9 p% V3 f+ f
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

# j0 [- {9 ~* k1 p# G这个还只是一个简单的库,实用性还是差一些的
zero99 回答时间:2017-6-26 13:17:46
厉害了楼主~
我为电狂 回答时间:2017-6-27 16:27:22
ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
epochal 回答时间:2017-6-27 18:30:17
不错,学习了!
anobodykey 回答时间:2017-6-28 09:22:13
我为电狂 发表于 2017-6-27 16:27
& Y. E2 O: h0 S9 b  G; yff.h在哪里呀,我的是keil4.73版本,需要手动添加吗
4 |, f: Y, `6 x7 I
ff.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22
2 \( J1 t2 j5 I4 J1 b1 D% p( f  z- Qff.h是FATfs中的文件

' q( W' x2 d, h; t嗯,这个画线能改变线宽吗

所属标签

相似分享

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