diff --git a/build_lib.sh b/build_lib.sh
index fc737d8..0610081 100755
--- a/build_lib.sh
+++ b/build_lib.sh
@@ -1,7 +1,7 @@
#!/bin/bash
APP_NAME="libgofunc"
-VERSION="${1:-v0.1.5}"
+VERSION="${1:-v0.1.7}"
OUTPUT_DIR="../assets"
BUILD_DIR="../build"
diff --git a/cmd/logo.png b/cmd/logo.png
deleted file mode 100644
index 0568ee9..0000000
Binary files a/cmd/logo.png and /dev/null differ
diff --git a/cmd/main.go b/cmd/main.go
index cd27e83..b151738 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -20,7 +20,7 @@ func Sum(a, b int) int {
func main() {
payload := `{ "sales": [ { "shiftId": "1001", "tran_seq": 1, "salePerson": "John Doe", "timeSec": "1717243200", "timeValue": "2026-06-01 14:30:00", "fpId": 3, "productId": 101, "product": "Diesel Premium", "price": "2500", "volume": "40", "amount": "100000", "discount_amount": "5000", "discount_percent": 5.0, "discount_money": 5000, "rule_types": "LOYALTY,FLEET", "promotion_status": true, "custom_promotion_status": false, "discount_volume": "2", "customerId": 5001, "customer_name": "ABC Logistics Pte Ltd", "vehicle_type": "Truck", "vehicle_type_extension": "10-Wheeler", "carNumber": "SGX1234A", "status": "COMPLETED", "receiptNumber": "RCP-20260601-0001", "receiptCount": 1, "mop": "CARD", "local_used_credit": 100.50, "local_credit_limit": 5000.00, "local_credit_balance": 4899.50, "local_debit_balance": 250.75, "loyalty_type": "GOLD", "points_balance": 12500, "reward_amount": 50.25, "reward_points": 500, "redeem_amount": 25.00, "redeem_points": 250, "redeem_exchange_rate": 0.1, "point_exchange_rate": 10.0, "used_credit": 100.50, "credit_limit": 10000.00, "credit_amount": 100.50, "credit_balance": 9899.50, "debit_amount": 50.25, "debit_balance": 449.75, "payment_customer_id": "PAYCUST001", "payment_customer_name": "ABC Logistics", "payment_customer_number": "+6591234567", "corp_id": "CORP001", "corp_name": "ABC Logistics Group", "card_number": "411111******1111", "upload": true, "upload_status": "SUCCESS", "send_sale_data_confirm": true, "loan_amount": 1000, "tax_percent": 9.0, "tax_status": true, "tier": 2, "dealNumber": "DL-20260601-001", "bank_name": "DBS", "bank_payment_type": "VISA", "session_id": "sess_abc123xyz", "tran_id": "txn_987654321", "qrcode_data": "SGQR|PAYNOW|ABCLOGISTICS", "fp_total": 8, "missed_sale_status": false, "opo_status": true, "ip_printer_status": true, "sale_type": "NORMAL" }, { "shiftId": "1001", "tran_seq": 1, "salePerson": "John Doe", "timeSec": "1717243200", "timeValue": "2026-06-01 14:30:00", "fpId": 3, "productId": 101, "product": "Diesel Premium", "price": "2500", "volume": "40", "amount": "100000", "discount_amount": "5000", "discount_percent": 5.0, "discount_money": 5000, "rule_types": "LOYALTY,FLEET", "promotion_status": true, "custom_promotion_status": false, "discount_volume": "2", "customerId": 5001, "customer_name": "ABC Logistics Pte Ltd", "vehicle_type": "Truck", "vehicle_type_extension": "10-Wheeler", "carNumber": "SGX1234A", "status": "COMPLETED", "receiptNumber": "RCP-20260601-0001", "receiptCount": 1, "mop": "CARD", "local_used_credit": 100.50, "local_credit_limit": 5000.00, "local_credit_balance": 4899.50, "local_debit_balance": 250.75, "loyalty_type": "GOLD", "points_balance": 12500, "reward_amount": 50.25, "reward_points": 500, "redeem_amount": 25.00, "redeem_points": 250, "redeem_exchange_rate": 0.1, "point_exchange_rate": 10.0, "used_credit": 100.50, "credit_limit": 10000.00, "credit_amount": 100.50, "credit_balance": 9899.50, "debit_amount": 50.25, "debit_balance": 449.75, "payment_customer_id": "PAYCUST001", "payment_customer_name": "ABC Logistics", "payment_customer_number": "+6591234567", "corp_id": "CORP001", "corp_name": "ABC Logistics Group", "card_number": "411111******1111", "upload": true, "upload_status": "SUCCESS", "send_sale_data_confirm": true, "loan_amount": 1000, "tax_percent": 9.0, "tax_status": true, "tier": 2, "dealNumber": "DL-20260601-001", "bank_name": "DBS", "bank_payment_type": "VISA", "session_id": "sess_abc123xyz", "tran_id": "txn_987654321", "qrcode_data": "SGQR|PAYNOW|ABCLOGISTICS", "fp_total": 8, "missed_sale_status": false, "opo_status": true, "ip_printer_status": true, "sale_type": "NORMAL" } ], "station": { "id": "1", "name": "Jurong Fuel Station", "address": "123 Boon Lay Way, Singapore 640123", "phones": "+65 6123 4567,+65 6987 6543", "code": "STN001", "money_divider": 100, "volume_divider": 1000, "check_tran_duration": 60, "fho_server_offline_duration": 300, "loyalty_backlog_duration": 1440, "token": "station-secret-token-123", "monthly_view": true, "pump_status": true, "currency": "SGD", "tank_manual_status": false, "update_price_type": "AUTO", "show_price_history": true, "old_receipt_status": false, "car_number_modification_status": true, "car_number_entry_status": 2, "shop_code": "SHOP001" }}`
const temp = `
-
+
Address: မင်္ဂလာပါ {{(index .sales 0).salePerson}}
@@ -58,7 +58,7 @@ func main() {စက်သုံးဆီ အရေအတွက် နှင့် အရည်အသွေးစျေးနှုန်းများ အားသံသယရှိပါက ph 09450539099, 09765421033, 09765421029 သို့တိုင်ကြား နိုင်ပါသည်။
` - result := libgofunc.GenImg(550, "./out.png", payload, temp) + result := libgofunc.GenImg(550, "./out.png", payload, temp, "./") fmt.Println("Result:", result) // PrintImg(C.CString("usb:/dev/usb/lp1"), C.CString("build/out.png")) // libgofunc.Print("int:/dev/bus/usb/001/046", "./out.png") diff --git a/img.go b/img.go index d366bb5..40689a5 100644 --- a/img.go +++ b/img.go @@ -26,6 +26,7 @@ import ( ) import ( "log" + "path" "strconv" "golang.org/x/text/language" @@ -46,11 +47,12 @@ const ( var fontFs embed.FS //export GenPNG -func GenPNG(width C.int, outputPath *C.char, payload *C.char, tmpl *C.char) *C.char { +func GenPNG(width C.int, outputPath *C.char, payload *C.char, tmpl *C.char, workingDirC *C.char) *C.char { canvasWidth := int(width) goPath := C.GoString(outputPath) goPayload := C.GoString(payload) goTmpl := C.GoString(tmpl) + workingDir := C.GoString(workingDirC) data := make(map[string]interface{}) err := json.Unmarshal([]byte(goPayload), &data) @@ -91,7 +93,10 @@ func GenPNG(width C.int, outputPath *C.char, payload *C.char, tmpl *C.char) *C.c dc.SetFontFace(*face) y := 0 - renderNode(dc, canvasWidth, body, &y, *face) + err = renderNode(dc, canvasWidth, body, &y, *face, workingDir) + if err != nil { + return NewErr(err) + } err = dc.SavePNG(goPath) if err != nil { @@ -102,8 +107,8 @@ func GenPNG(width C.int, outputPath *C.char, payload *C.char, tmpl *C.char) *C.c return NewOk(nil) } -func GenImg(width int, outputPath, payload, tmpl string) string { - result := GenPNG(C.int(width), C.CString(outputPath), C.CString(payload), C.CString(tmpl)) +func GenImg(width int, outputPath, payload, tmpl, workingDir string) string { + result := GenPNG(C.int(width), C.CString(outputPath), C.CString(payload), C.CString(tmpl), C.CString(workingDir)) r := C.GoString(result) return r } @@ -125,7 +130,7 @@ func renderTemplate(tmp string, data map[string]interface{}) (string, error) { return buf.String(), nil } -func renderNode(dc *gg.Context, canvasWidth int, n *Node, y *int, face font.Face) { +func renderNode(dc *gg.Context, canvasWidth int, n *Node, y *int, face font.Face, workingDir string) error { before := *y if n.Style.PaddingTop > 0 { *y += int(n.Style.PaddingTop) @@ -146,7 +151,9 @@ func renderNode(dc *gg.Context, canvasWidth int, n *Node, y *int, face font.Face case "hr": renderLine(dc, n, canvasWidth, y) case "img": - drawImage(dc, n, y) + if err := drawImage(dc, n, y, workingDir); err != nil { + return err + } case "table": renderTable(dc, canvasWidth, n, y, face) } @@ -156,8 +163,9 @@ func renderNode(dc *gg.Context, canvasWidth int, n *Node, y *int, face font.Face log.Printf("render %s y, y', height: %d, %d, %d\n", n.Tag, before, *y, *y-before) for _, c := range n.Children { - renderNode(dc, canvasWidth, c, y, face) + renderNode(dc, canvasWidth, c, y, face, workingDir) } + return nil } func drawTextBlock(dc *gg.Context, n *Node, canvasWidth int, size float64, y *int, face font.Face) { @@ -194,14 +202,18 @@ func wordWrap(dc *gg.Context, text string, maxWidth int) []string { return lines } -func drawImage(dc *gg.Context, n *Node, y *int) { +func drawImage(dc *gg.Context, n *Node, y *int, workingDir string) error { src := n.getSrc() - file, err := os.Open(src) + s := path.Join(workingDir, src) + file, err := os.Open(s) if err != nil { - return + return fmt.Errorf("open file src: '%s', working directory: '%s', error : %s", src, workingDir, err.Error()) } defer file.Close() - img, _, _ := image.Decode(file) + img, _, err := image.Decode(file) + if err != nil { + return err + } padding := n.Style.PaddingLeft h := n.Style.Height if n.Style.Width > 0 { @@ -224,6 +236,7 @@ func drawImage(dc *gg.Context, n *Node, y *int) { dc.DrawImage(img, int(padding), *y) *y += img.Bounds().Dy() } + return nil } func renderTable(dc *gg.Context, canvasWidth int, table *Node, y *int, face font.Face) {