Commit 9ede5c7a90d494de4c0904120595b3a82c933adc
1 parent
28aa66b2f4
Exists in
master
removed unused stuff
Showing
1 changed file
with
55 additions
and
150 deletions
Show diff stats
pdfhelper/pdf.go
1 | package pdfhelper | 1 | package pdfhelper |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "strings" | 5 | "strings" |
6 | 6 | ||
7 | "git.to-net.rs/marko.tikvic/gofpdf" | 7 | "git.to-net.rs/marko.tikvic/gofpdf" |
8 | ) | 8 | ) |
9 | 9 | ||
10 | // Block ... | 10 | // Block ... |
11 | const ( | 11 | const ( |
12 | CENTER = "C" | 12 | CENTER = "C" |
13 | LEFT = "L" | 13 | LEFT = "L" |
14 | RIGHT = "R" | 14 | RIGHT = "R" |
15 | TOP = "T" | 15 | TOP = "T" |
16 | BOTTOM = "B" | 16 | BOTTOM = "B" |
17 | FULL = "1" | 17 | FULL = "1" |
18 | NOBORDER = "" | 18 | NOBORDER = "" |
19 | ) | 19 | ) |
20 | 20 | ||
21 | const ( | 21 | const ( |
22 | CONTINUE = 0 | 22 | CONTINUE = 0 |
23 | NEWLINE = 1 | 23 | NEWLINE = 1 |
24 | BELLOW = 2 | 24 | BELLOW = 2 |
25 | ) | 25 | ) |
26 | 26 | ||
27 | const ( | 27 | const ( |
28 | cyrillicEncoding = "cp1251" | 28 | cyrillicEncoding = "cp1251" |
29 | latinEncoding = "cp1250" | 29 | latinEncoding = "cp1250" |
30 | ) | 30 | ) |
31 | 31 | ||
32 | const threeDots = "\u2056\u2056\u2056" | ||
33 | |||
34 | type TableCell struct { | ||
35 | W, H float64 | ||
36 | Text string | ||
37 | Font, FontStyle string | ||
38 | FontSize float64 | ||
39 | Border string | ||
40 | Alignment string | ||
41 | } | ||
42 | |||
32 | // Helper ... | 43 | // Helper ... |
33 | type Helper struct { | 44 | type Helper struct { |
34 | *gofpdf.Fpdf | 45 | *gofpdf.Fpdf |
35 | translators map[string]func(string) string | 46 | translators map[string]func(string) string |
36 | } | 47 | } |
37 | 48 | ||
38 | // New ... | 49 | // New ... |
39 | func New(ori, unit, size string) *Helper { | 50 | func New(ori, unit, size string) *Helper { |
40 | helper := &Helper{ | 51 | helper := &Helper{ |
41 | Fpdf: gofpdf.New(ori, unit, size, ""), | 52 | Fpdf: gofpdf.New(ori, unit, size, ""), |
42 | } | 53 | } |
43 | 54 | ||
44 | return helper | 55 | return helper |
45 | } | 56 | } |
46 | 57 | ||
47 | func (pdf *Helper) LoadTranslators() { | 58 | func (pdf *Helper) LoadTranslators() { |
48 | pdf.translators = make(map[string]func(string) string) | 59 | pdf.translators = make(map[string]func(string) string) |
49 | pdf.translators[latinEncoding] = pdf.UnicodeTranslatorFromDescriptor(latinEncoding) | 60 | pdf.translators[latinEncoding] = pdf.UnicodeTranslatorFromDescriptor(latinEncoding) |
50 | pdf.translators[cyrillicEncoding] = pdf.UnicodeTranslatorFromDescriptor(cyrillicEncoding) | 61 | pdf.translators[cyrillicEncoding] = pdf.UnicodeTranslatorFromDescriptor(cyrillicEncoding) |
51 | } | 62 | } |
52 | 63 | ||
53 | // InsertTab ... | 64 | func (pdf *Helper) DrawCell(x, y float64, c TableCell) { |
54 | func (pdf *Helper) InsertTab(count int, w, h float64) { | ||
55 | for i := 0; i < count; i++ { | ||
56 | pdf.Cell(w, h, "") | ||
57 | } | ||
58 | } | ||
59 | |||
60 | // CellWithBox ... | ||
61 | func (pdf *Helper) CellWithBox(w, h float64, text, align string) { | ||
62 | //pdf.drawCellMargins(w, h) | ||
63 | //pdf.Cell(w, h, text) | ||
64 | pdf.CellFormat(w, h, pdf.ToUTF8(text), FULL, CONTINUE, align, false, 0, "") | ||
65 | } | ||
66 | |||
67 | func (pdf *Helper) CellWithMargins(w, h float64, text, align string, index, of int) { | ||
68 | len := of - 1 | ||
69 | border := "" | ||
70 | |||
71 | // if top cell | ||
72 | if index == 0 { | ||
73 | border += "T" | ||
74 | } | ||
75 | |||
76 | border += "LR" // always draw these | ||
77 | |||
78 | // if bottom cell | ||
79 | if index == len { | ||
80 | border += "B" | ||
81 | } | ||
82 | |||
83 | pdf.CellFormat(w, h, pdf.ToUTF8(text), border, CONTINUE, align, false, 0, "") | ||
84 | } | ||
85 | |||
86 | // MultiRowCellWithBox ... | ||
87 | func (pdf *Helper) MultiRowCellWithBox(w, h float64, text []string, align string) { | ||
88 | pdf.drawCellMargins(w, h*float64(len(text))) | ||
89 | for i := range text { | ||
90 | pdf.CellFormat(w, h, pdf.ToUTF8(text[i]), "", BELLOW, align, false, 0, "") | ||
91 | } | ||
92 | } | ||
93 | |||
94 | // CellFormat(w, h, text, borders, newLine, fill) | ||
95 | |||
96 | type FormatedCell struct { | ||
97 | W, H float64 | ||
98 | Text string | ||
99 | Font, FontStyle string | ||
100 | FontSize float64 | ||
101 | Border string | ||
102 | Alignment string | ||
103 | } | ||
104 | |||
105 | func (pdf *Helper) FCell(x, y float64, c FormatedCell) { | ||
106 | pdf.SetXY(x, y) | 65 | pdf.SetXY(x, y) |
107 | pdf.SetFont(c.Font, c.FontStyle, c.FontSize) | 66 | pdf.SetFont(c.Font, c.FontStyle, c.FontSize) |
108 | pdf.CellFormat(c.W, c.H, pdf.ToUTF8(c.Text), c.Border, BELLOW, c.Alignment, false, 0, "") | 67 | pdf.CellFormat(c.W, c.H, pdf.toUTF8(c.Text), c.Border, BELLOW, c.Alignment, false, 0, "") |
109 | } | 68 | } |
110 | 69 | ||
111 | func (pdf *Helper) Column(x, y float64, cells []FormatedCell) { | 70 | func (pdf *Helper) DrawColumn(x, y float64, cells []TableCell) { |
112 | pdf.SetXY(x, y) | 71 | pdf.SetXY(x, y) |
113 | for _, c := range cells { | 72 | for _, c := range cells { |
114 | pdf.SetFont(c.Font, c.FontStyle, c.FontSize) | 73 | pdf.SetFont(c.Font, c.FontStyle, c.FontSize) |
115 | pdf.CellFormat(c.W, c.H, pdf.ToUTF8(c.Text), c.Border, BELLOW, c.Alignment, false, 0, "") | 74 | pdf.CellFormat(c.W, c.H, pdf.toUTF8(c.Text), c.Border, BELLOW, c.Alignment, false, 0, "") |
116 | //pdf.CellFormat(c.w, c.h, c.text, c.border, BELLOW, align, false, 0, "") | ||
117 | } | 75 | } |
118 | } | 76 | } |
119 | 77 | ||
120 | // NewLine ... | 78 | func (pdf *Helper) DrawRow(x, y float64, cells []TableCell) { |
121 | func (pdf *Helper) NewLine(h float64) { | ||
122 | pdf.Ln(h) | ||
123 | } | ||
124 | |||
125 | // WriteColumns ... | ||
126 | func (pdf *Helper) WriteColumns(align string, cols []PDFCell) { | ||
127 | for _, c := range cols { | ||
128 | pdf.CellFormat(c.width, c.height, pdf.ToUTF8(c.data), "", CONTINUE, align, false, 0, "") | ||
129 | } | ||
130 | } | ||
131 | |||
132 | func (pdf *Helper) Row(x, y float64, cells []FormatedCell) { | ||
133 | pdf.SetXY(x, y) | 79 | pdf.SetXY(x, y) |
134 | for _, c := range cells { | 80 | for _, c := range cells { |
135 | pdf.SetFont(c.Font, c.FontStyle, c.FontSize) | 81 | pdf.SetFont(c.Font, c.FontStyle, c.FontSize) |
136 | pdf.CellFormat(c.W, c.H, pdf.ToUTF8(c.Text), c.Border, CONTINUE, c.Alignment, false, 0, "") | 82 | pdf.CellFormat(c.W, c.H, pdf.toUTF8(c.Text), c.Border, CONTINUE, c.Alignment, false, 0, "") |
137 | } | 83 | } |
138 | } | 84 | } |
139 | 85 | ||
140 | const threeDots = "\u2056\u2056\u2056" | 86 | func (pdf *Helper) TextLength(txt, family, style string, size float64) float64 { |
141 | 87 | family, _, _, _ = pdf.setCorrectFontFamily(textEncoding(txt)) | |
142 | // WriteColumnsWithAlignment ... | 88 | return pdf.Fpdf.TextLength(txt, family, style, size) |
143 | func (pdf *Helper) WriteColumnsWithAlignment(cols []PDFCellAligned) { | ||
144 | for _, c := range cols { | ||
145 | lines := pdf.SplitText(c.data, c.width) | ||
146 | if len(lines) == 1 { | ||
147 | pdf.CellFormat(c.width, c.height, pdf.ToUTF8(lines[0]), "", CONTINUE, c.alignment, false, 0, "") | ||
148 | } else { | ||
149 | pdf.CellFormat(c.width, c.height, pdf.ToUTF8(lines[0]+threeDots), "", CONTINUE, c.alignment, false, 0, "") | ||
150 | } | ||
151 | } | ||
152 | |||
153 | } | 89 | } |
154 | 90 | ||
155 | func (pdf *Helper) LimitText(text, limiter string, maxWidth float64) string { | 91 | func (pdf *Helper) LimitText(text, limiter string, maxWidth float64) string { |
156 | parts := pdf.Fpdf.SplitText(text, maxWidth) | 92 | parts := pdf.Fpdf.SplitText(text, maxWidth) |
157 | if len(parts) > 1 { | 93 | if len(parts) > 1 { |
158 | return parts[0] + limiter | 94 | return parts[0] + limiter |
159 | } | 95 | } |
160 | 96 | ||
161 | return text | 97 | return text |
162 | } | 98 | } |
163 | 99 | ||
164 | // InsertImage ... | 100 | // InsertImage ... |
165 | func (pdf *Helper) InsertImage(img string, x, y, w, h float64) { | 101 | func (pdf *Helper) InsertImage(img string, x, y, w, h float64) { |
166 | imgType := "" | 102 | imgType := "" |
167 | if parts := strings.Split(img, "."); len(parts) >= 2 { | 103 | if parts := strings.Split(img, "."); len(parts) >= 2 { |
168 | imgType = parts[len(parts)-1] | 104 | imgType = parts[len(parts)-1] |
169 | } | 105 | } |
170 | opt := gofpdf.ImageOptions{ | 106 | opt := gofpdf.ImageOptions{ |
171 | ImageType: imgType, | 107 | ImageType: imgType, |
172 | ReadDpi: false, | 108 | ReadDpi: false, |
173 | AllowNegativePosition: false, | 109 | AllowNegativePosition: false, |
174 | } | 110 | } |
175 | autoBreak := false // if it's not false then you can't draw the image at an arbitrary height (y position) | 111 | autoBreak := false // if it's not false then you can't draw the image at an arbitrary height (y position) |
176 | pdf.ImageOptions(img, x, y, w, h, autoBreak, opt, 0, "") | 112 | pdf.ImageOptions(img, x, y, w, h, autoBreak, opt, 0, "") |
177 | } | 113 | } |
178 | 114 | ||
179 | // PDFCell ... | 115 | func (pdf *Helper) PageHasSpace(requiredHeight float64) bool { |
180 | type PDFCell struct { | 116 | _, h := pdf.GetPageSize() |
181 | data string | 117 | _, _, _, bot := pdf.GetMargins() |
182 | height, width float64 | 118 | return (h - bot - pdf.GetY()) > requiredHeight |
183 | } | 119 | } |
184 | 120 | ||
185 | // PDFCellAligned ... | 121 | // DrawBox ... |
186 | type PDFCellAligned struct { | 122 | func (pdf Helper) DrawBox(x0, y0, w, h float64) { |
187 | alignment string | 123 | pdf.Line(x0, y0, x0+w, y0) |
188 | data string | 124 | pdf.Line(x0+w, y0, x0+w, y0+h) |
189 | height, width float64 | 125 | pdf.Line(x0+w, y0+h, x0, y0+h) |
126 | pdf.Line(x0, y0+h, x0, y0) | ||
190 | } | 127 | } |
191 | 128 | ||
192 | func (pdf *Helper) TextLength(txt, family, style string, size float64) float64 { | 129 | // Strana %d/{TotalPages} |
193 | family, _, _, _ = pdf.setCorrectFontFamily(textEncoding(txt)) | 130 | func (pdf *Helper) InsertPageNumber(x, y float64, format string) { |
194 | return pdf.Fpdf.TextLength(txt, family, style, size) | 131 | num := fmt.Sprintf(format, pdf.PageNo()) |
132 | pdf.DrawColumn(x, y, []TableCell{{10, 1, num, "DejaVuSans", "", 8, NOBORDER, LEFT}}) | ||
133 | } | ||
134 | |||
135 | func (pdf *Helper) SuperscriptText(x, y, cw, ch float64, text, script string) { | ||
136 | family, style, size, sizeU := pdf.setCorrectFontFamily(textEncoding(text)) | ||
137 | |||
138 | pdf.DrawCell(x, y, TableCell{cw, ch, text, family, style, size, NOBORDER, LEFT}) | ||
139 | |||
140 | sx := x + pdf.TextLength(text, family, style, size) | ||
141 | sy := y - sizeU*0.2 | ||
142 | pdf.DrawCell(sx, sy, TableCell{cw, ch, script, family, style, size - 2, NOBORDER, LEFT}) | ||
143 | } | ||
144 | |||
145 | // toUTF8 ... | ||
146 | func (pdf *Helper) toUTF8(s string) string { | ||
147 | encoding := textEncoding(s) | ||
148 | pdf.setCorrectFontFamily(encoding) | ||
149 | translator, ok := pdf.translators[encoding] | ||
150 | if !ok { | ||
151 | return "" | ||
152 | } | ||
153 | return translator(s) | ||
195 | } | 154 | } |
196 | 155 | ||
197 | func textEncoding(s string) string { | 156 | func textEncoding(s string) string { |
198 | encoding := latinEncoding | 157 | encoding := latinEncoding |
199 | runes := []rune(s) | 158 | runes := []rune(s) |
200 | for _, r := range runes { | 159 | for _, r := range runes { |
201 | if uint64(r) >= 0x0402 && uint64(r) <= 0x044f { | 160 | if uint64(r) >= 0x0402 && uint64(r) <= 0x044f { |
202 | encoding = cyrillicEncoding | 161 | encoding = cyrillicEncoding |
203 | break | 162 | break |
204 | } | 163 | } |
205 | } | 164 | } |
206 | return encoding | 165 | return encoding |
207 | } | 166 | } |
208 | 167 | ||
209 | // ToUTF8 ... | ||
210 | func (pdf *Helper) ToUTF8(s string) string { | ||
211 | encoding := textEncoding(s) | ||
212 | pdf.setCorrectFontFamily(encoding) | ||
213 | translator, ok := pdf.translators[encoding] | ||
214 | if !ok { | ||
215 | return "" | ||
216 | } | ||
217 | return translator(s) | ||
218 | } | ||
219 | |||
220 | func (pdf *Helper) setCorrectFontFamily(enc string) (family, style string, ptSize, unitSize float64) { | 168 | func (pdf *Helper) setCorrectFontFamily(enc string) (family, style string, ptSize, unitSize float64) { |
221 | family, style, ptSize, unitSize = pdf.GetFontInfo() | 169 | family, style, ptSize, unitSize = pdf.GetFontInfo() |
222 | if enc == cyrillicEncoding { | 170 | if enc == cyrillicEncoding { |
223 | if !strings.HasSuffix(family, "cyrillic") { | 171 | if !strings.HasSuffix(family, "cyrillic") { |
224 | family += "cyrillic" | 172 | family += "cyrillic" |
225 | } | 173 | } |
226 | } else { | 174 | } else { |
227 | if strings.HasSuffix(family, "cyrillic") { | 175 | if strings.HasSuffix(family, "cyrillic") { |
228 | family = strings.TrimSuffix(family, "cyrillic") | 176 | family = strings.TrimSuffix(family, "cyrillic") |
229 | } | 177 | } |
230 | } | 178 | } |
231 | pdf.SetFont(family, style, ptSize) | 179 | pdf.SetFont(family, style, ptSize) |
232 | return family, style, ptSize, unitSize | 180 | return family, style, ptSize, unitSize |
233 | } | 181 | } |
234 | |||
235 | func (pdf *Helper) PageHasSpace(requiredHeight float64) bool { | ||
236 | _, h := pdf.GetPageSize() | ||
237 | _, _, _, bot := pdf.GetMargins() | ||
238 | return (h - bot - pdf.GetY()) > requiredHeight | ||
239 | } | ||
240 | |||
241 | func (pdf *Helper) imageCenterOffset(w, h float64) (x, y float64) { | ||
242 | pageW, pageH := pdf.GetPageSize() | ||
243 | x = pageW/2.0 - w/2.0 |