From ea45784554bb02a107b6fdbcd8a352ff1197e08f Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Sun, 14 Apr 2019 21:25:21 +0200 Subject: sklad: import label printing capability from label-tool --- label-tool/main.go | 52 ++++++-------------------------------------------- sklad/db.go | 21 ++++++++++++++++++++ sklad/label.tmpl | 13 +++++++++++++ sklad/main.go | 56 +++++++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 91 insertions(+), 51 deletions(-) create mode 100644 sklad/label.tmpl diff --git a/label-tool/main.go b/label-tool/main.go index 1d25b1b..b085bf8 100644 --- a/label-tool/main.go +++ b/label-tool/main.go @@ -4,60 +4,20 @@ import ( "errors" "html/template" "image" - "image/draw" "image/png" "log" "net/http" "os" "strconv" - "github.com/boombuler/barcode" - "github.com/boombuler/barcode/qr" - "janouch.name/sklad/bdf" "janouch.name/sklad/imgutil" + "janouch.name/sklad/label" "janouch.name/sklad/ql" ) var font *bdf.Font -func genLabelForHeight(text string, height, scale int) image.Image { - // Create a scaled bitmap of the text label. - textRect, _ := font.BoundString(text) - textImg := image.NewRGBA(textRect) - draw.Draw(textImg, textRect, image.White, image.ZP, draw.Src) - font.DrawString(textImg, image.ZP, text) - - scaledTextImg := imgutil.Scale{Image: textImg, Scale: scale} - scaledTextRect := scaledTextImg.Bounds() - - remains := height - scaledTextRect.Dy() - 20 - - width := scaledTextRect.Dx() - if remains > width { - width = remains - } - - // Create a scaled bitmap of the QR code. - qrImg, _ := qr.Encode(text, qr.H, qr.Auto) - qrImg, _ = barcode.Scale(qrImg, remains, remains) - qrRect := qrImg.Bounds() - - // Combine. - combinedRect := image.Rect(0, 0, width, height) - combinedImg := image.NewRGBA(combinedRect) - draw.Draw(combinedImg, combinedRect, image.White, image.ZP, draw.Src) - draw.Draw(combinedImg, - combinedRect.Add(image.Point{X: (width - qrRect.Dx()) / 2, Y: 0}), - qrImg, image.ZP, draw.Src) - - target := image.Rect( - (width-scaledTextRect.Dx())/2, qrRect.Dy()+20, - combinedRect.Max.X, combinedRect.Max.Y) - draw.Draw(combinedImg, target, &scaledTextImg, scaledTextRect.Min, draw.Src) - return combinedImg -} - var tmpl = template.Must(template.New("form").Parse(` @@ -183,12 +143,12 @@ func handle(w http.ResponseWriter, r *http.Request) { params.Scale = 3 } - var label image.Image + var img image.Image if mediaInfo != nil { - label = &imgutil.LeftRotate{Image: genLabelForHeight( - params.Text, mediaInfo.PrintAreaPins, params.Scale)} + img = &imgutil.LeftRotate{Image: label.GenLabelForHeight( + font, params.Text, mediaInfo.PrintAreaPins, params.Scale)} if r.FormValue("print") != "" { - if err := printer.Print(label); err != nil { + if err := printer.Print(img); err != nil { log.Println("print error:", err) } } @@ -206,7 +166,7 @@ func handle(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "image/png") - if err := png.Encode(w, label); err != nil { + if err := png.Encode(w, img); err != nil { http.Error(w, err.Error(), 500) return } diff --git a/sklad/db.go b/sklad/db.go index aae695f..def18a5 100644 --- a/sklad/db.go +++ b/sklad/db.go @@ -7,6 +7,8 @@ import ( "os" "strings" "time" + + "janouch.name/sklad/bdf" ) type Series struct { @@ -46,6 +48,9 @@ type Database struct { Prefix string // prefix for all container IDs Series []*Series // all known series Containers []*Container // all known containers + + BDFPath string // path to bitmap font file + BDFScale int // integer scaling for the bitmap font } var ( @@ -57,6 +62,8 @@ var ( indexSeries = map[string]*Series{} indexContainer = map[ContainerId]*Container{} indexChildren = map[ContainerId][]*Container{} + + labelFont *bdf.Font ) // TODO: Some functions to add, remove and change things in the database. @@ -192,6 +199,20 @@ func loadDatabase() error { } } + // Prepare label printing. + if db.BDFScale <= 0 { + db.BDFScale = 1 + } + + if f, err := os.Open(db.BDFPath); err != nil { + return fmt.Errorf("cannot load label font: %s", err) + } else { + defer f.Close() + if labelFont, err = bdf.NewFromBDF(f); err != nil { + return fmt.Errorf("cannot load label font: %s", err) + } + } + // Open database log file for appending. if dbLog, err = os.OpenFile(dbPath+".log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err != nil { diff --git a/sklad/label.tmpl b/sklad/label.tmpl new file mode 100644 index 0000000..da17c58 --- /dev/null +++ b/sklad/label.tmpl @@ -0,0 +1,13 @@ +{{ define "Title" }}Tisk štítku{{ end }} +{{ define "Content" }} +

Tisk štítku pro {{ .Id }}

+ +{{ if .UnknownId }} +

Neznámý obal. +{{ else if .Error }} +

Tisk selhal: {{ .Error }} +{{ else }} +

Tisk proběhl úspěšně. +{{ end }} + +{{ end }} diff --git a/sklad/main.go b/sklad/main.go index 9df1fd5..9a7be68 100644 --- a/sklad/main.go +++ b/sklad/main.go @@ -1,6 +1,7 @@ package main import ( + "errors" "html/template" "io" "log" @@ -9,6 +10,10 @@ import ( "os" "path/filepath" "time" + + "janouch.name/sklad/imgutil" + "janouch.name/sklad/label" + "janouch.name/sklad/ql" ) var templates = map[string]*template.Template{} @@ -170,18 +175,59 @@ func handleSearch(w http.ResponseWriter, r *http.Request) { executeTemplate("search.tmpl", w, ¶ms) } +func printLabel(id string) error { + printer, err := ql.Open() + if err != nil { + return err + } + if printer == nil { + return errors.New("no suitable printer found") + } + defer printer.Close() + + printer.StatusNotify = func(status *ql.Status) { + log.Printf("\x1b[1mreceived status\x1b[m\n%+v\n%s", + status[:], status) + } + + if err := printer.Initialize(); err != nil { + return err + } + if err := printer.UpdateStatus(); err != nil { + return err + } + + mediaInfo := ql.GetMediaInfo( + printer.LastStatus.MediaWidthMM(), + printer.LastStatus.MediaLengthMM(), + ) + if mediaInfo == nil { + return errors.New("unknown media") + } + + return printer.Print(&imgutil.LeftRotate{Image: label.GenLabelForHeight( + labelFont, id, mediaInfo.PrintAreaPins, db.BDFScale)}) +} + func handleLabel(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } - id := r.FormValue("id") - _ = id - - // TODO: See if such a container exists, print a label on the printer. + params := struct { + Id string + UnknownId bool + Error error + }{ + Id: r.FormValue("id"), + } - params := struct{}{} + if c := indexContainer[ContainerId(params.Id)]; c == nil { + params.UnknownId = true + } else { + params.Error = printLabel(params.Id) + } executeTemplate("label.tmpl", w, ¶ms) } -- cgit v1.2.3-70-g09d2