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

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

MCU生成简单PDF文档  

[复制链接]
anobodykey 发布时间:2017-6-17 23:03
本帖最后由 anobodykey 于 2017-9-24 14:09 编辑 . Y. q2 Q3 r, c# G/ E$ Q

/ V! f/ O& \( \6 w; F& [' E

主机环境: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__
    " J& p$ n  N1 t* v8 g
  2. #define __PDFLIB_H__) c$ f6 Y- p* Q( L5 ?7 {

  3. ' P3 ^& F7 U3 r/ i6 `
  4. #include "ff.h"
    2 A, j. m+ N' ?
  5. /*----- standard C library functions -----------------------------------------*/
    0 x4 ~: C5 b" ?5 q* V: i/ R
  6. 3 M8 ?$ x* P# J; _
  7. #define LPDF_FOPEN                  f_open
    6 `6 o8 m$ ~. Y+ T
  8. #define LPDF_FCLOSE                 f_close
    , V- S' o! S' b& E# y
  9. #define LPDF_FREAD                  f_read7 C- s# ~. i$ ?. w0 A, j/ {
  10. #define LPDF_FWRITE                 f_write
    6 ^/ O5 c4 p- _" Z5 Q6 s- u% g
  11. #define LPDF_FFLUSH                 f_sync: x* s9 b# @* p0 B! ^
  12. #define LPDF_FSEEK                  f_seek
    + N& N! R( I! n; x, G1 l
  13. #define LPDF_FTELL                  f_tell: c% a5 X" A$ V+ k8 }
  14. #define LPDF_FEOF                   f_eof
    , e9 i, ~# e: U2 i  @* h! I
  15. #define LPDF_FERROR                 f_error
    6 }% C. m# O( Q# v, M) ]1 o) `
  16. #define LPDF_RENAME                 f_rename5 ?3 m. M. u, R- \. k( Y& ?
  17. #define LPDF_REMOVE                 f_unlink
    . F5 M4 l. W; z4 r$ r3 }* I
  18. #define LPDF_MALLOC                 malloc2 v  o6 U' b& c4 q# v
  19. #define LPDF_FREE                   free# o3 N0 h  Q5 D9 q/ J
  20. #define LPDF_FILE                   FIL7 e, T% y. s: |7 s3 N$ e. i7 r
  21. #define LPDF_TIME                   time
    6 [/ k: k7 {+ [( O0 J
  22. #define LPDF_PRINTF                 printf
    0 N; j3 p- T- f. I0 @
  23. #define LPDF_SPRINTF                sprintf
    1 o' g5 @0 B: I, u+ ?
  24. #define LPDF_FPRINTF                f_printf3 Q1 f0 W; b3 Y
  25. #define LPDF_VOID                   void
    3 r+ y! Q8 [5 O$ {: Y2 b
  26. #define LPDF_SIN                    sin$ O3 _0 K% v2 W8 v( a
  27. #define LPDF_COS                    cos$ s0 @% u, ]. A1 r$ E3 \
  28. 3 x# ]$ X# W: A4 h% N/ N  [. f
  29. /*  native OS integer types */. Z$ f8 ]3 [* g! k, k
  30. typedef  signed int          LPDF_INT;
    $ N- A  Z. K7 ?7 m, w# b* m
  31. typedef  unsigned int        LPDF_UINT;
    ; A7 _0 G/ t, Q+ V; a. k* V; M$ |
  32. 9 G+ R; W" F5 q, X+ o

  33. , }# t9 B+ a( Y: V& w- b3 _! S
  34. /*  32bit integer types3 s$ I. j5 {0 [7 j% C* |& Q8 l
  35. */
    ; h6 y- y* n" B+ n" U3 s
  36. typedef  signed int          LPDF_INT32;5 g- G3 x" H' |% B% Z; f/ f
  37. typedef  unsigned int        LPDF_UINT32;
    + q7 U6 N  V& g
  38. 1 d8 \1 N3 _- V% ]
  39. 0 [- G$ C0 z: s: N1 ^( |
  40. /*  16bit integer types1 u/ P# A* s% M6 u$ S
  41. */) C" d- d) Z& B. a  v
  42. typedef  signed short        LPDF_INT16;" c" |3 K. A" Y( I" S
  43. typedef  unsigned short      LPDF_UINT16;  P0 K$ @. a& k4 s$ {9 `, N

  44. ( S, N8 z7 ?4 A- i
  45. ) ~! G( \; H- G* Q6 H' N6 J6 i& L
  46. /*  8bit integer types
    + V3 k* A4 `% H' v: l  Q6 a  a
  47. */
    0 o1 L( R1 x- T, i
  48. typedef  signed char         LPDF_INT8;$ Q5 c2 r1 \& |% n
  49. typedef  unsigned char       LPDF_UINT8;
    2 C0 g1 ~' H- M: K& k$ e( W
  50. $ y7 g4 V, `4 F" l4 p
  51. # S+ J( [; a: ~* S& I; {7 X
  52. /*  8bit binary types
    9 Y2 `  w" W% u. i7 L. u9 p/ q1 w
  53. */
    " N& e9 R) `. D7 O- @0 k0 o3 D
  54. typedef  unsigned char       LPDF_BYTE;, D9 b( B+ Z. ~8 C6 q0 ~; z% W! P

  55. ( L) c+ C6 f% g3 p' r& y

  56. 5 a% Z9 }: d8 K9 U0 Z8 w5 C
  57. /*  float type (32bit IEEE754)
    # x5 O/ n8 w$ U1 b/ @& M
  58. */
    / O; r+ D3 w2 |5 p2 O
  59. typedef  float               LPDF_REAL;
    - t6 C7 ~2 Y- o1 w& i4 X

  60. ; _2 Y, D$ z: h+ I* i4 I' x# k
  61. : H% y4 E8 Q8 C6 O
  62. /*  double type (64bit IEEE754)
    - K6 ?% g" }  ~" P7 o
  63. */
      I, p: E) L7 g4 B# U1 M6 z3 v
  64. typedef  double              LPDF_DOUBLE;+ \: _1 l4 O/ ^: i

  65. 4 i3 f1 l( P" t& S6 ~: j8 _
  66. : c! V) U# i$ w1 R0 D6 K; u
  67. /*  boolean type (0: False, !0: True)
    0 y5 R) |  {8 `8 p" x" K& g4 p$ L
  68. */
    ! u6 ?8 ^( [9 r
  69. typedef  signed int          LPDF_BOOL;& @2 u5 Q& o7 R: l8 @
  70. ( p5 f- N3 S' \1 h. H7 }4 f; w
  71. , P4 j: p3 T6 q7 l. X
  72. /*  error-no type (32bit unsigned integer)
    " p2 S- I# m5 U1 \# v7 P2 j
  73. */
    0 o5 P4 ^" b' j) |
  74. typedef  unsigned long       LPDF_STATUS;
    . Z- V4 L3 e; K5 I1 y& D- G

  75. 5 K; U  ]* a: I) U) O! M
  76. #define LPDF_OK                     0  n$ M1 ?. x$ q: B. W  Q$ m) W
  77. #define LPDF_FAILED                 1
    , s4 T! [2 X# m3 @$ C+ ~
  78. $ s" s; \& n4 [5 I
  79. /*----- font state -----------------------------------------------------------*/
    " {5 z5 q. z9 l
  80. #define   LPDF_FONT_INVALID                 0x00FF
    ' f* j7 l% ]4 z' V+ Q
  81. #define   LPDF_FONT_COURIER                 0x0000* V3 G& x7 ?/ T  V! B3 m
  82. #define   LPDF_FONT_COURIER_B               0x0001$ k- I, t/ j1 M0 z! g2 N
  83. #define   LPDF_FONT_COURIER_O               0x0002, B; p, m; x" }4 T
  84. #define   LPDF_FONT_COURIER_OB              0x0003
    * Z9 |, [8 y3 r8 m# {: H
  85. #define   LPDF_FONT_HELVETICA               0x0004. C. L* ]+ \$ W' @# r
  86. #define   LPDF_FONT_HELVETICA_B             0x0005
    ; c& w4 n/ F: ?; |
  87. #define   LPDF_FONT_HELVETICA_O             0x0006: g* o6 C" [" w+ R: H9 \
  88. #define   LPDF_FONT_HELVETICA_BO            0x0007; E3 B/ S( c' ]. V; r, M
  89. #define   LPDF_FONT_TIMES_R                 0x0008
    3 [  o. y1 T: s. X$ ^/ G0 Q
  90. #define   LPDF_FONT_TIMES_B                 0x00090 X7 I5 R. y& n' G+ m
  91. #define   LPDF_FONT_TIMES_I                 0x000A
    4 ^' I2 @8 C; ]; I" \
  92. #define   LPDF_FONT_TIMES_BI                0x000B, M8 v% C0 g) f, _0 r  {
  93. #define   LPDF_FONT_SYMBOL                  0x000C: Q: p4 v; `8 K; Z4 C
  94. #define   LPDF_FONT_ZAP                     0x000D3 E) p( H( w/ f
  95. /*----- Graphis mode ---------------------------------------------------------*/% y& Z' I9 S$ G2 z" N
  96. #define   LPDF_GMODE_PAGE_DESCRIPTION       0x0001
    # S' ~# C" s9 A4 E1 c6 ?: F- i
  97. #define   LPDF_GMODE_PATH_OBJECT            0x0002  z! q" N/ W# y, Q# _
  98. #define   LPDF_GMODE_TEXT_OBJECT            0x0004
    ) I! F* {, p3 O9 k" z: ^
  99. #define   LPDF_GMODE_CLIPPING_PATH          0x0008  x0 H8 [# W& x9 I6 e0 S  P2 b
  100. #define   LPDF_GMODE_SHADING                0x0010$ }2 V: @# G6 ]- R1 I. C6 O9 r
  101. #define   LPDF_GMODE_INLINE_IMAGE           0x0020
    5 X0 Y3 W5 {5 t% G
  102. #define   LPDF_GMODE_EXTERNAL_OBJECT        0x0040
    ' Z" G. r% \! o; m- N
  103. #define   LPDF_GMODE_INVALID                0x0080
    2 ]! e9 u8 `$ K6 A
  104. #define   LPDF_GMODE_OVER                   0x0100+ ?; i" ~% b$ b3 e" {! E
  105. + j* d7 j1 c2 W7 L; ~# P  i, n1 S; l
  106. #define OBJ_MAX_NUM     256* I, Z& j( X8 S$ L' B9 K* y& @
  107. / E- \8 v2 H- {, p4 T+ p  L$ g! K
  108. /* Page的结构信息是否需要树形结构 */
    + O3 `: {# Y/ Y
  109. typedef enum 0 x! \" X" m4 n4 r$ }
  110. {8 a1 d$ p* H, n* p5 [  Y
  111.     OBJ_info,
    & ~4 |  o. j+ w# ~/ f
  112.     OBJ_stream,) Y$ z( U9 o7 `: l( k
  113.     OBJ_font,
    * f" s' t' u! n) T$ f, O
  114.     OBJ_page,8 c% y, M( r, e) `3 p; U  n7 _0 ?( Q
  115.     OBJ_catalog,, g9 }! i+ G8 z7 H6 a
  116.     OBJ_pages,4 l0 a: c, t6 n* @, d1 B% y( Z
  117.     OBJ_image,. c# \" j  m& ^4 G0 a* h, e) E
  118. }LPDF_ObjType;6 N. H# R/ l+ H" @5 x% U

  119. / o( D" D; E$ ^# s# A$ n
  120. typedef struct
    4 A. Q' X6 L. F! E, e" f% ?0 D$ j
  121. {
    + t1 s6 t; e2 r0 i- C: U
  122.     LPDF_ObjType objType;/ J$ u5 |' R0 E
  123.     LPDF_UINT16 objIdx;
    1 c4 J8 p$ z& s; k
  124.     LPDF_UINT16 height;5 q# _. a1 M/ X! O# E% @5 L
  125.     LPDF_UINT16 width;
    & w7 P: m+ {3 x1 X! s3 q
  126.     LPDF_UINT16 length;; E4 z/ _  B! Q8 p2 v- S
  127.     LPDF_UINT gMode;4 g. e) g' ?! x% G
  128.     LPDF_BYTE fontType;
    ! w% W, B. G. [8 m3 n
  129.     LPDF_BYTE fontSize;& Z( q$ X. e  q1 l
  130.     LPDF_BYTE pState;' f+ V( D4 T# |  f+ b2 x
  131.     LPDF_VOID *doc;
    5 R2 ?# c) o$ a, c" n$ V- n
  132. }LPDF_Obj;
    ( u) T. J. S1 L$ `

  133. , N7 h$ X' g, [! L5 y0 A
  134. typedef struct8 j! d1 s5 d2 q9 E$ L9 V+ k
  135. {
      S+ U. A, J! f  R( V3 y
  136.     LPDF_Obj obj[OBJ_MAX_NUM];8 `" b/ C, Y6 x3 Y8 O0 z0 K" _
  137.     LPDF_UINT32 offset;& t& t. Z( O) {1 P) o: D, v
  138.     LPDF_UINT16 objNumber;# h; s# t6 f/ B# q* R4 M
  139.     LPDF_FILE file;% ?' n4 F0 h4 o) i  q$ w" Z
  140. }LPDF_Doc_Rec;1 u0 B2 X  k- o. s/ k8 f2 M. g

  141. 0 M, x7 ^& N4 w2 C# [6 [
  142. typedef LPDF_Doc_Rec *LPDF_Doc;
    # V) X9 P  j. T' s4 B1 l+ w9 u
  143. typedef LPDF_Obj *LPDF_Page;
    8 c( Q" g4 a! K2 N* i8 ~
  144. typedef LPDF_Obj *LPDF_Image;; J$ M. I- c+ t, i  T0 t
  145. extern const char *font_list[];
    % b3 a: ]+ T5 V! i  j
  146. /*----- LPDF Interfaces-------------------------------------------------------*/( v: j4 @* \4 b6 i' `
  147. const char * LPDF_GetVersion(void);
    7 i& I9 q4 S, D2 V0 t0 b
  148. LPDF_Doc LPDF_New(void);5 q$ V+ \% F( T2 I5 \% Q; G% p* k
  149. LPDF_Page LPDF_AddPage(LPDF_Doc pdf);
    8 n( h1 G8 H# Q# g& k) N: f9 \+ V
  150. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name);3 `  O: ], C( m7 {- R) a6 `9 z2 A) U7 M5 R
  151. LPDF_STATUS LPDF_Free(LPDF_Doc pdf);4 L+ w; a8 [8 m* _( V0 P, J$ T, u
  152. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode);
    ! C# ~, F% e. m5 X: I
  153. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    1 j; L* l+ T2 C1 }
  154.                            const char *font_name, LPDF_UINT8 size);
    / }( U& H" u. C" ~# n% W
  155. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page);
      t% X% Z0 L: `" l$ s, Z- T
  156. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page);& N  [( O, ^# R6 S. P$ ?- o
  157. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page);
    ' L' I( `" j! Q' A9 M4 q5 G0 D
  158. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page);
    * x8 D  [4 U6 y7 k. p$ \$ T3 y
  159. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page);- {; c; ^' o; G$ D5 k" ^% o
  160. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page);
    . q) e: K' L$ z# I2 }
  161. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value);; |% |3 h; x1 u5 B" J& R# Y9 Q
  162. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value);
    , V5 r# c" N. h4 L. V
  163. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text);1 d% N. I1 O% H2 g" ^$ w4 e
  164. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,' m. O1 R! Z8 ^, u
  165.                          LPDF_INT x, LPDF_INT y);0 Y* `! Z) u2 q1 O# k9 V% h8 |* `
  166. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, # Q8 g5 v, T* `
  167.                          LPDF_UINT16 x, LPDF_UINT16 y,
    1 U+ ~5 ]! G7 {" |+ m
  168.                          const char *text);
    5 o- M! e( N* q7 Z# n: T3 @. z
  169. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,
    * R6 P8 u9 g! |; B) ?. E
  170.                          LPDF_REAL r,0 |9 U: ]) U- d$ b
  171.                          LPDF_REAL g,
    * d' Z4 o; M/ H: l4 {5 @9 k* p
  172.                          LPDF_REAL b);
    % l2 Y- A7 Y/ ?* [2 [, a( u7 V
  173. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,' @, }# e9 A; I" m
  174.                          LPDF_REAL r,. C' {- R+ r2 g$ T# \
  175.                          LPDF_REAL g,* a: I+ }" w+ M, e9 |- O
  176.                          LPDF_REAL b);
    6 j# a$ Q9 d* E2 l9 j
  177. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    & R% Y7 s# t0 _9 G. z/ H; q
  178.                          LPDF_UINT16 x,- t6 i0 t. Y* l. |0 C5 z
  179.                          LPDF_UINT16 y);1 G0 G6 k! f$ E
  180. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page," t* K- Q$ p" b/ S6 @& `
  181.                          LPDF_UINT16 x,
    4 p% \1 d9 F2 z7 U: c/ X' N
  182.                          LPDF_UINT16 y);) L$ r5 p' R" p4 N$ d
  183. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page);, v* ?  `; ?. n9 O% d! S
  184. LPDF_STATUS LPDF_Page_ClosePathStroke(LPDF_Page page);
    ; V1 ?8 f5 p: W- \
  185. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,
    1 n% [& s+ _% [! t+ I5 F1 n
  186.                       LPDF_Image image,  d. a8 a, F1 c. a3 F8 e/ E0 ]
  187.                       LPDF_UINT16 x,$ B! P% U( ?9 R# y' h1 P
  188.                       LPDF_UINT16 y,6 b/ x: H8 _: J0 P/ Q; u! ]/ G
  189.                       LPDF_UINT16 width,' N! `$ t6 H) P1 Z( o: J' V
  190.                       LPDF_UINT16 height);
    7 b, z+ O2 f/ X6 U$ W2 S! z
  191.                                                                                         3 r1 y0 B+ \" }' R( E- W5 c& n8 Z
  192. #endif& G1 O/ M  @! j" E( c7 g2 W
复制代码

源文件如下:

  1. #include <stdio.h>, K2 Q3 W6 I" n: N) H2 V- B) F
  2. #include <stdlib.h>
    3 n" J$ K! U$ `# l; n% v) v
  3. #include <stdint.h>
      ^* t1 j7 Z* d$ H" G
  4. #include <string.h>9 {+ Q$ |1 K* S( g: ~* J  x# p
  5. #include "pdflib.h"! K0 E' U3 z$ g
  6. 7 b; q3 G) k9 t3 }3 V6 O, F
  7. #define LPDF_INVALID_OBJECT                       0x1033  w3 o7 {. m7 n4 r9 q

  8. ( O) T1 p/ L# C2 {4 s3 H
  9. static char pdf_buf[512];
    # F* u' ~& E$ c2 c( z

  10. 2 K" S- p7 ^6 h  m
  11. #define LPDF_VERSIOIN_TEXT          "0.0.1"
    , G' N' y% t# j3 z! u) I
  12. #define LPDF_FILE_HEADER_LEN        15
    * {: B* J" e' X; }7 N, B
  13. #define LPDF_BASEFONT_NUM           14
    ( B1 g4 k; a/ ?2 G
  14. const char LPDF_FILE_HEADER[] = "%%PDF-1.4\n%%\xAA\xBB\xCC\xDD\n";2 S. G9 e3 S' `3 K5 o- U& x
  15. const char *font_list[] = {
    0 t; h/ \: x0 a. X( U
  16.     "Courier",: R7 o$ R1 ]. ^5 @6 v' g! M* ^
  17.     "Courier-Bold",
    / l; O% w% f* l3 D" g
  18.     "Courier-Oblique"," K( q9 K. ?3 b9 P
  19.     "Courier-BoldOblique",9 g) k/ y- e- [% T6 X
  20.     "Helvetica",
    2 I, H' B) W7 _# Z" P! {. C
  21.     "Helvetica-Bold",5 r9 d* |6 q. V/ p* r; b
  22.     "Helvetica-Oblique",& W; I9 ?2 q1 l2 K" k$ S, b0 v
  23.     "Helvetica-BoldOblique",
    . C& Y; h" ?* u/ e
  24.     "Times-Roman",
    8 f% r( A& r, J, D" I
  25.     "Times-Bold",
    * G+ a4 }8 g( v- d4 ?) `
  26.     "Times-Italic",2 w% D% f9 w0 k7 @. h  q$ r
  27.     "Times-BoldItalic",1 I! ~0 K( M7 I  r/ r$ x3 v! m
  28.     "Symbol",
    8 R+ U1 U/ @& P* ]- S% y" |; }# o
  29.     "ZapfDingbats",; J" p, d. p) U8 r1 Q
  30.     NULL7 V8 j5 A; D8 n% L) I  n2 K! |
  31. };" E- n) E! l- |* }+ i/ ~$ y7 \1 \- t

  32. + V3 [1 d& x$ R3 i

  33. ) P3 ?9 N5 c% {2 v4 M9 i
  34. const char * LPDF_GetVersion(void)! m2 u! A( Z7 v6 f7 r. L
  35. {
    0 _0 W* ]. C; G9 ?7 O+ G# z* A6 c
  36.     return LPDF_VERSIOIN_TEXT;
    2 O" ]9 L9 ]! b
  37. }
    9 e$ s; y1 O, H/ Z3 w3 l4 R0 H# B

  38. 0 r2 t- S; |4 d' \
  39. LPDF_Doc LPDF_New(void)
    ( h; {* S! E8 y9 h
  40. {' k- C4 k2 N7 W# u# P
  41.     static LPDF_Doc_Rec pdf;! Z# f. v" ]& e1 @& w. D1 v) T
  42.     LPDF_INT length = 0, i = 0;! L* `! u9 T1 {" q0 s+ L7 c
  43.         LPDF_UINT writeBytes = 0;( U( x* o: a& o
  44.         FRESULT fr;; }  c4 {4 |8 R* Q* t
  45.    
    1 X3 u: G( R% l3 d4 D9 ^+ z" f& M
  46.     fr = LPDF_FOPEN(&pdf.file,"/tmp.pdf",FA_CREATE_ALWAYS|FA_WRITE);" ]& Y, s1 R; S8 l
  47.         if(fr)% v" w8 d8 P' s8 w9 `4 H' D
  48.         {. `- C: T* ~1 a/ A$ Z% C- c
  49.                 LPDF_PRINTF("create tmp.pdf failed!\r\n");
    6 c+ A) d8 s& {! C0 s1 d
  50.                 return NULL;! ?8 Z( s3 a3 c: e
  51.         }
    . e7 I2 u4 c2 T0 ^
  52.     LPDF_FPRINTF(&pdf.file,LPDF_FILE_HEADER);   /* 写入文件头 */1 M: A3 G2 P3 G' ?; S' k
  53.     pdf.offset = LPDF_FILE_HEADER_LEN;
    / `/ q2 x9 I8 G7 J; y3 T$ q
  54.    1 f: B$ C+ G' Y: ?) M# W' |
  55.     pdf.obj[0].objIdx = pdf.offset;1 D2 B- s: Y- I) r! h+ L
  56.     length = LPDF_SPRINTF(pdf_buf,"1 0 obj\n<<\n/Type /Catalog\n/Pages 17 0 R\n>>\nendobj\n\n");9 {' {9 d1 c( j0 a
  57.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    ) u+ U! @' W, h) J* F5 Z
  58.     pdf.offset += length;7 p# t8 C" u+ @8 G
  59.     5 \3 ~4 y8 u4 {' ?- D. f$ S0 [8 `
  60.     pdf.obj[1].objIdx = pdf.offset;9 X5 J' b- O2 J$ L7 |5 n+ O
  61.     length = LPDF_SPRINTF(pdf_buf,"2 0 obj\n<<\n/Creator (light pdf library 0.0.1)\n"
    2 n( L# {: M7 w1 N1 @: \7 f5 q
  62.                     "/Auther (anobodykey)\n>>\nendobj\n\n");
    9 Y( @! j3 |9 H1 q3 l
  63.     LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);& @( R; ~' Z; ^. l! F) M
  64.     pdf.offset += length;
    9 w* _8 G# I% S, ]
  65.    
    6 a( k4 R# e, f4 E
  66.     for(i = 0; i < LPDF_BASEFONT_NUM-2; i++)  I9 W3 g( |! Y3 i8 e( L, ?
  67.     {3 f: @- D) G' J% Y% z9 ?
  68.         pdf.obj[2+i].objIdx = pdf.offset;
    . q$ _7 Q& p9 }% @" }0 [/ B9 o: @
  69.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"- K9 R# F+ S, R" _* M8 _
  70.                         "/BaseFont /%s\n/Encoding /WinAnsiEncoding\n>>\n"0 |: o' `; _, z' G$ r! U6 M
  71.                         "endobj\n\n",3+i,font_list[i]);# Z' f& N6 a  L+ O( f
  72.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);
    2 w7 g$ t- [) x
  73.         pdf.offset += length;0 a; @# y5 E! \" y: T0 v
  74.     }- |7 s5 T  k' ^% S: \
  75.     for(; i < LPDF_BASEFONT_NUM; i++)$ O' ^5 N, y& c+ D4 O6 w
  76.     {
    ; z3 P$ s; o+ g1 S# G. v5 h
  77.         pdf.obj[2+i].objIdx = pdf.offset;' {- c; ]2 t( a8 [
  78.         length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n"
    6 l3 k% V4 N1 w' f
  79.                         "/BaseFont /%s\n>>\nendobj\n\n",3+i,font_list[i]);( ]+ Q& f) N3 ?* d
  80.         LPDF_FWRITE(&pdf.file,pdf_buf,length,&writeBytes);& z- u1 |2 ]( H# F) l
  81.         pdf.offset += length;: }- a& z* \6 C8 i- J) o% w
  82.     }  W- `' X! `4 P8 |7 Z. f: {
  83.     pdf.objNumber = 3+i;
    " w% e, w- V1 Q: ^
  84.   
    ) L$ V) X+ \; O6 b1 A& }& l# N' ~2 z
  85.     return (LPDF_Doc)&pdf;
    * o* U1 ~, x9 T' @
  86. }0 s" X( C9 l, _0 t) s: g
  87. ; _. }1 u7 E" \
  88. LPDF_STATUS LPDF_SaveToFile(LPDF_Doc pdf,const char *file_name)+ j3 b4 z4 a2 S
  89. {1 _: g2 V: L4 X6 }& ~
  90.     LPDF_UINT16 i = 0, child_pages = 0;
    2 h1 {2 w* z8 X7 F  v
  91.     LPDF_INT length = 0;5 L6 C; R" W$ S5 J: `  U3 n. u7 A
  92.         LPDF_UINT writeBytes = 0;
    ' ]5 k! [5 m: a( o' Q& n5 _

  93. . r; W+ `+ ]$ v' v7 [8 I/ x
  94.     pdf->obj[16].objIdx = pdf->offset;% m9 {6 G6 Z* r1 q
  95.     child_pages = (pdf->objNumber-2-LPDF_BASEFONT_NUM)/3 ;
    * j: \) }1 x8 l2 c  c- f
  96.     length = LPDF_SPRINTF(pdf_buf,"17 0 obj\n<<\n/Types /Pages\n/Count %d\n/Kids [ ",child_pages);' C2 `" d0 k5 o
  97.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);; P% R3 w0 Z7 S+ L
  98.     pdf->offset += length;5 w2 n2 z6 l  D# O
  99.     for(i = 0; i < child_pages; i++)
    ! S# {9 _& G3 }# F
  100.     {
    ( O9 y# r& a" y/ B- t: P' q+ F6 @
  101.         length = LPDF_SPRINTF(pdf_buf,"%d 0 R\n",18+i*3);3 d, \4 s( \- C, v: v+ C4 `% _
  102.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    - B; X7 i5 M$ y, @1 ]/ y
  103.         pdf->offset += length;
    8 i* m# O3 w9 h) s! Y7 {$ c+ ]( s
  104.     }/ D  V' @* n8 T
  105.     length = LPDF_SPRINTF(pdf_buf,"]\n>>\nendobj\n\n");5 l  c( p# X7 _6 L5 m* s
  106.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    & D5 J. G5 q- J. p0 l
  107.     pdf->offset += length;/ h# C/ T4 I) d& n1 I( s, X) G
  108.       N% n3 Z# S  ?7 h4 d
  109.     LPDF_FPRINTF(&pdf->file,"xref\n0 %d\n0000000000 65535 f\r\n",pdf->objNumber+1);) h2 i6 k( @8 v1 |
  110.     for(i = 0 ; i < pdf->objNumber; i++)
    ) q/ g: [4 j- r2 ?" Q* D* |
  111.     {" w% t3 n  P1 C3 S
  112.         LPDF_FPRINTF(&pdf->file,"%10.10d 00000 n\r\n",pdf->obj[i].objIdx);# X: `+ R; R! e& A
  113.     }
    + K. W3 u$ m1 s
  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",/ A5 k" I' j- N% ^0 {. W. F
  115.                 pdf->objNumber+1,pdf->offset);- @9 q  O. z0 O
  116.     LPDF_FCLOSE(&pdf->file);) I; u# _6 z$ x
  117.     LPDF_REMOVE(file_name);
    0 c0 w( l' m; m
  118.     LPDF_RENAME("tmp.pdf",file_name);
    * ~4 o- _* N- J1 o) s
  119.     return LPDF_OK;
    ; Q* p- c" G- k! Z
  120. }
    8 d1 c! D# Y3 f; n$ H; G3 G

  121. 3 E2 U' k$ W, x. I5 k: T
  122. LPDF_STATUS LPDF_Free(LPDF_Doc pdf)2 L) m6 y( {/ a; z% n
  123. {2 @* n, U: v! R) r
  124.     memset(pdf,sizeof(LPDF_Doc_Rec),0);
      m% n9 ~* W- a( a) @" ?
  125.     return LPDF_OK;
    5 N3 k+ Y& t; a& I- M5 Q) @
  126. }
    7 E( p6 a7 w6 X

  127. " Y0 S& {; J0 n) v4 x# Z8 `2 N
  128. LPDF_Page LPDF_AddPage(LPDF_Doc pdf)
    7 j6 T" ?+ x4 f
  129. {
    : \! N) u; s8 O$ _% d, `
  130.     LPDF_INT length = 0,i = 0;
    # J' N# T. f& t1 Y4 K$ _5 O3 p! ^
  131.     LPDF_Page page = NULL;
    . d: h( M" v" N2 p- J
  132.         LPDF_UINT writeBytes = 0;$ A1 C4 X$ D7 E1 h2 _
  133.     0 f4 K- N& C! ~. y3 x5 H& O/ {
  134.     pdf->obj[pdf->objNumber].objIdx = pdf->offset;
    ' n$ H" U- B( P/ H5 p& T7 @
  135.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<<\n/Type /Page\n/Parent 4 0 R\n/Contents %d 0 R\n"
    # c( H8 S- n5 r. H7 W, K
  136.                     "/Resources <<\n/ProcSet [/PDF /TEXT /ImageB /ImageC /ImageI]\n"
    1 Q$ Z) k& t; ^2 D3 E9 ?8 n$ X
  137.                     "/Font <<\n",pdf->objNumber+1,pdf->objNumber+2);9 m' {( [) c- h; \
  138.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);3 A; f) o* y% D/ b% A  z
  139.     pdf->offset += length;& c" @5 S( H4 N( `+ L
  140.     while(font_list[i])- m( z/ @# E0 o* B$ i; u
  141.     {
    $ |4 ]- {' j+ y
  142.         length = LPDF_SPRINTF(pdf_buf,"/F%d %d 0 R\n",i+1,3+i);2 }% x1 ^9 i1 G; b  d# `2 ^
  143.         LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    , f4 T& z3 w9 F. j/ g, Z4 C
  144.         pdf->offset += length;
    . ?( y# }7 y) T- |# p* y3 o
  145.         i+=1;9 `" F* ?0 R! f- R5 \9 G
  146.     }  w' u3 C9 y1 v7 p* v, p  I
  147.     LPDF_FPRINTF(&pdf->file,">>\n>>\n");  K$ K# B: T0 R# p: U
  148.     pdf->offset += 4;
    8 |, K  a) b4 L' _
  149.     page = (LPDF_Page)&pdf->obj[pdf->objNumber];* O0 p9 @3 h* f
  150.     page->width = 595;* ]! X5 h, v; ]% [0 h0 e% P
  151.     page->height = 842;4 [+ Y5 j& N" f/ {7 A: Z
  152.     page->gMode = LPDF_GMODE_INVALID;
    $ [: B, G8 _: }! }& @. L
  153.     page->fontType = LPDF_FONT_INVALID;
    ' {) F3 C. ^6 y. e& J2 u
  154.     page->doc = pdf;
    5 L) _- @* e- `3 C; }2 ]2 K' |
  155.     return page;- F: b7 t( y& Y; d, _
  156. }* ^2 d3 I9 P8 R# W3 H0 S& J
  157. ! _5 ]  R0 P$ Q# V2 J" X6 q
  158. LPDF_STATUS LPDF_Page_SetHeight(LPDF_Page page, LPDF_UINT16 value)
    # K0 ]7 o3 c- p8 ~% N
  159. {2 ^3 O1 e1 K7 b
  160.     page->height = value;; U; U, s% O5 }; F7 s5 _9 f2 O# T
  161.     return LPDF_OK;" f7 |: J- Y1 o0 E; F6 u( n
  162. }: s. c% P2 G( t4 C; O! B3 ]
  163. LPDF_STATUS LPDF_Page_SetWidth(LPDF_Page page, LPDF_UINT16 value)# ]' k7 p" E, l7 C# k5 q" B
  164. {" \( @! U6 z/ _" E* Q7 b
  165.     page->width = value;' b7 _$ h9 L5 [: ~4 G3 t# N. c
  166.     return LPDF_OK;7 F( A8 Q7 S" U, q
  167. }* G4 f* T! _2 V# o! X
  168. . P1 n/ c' w" F) F! S1 {% Z0 O) y  F
  169. LPDF_UINT16 LPDF_Page_GetHeight(LPDF_Page page)
    & \( z  l2 V7 z; c$ a
  170. {3 F: {+ `/ {* D9 N/ o
  171.     if(page)
    ( x) \7 Q. B# d" c9 T% Y. n" w/ i
  172.     {4 _" Z, R+ z$ ]* F! i
  173.         return page->height;
    # H5 i2 c" |3 c
  174.     }( g" n/ \; A$ {2 ]( l
  175.    
    ; B0 U0 `& w* `' i! Q& N' X4 E+ ~4 @
  176.     return LPDF_OK;7 p5 H) f( V. f1 t$ T4 Q  _7 j
  177. }
    . k) ]/ c, O% P
  178. $ Q" W' i" o6 h; n
  179. LPDF_UINT16 LPDF_Page_GetWidth(LPDF_Page page)
    % `( v  n- [" j* V
  180. {
    ( O3 {0 j& l! l9 M' v$ ^1 O9 ^5 a
  181.     if(page)- B& E' c* f' L1 j6 g3 j/ ^& @
  182.     {* e# m+ z' j5 j8 P0 e7 @6 w  S
  183.         return page->width;) T1 p$ {6 u! v& S
  184.     }
    . Y! ]' U# v/ K; `, |. Z
  185.    
    - ^+ M9 @. J* @" p- T
  186.     return LPDF_OK;# E% D% P+ S8 Z5 r$ ?
  187. }
    8 d. N  z, R% |

  188. / x9 K% T- j. T
  189. LPDF_STATUS LPDF_Page_CheckState(LPDF_Page page, LPDF_UINT mode)
    & h# Q  r' \8 y3 p; M) r" N
  190. {; s" x: j8 I. Y! _2 p, x5 t7 Z
  191.     if(!page); h5 @0 Y+ p5 Y6 y
  192.         return LPDF_INVALID_OBJECT;3 z# H( l) X# v6 W
  193.     if(!(page->gMode&mode))& z5 {3 ~8 G4 c% H2 ]
  194.         return LPDF_FAILED;9 Y5 t" i: e: L5 V5 W3 G' f6 S
  195. 1 o% H. Q; v4 p" }' b9 o$ _* B
  196.     return LPDF_OK;
    ( I0 Y: q! O- ?# R6 |1 X0 C. P
  197. }1 m* X3 x9 `; u) u" s/ Z

  198. 1 W. F9 p  q0 F
  199. LPDF_STATUS LPDF_Page_SetFontAndSize(LPDF_Page page,
    " L6 Y/ p! P! z3 ]7 W
  200.                            const char *font_name, LPDF_UINT8 size)
    1 j2 p  U2 d* p% L& c: r
  201. {% r$ A- O4 I% I0 _  k# P8 ^
  202.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    ' \" o$ o9 U) d1 n
  203.     LPDF_INT i = 0,length = 0;  A$ L% s2 i& Q1 s, J
  204.         LPDF_UINT writeBytes = 0;
    # w4 }. ]' g# e1 d9 ]' O2 `
  205.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    " a7 r+ `# {- S) Z( H" d" A* E3 H
  206.     if(LPDF_OK != ret)! ]: y6 B( b& p+ ~' q
  207.         return ret;2 z. o% X- w7 }+ h4 p! W! q* K4 Q

  208. . _* D: X% W6 e2 s
  209.     while(font_list[i])$ }7 ?* I  R/ y, T
  210.     {
    . k9 `4 R- ~+ w2 j1 ~( I3 W( z
  211.         if(0 == strcmp(font_list[i],font_name))
    ) f" X+ ^' a0 l* v
  212.         {" Q! D$ Z6 _3 E1 i( @0 f
  213.             page->fontType = i;4 w4 D, U& e4 M
  214.             page->fontSize = size;4 V4 k, h# l& X9 m. E" ^
  215.             length = LPDF_SPRINTF(pdf_buf,"/F%d %d Tf\n",i+1,size);
    / ]7 K6 `  F9 K
  216.             LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    1 [9 ?4 V9 Q  s# @2 {. }
  217.             pdf->offset += length;: X9 t! T7 s  z+ L6 f
  218.             page->length += length;) L' [3 L, N- b- S% ?" u+ p# F
  219.             return LPDF_OK;' A- @6 l) g& f- e  j& H! i3 l
  220.         }
    & m2 b! a+ l( }
  221.         i+=1;
    * E: ~% k. T: i  ^5 \8 E0 b& D7 g
  222.     }
    4 w8 s% ]/ a( y+ c
  223.     ( H' i6 U& U/ q- C
  224.     return LPDF_OK;
    . K: x) r5 \3 _. h/ D! N5 b# \  [
  225. }' n( A1 m% {# B! l  T
  226. - ], ~) z$ a' G' V/ @9 H
  227. LPDF_STATUS LPDF_Page_SaveParams(LPDF_Page page)/ L) l0 i5 \- v' `% {; Q* m7 M5 l
  228. {
    9 Q2 a( S# _- ?: ]4 v! e. ^1 m
  229.     LPDF_INT length;: t' U( ~( U7 K  I
  230.         LPDF_UINT writeBytes = 0;
    6 d3 V3 c) b6 a& `
  231.     LPDF_Doc pdf = (LPDF_Doc)page->doc;3 Q- B1 P3 J/ S  h) N; B2 o8 j7 o
  232.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_INVALID);
    . B- X/ D: S; V' ^
  233.     if(LPDF_OK != ret)
    : Y- h3 G$ P; `0 I0 T) L1 r; }
  234.         return ret;
    4 B1 u" D5 J9 Q- N( B! E" T
  235.    
    ) K! E- f7 L- e8 n
  236.     /* 对于每个page来说该接口只能调用一次即在GMODE为INVALID的模式下 */
    9 _" _$ v5 p/ |+ `( _1 `% I
  237.     length = LPDF_SPRINTF(pdf_buf,"/MediaBox [ 0 0 %d %d ]\n>>\nendobj\n\n",6 K0 e+ X' M& Q, Y2 M- M
  238.                         page->width, page->height);( p0 D" V0 a! n
  239.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);* J) \  ^2 b  p+ e
  240.     pdf->offset += length;
    6 M; j0 {; K4 K
  241.     pdf->obj[pdf->objNumber+1].objIdx = pdf->offset;$ j! u) L5 ?. K- X) j# d0 d+ w4 T
  242.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n<</Length %d 0 R>>\nstream\n",
    , v0 `9 W) a. s+ f- }/ S; h
  243.                         pdf->objNumber+2, pdf->objNumber+3);
    + J3 U7 G+ f& o, |5 x
  244.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    $ w- c% Q9 x1 c- L5 {
  245.     pdf->offset += length;
    ; J# I* l2 Z2 I5 m/ F$ y" X
  246.     page->length = 0;7 z/ ?% }- p! P* G
  247.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;" j% _* [3 S. v+ u9 U
  248.     return LPDF_OK;
    8 E% U% H' o: c
  249. }7 f* _( T$ Z; O$ F9 ?

  250. 6 j: I  _5 x+ c7 q8 b4 w
  251. LPDF_STATUS LPDF_Page_SaveContext(LPDF_Page page). E! f3 {+ M; b$ Y2 x+ Q  g- W8 c. M
  252. {' j: N3 U1 T: X9 A9 L
  253.     LPDF_INT length;
    , R! \( d( W" I1 p
  254.         LPDF_UINT writeBytes = 0;
    + r2 D! `$ ?( W0 [
  255.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    5 m7 C( J: A; e. K8 \, a- m& y
  256.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);
    - W. }' s$ L" ], ]8 E
  257.     if(LPDF_OK != ret)5 [, a( s) C% Z
  258.         return ret;6 ^( F* H5 w. b
  259.      /* 对于每个page来说该接口只能调用一次即在GMODE为PAGE_DESCRIPTION的模式下 */
    5 c! ?# W3 H$ I& t( w  K
  260.     length = LPDF_SPRINTF(pdf_buf,"endstream\nendobj\n\n");
    ! \  d7 \6 r* y6 a
  261.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ' N  U4 ^9 {6 r* X3 @5 l
  262.     pdf->offset += length;
      p( I; D% h% b
  263.     pdf->obj[pdf->objNumber+2].objIdx = pdf->offset;
    $ s% |2 ~- `. X2 X* K
  264.     length = LPDF_SPRINTF(pdf_buf,"%d 0 obj\n%d\nendobj\n\n",
    ' d6 O5 B3 n6 F) n9 r6 w
  265.                         pdf->objNumber+3,page->length);
    & V2 n0 V, }" t/ J
  266.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    + ^1 e! Z5 x' z$ D
  267.     pdf->offset += length;
    7 ^5 p4 @" N" q4 E
  268.     pdf->objNumber += 3;
    % a; {5 O3 e8 O5 Y
  269.     page->gMode = LPDF_GMODE_OVER;
      b  t6 s) }0 c. q; b' t$ [
  270.     return LPDF_OK;
    # @  X& R& K7 r$ I% o# c5 R( J
  271. }
    . n5 J8 [+ Y0 G$ ?& h' x
  272. * c; d0 n3 G" ^: c
  273. LPDF_STATUS LPDF_Page_BeginText(LPDF_Page page)
    7 @! U# Y& H# ~1 e2 X: n
  274. {
    3 d$ M: Q) ]- ~4 V3 a' [: L3 p, k+ |
  275.     LPDF_Doc pdf = (LPDF_Doc)page->doc;/ t1 q1 c) d( u9 |$ f
  276.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION);' `! c9 X: a. @% b* E9 Y$ @
  277.     if(LPDF_OK != ret). g$ C1 d8 F+ Q. L8 _
  278.         return ret;; m5 V0 A1 _8 b$ C; B
  279.     LPDF_FPRINTF(&pdf->file,"BT\n");/ B4 M# L* E5 S" I% W9 a: Z
  280.     pdf->offset += 3;
    4 E1 r: j- h6 [# p
  281.     page->length += 3;  {' e/ D0 l+ E
  282.     page->gMode = LPDF_GMODE_TEXT_OBJECT;
    4 Q' K. X( o" u/ t: l
  283.     return LPDF_OK;
    3 B% i1 f/ m( o6 V- d3 u7 B& @2 y! {
  284. }# m) C; R  r3 o) a5 @& c8 y
  285. LPDF_STATUS LPDF_Page_EndText(LPDF_Page page)
    $ p) N/ @+ ^2 Y) W: p* E
  286. {
    ( `* s0 u* m+ P* \
  287.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    . e3 H, J/ _: x6 O0 N3 `
  288.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    ! S- e  ?  h  Z5 d; M8 o
  289.     if(LPDF_OK != ret); Y) Y& R! R  m" P
  290.         return ret;7 |$ L, \9 @. W3 z3 H
  291.     LPDF_FPRINTF(&pdf->file,"ET\n");
    # w9 d: F: U4 ^
  292.     pdf->offset += 3;
    / F. l9 `5 S, O+ k6 Q
  293.     page->length += 3;
    9 z5 R% S+ Q7 E% `( e3 D4 i
  294.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;- s9 I+ a. T2 g: x. m
  295.     return LPDF_OK;
    , D, f. Q! i  C: b/ X
  296. }- @5 O; B- @( k2 t

  297. 7 _, u9 M- L6 {& |
  298. LPDF_STATUS LPDF_Page_ShowText(LPDF_Page page, const char *text)
    - F8 o$ X0 k  k" |/ P/ v$ [1 L
  299. {
    ) `) P, R8 o& z1 [# L
  300.     LPDF_INT length = 0;8 M" o: ]* V4 I- X. j/ u# U
  301.         LPDF_UINT writeBytes = 0;# O) d) e! i& i8 [4 i3 P/ G
  302.     LPDF_Doc pdf = (LPDF_Doc)page->doc;2 Z1 }- |) O3 [" l9 O+ _
  303.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    ; _% k  P3 c9 z* g
  304.     if(LPDF_OK != ret)" r7 u7 @2 m6 A& b* Q4 M. n8 D
  305.         return ret;
    . \8 T) o# k3 \7 {) |" }  j* }1 m
  306.     if(LPDF_FONT_INVALID == page->fontType)' k, ?8 y8 @* W/ ^: Z9 z
  307.         return LPDF_OK;
    + S+ g( o, T7 f, j) b& E
  308.     length = LPDF_SPRINTF(pdf_buf,"(%s) Tj\n",text);; V& w- {( j$ ~! R7 M8 A
  309.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    ' |# K  O7 h; m9 T! i, |& `+ Y
  310.     pdf->offset += length;0 d7 K  y  s. E4 f
  311.     page->length += length;  l' n5 M$ w' s8 i1 L6 l
  312.     return LPDF_OK;
    6 J" \+ h4 W  `  `" u
  313.     0 q) j7 r2 ]" m4 w
  314. }. c  n, a+ ~5 Z5 \2 p/ C
  315. LPDF_STATUS LPDF_Page_MoveTextPos(LPDF_Page page,$ g. f! Z( t) e/ c) b
  316.                         LPDF_INT x, LPDF_INT y). ]% b4 e/ U  k9 s
  317. {
    3 W6 Q, f9 f% \* ^
  318.     LPDF_INT length = 0;
    % @( Y9 o  `) `1 T9 D' B
  319.         LPDF_UINT writeBytes = 0;+ U' p& m4 ^( L, H2 s6 L3 a3 T5 ^. q# J
  320.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    1 w9 m, X* [; q: _8 V
  321.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT);
    7 V( n* r1 m8 k5 P
  322.     if(LPDF_OK != ret)  l  w2 n- b/ x
  323.         return ret;
    0 s1 e' L% q& U, e% r% D
  324.     length = LPDF_SPRINTF(pdf_buf,"%d %d Td\n",x,y);. {  U& |9 S" c& y8 [
  325.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);4 X- N9 C! z. _8 c6 V5 ?$ b9 A
  326.     pdf->offset += length;
    0 X) |! E; f5 @
  327.     page->length += length;
    3 N1 I9 e1 K4 S3 S* f# m1 \
  328. 4 l4 D/ {# z/ w+ @; l/ B7 S& B; _+ x
  329.     return LPDF_OK;
      O) P0 }" b: S8 Q! G
  330. }
    ; v/ D5 R0 j! H$ r5 X$ p0 w
  331. LPDF_STATUS LPDF_Page_TextOut(LPDF_Page page, % `. F* N7 b$ [) q( F7 @
  332.                         LPDF_UINT16 x, LPDF_UINT16 y,2 [+ R" q) I6 l+ l. h
  333.                         const char *text)
      @& |  W3 t$ v4 Q% R) v& {
  334. {* g3 u& p5 x0 a8 M' ?( h: x
  335.     return LPDF_OK;
    : e: E$ }% r) l, w' l$ L9 r
  336. }5 x. H8 u4 E+ a) r- O& \. D7 }" x

  337. 8 A' b7 g, \8 A( i  q9 V
  338. LPDF_STATUS LPDF_Page_SetRGBStroke(LPDF_Page page,) F. t4 a8 f, w8 W" `( {' a0 y
  339.                          LPDF_REAL r,
    , W  g, v: ?; Q7 v
  340.                          LPDF_REAL g,  {/ O% ]0 j6 N9 H. L
  341.                          LPDF_REAL b)
    % f$ `; z9 f7 a4 F; t
  342. {  k0 {& r/ l9 I
  343.     LPDF_INT length = 0;; }7 ]% P) n8 Y) |/ G# |, u: j  K
  344.         LPDF_UINT writeBytes = 0;0 j( [& U; V: Y7 ]
  345.     LPDF_Doc pdf = (LPDF_Doc)page->doc;% m- t3 j% T- V+ q2 I
  346.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);8 \' P' W1 ?/ L% ?
  347.     if(LPDF_OK != ret)
    . B6 n+ W& j9 W* K- ?6 ^& ]
  348.         return ret;
    - T0 Q# j6 _4 t+ B5 R2 Y; \
  349. & Y3 M, ~& a* P; M
  350.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f RG\n",r,g,b);
    5 `9 ^9 D9 y# l, V: Q
  351.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);
    $ N9 p* S$ {% Y5 [4 ^. [+ |
  352.     pdf->offset += length;
    ; Y7 [$ X& K2 x/ D  P7 y! D
  353.     page->length += length;
    / _9 s: K. W$ k; {3 I0 {" z
  354.     return LPDF_OK;; K! _% u" F1 C7 D+ y' y
  355. }
    5 B9 m/ g8 V, j

  356. 5 i2 W  p# K* `8 b- ^, Q
  357. LPDF_STATUS LPDF_Page_SetRGBFill(LPDF_Page page,
    2 u5 v/ p+ o0 c8 {3 d
  358.                          LPDF_REAL r,
    ) \* }/ d7 [$ V4 G/ P
  359.                          LPDF_REAL g,3 u7 D; J- H; }
  360.                          LPDF_REAL b)8 z& n# s( e' [. I/ g
  361. {- t4 ]6 Y0 W2 C5 c. b5 W2 X
  362.     LPDF_INT length = 0;
    % H4 m8 r* q, B8 J  j
  363.         LPDF_UINT writeBytes = 0;$ p+ G9 h1 J5 ]1 G4 x
  364.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    + x  i( I6 r* H2 n; l) E% E& D/ [
  365.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_TEXT_OBJECT|LPDF_GMODE_PAGE_DESCRIPTION);
    & E% e% z8 u! _8 W8 J+ ^9 B0 _6 F
  366.     if(LPDF_OK != ret)
    1 D1 t7 u/ }: t- P( X# T2 {5 `
  367.         return ret;6 r+ B8 p" `5 n5 |
  368. ) G8 v9 N* _5 Y+ y4 s
  369.     length = LPDF_SPRINTF(pdf_buf,"%.1f %.1f %.1f rg\n",r,g,b);. t; V: k5 a! n/ x4 R/ D
  370.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);. t3 L8 z, r/ z" ?9 L, f6 N( @4 `
  371.     pdf->offset += length;
    ' z* G( V9 K0 C
  372.     page->length += length;, A. k8 r: H! [4 d8 z
  373.     return LPDF_OK;
      @  _0 T( c, N) }+ s7 v# S! O% c) G
  374. }1 X* f. o: Z, H2 k2 \
  375. LPDF_STATUS LPDF_Page_MoveTo (LPDF_Page page,
    4 ^. B1 [, I3 \5 P
  376.                          LPDF_UINT16 x,* U0 q7 s4 `  c/ d7 n5 \( S6 z
  377.                          LPDF_UINT16 y)
    : m# r, A; c' I% i$ ^
  378. {
    # t; ^7 v" U* x+ {' F: O
  379.     LPDF_INT length = 0;
    8 p, Y' z" u; a
  380.         LPDF_UINT writeBytes = 0;
    , a  I# F* e1 S! z( U
  381.     LPDF_Doc pdf = (LPDF_Doc)page->doc;
    8 c1 a  N2 W# Q+ B; V% i
  382.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PAGE_DESCRIPTION|LPDF_GMODE_PATH_OBJECT);
    & }* A' S7 L) O' Q: I1 H( V4 K
  383.     if(LPDF_OK != ret)
    + T3 e4 g, r' u  k9 p" j; ?8 ]- `4 x
  384.         return ret;1 x* @! @/ ]( d& @1 M
  385.     length = LPDF_SPRINTF(pdf_buf,"%d %d m\n",x,y);
    1 D( U$ T; g' u0 o/ u; W) L
  386.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);0 s& _* _0 p9 K9 G; r) B
  387.     pdf->offset += length;; v2 y8 g9 m5 b; M
  388.     page->length += length;
    . V3 S+ i2 ?2 z
  389.     page->gMode = LPDF_GMODE_PATH_OBJECT;: w& d8 K/ V4 b/ T, X) G
  390.     return LPDF_OK;
    ! v7 t3 `/ m1 m
  391. }8 T5 p' ?5 S$ x7 Z5 j
  392. LPDF_STATUS LPDF_Page_LineTo (LPDF_Page page,. j6 z, f% y, O6 y4 _" s
  393.                          LPDF_UINT16 x,3 b% `: S2 @; }& E+ S1 k* _% o
  394.                          LPDF_UINT16 y)6 }! i' l$ f+ s9 X- `5 ^, m8 {- D
  395. {7 m4 P: }& ]6 q" i! R8 `8 X
  396.     LPDF_INT length = 0;
    " S7 B) w& K' I1 ?; N, G3 a; S& D
  397.         LPDF_UINT writeBytes = 0;; j7 }2 V# K9 X) J( E
  398.     LPDF_Doc pdf = (LPDF_Doc)page->doc;4 \9 |8 b6 R7 i8 A0 l6 i
  399.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);+ C1 X$ y6 ^# ^8 ~
  400.     if(LPDF_OK != ret)
    4 C) l* X* @2 y; ~# M0 c% f
  401.         return ret;2 i- O' t. B+ M  }" g! t
  402.     length = LPDF_SPRINTF(pdf_buf,"%d %d l\n",x,y);
    ( ^# a& M, G1 Q7 b% P
  403.     LPDF_FWRITE(&pdf->file,pdf_buf,length,&writeBytes);7 o5 ~9 f* u( g! l% Q7 T4 ]; m, R
  404.     pdf->offset += length;& ]  a9 G1 d- X" ]4 c2 `
  405.     page->length += length;' Q6 d5 I' w( K% m
  406.     return LPDF_OK;% E1 d( }8 |2 I3 H, m. D" L! Q
  407. }
    . u1 X9 g% e" H. X5 [. O8 _4 f
  408. LPDF_STATUS LPDF_Page_Stroke(LPDF_Page page)
    ! r, m( W: C7 ?9 v2 w" z- b
  409. {
    5 H8 A, c/ N  J
  410.     LPDF_Doc pdf = (LPDF_Doc)page->doc;* z/ t# R$ i3 E2 f
  411.     LPDF_STATUS ret = LPDF_Page_CheckState(page,LPDF_GMODE_PATH_OBJECT);
    # ~3 q/ F+ D0 E5 \5 V4 c
  412.     if(LPDF_OK != ret)0 F  {- u" u% N3 a" t
  413.         return ret;
    2 E% o  ^: W6 ~4 t7 Q2 S# }% S
  414.     LPDF_FPRINTF(&pdf->file,"S\n");$ V+ w) ^/ l) G. ~7 t
  415.     pdf->offset += 2;
    8 A( H/ ^6 P9 a
  416.     page->length += 2;
    6 M, q- {/ |+ M7 m& |
  417.     page->gMode = LPDF_GMODE_PAGE_DESCRIPTION;4 s. d$ r0 F. X- v1 Z0 @
  418.     return LPDF_OK;' |3 E7 a6 e' \9 ^
  419. }. U8 \+ M% n- a( A
  420. LPDF_STATUS LPDF_Page_DrawImage(LPDF_Page page,! ~/ W7 M" z' `% S
  421.                       LPDF_Image image,
    7 p  `/ N" S/ G/ |4 b9 w) r
  422.                       LPDF_UINT16 x,
    % f7 P( E: E: |5 U' @2 B1 B
  423.                       LPDF_UINT16 y,
    2 C* {7 |7 h; V% O% ~, i
  424.                       LPDF_UINT16 width,
    " L. V4 F' `1 g) w
  425.                       LPDF_UINT16 height)
    ; j- Q9 g6 `- d7 r' Z6 C$ v
  426. {
    9 @, f1 b* L( m: K% K
  427.         return LPDF_OK;
    6 ~: A% |: ~* c# Q; ]
  428. }
    7 }3 N3 D- _. M4 s/ E- J2 l
复制代码

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

  1. pdf = LPDF_New();- Q2 M6 v* n; v0 d, l% _
  2.     page[0] = LPDF_AddPage(pdf);% G4 n6 e- x9 G9 l% P- P, K! |
  3.     LPDF_Page_SaveParams(page[0]);) z% ^, ~) [# `8 K9 \
  4.     width = LPDF_Page_GetWidth(page[0]);
    1 H) r8 H+ f7 F2 N0 U
  5.     height = LPDF_Page_GetHeight(page[0]);
    2 }9 U, q9 X0 j& q: y
  6.     LPDF_Page_SetRGBFill(page[0], 1.0, 0.0, 0.0);
    ' z( R- o- n/ [2 O' ?% [
  7.     LPDF_Page_BeginText(page[0]);- e9 c% ^  T, z/ s+ Y
  8.     LPDF_Page_MoveTextPos(page[0], 50, height-20);
    0 c  d' ^7 W9 U% _% ]
  9.     while(font_list[i])
    $ m7 y2 a6 T8 B) B5 G) Q
  10.     {
      j/ ~  X" U7 ^5 X
  11.         LPDF_Page_SetFontAndSize(page[0], font_list[i], 24);
    . a. L3 g0 ^5 S8 t' L
  12.         LPDF_Page_ShowText(page[0], "abcdefgABCDEFG12345!\043$\045&+-@?");
    8 L0 Q4 D# Q, N% ]3 B4 `% m
  13.         LPDF_Page_MoveTextPos(page[0], 0, -30);
    7 N- @! c' R  E! w2 G
  14.         i++;
    6 Z- q- a! D3 u
  15.     }
    7 }# `: V: R& ?5 ?# c3 l: P
  16.         LPDF_Page_SetFontAndSize(page[0], font_list[0], 24);3 B' M1 q6 ~3 {
  17.     LPDF_Page_ShowText(page[0], LPDF_GetVersion());
    ! z) }' Q6 a4 p3 G( Z
  18.     LPDF_Page_EndText(page[0]);! [; i- M- t8 ^/ Q
  19.     LPDF_Page_SaveContext(page[0]);
    & @5 [; r3 Q3 w. E
  20.     page[1] = LPDF_AddPage(pdf);
    ' V8 F0 L; W, a" X/ s. W  Z
  21.     LPDF_Page_SaveParams(page[1]);
    0 n& _+ d" u- @6 [7 F- v
  22.     LPDF_Page_MoveTo(page[1], width/2-50, height-200);
    " y/ d5 o. w5 r/ c% `
  23.     LPDF_Page_LineTo(page[1], width/2-50, height-300);
    6 c, m. L0 Y% ~3 n! X2 B
  24.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);% Q3 ^" @# N: q* v2 n9 s
  25.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);
    " x8 V& k4 g2 D( b# H7 H7 C
  26.     LPDF_Page_LineTo(page[1], width/2-50, height-200);
    . x1 [: m7 l% f
  27.     LPDF_Page_LineTo(page[1], width/2-50+40, height-140);3 @" ?+ W, y1 ]/ w) Z# F/ \
  28.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-140);7 Z% h( E8 c" \( [+ l7 s& f  m
  29.     LPDF_Page_LineTo(page[1], width/2-50+100, height-200);5 A, |: I5 t; I4 o: D
  30.     LPDF_Page_Stroke(page[1]);8 b9 k. Y2 }. n- s) J9 T
  31.     LPDF_Page_MoveTo(page[1], width/2-50+40+100, height-140);
    $ w, d" Z4 k7 l5 V2 Q
  32.     LPDF_Page_LineTo(page[1], width/2-50+40+100, height-240);# C" m/ ~9 [6 |
  33.     LPDF_Page_LineTo(page[1], width/2-50+100, height-300);
    ( r: b) e6 C# V* b
  34.     LPDF_Page_Stroke(page[1]);
    ; d, x' o- v& l5 _; U
  35.     LPDF_Page_SaveContext(page[1]);
    : w8 @6 t5 c1 `/ [  T+ O7 y2 a
  36.     LPDF_SaveToFile(pdf, "/red.pdf");
    # p% E: j8 B  A( l
  37.         PRINTF("\r\nCreate pdf file success!\r\n");
    5 I. C* F: Y, \) W; G- s$ e; I
  38.   
复制代码

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

无标题.png

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

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

PS:更新为V0.04版本了9 B5 g+ r0 Y2 h

更新说明: V0.04

  • 增加了SimSun中文字体
  • 修复了LPDF_Page_SetLineWidth接口中内容长度错误的问题
  • pdflib源文件以及测试文件均需使用ANSI编码,否则无法正确显示中文字体
    ; y4 D6 `: H# y/ N: L8 v4 e! d
+ ?2 U; P& p% g& {

pdflib_V0.04.rar

下载

6.1 KB, 下载次数: 424

pdflib库

评分

参与人数 4 ST金币 +24 收起 理由
tanganrong-1584 + 5
g921002 + 8 很给力!
lemonjohn + 1 很给力!
wofei1314 + 10 很给力!

查看全部评分

4 收藏 22 评论149 发布时间:2017-6-17 23:03

举报

149个回答
kiki.zhang 回答时间:2018-2-27 10:19:19
anobodykey 发表于 2018-2-26 22:55% Y8 I, |( J5 \; A5 q( V# @! d
只研究了一点,现在这个版本可以添加图片的,你可以看下,添加图片也有好几种方式,弄了个最简单的 ...

& f0 R; X) `: s/ FLZ,我怎么没看到有添加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
9 P! J( v+ @5 l* T8 j7 R( I& Q首先谢谢你的回复和帮助。。。还有你那个更新的dflib_v0.04(可以输出中文)里面没有HPDF_UseCNSFonts(), ...

0 E" h, p6 P1 H9 o/ `& f66楼附件有的
anobodykey 回答时间:2017-6-17 23:04:09
自己顶一下,
深谷幽泉 回答时间:2017-6-18 11:45:33
看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分享~
weigr 回答时间:2017-6-18 15:47:15
有意思& Y3 D; \+ V9 D" C  |) e# b( S, R
anobodykey 回答时间:2017-6-18 15:55:19
深谷幽泉 发表于 2017-6-18 11:45
- l- m' |, ~0 T2 I看起来很高端的样子,居然没人顶。不过,请问楼主,用MCU生成PDF文件这种操作会在哪种应用场景下出现?求分 ...

0 P% S! T$ {* C这个我也还没遇到过,只是之前看到有人问这个,所以看看
pwdzsj 回答时间:2017-6-18 17:04:27
不错还挺好的
好吃好好吃 回答时间:2017-6-18 19:07:12
高手啊
netlhx 回答时间:2017-6-18 20:27:00
赞,楼主功力深厚
graycker 回答时间:2017-6-19 08:44:11
厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接
anobodykey 回答时间:2017-6-19 10:41:48
graycker 发表于 2017-6-19 08:44
: T& V/ L8 m4 c( m0 p% l# q4 @2 F- q厉害啊,前几个月朋友让做个单片机生成pdf的工具我都没接

" E: C3 Y( X$ T3 |! J( `% h这个还只是一个简单的库,实用性还是差一些的
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
9 W# f! R# a' {" w8 |ff.h在哪里呀,我的是keil4.73版本,需要手动添加吗

9 [) g% ^# v/ |# ~4 n% m% v: off.h是FATfs中的文件
我为电狂 回答时间:2017-7-10 10:00:04
anobodykey 发表于 2017-6-28 09:22: O! o0 x9 E+ v1 S7 l& H& y
ff.h是FATfs中的文件

3 Q& f, Z8 y& F% z. P+ n" l嗯,这个画线能改变线宽吗

所属标签

相似分享

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