Пример #1
0
func BenchmarkDrawString(b *testing.B) {
	data, err := ioutil.ReadFile("../licenses/gpl.txt")
	if err != nil {
		b.Fatal(err)
	}
	lines := strings.Split(string(data), "\n")
	data, err = ioutil.ReadFile("../testdata/luxisr.ttf")
	if err != nil {
		b.Fatal(err)
	}
	f, err := Parse(data)
	if err != nil {
		b.Fatal(err)
	}
	dst := image.NewRGBA(image.Rect(0, 0, 800, 600))
	draw.Draw(dst, dst.Bounds(), image.White, image.ZP, draw.Src)
	d := &font.Drawer{
		Dst:  dst,
		Src:  image.Black,
		Face: NewFace(f, nil),
	}
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		for j, line := range lines {
			d.Dot = fixed.P(0, (j*16)%600)
			d.DrawString(line)
		}
	}
}
Пример #2
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)
	}
}
Пример #3
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...........
}
Пример #4
0
func main() {
	flag.Parse()

	// Read the font data.
	fontBytes, err := ioutil.ReadFile(*fontfile)
	if err != nil {
		log.Println(err)
		return
	}
	f, err := truetype.Parse(fontBytes)
	if err != nil {
		log.Println(err)
		return
	}

	// Draw the background and the guidelines.
	fg, bg := image.Black, image.White
	ruler := color.RGBA{0xdd, 0xdd, 0xdd, 0xff}
	if *wonb {
		fg, bg = image.White, image.Black
		ruler = color.RGBA{0x22, 0x22, 0x22, 0xff}
	}
	const imgW, imgH = 640, 480
	rgba := image.NewRGBA(image.Rect(0, 0, imgW, imgH))
	draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
	for i := 0; i < 200; i++ {
		rgba.Set(10, 10+i, ruler)
		rgba.Set(10+i, 10, ruler)
	}

	// Draw the text.
	h := font.HintingNone
	switch *hinting {
	case "full":
		h = font.HintingFull
	}
	d := &font.Drawer{
		Dst: rgba,
		Src: fg,
		Face: truetype.NewFace(f, &truetype.Options{
			Size:    *size,
			DPI:     *dpi,
			Hinting: h,
		}),
	}
	y := 10 + int(math.Ceil(*size**dpi/72))
	dy := int(math.Ceil(*size * *spacing * *dpi / 72))
	d.Dot = fixed.Point26_6{
		X: (fixed.I(imgW) - d.MeasureString(title)) / 2,
		Y: fixed.I(y),
	}
	d.DrawString(title)
	y += dy
	for _, s := range text {
		d.Dot = fixed.P(10, y)
		d.DrawString(s)
		y += dy
	}

	// Save that RGBA image to disk.
	outFile, err := os.Create("out.png")
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
	defer outFile.Close()
	b := bufio.NewWriter(outFile)
	err = png.Encode(b, rgba)
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
	err = b.Flush()
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
	fmt.Println("Wrote out.png OK.")
}