11package main
22
33import (
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
2220const (
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
159166type 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
295234func 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}
0 commit comments