git.lucas.co / go_mono
git clone https://git.lucas.co/go_mono.git

font/sfnt/example_test.go (3.5K)

  1 // Copyright 2017 The Go Authors. All rights reserved.
  2 // Use of this source code is governed by a BSD-style
  3 // license that can be found in the LICENSE file.
  4 
  5 package sfnt_test
  6 
  7 import (
  8 	"image"
  9 	"image/draw"
 10 	"log"
 11 	"os"
 12 
 13 	"golang.org/x/image/font/gofont/goregular"
 14 	"golang.org/x/image/font/sfnt"
 15 	"golang.org/x/image/math/fixed"
 16 	"golang.org/x/image/vector"
 17 )
 18 
 19 func Example_rasterizeGlyph() {
 20 	const (
 21 		ppem    = 32
 22 		width   = 24
 23 		height  = 36
 24 		originX = 0
 25 		originY = 32
 26 	)
 27 
 28 	// Load the 'G' glyph from the Go Regular font.
 29 	f, err := sfnt.Parse(goregular.TTF)
 30 	if err != nil {
 31 		log.Fatalf("Parse: %v", err)
 32 	}
 33 	var b sfnt.Buffer
 34 	x, err := f.GlyphIndex(&b, 'Ġ')
 35 	if err != nil {
 36 		log.Fatalf("GlyphIndex: %v", err)
 37 	}
 38 	if x == 0 {
 39 		log.Fatalf("GlyphIndex: no glyph index found for the rune 'Ġ'")
 40 	}
 41 	segments, err := f.LoadGlyph(&b, x, fixed.I(ppem), nil)
 42 	if err != nil {
 43 		log.Fatalf("LoadGlyph: %v", err)
 44 	}
 45 
 46 	// Translate and scale that glyph as we pass it to a vector.Rasterizer.
 47 	r := vector.NewRasterizer(width, height)
 48 	r.DrawOp = draw.Src
 49 	for _, seg := range segments {
 50 		// The divisions by 64 below is because the seg.Args values have type
 51 		// fixed.Int26_6, a 26.6 fixed point number, and 1<<6 == 64.
 52 		switch seg.Op {
 53 		case sfnt.SegmentOpMoveTo:
 54 			r.MoveTo(
 55 				originX+float32(seg.Args[0].X)/64,
 56 				originY+float32(seg.Args[0].Y)/64,
 57 			)
 58 		case sfnt.SegmentOpLineTo:
 59 			r.LineTo(
 60 				originX+float32(seg.Args[0].X)/64,
 61 				originY+float32(seg.Args[0].Y)/64,
 62 			)
 63 		case sfnt.SegmentOpQuadTo:
 64 			r.QuadTo(
 65 				originX+float32(seg.Args[0].X)/64,
 66 				originY+float32(seg.Args[0].Y)/64,
 67 				originX+float32(seg.Args[1].X)/64,
 68 				originY+float32(seg.Args[1].Y)/64,
 69 			)
 70 		case sfnt.SegmentOpCubeTo:
 71 			r.CubeTo(
 72 				originX+float32(seg.Args[0].X)/64,
 73 				originY+float32(seg.Args[0].Y)/64,
 74 				originX+float32(seg.Args[1].X)/64,
 75 				originY+float32(seg.Args[1].Y)/64,
 76 				originX+float32(seg.Args[2].X)/64,
 77 				originY+float32(seg.Args[2].Y)/64,
 78 			)
 79 		}
 80 	}
 81 
 82 	// Finish the rasterization: the conversion from vector graphics (shapes)
 83 	// to raster graphics (pixels).
 84 	dst := image.NewAlpha(image.Rect(0, 0, width, height))
 85 	r.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
 86 
 87 	// Visualize the pixels.
 88 	const asciiArt = ".++8"
 89 	buf := make([]byte, 0, height*(width+1))
 90 	for y := 0; y < height; y++ {
 91 		for x := 0; x < width; x++ {
 92 			a := dst.AlphaAt(x, y).A
 93 			buf = append(buf, asciiArt[a>>6])
 94 		}
 95 		buf = append(buf, '\n')
 96 	}
 97 	os.Stdout.Write(buf)
 98 
 99 	// Output:
100 	// ........................
101 	// ........................
102 	// ........................
103 	// ............888.........
104 	// ............888.........
105 	// ............888.........
106 	// ............+++.........
107 	// ........................
108 	// ..........+++++++++.....
109 	// .......+8888888888888+..
110 	// ......8888888888888888..
111 	// ....+8888+........++88..
112 	// ....8888................
113 	// ...8888.................
114 	// ..+888+.................
115 	// ..+888..................
116 	// ..888+..................
117 	// .+888+..................
118 	// .+888...................
119 	// .+888...................
120 	// .+888...................
121 	// .+888..........+++++++..
122 	// .+888..........8888888..
123 	// .+888+.........+++8888..
124 	// ..888+............+888..
125 	// ..8888............+888..
126 	// ..+888+...........+888..
127 	// ...8888+..........+888..
128 	// ...+8888+.........+888..
129 	// ....+88888+.......+888..
130 	// .....+8888888888888888..
131 	// .......+888888888888++..
132 	// ..........++++++++......
133 	// ........................
134 	// ........................
135 	// ........................
136 }