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 }