9fans.net/go@v0.0.5/draw/getsubfont.go (about)

     1  package draw
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"log"
     8  	"os"
     9  	"strings"
    10  )
    11  
    12  func getsubfont(d *Display, name string) (*subfont, error) {
    13  	scale, fname := parsefontscale(name)
    14  	data, err := ioutil.ReadFile(fname)
    15  	if err != nil && strings.HasPrefix(fname, "/mnt/font/") {
    16  		data1, err1 := fontPipe(fname[len("/mnt/font/"):])
    17  		if err1 == nil {
    18  			data, err = data1, err1
    19  		}
    20  	}
    21  	if err != nil {
    22  		fmt.Fprintf(os.Stderr, "getsubfont: %v\n", err)
    23  		return nil, err
    24  	}
    25  	f, err := d.readSubfont(name, bytes.NewReader(data), nil)
    26  	if err != nil {
    27  		fmt.Fprintf(os.Stderr, "getsubfont: can't read %s: %v\n", fname, err)
    28  	}
    29  	if scale > 1 {
    30  		scalesubfont(f, scale)
    31  	}
    32  	return f, err
    33  }
    34  
    35  func scalesubfont(f *subfont, scale int) {
    36  	r := f.Bits.R
    37  	r2 := r
    38  	r2.Min.X *= scale
    39  	r2.Min.Y *= scale
    40  	r2.Max.X *= scale
    41  	r2.Max.Y *= scale
    42  
    43  	srcn := BytesPerLine(r, f.Bits.Depth)
    44  	src := make([]byte, srcn)
    45  	dstn := BytesPerLine(r2, f.Bits.Depth)
    46  	dst := make([]byte, dstn)
    47  	i, err := allocImage(f.Bits.Display, nil, r2, f.Bits.Pix, false, Black, 0, 0)
    48  	if err != nil {
    49  		log.Fatalf("allocimage: %v", err)
    50  	}
    51  	for y := r.Min.Y; y < r.Max.Y; y++ {
    52  		_, err := f.Bits.unload(Rect(r.Min.X, y, r.Max.X, y+1), src)
    53  		if err != nil {
    54  			log.Fatalf("unloadimage: %v", err)
    55  		}
    56  		for i := range dst {
    57  			dst[i] = 0
    58  		}
    59  		pack := 8 / f.Bits.Depth
    60  		mask := byte(1<<uint(f.Bits.Depth) - 1)
    61  		for x := 0; x < r.Dx(); x++ {
    62  			v := ((src[x/pack] << uint((x%pack)*f.Bits.Depth)) >> uint(8-f.Bits.Depth)) & mask
    63  			for j := 0; j < scale; j++ {
    64  				x2 := x*scale + j
    65  				dst[x2/pack] |= v << uint(8-f.Bits.Depth) >> uint((x2%pack)*f.Bits.Depth)
    66  			}
    67  		}
    68  		for j := 0; j < scale; j++ {
    69  			i.load(Rect(r2.Min.X, y*scale+j, r2.Max.X, y*scale+j+1), dst)
    70  		}
    71  	}
    72  	f.Bits.free()
    73  	f.Bits = i
    74  	f.Height *= scale
    75  	f.Ascent *= scale
    76  
    77  	for j := 0; j < f.N; j++ {
    78  		p := &f.Info[j]
    79  		p.X *= scale
    80  		p.Top *= uint8(scale)
    81  		p.Bottom *= uint8(scale)
    82  		p.Left *= int8(scale)
    83  		p.Width *= uint8(scale)
    84  	}
    85  }