1 package gofpdf
2
3 import (
4 "bytes"
5 "crypto/sha1"
6 "encoding/gob"
7 "errors"
8 "fmt"
9 )
10
11
27
28
29 func newTpl(corner PointType, size SizeType, orientationStr, unitStr, fontDirStr string, fn func(*Tpl), copyFrom *Fpdf) Template {
30 sizeStr := ""
31
32 fpdf := fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr, size)
33 tpl := Tpl{*fpdf}
34 if copyFrom != nil {
35 tpl.loadParamsFromFpdf(copyFrom)
36 }
37 tpl.Fpdf.AddPage()
38 fn(&tpl)
39
40 bytes := make([][]byte, len(tpl.Fpdf.pages))
41
42 for x := 1; x < len(bytes); x++ {
43 bytes[x] = tpl.Fpdf.pages[x].Bytes()
44 }
45
46 templates := make([]Template, 0, len(tpl.Fpdf.templates))
47 for _, key := range templateKeyList(tpl.Fpdf.templates, true) {
48 templates = append(templates, tpl.Fpdf.templates[key])
49 }
50 images := tpl.Fpdf.images
51
52 template := FpdfTpl{corner, size, bytes, images, templates, tpl.Fpdf.page}
53 return &template
54 }
55
56
57 type FpdfTpl struct {
58 corner PointType
59 size SizeType
60 bytes [][]byte
61 images map[string]*ImageInfoType
62 templates []Template
63 page int
64 }
65
66
67 func (t *FpdfTpl) ID() string {
68 return fmt.Sprintf("%x", sha1.Sum(t.Bytes()))
69 }
70
71
72 func (t *FpdfTpl) Size() (corner PointType, size SizeType) {
73 return t.corner, t.size
74 }
75
76
77 func (t *FpdfTpl) Bytes() []byte {
78 return t.bytes[t.page]
79 }
80
81
82 func (t *FpdfTpl) FromPage(page int) (Template, error) {
83
84 if page == 0 {
85 return nil, errors.New("Pages start at 1 No template will have a page 0")
86 }
87
88 if page > t.NumPages() {
89 return nil, fmt.Errorf("The template does not have a page %d", page)
90 }
91
92
93 if t.page == page {
94 return t, nil
95 }
96
97 t2 := *t
98 t2.page = page
99 return &t2, nil
100 }
101
102
103 func (t *FpdfTpl) FromPages() []Template {
104 p := make([]Template, t.NumPages())
105 for x := 1; x <= t.NumPages(); x++ {
106
107
108
109 p[x-1], _ = t.FromPage(x)
110 }
111
112 return p
113 }
114
115
116 func (t *FpdfTpl) Images() map[string]*ImageInfoType {
117 return t.images
118 }
119
120
121 func (t *FpdfTpl) Templates() []Template {
122 return t.templates
123 }
124
125
126 func (t *FpdfTpl) NumPages() int {
127
128
129 return len(t.bytes) - 1
130 }
131
132
133 func (t *FpdfTpl) Serialize() ([]byte, error) {
134 b := new(bytes.Buffer)
135 enc := gob.NewEncoder(b)
136 err := enc.Encode(t)
137
138 return b.Bytes(), err
139 }
140
141
142
143 func DeserializeTemplate(b []byte) (Template, error) {
144 tpl := new(FpdfTpl)
145 dec := gob.NewDecoder(bytes.NewBuffer(b))
146 err := dec.Decode(tpl)
147 return tpl, err
148 }
149
150
151
152
153 func (t *FpdfTpl) childrenImages() map[string]*ImageInfoType {
154 childrenImgs := make(map[string]*ImageInfoType)
155
156 for x := 0; x < len(t.templates); x++ {
157 imgs := t.templates[x].Images()
158 for key, val := range imgs {
159 name := sprintf("t%s-%s", t.templates[x].ID(), key)
160 childrenImgs[name] = val
161 }
162 }
163
164 return childrenImgs
165 }
166
167
168
169 func (t *FpdfTpl) childrensTemplates() []Template {
170 childrenTmpls := make([]Template, 0)
171
172 for x := 0; x < len(t.templates); x++ {
173 tmpls := t.templates[x].Templates()
174 childrenTmpls = append(childrenTmpls, tmpls...)
175 }
176
177 return childrenTmpls
178 }
179
180
181
182 func (t *FpdfTpl) GobEncode() ([]byte, error) {
183 w := new(bytes.Buffer)
184 encoder := gob.NewEncoder(w)
185
186 childrensTemplates := t.childrensTemplates()
187 firstClassTemplates := make([]Template, 0)
188
189 found_continue:
190 for x := 0; x < len(t.templates); x++ {
191 for y := 0; y < len(childrensTemplates); y++ {
192 if childrensTemplates[y].ID() == t.templates[x].ID() {
193 continue found_continue
194 }
195 }
196
197 firstClassTemplates = append(firstClassTemplates, t.templates[x])
198 }
199 err := encoder.Encode(firstClassTemplates)
200
201 childrenImgs := t.childrenImages()
202 firstClassImgs := make(map[string]*ImageInfoType)
203
204 for key, img := range t.images {
205 if _, ok := childrenImgs[key]; !ok {
206 firstClassImgs[key] = img
207 }
208 }
209
210 if err == nil {
211 err = encoder.Encode(firstClassImgs)
212 }
213 if err == nil {
214 err = encoder.Encode(t.corner)
215 }
216 if err == nil {
217 err = encoder.Encode(t.size)
218 }
219 if err == nil {
220 err = encoder.Encode(t.bytes)
221 }
222 if err == nil {
223 err = encoder.Encode(t.page)
224 }
225
226 return w.Bytes(), err
227 }
228
229
230 func (t *FpdfTpl) GobDecode(buf []byte) error {
231 r := bytes.NewBuffer(buf)
232 decoder := gob.NewDecoder(r)
233
234 firstClassTemplates := make([]*FpdfTpl, 0)
235 err := decoder.Decode(&firstClassTemplates)
236 t.templates = make([]Template, len(firstClassTemplates))
237
238 for x := 0; x < len(t.templates); x++ {
239 t.templates[x] = Template(firstClassTemplates[x])
240 }
241
242 firstClassImages := t.childrenImages()
243
244 t.templates = append(t.childrensTemplates(), t.templates...)
245
246 t.images = make(map[string]*ImageInfoType)
247 if err == nil {
248 err = decoder.Decode(&t.images)
249 }
250
251 for k, v := range firstClassImages {
252 t.images[k] = v
253 }
254
255 if err == nil {
256 err = decoder.Decode(&t.corner)
257 }
258 if err == nil {
259 err = decoder.Decode(&t.size)
260 }
261 if err == nil {
262 err = decoder.Decode(&t.bytes)
263 }
264 if err == nil {
265 err = decoder.Decode(&t.page)
266 }
267
268 return err
269 }
270
271
272
273
274 type Tpl struct {
275 Fpdf
276 }
277
278 func (t *Tpl) loadParamsFromFpdf(f *Fpdf) {
279 t.Fpdf.compress = false
280
281 t.Fpdf.k = f.k
282 t.Fpdf.x = f.x
283 t.Fpdf.y = f.y
284 t.Fpdf.lineWidth = f.lineWidth
285 t.Fpdf.capStyle = f.capStyle
286 t.Fpdf.joinStyle = f.joinStyle
287
288 t.Fpdf.color.draw = f.color.draw
289 t.Fpdf.color.fill = f.color.fill
290 t.Fpdf.color.text = f.color.text
291
292 t.Fpdf.fonts = f.fonts
293 t.Fpdf.currentFont = f.currentFont
294 t.Fpdf.fontFamily = f.fontFamily
295 t.Fpdf.fontSize = f.fontSize
296 t.Fpdf.fontSizePt = f.fontSizePt
297 t.Fpdf.fontStyle = f.fontStyle
298 t.Fpdf.ws = f.ws
299
300 for key, value := range f.images {
301 t.Fpdf.images[key] = value
302 }
303 }
304
View as plain text