Skip to content

Commit 15bf072

Browse files
committed
Add support for extra data files
Extra data files replace the previous command line data characters, allowing to specify both data and metadata separately.
1 parent df41788 commit 15bf072

8 files changed

Lines changed: 508 additions & 131 deletions

File tree

build.go

Lines changed: 25 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package main
22

33
import (
4-
"bytes"
5-
"encoding/binary"
64
"errors"
75
"fmt"
86
"image"
@@ -16,21 +14,30 @@ import (
1614

1715
"github.com/fiam/max7456tool/mcm"
1816

19-
"gopkg.in/urfave/cli.v1"
17+
"github.com/urfave/cli/v2"
2018
)
2119

2220
const (
2321
// all pixels = 01
2422
mcmTransparentByte = 85
2523
)
2624

27-
func buildMCM(ctx *cli.Context, chars map[int]*mcm.Char, meta *fontMetadata) error {
28-
if meta != nil {
29-
for k, v := range meta.data {
30-
if _, found := chars[k]; found {
31-
return fmt.Errorf("character %d has both data and metadata", k)
25+
func buildMCM(ctx *cli.Context, chars map[int]*mcm.Char, extra *fontDataSet) error {
26+
if extra != nil {
27+
for k, v := range extra.Values() {
28+
if prev, found := chars[k]; found {
29+
repl, err := v.MergeTo(prev)
30+
if err != nil {
31+
return fmt.Errorf("error merging binary data into existing character %d: %v", k, err)
32+
}
33+
chars[k] = repl
34+
} else {
35+
chr, err := v.Char()
36+
if err != nil {
37+
return fmt.Errorf("error decoding binary character %d: %v", k, err)
38+
}
39+
chars[k] = chr
3240
}
33-
chars[k] = v
3441
}
3542
}
3643
output := ctx.Args().Get(1)
@@ -95,7 +102,7 @@ func parseFilenameCharacterNums(nonExt string, im image.Image) ([]int, error) {
95102
return nums, nil
96103
}
97104

98-
func buildFromDirAction(ctx *cli.Context, dir string, meta *fontMetadata) error {
105+
func buildFromDirAction(ctx *cli.Context, dir string, extra *fontDataSet) error {
99106
entries, err := ioutil.ReadDir(dir)
100107
if err != nil {
101108
return err
@@ -153,14 +160,14 @@ func buildFromDirAction(ctx *cli.Context, dir string, meta *fontMetadata) error
153160
}
154161
}
155162
}
156-
return buildMCM(ctx, chars, meta)
163+
return buildMCM(ctx, chars, extra)
157164
}
158165

159166
type subImager interface {
160167
SubImage(r image.Rectangle) image.Image
161168
}
162169

163-
func buildFromPNGAction(ctx *cli.Context, filename string, meta *fontMetadata) error {
170+
func buildFromPNGAction(ctx *cli.Context, filename string, extra *fontDataSet) error {
164171
cols := ctx.Int("columns")
165172
margin := ctx.Int("margin")
166173
rows := int(math.Ceil(float64(mcm.CharNum) / float64(cols)))
@@ -221,75 +228,7 @@ func buildFromPNGAction(ctx *cli.Context, filename string, meta *fontMetadata) e
221228
}
222229
}
223230
}
224-
return buildMCM(ctx, chars, meta)
225-
}
226-
227-
type fontMetadata struct {
228-
data map[int]*mcm.Char
229-
}
230-
231-
func buildMetadata(metadata string) (*fontMetadata, error) {
232-
meta := &fontMetadata{
233-
data: make(map[int]*mcm.Char),
234-
}
235-
for _, c := range strings.Split(metadata, "-") {
236-
parts := strings.SplitN(c, "=", 2)
237-
ch, err := strconv.Atoi(parts[0])
238-
if err != nil {
239-
return nil, fmt.Errorf("invalid metadata character number %q: %v", parts[0], err)
240-
}
241-
var buf bytes.Buffer
242-
for _, p := range strings.Split(parts[1], ",") {
243-
vparts := strings.SplitN(p, ":", 2)
244-
vtyp := strings.ToLower(vparts[0])
245-
var byteOrder binary.ByteOrder
246-
switch vtyp[0] {
247-
case 'l':
248-
byteOrder = binary.LittleEndian
249-
case 'b':
250-
byteOrder = binary.BigEndian
251-
default:
252-
return nil, fmt.Errorf("unknown endianess %q", string(vtyp[0]))
253-
}
254-
v, err := strconv.ParseInt(vparts[1], 10, 64)
255-
if err != nil {
256-
return nil, fmt.Errorf("invalid value %q: %v", vparts[1], err)
257-
}
258-
var ev interface{}
259-
switch vtyp[1:] {
260-
case "u8":
261-
ev = uint8(v)
262-
case "i8":
263-
ev = int8(v)
264-
case "u16":
265-
ev = uint16(v)
266-
case "i16":
267-
ev = int16(v)
268-
case "u32":
269-
ev = uint32(v)
270-
case "i32":
271-
ev = int32(v)
272-
case "u64":
273-
ev = uint64(v)
274-
case "i64":
275-
ev = int64(v)
276-
default:
277-
return nil, fmt.Errorf("unknown metadata type %q", vtyp[1:])
278-
}
279-
if err := binary.Write(&buf, byteOrder, ev); err != nil {
280-
return nil, err
281-
}
282-
}
283-
for buf.Len() < mcm.CharBytes {
284-
buf.WriteByte(mcmTransparentByte)
285-
}
286-
mcmCh, err := mcm.NewCharFromData(buf.Bytes())
287-
if err != nil {
288-
return nil, err
289-
}
290-
meta.data[ch] = mcmCh
291-
}
292-
return meta, nil
231+
return buildMCM(ctx, chars, extra)
293232
}
294233

295234
func buildAction(ctx *cli.Context) error {
@@ -301,15 +240,14 @@ func buildAction(ctx *cli.Context) error {
301240
if err != nil {
302241
return err
303242
}
304-
var metadata *fontMetadata
305-
if m := ctx.String("metadata"); m != "" {
306-
metadata, err = buildMetadata(m)
307-
if err != nil {
243+
fontData := newFontDataSet()
244+
for _, e := range ctx.StringSlice("extra") {
245+
if err := fontData.ParseFile(e); err != nil {
308246
return err
309247
}
310248
}
311249
if st.IsDir() {
312-
return buildFromDirAction(ctx, input, metadata)
250+
return buildFromDirAction(ctx, input, fontData)
313251
}
314-
return buildFromPNGAction(ctx, input, metadata)
252+
return buildFromPNGAction(ctx, input, fontData)
315253
}

example_data.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# The supported types are:
2+
# s: string
3+
# i8: Signed 8 bits
4+
# u8: Unsigned 8 bits
5+
# li16: Signed 16 bits little endian
6+
# lu16: Unsigned 16 bits little endian
7+
# bi16: Signed 16 bits big endian
8+
# bu16: Unsigned 16 bits big endian
9+
# li32: Signed 32 bits little endian
10+
# lu32: Unsigned 32 bits little endian
11+
# bi32: Signed 32 bits big endian
12+
# bu32: Unsigned 32 bits big endian
13+
# li64: Signed 64 bits little endian
14+
# lu64: Unsigned 64 bits little endian
15+
# bi64: Signed 64 bits big endian
16+
# bu64: Unsigned 64 bits big endian
17+
#
18+
# Some examples:
19+
#
20+
# Add metadata to a character
21+
46:
22+
metadata:
23+
- s: 'o'
24+
- i8: 13
25+
- i8: 3
26+
# Generate 2 entire binary characters
27+
255: &fontmeta
28+
data:
29+
- s: "INAV"
30+
- u8: 1
31+
256: *fontmeta

extract.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99

1010
"github.com/fiam/max7456tool/mcm"
1111

12-
"gopkg.in/urfave/cli.v1"
12+
"github.com/urfave/cli/v2"
1313
)
1414

1515
func extractAction(ctx *cli.Context) error {

0 commit comments

Comments
 (0)