Ejemplo n.º 1
0
func ExampleParseFont() {
	readFile := func(name string) ([]byte, error) {
		return ioutil.ReadFile(filepath.FromSlash(path.Join("../testdata/fixed", name)))
	}
	fontData, err := readFile("unicode.7x13.font")
	if err != nil {
		log.Fatal(err)
	}
	face, err := plan9font.ParseFont(fontData, readFile)
	if err != nil {
		log.Fatal(err)
	}
	// TODO: derive the ascent from the face's metrics.
	const ascent = 11

	dst := image.NewRGBA(image.Rect(0, 0, 4*7, 13))
	draw.Draw(dst, dst.Bounds(), image.Black, image.Point{}, draw.Src)
	d := &font.Drawer{
		Dst:  dst,
		Src:  image.White,
		Face: face,
		Dot:  fixed.P(0, ascent),
	}
	// Draw:
	// 	- U+0053 LATIN CAPITAL LETTER S
	//	- U+03A3 GREEK CAPITAL LETTER SIGMA
	//	- U+222B INTEGRAL
	//	- U+3055 HIRAGANA LETTER SA
	// The testdata does not contain the CJK subfont files, so U+3055 HIRAGANA
	// LETTER SA (さ) should be rendered as U+FFFD REPLACEMENT CHARACTER (�).
	//
	// The missing subfont file will trigger an "open
	// ../testdata/shinonome/k12.3000: no such file or directory" log message.
	// This is expected and can be ignored.
	d.DrawString("SΣ∫さ")

	// Convert the dst image to ASCII art.
	var out []byte
	b := dst.Bounds()
	for y := b.Min.Y; y < b.Max.Y; y++ {
		out = append(out, '0'+byte(y%10), ' ')
		for x := b.Min.X; x < b.Max.X; x++ {
			if dst.RGBAAt(x, y).R > 0 {
				out = append(out, 'X')
			} else {
				out = append(out, '.')
			}
		}
		// Highlight the last row before the baseline. Glyphs like 'S' without
		// descenders should not affect any pixels whose Y coordinate is >= the
		// baseline.
		if y == ascent-1 {
			out = append(out, '_')
		}
		out = append(out, '\n')
	}
	os.Stdout.Write(out)

	// Output:
	// 0 ..................X.........
	// 1 .................X.X........
	// 2 .XXXX..XXXXXX....X.....XXX..
	// 3 X....X.X.........X....XX.XX.
	// 4 X.......X........X....X.X.X.
	// 5 X........X.......X....XXX.X.
	// 6 .XXXX.....X......X....XX.XX.
	// 7 .....X...X.......X....XX.XX.
	// 8 .....X..X........X....XXXXX.
	// 9 X....X.X.........X....XX.XX.
	// 0 .XXXX..XXXXXX....X.....XXX.._
	// 1 ...............X.X..........
	// 2 ................X...........
}
Ejemplo n.º 2
0
func main() {
	flag.Parse()

	// TODO: mmap the files.
	if *fontFlag == "" {
		flag.Usage()
		log.Fatal("no font specified")
	}
	var face font.Face
	if strings.HasSuffix(*fontFlag, ".font") {
		fontData, err := ioutil.ReadFile(*fontFlag)
		if err != nil {
			log.Fatal(err)
		}
		dir := filepath.Dir(*fontFlag)
		face, err = plan9font.ParseFont(fontData, func(name string) ([]byte, error) {
			return ioutil.ReadFile(filepath.Join(dir, filepath.FromSlash(name)))
		})
		if err != nil {
			log.Fatal(err)
		}
	} else {
		fontData, err := ioutil.ReadFile(*fontFlag)
		if err != nil {
			log.Fatal(err)
		}
		face, err = plan9font.ParseSubfont(fontData, rune(*firstRuneFlag))
		if err != nil {
			log.Fatal(err)
		}
	}

	dst := image.NewRGBA(image.Rect(0, 0, 800, 300))
	draw.Draw(dst, dst.Bounds(), image.Black, image.Point{}, draw.Src)

	d := &font.Drawer{
		Dst:  dst,
		Src:  image.White,
		Face: face,
	}
	ss := []string{
		"The quick brown fox jumps over the lazy dog.",
		"Hello, 世界.",
		"U+FFFD is \ufffd.",
	}
	for i, s := range ss {
		d.Dot = fixed.P(20, 100*i+80)
		dot0 := pt(d.Dot)
		d.DrawString(s)
		dot1 := pt(d.Dot)
		dst.SetRGBA(dot0.X, dot0.Y, color.RGBA{0xff, 0x00, 0x00, 0xff})
		dst.SetRGBA(dot1.X, dot1.Y, color.RGBA{0x00, 0x00, 0xff, 0xff})
	}

	out, err := os.Create("out.png")
	if err != nil {
		log.Fatal(err)
	}
	defer out.Close()
	if err := png.Encode(out, dst); err != nil {
		log.Fatal(err)
	}
}
Ejemplo n.º 3
0
func main() {
	// nGlyphs is the number of glyphs to generate: 95 characters in the range
	// [0x20, 0x7e], plus the replacement character.
	const nGlyphs = 95 + 1
	// The particular font (unicode.7x13.font) leaves the right-most column
	// empty in its ASCII glyphs. We don't have to include that column in the
	// generated glyphs, so we subtract one off the effective width.
	const width, height, ascent = 7 - 1, 13, 11

	readFile := func(name string) ([]byte, error) {
		return ioutil.ReadFile(filepath.FromSlash(path.Join("../testdata/fixed", name)))
	}
	fontData, err := readFile("unicode.7x13.font")
	if err != nil {
		log.Fatalf("readFile: %v", err)
	}
	face, err := plan9font.ParseFont(fontData, readFile)
	if err != nil {
		log.Fatalf("plan9font.ParseFont: %v", err)
	}

	dst := image.NewRGBA(image.Rect(0, 0, width, nGlyphs*height))
	draw.Draw(dst, dst.Bounds(), image.Black, image.Point{}, draw.Src)
	d := &font.Drawer{
		Dst:  dst,
		Src:  image.White,
		Face: face,
	}
	for i := 0; i < nGlyphs; i++ {
		r := '\ufffd'
		if i < nGlyphs-1 {
			r = 0x20 + rune(i)
		}
		d.Dot = fixed.P(0, height*i+ascent)
		d.DrawString(string(r))
	}

	w := bytes.NewBuffer(nil)
	w.WriteString(preamble)
	fmt.Fprintf(w, "// mask7x13 contains %d %d×%d glyphs in %d Pix bytes.\n", nGlyphs, width, height, nGlyphs*width*height)
	fmt.Fprintf(w, "var mask7x13 = &image.Alpha{\n")
	fmt.Fprintf(w, "  Stride: %d,\n", width)
	fmt.Fprintf(w, "  Rect: image.Rectangle{Max: image.Point{%d, %d*%d}},\n", width, nGlyphs, height)
	fmt.Fprintf(w, "  Pix: []byte{\n")
	b := dst.Bounds()
	for y := b.Min.Y; y < b.Max.Y; y++ {
		if y%height == 0 {
			if y != 0 {
				w.WriteByte('\n')
			}
			i := y / height
			if i < nGlyphs-1 {
				i += 0x20
				fmt.Fprintf(w, "// %#2x %q\n", i, rune(i))
			} else {
				fmt.Fprintf(w, "// U+FFFD REPLACEMENT CHARACTER\n")
			}
		}

		for x := b.Min.X; x < b.Max.X; x++ {
			if dst.RGBAAt(x, y).R > 0 {
				w.WriteString("0xff,")
			} else {
				w.WriteString("0x00,")
			}
		}
		w.WriteByte('\n')
	}
	w.WriteString("},\n}\n")

	fmted, err := format.Source(w.Bytes())
	if err != nil {
		log.Fatalf("format.Source: %v", err)
	}
	if err := ioutil.WriteFile("data.go", fmted, 0644); err != nil {
		log.Fatalf("ioutil.WriteFile: %v", err)
	}
}