|
8 | 8 | "image" |
9 | 9 | "image/png" |
10 | 10 | "io/ioutil" |
| 11 | + "math" |
11 | 12 | "math/rand" |
12 | 13 | "net" |
13 | 14 | "net/http" |
@@ -147,33 +148,75 @@ func print(db database.Database, printer printing.PossiblePrinter, html string) |
147 | 148 | renderCache.SetDefault(tempId, finalHtml) |
148 | 149 |
|
149 | 150 | // Render the html to image |
150 | | - image, err := rendering.RenderURL(fmt.Sprintf("http://127.0.0.1:7123/api/html/%s", tempId), settings.PrinterWidth) |
| 151 | + renderedImage, err := rendering.RenderURL(fmt.Sprintf("http://127.0.0.1:7123/api/html/%s", tempId), settings.PrinterWidth) |
151 | 152 | if err != nil { |
152 | 153 | return fmt.Errorf("html to image rendering failed: %w", err) |
153 | 154 | } |
154 | 155 |
|
155 | | - // Print |
156 | | - buf := &bytes.Buffer{} |
| 156 | + imageRgb := renderedImage.(*image.RGBA) |
| 157 | + height := imageRgb.Bounds().Max.Y |
| 158 | + width := imageRgb.Bounds().Max.X |
157 | 159 |
|
158 | | - if settings.Commands.ExplicitInit { |
159 | | - epson.InitPrinter(buf) |
160 | | - } |
| 160 | + var images []image.Image |
| 161 | + if settings.Commands.SplitPrinting && height > settings.Commands.SplitHeight { |
| 162 | + if settings.Commands.SplitHeight < 100 { |
| 163 | + return fmt.Errorf("please use a split height of at least 100") |
| 164 | + } |
161 | 165 |
|
162 | | - if settings.Commands.ForceStandardMode { |
163 | | - epson.SetStandardMode(buf) |
164 | | - } |
| 166 | + chunks := int(math.Ceil(float64(height) / float64(settings.Commands.SplitHeight))) |
165 | 167 |
|
166 | | - buf.WriteString(strings.Repeat("\n", settings.Commands.LinesBefore)) |
167 | | - epson.Image(buf, image) |
168 | | - buf.WriteString(strings.Repeat("\n", 5+settings.Commands.LinesAfter)) |
| 168 | + // Chunk the images |
| 169 | + for i := 0; i < chunks; i++ { |
| 170 | + y1 := i * settings.Commands.SplitHeight |
| 171 | + y2 := y1 + settings.Commands.SplitHeight |
| 172 | + if y2 > height { |
| 173 | + y2 = height |
| 174 | + } |
169 | 175 |
|
170 | | - if settings.Commands.Cut { |
171 | | - epson.CutPaper(buf) |
| 176 | + images = append(images, imageRgb.SubImage(image.Rect(0, y1, width, y2))) |
| 177 | + } |
| 178 | + } else { |
| 179 | + images = []image.Image{renderedImage} |
172 | 180 | } |
173 | 181 |
|
174 | | - err = selectedPrinter.Print(settings.PrinterEndpoint, image, buf.Bytes()) |
175 | | - if err != nil { |
176 | | - return fmt.Errorf("printer wasn't able to print: %w", err) |
| 182 | + // Print |
| 183 | + for i, img := range images { |
| 184 | + buf := &bytes.Buffer{} |
| 185 | + |
| 186 | + // At the first chunk set modes and lines |
| 187 | + if i == 0 { |
| 188 | + if settings.Commands.ExplicitInit { |
| 189 | + epson.InitPrinter(buf) |
| 190 | + } |
| 191 | + |
| 192 | + if settings.Commands.ForceStandardMode { |
| 193 | + epson.SetStandardMode(buf) |
| 194 | + } |
| 195 | + |
| 196 | + buf.WriteString(strings.Repeat("\n", settings.Commands.LinesBefore)) |
| 197 | + } |
| 198 | + |
| 199 | + epson.Image(buf, img) |
| 200 | + |
| 201 | + // At the last chunk insert lines and cut |
| 202 | + if i == len(images)-1 { |
| 203 | + buf.WriteString(strings.Repeat("\n", 5+settings.Commands.LinesAfter)) |
| 204 | + |
| 205 | + if settings.Commands.Cut { |
| 206 | + epson.CutPaper(buf) |
| 207 | + } |
| 208 | + } |
| 209 | + |
| 210 | + // Print chunk |
| 211 | + err = selectedPrinter.Print(settings.PrinterEndpoint, renderedImage, buf.Bytes()) |
| 212 | + if err != nil { |
| 213 | + return fmt.Errorf("printer wasn't able to print: %w", err) |
| 214 | + } |
| 215 | + |
| 216 | + // Add delay to consecutive prints |
| 217 | + if len(images) > 1 && settings.Commands.SplitDelay > 0 { |
| 218 | + time.Sleep(time.Millisecond * time.Duration(settings.Commands.SplitDelay)) |
| 219 | + } |
177 | 220 | } |
178 | 221 |
|
179 | 222 | return nil |
|
0 commit comments