// Copyright ©2021 The star-tex Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE-STAR-TEX file. package pkf import ( "fmt" "io" ) // Bitmap displays the rune c as an ASCII bitmap to the provided writer. func (fnt *Font) Bitmap(o io.Writer, c rune, h, w int) error { const raw = false return fnt.displayGlyph(o, c, h, w, raw, func(w io.Writer, u uint8, n int) { bit := uint8(1 << 7) for ; n > 0; n-- { switch { case u&bit != 0: fmt.Fprintf(w, "*") default: fmt.Fprintf(w, ".") } bit >>= 1 } }) } // Hexmap displays the rune c as an ASCII hexmap to the provided writer. func (fnt *Font) Hexmap(o io.Writer, c rune, h, w int) error { const raw = false return fnt.displayGlyph(o, c, h, w, raw, func(w io.Writer, v uint8, n int) { fmt.Fprintf(w, "%02x", v) }) } // Rawmap displays the rune c as an ASCII rawmap to the provided writer. func (fnt *Font) Rawmap(o io.Writer, c rune, h, w int) error { const raw = true return fnt.displayGlyph(o, c, h, w, raw, func(w io.Writer, v uint8, n int) { fmt.Fprintf(w, "0x%02x, ", lsbf(v)) }) } func (fnt *Font) displayGlyph(o io.Writer, c rune, h, w int, raw bool, fun func(w io.Writer, u uint8, n int)) error { var g *Glyph for i := range fnt.glyphs { if fnt.glyphs[i].code == uint32(c) { g = &fnt.glyphs[i] g.unpack() break } } if g == nil { return fmt.Errorf("could not find glyph 0x%x", c) } var ( H, dh int W, dw int ) H = int(g.height) if h == 0 { h = H } dh = (h - H) / 2 W = int(g.width) if w == 0 { w = W } dw = (w - W) / 2 fmt.Fprintf(o, "\n") switch { case raw: fmt.Fprintf(o, "#define %s_%c_width \t %d\n", "fname", g.code, w) fmt.Fprintf(o, "#define %s_%c_height \t %d\n", "fname", g.code, h) fmt.Fprintf(o, "#define %s_%c_xoff \t %d\n", "fname", g.code, dw) fmt.Fprintf(o, "#define %s_%c_yoff \t %d\n", "fname", g.code, dh) fmt.Fprintf(o, "static char %s_%c_bits[] = {", "fname", g.code) default: fmt.Fprintf(o, "character : %d (%c)\n", g.code, g.code) fmt.Fprintf(o, " height : %d\n", g.height) fmt.Fprintf(o, " width : %d\n", g.width) fmt.Fprintf(o, " xoff : %d\n", g.xoff) fmt.Fprintf(o, " yoff : %d\n", g.yoff) } for row := 0; row < h-H-dh; row++ { fmt.Fprintf(o, "\n ") for col := 0; col < w; col += 8 { n := clip(w-col, 8) fun(o, 0, n) } } var i int for row := 0; row < int(g.height); row++ { fmt.Fprintf(o, "\n ") for col := 0; col < int(g.width); col += 8 { v := g.mask[i] n := clip(int(g.width)-col, 8) fun(o, v, n) i++ } } for row := h - dh; row < h; row++ { fmt.Fprintf(o, "\n ") for col := 0; col < w; col += 8 { n := clip(w-col, 8) fun(o, 0, n) } } switch { case raw: fmt.Fprintf(o, "};\n") default: fmt.Fprintf(o, "\n") } return nil } func clip(v, max int) int { if v >= max { return max } return v } func lsbf(u uint8) uint8 { var ( bit, o uint8 ) for i := 0; i < 8; i++ { bit = u & 0o1 o = (o << 1) | bit u = u >> 1 } return o }